This commit is contained in:
Elliot Condon 2018-08-14 10:14:07 +02:00 committed by Remco Tolsma
parent 7eb289e3cb
commit a590a680f8
36 changed files with 2827 additions and 2134 deletions

12
acf.php
View File

@ -3,7 +3,7 @@
Plugin Name: Advanced Custom Fields PRO Plugin Name: Advanced Custom Fields PRO
Plugin URI: https://www.advancedcustomfields.com/ Plugin URI: https://www.advancedcustomfields.com/
Description: Customise WordPress with powerful, professional and intuitive fields. Description: Customise WordPress with powerful, professional and intuitive fields.
Version: 5.7.0 Version: 5.7.2
Author: Elliot Condon Author: Elliot Condon
Author URI: http://www.elliotcondon.com/ Author URI: http://www.elliotcondon.com/
Copyright: Elliot Condon Copyright: Elliot Condon
@ -18,7 +18,7 @@ if( ! class_exists('ACF') ) :
class ACF { class ACF {
/** @var string The plugin version number */ /** @var string The plugin version number */
var $version = '5.7.0'; var $version = '5.7.2';
/** @var array The plugin settings array */ /** @var array The plugin settings array */
var $settings = array(); var $settings = array();
@ -127,7 +127,7 @@ class ACF {
acf_include('includes/api/api-field.php'); acf_include('includes/api/api-field.php');
acf_include('includes/api/api-field-group.php'); acf_include('includes/api/api-field-group.php');
acf_include('includes/api/api-template.php'); acf_include('includes/api/api-template.php');
acf_include('includes/api/api-term.php');
// fields // fields
acf_include('includes/fields.php'); acf_include('includes/fields.php');
@ -141,7 +141,6 @@ class ACF {
// core // core
acf_include('includes/assets.php'); acf_include('includes/assets.php');
acf_include('includes/ajax.php');
acf_include('includes/cache.php'); acf_include('includes/cache.php');
acf_include('includes/compatibility.php'); acf_include('includes/compatibility.php');
acf_include('includes/deprecated.php'); acf_include('includes/deprecated.php');
@ -154,6 +153,11 @@ class ACF {
acf_include('includes/updates.php'); acf_include('includes/updates.php');
acf_include('includes/validation.php'); acf_include('includes/validation.php');
// ajax
acf_include('includes/ajax/class-acf-ajax.php');
acf_include('includes/ajax/class-acf-ajax-user-setting.php');
acf_include('includes/ajax/class-acf-ajax-query.php');
acf_include('includes/ajax/class-acf-ajax-query-terms.php');
// forms // forms
acf_include('includes/forms/form-attachment.php'); acf_include('includes/forms/form-attachment.php');

View File

@ -102,7 +102,6 @@
// initialize // initialize
this.$el = $('#acf-field-key-hide'); this.$el = $('#acf-field-key-hide');
this.addEvents();
// render // render
this.render(); this.render();
@ -247,8 +246,16 @@
return $('#' + this.getInputId() + '-' + name); return $('#' + this.getInputId() + '-' + name);
}, },
$meta: function(){
return this.$('.meta:first');
},
$handle: function(){
return this.$('.handle:first');
},
$settings: function(){ $settings: function(){
return this.$('.acf-field-settings:first > .acf-field'); return this.$('.settings:first');
}, },
$setting: function( name ){ $setting: function( name ){
@ -540,15 +547,16 @@
acf.doAction('submit_field_object', this); acf.doAction('submit_field_object', this);
}, },
onChange: function(){ onChange: function( e, $el ){
//console.log('onChange');
// save settings
this.save(); this.save();
// action for 3rd party customization // action for 3rd party customization
acf.doAction('change_field_object', this); acf.doAction('change_field_object', this);
}, },
onChanged: function( e, name, value ){ onChanged: function( e, $el, name, value ){
// ignore 'save' // ignore 'save'
if( name == 'save' ) { if( name == 'save' ) {
@ -1966,7 +1974,7 @@
$el.sortable({ $el.sortable({
handle: '.acf-sortable-handle', handle: '.acf-sortable-handle',
connectWith: '.acf-field-list', connectWith: '.acf-field-list',
start: function(e, ui){ start: function( e, ui ){
var field = acf.getFieldObject( ui.item ); var field = acf.getFieldObject( ui.item );
ui.placeholder.height( ui.item.height() ); ui.placeholder.height( ui.item.height() );
acf.doAction('sortstart_field_object', field, $el); acf.doAction('sortstart_field_object', field, $el);

File diff suppressed because one or more lines are too long

View File

@ -52,7 +52,7 @@
*/ */
acf.has = function( name ){ acf.has = function( name ){
return this.get(data) !== null; return this.get(name) !== null;
}; };
@ -983,10 +983,13 @@
}; };
*/ */
// Preferences // Preferences
var preferences = localStorage.getItem('acf'); // - use try/catch to avoid JS error if cookies are disabled on front-end form
preferences = preferences ? JSON.parse(preferences) : {}; try {
var preferences = JSON.parse(localStorage.getItem('acf')) || {};
} catch(e) {
var preferences = {};
}
/** /**
@ -1485,14 +1488,15 @@
return false return false
} }
// bail if select option does not exist
if( $input.is('select') && !$input.find('option[value="'+value+'"]').length ) {
return false;
}
// update value // update value
$input.val( value ); $input.val( value );
// prevent select elements displaying blank value if option doesn't exist
if( $input.is('select') && $input.val() === null ) {
$input.val( prevValue );
return false;
}
// update with trigger // update with trigger
if( silent !== true ) { if( silent !== true ) {
$input.trigger('change'); $input.trigger('change');
@ -2092,7 +2096,7 @@
acf.doAction('load'); acf.doAction('load');
}); });
$(window).on('unload', function(){ $(window).on('beforeunload', function(){
acf.doAction('unload'); acf.doAction('unload');
}); });
@ -2762,12 +2766,19 @@
proxyEvent: function( callback ){ proxyEvent: function( callback ){
return this.proxy(function(e){ return this.proxy(function(e){
// validate
if( !this.validateEvent(e) ) { if( !this.validateEvent(e) ) {
return; return;
} }
var args = acf.arrayArgs(arguments);
args.push( $(e.currentTarget) ); // construct args
callback.apply(this, args); var args = acf.arrayArgs( arguments );
var extraArgs = args.slice(1);
var eventArgs = [ e, $(e.currentTarget) ].concat( extraArgs );
// callback
callback.apply(this, eventArgs);
}); });
}, },
@ -4892,10 +4903,18 @@
var fieldsEventManager = new acf.Model({ var fieldsEventManager = new acf.Model({
id: 'fieldsEventManager', id: 'fieldsEventManager',
events: { events: {
'click .acf-field a[href="#"]': 'onClick' 'click .acf-field a[href="#"]': 'onClick',
'change .acf-field': 'onChange'
}, },
onClick: function( e ){ onClick: function( e ){
// prevent default of any link with an href of #
e.preventDefault(); e.preventDefault();
},
onChange: function(){
// preview hack allows post to save with no title or content
$('#_acf_changed').val(1);
} }
}); });
@ -5612,6 +5631,10 @@
return this.$('.search'); return this.$('.search');
}, },
$canvas: function(){
return this.$('.canvas');
},
addClass: function( name ){ addClass: function( name ){
this.$control().addClass( name ); this.$control().addClass( name );
}, },
@ -5729,10 +5752,6 @@
return this.$search().val(); return this.$search().val();
}, },
getCanvas: function(){
return this.$('.canvas');
},
initialize: function(){ initialize: function(){
// bail early if too early // bail early if too early
@ -5770,7 +5789,7 @@
autocomplete: {} autocomplete: {}
}; };
mapArgs = acf.applyFilters('google_map_args', mapArgs, this); mapArgs = acf.applyFilters('google_map_args', mapArgs, this);
var map = new google.maps.Map( this.getCanvas()[0], mapArgs ); var map = new google.maps.Map( this.$canvas()[0], mapArgs );
this.addMapEvents( map, this ); this.addMapEvents( map, this );
@ -5810,15 +5829,17 @@
// bind // bind
autocomplete.bindTo('bounds', map); autocomplete.bindTo('bounds', map);
// event // 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
google.maps.event.addListener(autocomplete, 'place_changed', function() { google.maps.event.addListener(autocomplete, 'place_changed', function() {
field.setPlace( this.getPlace() ); var place = this.getPlace();
place.address = field.getSearchVal();
field.setPlace( place );
}); });
} }
// click // click
google.maps.event.addListener( map, 'click', function( e ) { google.maps.event.addListener( map, 'click', function( e ) {
// vars // vars
var lat = e.latLng.lat(); var lat = e.latLng.lat();
var lng = e.latLng.lng(); var lng = e.latLng.lng();
@ -5832,7 +5853,6 @@
// dragend // dragend
google.maps.event.addListener( marker, 'dragend', function(){ google.maps.event.addListener( marker, 'dragend', function(){
// vars // vars
var position = this.getPosition(); var position = this.getPosition();
var lat = position.lat(); var lat = position.lat();
@ -5901,7 +5921,7 @@
// vars // vars
var lat = place.geometry.location.lat(); var lat = place.geometry.location.lat();
var lng = place.geometry.location.lng(); var lng = place.geometry.location.lng();
var address = place.formatted_address; var address = place.address || place.formatted_address;
// update // update
this.setValue({ this.setValue({
@ -5937,7 +5957,7 @@
$wrap.addClass('-loading'); $wrap.addClass('-loading');
// callback // callback
var callback = $.proxy(function( results, status ){ var callback = this.proxy(function( results, status ){
// remove class // remove class
$wrap.removeClass('-loading'); $wrap.removeClass('-loading');
@ -5954,7 +5974,7 @@
} else { } else {
lat = results[0].geometry.location.lat(); lat = results[0].geometry.location.lat();
lng = results[0].geometry.location.lng(); lng = results[0].geometry.location.lng();
address = results[0].formatted_address; //address = results[0].formatted_address;
} }
// update val // update val
@ -5966,7 +5986,7 @@
//acf.doAction('google_map_geocode_results', results, status, this.$el, this); //acf.doAction('google_map_geocode_results', results, status, this.$el, this);
}, this); });
// query // query
api.geocoder.geocode({ 'address' : address }, callback); api.geocoder.geocode({ 'address' : address }, callback);
@ -6848,8 +6868,8 @@
getValue: function(){ getValue: function(){
var val = this.$input().val(); var val = this.$input().val();
if( val === 'other' ) { if( val === 'other' && this.get('other_choice') ) {
val = this.inputText().val(); val = this.$inputText().val();
} }
return val; return val;
}, },
@ -9734,7 +9754,7 @@
remove: function(){ remove: function(){
this.frame.detach(); this.frame.detach();
this.frame.dispose(); this.frame.remove();
}, },
getFrameOptions: function(){ getFrameOptions: function(){
@ -10105,10 +10125,16 @@
initialize: function(){ initialize: function(){
// bail early if no media views // bail early if no media views
if( !acf.isset(wp, 'media', 'view') ) { if( !acf.isset(window, 'wp', 'media', 'view') ) {
return; return;
} }
// fix bug where CPT without "editor" does not set post.id setting which then prevents uploadedTo from working
var postID = getPostID();
if( postID && acf.isset(wp, 'media', 'view', 'settings', 'post') ) {
wp.media.view.settings.post.id = postID;
}
// customize // customize
this.customizeAttachmentsRouter(); this.customizeAttachmentsRouter();
this.customizeAttachmentFilters(); this.customizeAttachmentFilters();
@ -10215,46 +10241,30 @@
// Each instance will attempt to render when a new modal is created. // Each instance will attempt to render when a new modal is created.
// Use a property to avoid this and only render once per instance. // Use a property to avoid this and only render once per instance.
if( this.rendered ) { if( this.rendered ) {
//console.log('ignore render', this.cid);
return this; return this;
} }
this.rendered = true;
// render // render HTML
//console.log('render', this.cid);
AttachmentCompat.prototype.render.apply( this, arguments ); AttachmentCompat.prototype.render.apply( this, arguments );
// when uploading, render is called twice.
// ignore first render by checking for #acf-form-data element
if( !this.$('#acf-form-data').length ) {
return this;
}
// clear timeout // clear timeout
clearTimeout( timeout ); clearTimeout( timeout );
// setTimeout // setTimeout
timeout = setTimeout($.proxy(function(){ timeout = setTimeout($.proxy(function(){
this.rendered = true;
// check if element is visible to avoid logic on previous instances (which are hidden) acf.doAction('append', this.$el);
if( this.$el.is(':visible') ) {
//console.log('append', this.cid);
acf.doAction('append', this.$el);
}
}, this), 50); }, this), 50);
// return // return
return this; return this;
},
// commented out function causing JS errors when navigating through media grid
// dispose (and remove) are called after the element has been detached, so this only causes extra JS initialization
dispose: function(){
// remove
if( this.$el.is(':visible') ) {
//acf.doAction('remove', this.$el);
console.log('removed visible');
}
// dispose
return AttachmentCompat.prototype.dispose.apply( this, arguments );
} }
}); });
}, },
@ -11296,6 +11306,7 @@
var locale = acf.get('locale'); var locale = acf.get('locale');
var rtl = acf.get('rtl'); var rtl = acf.get('rtl');
var l10n = acf.get('select2L10n'); var l10n = acf.get('select2L10n');
var version = getVersion();
// bail ealry if no l10n // bail ealry if no l10n
if( !l10n ) { if( !l10n ) {
@ -11308,9 +11319,9 @@
} }
// initialize // initialize
if( getVersion() == 4 ) { if( version == 4 ) {
this.addTranslations4(); this.addTranslations4();
} else { } else if( version == 3 ) {
this.addTranslations3(); this.addTranslations3();
} }
}, },
@ -11848,10 +11859,10 @@
}, },
events: { events: {
'click #publish': 'onClickPublish', 'click input[type="submit"]': 'onClickSubmit',
'click #submit': 'onClickPublish', 'click button[type="submit"]': 'onClickSubmit',
'click #save-post': 'onClickSave', 'click #save-post': 'onClickSave',
'submit form': 'onSubmit', 'submit form': 'onSubmit',
}, },
initialize: function(){ initialize: function(){
@ -12075,6 +12086,8 @@
// create event specific success callback // create event specific success callback
if( args.event ) { if( args.event ) {
// create new event to avoid conflicts with prevenDefault (as used in taxonomy form)
var event = $.Event(null, args.event); var event = $.Event(null, args.event);
args.success = function(){ args.success = function(){
$(event.target).trigger( event ); $(event.target).trigger( event );
@ -12083,7 +12096,7 @@
// action for 3rd party // action for 3rd party
acf.doAction('validation_begin', $form); acf.doAction('validation_begin', $form);
// data // data
var data = acf.serialize( $form ); var data = acf.serialize( $form );
data.action = 'acf/validate_save_post'; data.action = 'acf/validate_save_post';
@ -12182,7 +12195,7 @@
addInputEvents: function( $el ){ addInputEvents: function( $el ){
// vars // vars
var $inputs = $('.acf-field [name]'); var $inputs = $('.acf-field [name]', $el);
// check // check
if( $inputs.length ) { if( $inputs.length ) {
@ -12211,19 +12224,15 @@
$form.submit(); $form.submit();
}, },
// fixes bug on User Profile edit form onClickSubmit: function( e, $el ){
// - WP prevents $form.submit() events for unknown reason
// - temp store 'click event' and use later in onSubmit // store the "click event" for later use in this.onSubmit()
onClickPublish: function( e, $el ){
this.set('originalEvent', e); this.set('originalEvent', e);
this.setTimeout(function(){
this.set('originalEvent', null);
}, 100);
}, },
onClickSave: function( e, $el ) { onClickSave: function( e, $el ) {
// ignore errors // ignore errors when saving
this.pass(); this.pass();
}, },
@ -12232,7 +12241,7 @@
// validate // validate
var valid = acf.validateForm({ var valid = acf.validateForm({
form: $form, form: $form,
event: this.get('originalEvent') || e event: this.get('originalEvent')
}); });
// if not valid, stop event and allow validation to continue // if not valid, stop event and allow validation to continue
@ -12293,7 +12302,7 @@
// vars // vars
var $wrap = this.findSubmitWrap( $form ); var $wrap = this.findSubmitWrap( $form );
var $submit = $wrap.find('.button, .acf-button'); var $submit = $wrap.find('.button, [type="submit"]');
var $spinner = $wrap.find('.spinner, .acf-spinner'); var $spinner = $wrap.find('.spinner, .acf-spinner');
// hide all spinners (hides the preview spinner) // hide all spinners (hides the preview spinner)
@ -12308,7 +12317,7 @@
// vars // vars
var $wrap = this.findSubmitWrap( $form ); var $wrap = this.findSubmitWrap( $form );
var $submit = $wrap.find('.button, .acf-button'); var $submit = $wrap.find('.button, [type="submit"]');
var $spinner = $wrap.find('.spinner, .acf-spinner'); var $spinner = $wrap.find('.spinner, .acf-spinner');
// unlock // unlock

File diff suppressed because one or more lines are too long

View File

@ -444,7 +444,7 @@ class acf_admin_field_group {
acf_disable_filters(); acf_disable_filters();
// save fields // save fields
if( !empty($_POST['acf_fields']) ) { if( !empty($_POST['acf_fields']) ) {
// loop // loop
foreach( $_POST['acf_fields'] as $field ) { foreach( $_POST['acf_fields'] as $field ) {

View File

@ -152,32 +152,20 @@
</div> </div>
<?php elseif( $active == 'changelog' ): ?> <?php elseif( $active == 'changelog' ): ?>
<p class="about-description"><?php printf(__("We think you'll love the changes in %s.", 'acf'), $version); ?></p> <p class="about-description"><?php printf(__("We think you'll love the changes in %s.", 'acf'), $version); ?></p>
<?php <?php
$items = file_get_contents( acf_get_path('readme.txt') );
$items = explode('= ' . $version . ' =', $items);
$items = end( $items ); // extract changelog and parse markdown
$items = current( explode("\n\n", $items) ); $readme = file_get_contents( acf_get_path('readme.txt') );
$items = array_filter( array_map('trim', explode("*", $items)) ); $changelog = '';
if( preg_match( '/(= '.$version.' =)(.+?)(=|$)/s', $readme, $match ) && $match[2] ) {
$changelog = acf_parse_markdown( $match[2] );
}
echo acf_parse_markdown($changelog);
?> endif; ?>
<ul class="changelog">
<?php foreach( $items as $item ):
$item = explode('http', $item);
?>
<li><?php echo $item[0]; ?><?php if( isset($item[1]) ): ?><a href="http<?php echo $item[1]; ?>" target="_blank">[...]</a><?php endif; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div> </div>

View File

@ -1,86 +0,0 @@
<?php
/*
* ACF AJAX Class
*
* All the logic for misc AJAX functionality
*
* @class acf_ajax
* @package ACF
* @subpackage Core
*/
if( ! class_exists('acf_ajax') ) :
class acf_ajax {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function __construct() {
// acf/update_user_setting
add_action( 'wp_ajax_acf/update_user_setting', array($this, 'update_user_setting') );
add_action( 'wp_ajax_nopriv_acf/update_user_setting', array($this, 'update_user_setting') );
}
/*
* update_user_setting
*
* This function will update a user setting
*
* @type function
* @date 15/07/2014
* @since 5.0.0
*
* @param $post_id (int)
* @return $post_id (int)
*/
function update_user_setting() {
// options
$options = wp_parse_args( $_POST, array(
'name' => '',
'value' => '',
'nonce' => '',
));
// validate
if( ! wp_verify_nonce($options['nonce'], 'acf_nonce') || empty($options['name']) ) {
die('0');
}
// upadte setting
acf_update_user_setting( $options['name'], $options['value'] );
// return
die('1');
}
}
new acf_ajax();
endif;
?>

View File

@ -0,0 +1,141 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Ajax_Query_Terms') ) :
class ACF_Ajax_Query_Terms extends ACF_Ajax_Query {
/** @var string The AJAX action name */
var $action = 'acf/ajax/query_terms';
/**
* get_args
*
* description
*
* @date 31/7/18
* @since 5.7.2
*
* @param type $var Description. Default.
* @return type Description.
*/
function get_args() {
// defaults
$args = wp_parse_args($this->get('query'), array(
'taxonomy' => 'category',
'search' => $this->search,
'number' => $this->per_page,
));
// pagination
if( $this->page > 0 ) {
$args['offset'] = $this->per_page * ($this->page - 1);
}
// return
return $args;
}
/**
* get_results
*
* description
*
* @date 31/7/18
* @since 5.7.2
*
* @param type $var Description. Default.
* @return type Description.
*/
function get_results( $args ) {
// vars
$results = array();
// get terms
$groups = acf_get_grouped_terms( $args );
// loop
if( $groups ) {
foreach( $groups as $label => $terms ) {
// data
$data = array(
'text' => $label,
'children' => array()
);
// convert object to string
foreach( $terms as $id => $term ) {
$terms[ $id ] = $this->get_result( $term );
}
// order posts by search
if( $this->search && !isset($args['orderby']) ) {
$terms = acf_order_by_search( $terms, $this->search );
}
// append to $data
foreach( $terms as $id => $text ) {
$this->count++;
$data['children'][] = array(
'id' => $id,
'text' => $text
);
}
// append to $results
$results[] = $data;
}}
// extract group children for a single taxonomy
$taxonomies = acf_get_array($args['taxonomy']);
if( count($taxonomies) == 1 ) {
$results = $results[0]['children'];
}
// return
return $results;
}
/**
* get_result
*
* description
*
* @date 31/7/18
* @since 5.7.2
*
* @param type $var Description. Default.
* @return type Description.
*/
function get_result( $term ) {
// vars
$title = $term->name;
// ancestors
$ancestors = get_ancestors( $term->term_id, $term->taxonomy );
if( $ancestors ) {
$prepend = str_repeat('- ', count($ancestors));
return $prepend . $title;
}
// return
return $title;
}
}
acf_new_instance('ACF_AJAX_Query_Terms');
endif; // class_exists check
?>

View File

@ -0,0 +1,133 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Ajax_Query') ) :
class ACF_Ajax_Query extends ACF_Ajax {
/** @var array The ACF field used for querying */
var $field = false;
/** @var int The page of results to return */
var $page = 1;
/** @var int The number of results per page */
var $per_page = 20;
/** @var string The searched term */
var $search = '';
/** @var int The number of results found */
var $count = 0;
/**
* response
*
* The actual logic for this AJAX request.
*
* @date 31/7/18
* @since 5.7.2
*
* @param void
* @return void
*/
function response() {
// field
if( $this->has('field_key') ) {
$this->field = acf_get_field( $this->get('field_key') );
}
// pagination
if( $this->has('paged') ) {
$this->page = (int) $this->get('paged');
}
// search
if( $this->has('s') ) {
$this->search = $this->get('s');
}
// get response
$args = $this->get_args();
$results = $this->get_results($args);
$response = $this->get_response($results, $args);
// return
return $response;
}
/**
* get_args
*
* description
*
* @date 31/7/18
* @since 5.7.2
*
* @param type $var Description. Default.
* @return type Description.
*/
function get_args() {
return array();
}
/**
* get_results
*
* description
*
* @date 31/7/18
* @since 5.7.2
*
* @param type $var Description. Default.
* @return type Description.
*/
function get_results( $args ) {
return array();
}
/**
* get_result
*
* description
*
* @date 31/7/18
* @since 5.7.2
*
* @param type $var Description. Default.
* @return type Description.
*/
function get_result( $item ) {
return '';
}
/**
* get_response
*
* description
*
* @date 31/7/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function get_response( $results, $args ) {
return array(
'results' => $results,
'more' => ($this->count >= $this->per_page)
);
}
}
endif; // class_exists check
?>

View File

@ -0,0 +1,44 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Ajax_User_Setting') ) :
class ACF_Ajax_User_Setting extends ACF_Ajax{
/** @var string The AJAX action name */
var $action = 'acf/update_user_setting';
/** @var bool Prevents access for non-logged in users */
var $public = true;
/**
* get_response
*
* The actual logic for this AJAX request.
*
* @date 31/7/18
* @since 5.7.2
*
* @param void
* @return mixed The response data to send back or WP_Error.
*/
function response() {
// update
if( $this->has('value') ) {
return acf_update_user_setting( $this->get('name'), $this->get('value') );
// get
} else {
return acf_get_user_setting( $this->get('name') );
}
}
}
acf_new_instance('ACF_Ajax_User_Setting');
endif; // class_exists check
?>

View File

@ -0,0 +1,195 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Ajax') ) :
class ACF_Ajax {
/** @var string The AJAX action name */
var $action = '';
/** @var array The $_REQUEST data */
var $request;
/** @var bool Prevents access for non-logged in users */
var $public = false;
/**
* __construct
*
* Sets up the class functionality.
*
* @date 31/7/18
* @since 5.7.2
*
* @param void
* @return void
*/
function __construct() {
// initialize
$this->initialize();
// add actions
$this->add_actions();
}
/**
* initialize
*
* Allows easy access to modifying properties without changing constructor.
*
* @date 31/7/18
* @since 5.7.2
*
* @param void
* @return void
*/
function initialize() {
/* do nothing */
}
/**
* has
*
* Returns true if the request has data for the given key
*
* @date 31/7/18
* @since 5.7.2
*
* @param string $key The data key
* @return boolean
*/
function has( $key = '' ) {
return isset($this->request[$key]);
}
/**
* get
*
* Returns request data for the given key
*
* @date 31/7/18
* @since 5.7.2
*
* @param string $key The data key
* @return mixed
*/
function get( $key = '' ) {
return isset($this->request[$key]) ? $this->request[$key] : null;
}
/**
* set
*
* Sets request data for the given key
*
* @date 31/7/18
* @since 5.7.2
*
* @param string $key The data key
* @return mixed
*/
function set( $key = '', $value ) {
$this->request[$key] = $value;
}
/**
* add_actions
*
* Adds the ajax actions for this response.
*
* @date 31/7/18
* @since 5.7.2
*
* @param void
* @return void
*/
function add_actions() {
// add action for logged-in users
add_action( "wp_ajax_{$this->action}", array($this, 'request') );
// add action for non logged-in users
if( $this->public ) {
add_action( "wp_ajax_nopriv_{$this->action}", array($this, 'request') );
}
}
/**
* request
*
* Callback for ajax action. Sets up properties and calls the get_response() function.
*
* @date 1/8/18
* @since 5.7.2
*
* @param void
* @return void
*/
function request() {
// verify ajax request
if( !acf_verify_ajax() ) {
wp_send_json_error();
}
// store data for has() and get() functions
$this->request = wp_unslash($_REQUEST);
// send response
$this->send( $this->response() );
}
/**
* response
*
* The actual logic for this AJAX request.
*
* @date 31/7/18
* @since 5.7.2
*
* @param void
* @return mixed The response data to send back or WP_Error.
*/
function response() {
return true;
}
/**
* send
*
* Sends back JSON based on the $response as either success or failure.
*
* @date 31/7/18
* @since 5.7.2
*
* @param mixed $response The response to send back.
* @return void
*/
function send( $response ) {
// return error
if( is_wp_error($response) ) {
wp_send_json_error(array( 'error' => $response->get_error_message() ));
// return success
} else {
wp_send_json_success($response);
}
}
}
endif; // class_exists check
?>

View File

@ -1011,93 +1011,40 @@ function acf_untrash_field_group( $selector = 0 ) {
function acf_get_field_group_style( $field_group ) { function acf_get_field_group_style( $field_group ) {
// vars // vars
$e = ''; $style = '';
$elements = array(
'permalink' => '#edit-slug-box',
'the_content' => '#postdivrich',
'excerpt' => '#postexcerpt',
'custom_fields' => '#postcustom',
'discussion' => '#commentstatusdiv',
'comments' => '#commentsdiv',
'slug' => '#slugdiv',
'author' => '#authordiv',
'format' => '#formatdiv',
'page_attributes' => '#pageparentdiv',
'featured_image' => '#postimagediv',
'revisions' => '#revisionsdiv',
'categories' => '#categorydiv',
'tags' => '#tagsdiv-post_tag',
'send-trackbacks' => '#trackbacksdiv'
);
// loop over field group settings and generate list of selectors to hide
// bail early if no array or is empty if( is_array($field_group['hide_on_screen']) ) {
if( !acf_is_array($field_group['hide_on_screen']) ) return $e; $hide = array();
foreach( $field_group['hide_on_screen'] as $k ) {
if( isset($elements[ $k ]) ) {
// add style to html $id = $elements[ $k ];
if( in_array('permalink',$field_group['hide_on_screen']) ) $hide[] = $id;
{ $hide[] = '#screen-meta label[for=' . substr($id, 1) . '-hide]';
$e .= '#edit-slug-box {display: none;} '; }
}
$style = implode(', ', $hide) . ' {display: none;}';
} }
if( in_array('the_content',$field_group['hide_on_screen']) )
{
$e .= '#postdivrich {display: none;} ';
}
if( in_array('excerpt',$field_group['hide_on_screen']) )
{
$e .= '#postexcerpt, #screen-meta label[for=postexcerpt-hide] {display: none;} ';
}
if( in_array('custom_fields',$field_group['hide_on_screen']) )
{
$e .= '#postcustom, #screen-meta label[for=postcustom-hide] { display: none; } ';
}
if( in_array('discussion',$field_group['hide_on_screen']) )
{
$e .= '#commentstatusdiv, #screen-meta label[for=commentstatusdiv-hide] {display: none;} ';
}
if( in_array('comments',$field_group['hide_on_screen']) )
{
$e .= '#commentsdiv, #screen-meta label[for=commentsdiv-hide] {display: none;} ';
}
if( in_array('slug',$field_group['hide_on_screen']) )
{
$e .= '#slugdiv, #screen-meta label[for=slugdiv-hide] {display: none;} ';
}
if( in_array('author',$field_group['hide_on_screen']) )
{
$e .= '#authordiv, #screen-meta label[for=authordiv-hide] {display: none;} ';
}
if( in_array('format',$field_group['hide_on_screen']) )
{
$e .= '#formatdiv, #screen-meta label[for=formatdiv-hide] {display: none;} ';
}
if( in_array('page_attributes',$field_group['hide_on_screen']) )
{
$e .= '#pageparentdiv {display: none;} ';
}
if( in_array('featured_image',$field_group['hide_on_screen']) )
{
$e .= '#postimagediv, #screen-meta label[for=postimagediv-hide] {display: none;} ';
}
if( in_array('revisions',$field_group['hide_on_screen']) )
{
$e .= '#revisionsdiv, #screen-meta label[for=revisionsdiv-hide] {display: none;} ';
}
if( in_array('categories',$field_group['hide_on_screen']) )
{
$e .= '#categorydiv, #screen-meta label[for=categorydiv-hide] {display: none;} ';
}
if( in_array('tags',$field_group['hide_on_screen']) )
{
$e .= '#tagsdiv-post_tag, #screen-meta label[for=tagsdiv-post_tag-hide] {display: none;} ';
}
if( in_array('send-trackbacks',$field_group['hide_on_screen']) )
{
$e .= '#trackbacksdiv, #screen-meta label[for=trackbacksdiv-hide] {display: none;} ';
}
// return // return
return apply_filters('acf/get_field_group_style', $e, $field_group); return apply_filters('acf/get_field_group_style', $style, $field_group);
} }

View File

@ -993,29 +993,18 @@ function acf_verify_nonce( $value) {
function acf_verify_ajax() { function acf_verify_ajax() {
// vars // vars
$action = acf_maybe_get_POST('action'); $nonce = isset($_REQUEST['nonce']) ? $_REQUEST['nonce'] : '';
$nonce = acf_maybe_get_POST('nonce');
// bail early if not acf action
if( !$action || substr($action, 0, 3) !== 'acf' ) {
return false;
}
// bail early if not acf nonce // bail early if not acf nonce
if( !$nonce || !wp_verify_nonce($nonce, 'acf_nonce') ) { if( !$nonce || !wp_verify_nonce($nonce, 'acf_nonce') ) {
return false; return false;
} }
// action for 3rd party customization // action for 3rd party customization
do_action('acf/verify_ajax'); do_action('acf/verify_ajax');
// return // return
return true; return true;
} }
@ -1248,105 +1237,6 @@ function acf_get_terms( $args ) {
} }
/*
* acf_get_taxonomies
*
* This function will return an array of available taxonomies
*
* @type function
* @date 7/10/13
* @since 5.0.0
*
* @param n/a
* @return (array)
*/
function acf_get_taxonomies() {
// get all taxonomies
$taxonomies = get_taxonomies( false, 'objects' );
$ignore = array( 'nav_menu', 'link_category' );
$r = array();
// populate $r
foreach( $taxonomies as $taxonomy )
{
if( in_array($taxonomy->name, $ignore) )
{
continue;
}
$r[ $taxonomy->name ] = $taxonomy->name; //"{$taxonomy->labels->singular_name}"; // ({$taxonomy->name})
}
// return
return $r;
}
function acf_get_pretty_taxonomies( $taxonomies = array() ) {
// get post types
if( empty($taxonomies) ) {
// get all custom post types
$taxonomies = acf_get_taxonomies();
}
// get labels
$ref = array();
$r = array();
foreach( array_keys($taxonomies) as $i ) {
// vars
$taxonomy = acf_extract_var( $taxonomies, $i);
$obj = get_taxonomy( $taxonomy );
$name = $obj->labels->singular_name;
// append to r
$r[ $taxonomy ] = $name;
// increase counter
if( !isset($ref[ $name ]) ) {
$ref[ $name ] = 0;
}
$ref[ $name ]++;
}
// get slugs
foreach( array_keys($r) as $i ) {
// vars
$taxonomy = $r[ $i ];
if( $ref[ $taxonomy ] > 1 ) {
$r[ $i ] .= ' (' . $i . ')';
}
}
// return
return $r;
}
/* /*
* acf_get_taxonomy_terms * acf_get_taxonomy_terms
* *
@ -5335,4 +5225,46 @@ function acf_get_post_templates() {
} }
/**
* acf_parse_markdown
*
* A very basic regex-based Markdown parser function based off [slimdown](https://gist.github.com/jbroadway/2836900).
*
* @date 6/8/18
* @since 5.7.2
*
* @param string $text The string to parse.
* @return string
*/
function acf_parse_markdown( $text = '' ) {
// trim
$text = trim($text);
// rules
$rules = array (
'/=== (.+?) ===/' => '<h2>$1</h2>', // headings
'/== (.+?) ==/' => '<h3>$1</h3>', // headings
'/= (.+?) =/' => '<h4>$1</h4>', // headings
'/\[([^\[]+)\]\(([^\)]+)\)/' => '<a href="$2">$1</a>', // links
'/(\*\*)(.*?)\1/' => '<strong>$2</strong>', // bold
'/(\*)(.*?)\1/' => '<em>$2</em>', // intalic
'/`(.*?)`/' => '<code>$1</code>', // inline code
'/\n\*(.*)/' => "\n<ul>\n\t<li>$1</li>\n</ul>", // ul lists
'/\n[0-9]+\.(.*)/' => "\n<ol>\n\t<li>$1</li>\n</ol>", // ol lists
'/<\/ul>\s?<ul>/' => '', // fix extra ul
'/<\/ol>\s?<ol>/' => '', // fix extra ol
);
foreach( $rules as $k => $v ) {
$text = preg_replace($k, $v, $text);
}
// autop
$text = wpautop($text);
// return
return $text;
}
?> ?>

236
includes/api/api-term.php Normal file
View File

@ -0,0 +1,236 @@
<?php
/*
* acf_get_taxonomies
*
* Returns an array of taxonomy names.
*
* @date 7/10/13
* @since 5.0.0
*
* @param array $args An array of args used in the get_taxonomies() function.
* @return array An array of taxonomy names.
*/
function acf_get_taxonomies( $args = array() ) {
// vars
$taxonomies = array();
// get taxonomy objects
$objects = get_taxonomies( $args, 'objects' );
// loop
foreach( $objects as $i => $object ) {
// bail early if is builtin (WP) private post type
// - nav_menu_item, revision, customize_changeset, etc
if( $object->_builtin && !$object->public ) continue;
// append
$taxonomies[] = $i;
}
// filter
$taxonomies = apply_filters('acf/get_taxonomies', $taxonomies, $args);
// return
return $taxonomies;
}
/*
* acf_get_taxonomy_labels
*
* Returns an array of taxonomies in the format "name => label" for use in a select field.
*
* @date 3/8/18
* @since 5.7.2
*
* @param array $taxonomies Optional. An array of specific taxonomies to return.
* @return array
*/
function acf_get_taxonomy_labels( $taxonomies = array() ) {
// default
if( empty($taxonomies) ) {
$taxonomies = acf_get_taxonomies();
}
// vars
$ref = array();
$data = array();
// loop
foreach( $taxonomies as $taxonomy ) {
// vars
$object = get_taxonomy( $taxonomy );
$label = $object->labels->singular_name;
// append
$data[ $taxonomy ] = $label;
// increase counter
if( !isset($ref[ $label ]) ) {
$ref[ $label ] = 0;
}
$ref[ $label ]++;
}
// show taxonomy name next to label for shared labels
foreach( $data as $taxonomy => $label ) {
if( $ref[$label] > 1 ) {
$data[ $taxonomy ] .= ' (' . $taxonomy . ')';
}
}
// return
return $data;
}
/**
* acf_get_grouped_terms
*
* Returns an array of terms for the given query $args and groups by taxonomy name.
*
* @date 2/8/18
* @since 5.7.2
*
* @param array $args An array of args used in the get_terms() function.
* @return array
*/
function acf_get_grouped_terms( $args ) {
// vars
$data = array();
// defaults
$args = wp_parse_args($args, array(
'taxonomy' => 'category',
'hide_empty' => false,
'update_term_meta_cache' => false,
));
// vars
$taxonomies = acf_get_taxonomy_labels( acf_get_array($args['taxonomy']) );
$is_single = (count($taxonomies) == 1);
// add filter to group results by taxonomy
if( !$is_single ) {
add_filter('terms_clauses', '_acf_terms_clauses', 10, 3);
}
// get terms
$terms = get_terms( $args );
// remove this filter (only once)
if( !$is_single ) {
remove_filter('terms_clauses', '_acf_terms_clauses', 10, 3);
}
// loop
foreach( $taxonomies as $taxonomy => $label ) {
// vars
$this_terms = array();
// populate $this_terms
foreach( $terms as $term ) {
if( $term->taxonomy == $taxonomy ) {
$this_terms[] = $term;
}
}
// bail early if no $items
if( empty($this_terms) ) continue;
// sort into hierachial order
// this will fail if a search has taken place because parents wont exist
if( is_taxonomy_hierarchical($taxonomy) && empty($args['s'])) {
// get all terms from this taxonomy
$all_terms = get_terms(array_merge($args, array(
'number' => 0,
'offset' => 0,
'taxonomy' => $taxonomy
)));
// vars
$length = count($this_terms);
$offset = 0;
// find starting point (offset)
foreach( $all_terms as $i => $term ) {
if( $term->term_id == $this_terms[0]->term_id ) {
$offset = $i;
break;
}
}
// order terms
$parent = acf_maybe_get( $args, 'parent', 0 );
$parent = acf_maybe_get( $args, 'child_of', $parent );
$ordered_terms = _get_term_children( $parent, $all_terms, $taxonomy );
// compare aray lengths
// if $ordered_posts is smaller than $all_posts, WP has lost posts during the get_page_children() function
// this is possible when get_post( $args ) filter out parents (via taxonomy, meta and other search parameters)
if( count($ordered_terms) == count($all_terms) ) {
$this_terms = array_slice($ordered_terms, $offset, $length);
}
}
// populate group
$data[ $label ] = array();
foreach( $this_terms as $term ) {
$data[ $label ][ $term->term_id ] = $term;
}
}
// return
return $data;
}
/**
* _acf_terms_clauses
*
* Used in the 'terms_clauses' filter to order terms by taxonomy name.
*
* @date 2/8/18
* @since 5.7.2
*
* @param array $pieces Terms query SQL clauses.
* @param array $taxonomies An array of taxonomies.
* @param array $args An array of terms query arguments.
* @return array $pieces
*/
function _acf_terms_clauses( $pieces, $taxonomies, $args ) {
// prepend taxonomy to 'orderby' SQL
if( is_array($taxonomies) ) {
$sql = "FIELD(tt.taxonomy,'" . implode("', '", array_map('esc_sql', $taxonomies)) . "')";
$pieces['orderby'] = str_replace("ORDER BY", "ORDER BY $sql,", $pieces['orderby']);
}
// return
return $pieces;
}
/**
* acf_get_pretty_taxonomies
*
* Deprecated in favor of acf_get_taxonomy_labels() function.
*
* @date 7/10/13
* @since 5.0.0
* @deprecated 5.7.2
*/
function acf_get_pretty_taxonomies( $taxonomies = array() ) {
return acf_get_taxonomy_labels( $taxonomies );
}
?>

View File

@ -50,7 +50,7 @@ class acf_field_email extends acf_field {
// vars // vars
$atts = array(); $atts = array();
$keys = array( 'type', 'id', 'class', 'name', 'value', 'placeholder', 'pattern' ); $keys = array( 'type', 'id', 'class', 'name', 'value', 'placeholder', 'pattern' );
$keys2 = array( 'readonly', 'disabled', 'required' ); $keys2 = array( 'readonly', 'disabled', 'required', 'multiple' );
$html = ''; $html = '';

View File

@ -644,6 +644,36 @@ class acf_field__group extends acf_field {
return $sub_fields; return $sub_fields;
} }
/*
* delete_value
*
* Called when deleting this field's value.
*
* @date 1/07/2015
* @since 5.2.3
*
* @param mixed $post_id The post ID being saved
* @param string $meta_key The field name as seen by the DB
* @param array $field The field settings
* @return void
*/
function delete_value( $post_id, $meta_key, $field ) {
// bail ealry if no sub fields
if( empty($field['sub_fields']) ) return null;
// modify names
$field = $this->prepare_field_for_db( $field );
// loop
foreach( $field['sub_fields'] as $sub_field ) {
acf_delete_value( $post_id, $sub_field );
}
}
} }

View File

@ -266,27 +266,16 @@ class acf_field_select extends acf_field {
} }
// prepend empty choice for single inputs // prepend empty choice
$prepend = false; // - only for single selects
if( !$field['multiple'] ) {
// allow null or ajax
if( $field['allow_null'] || $field['ajax'] ) {
$prepend = true;
}
}
// allow null
// - have tried array_merge but this causes keys to re-index if is numeric (post ID's) // - have tried array_merge but this causes keys to re-index if is numeric (post ID's)
if( $prepend ) { if( $field['allow_null'] && !$field['multiple'] ) {
$placeholder = '- ' . $field['placeholder'] . ' -'; $choices = array( '' => "- {$field['placeholder']} -" ) + $choices;
$choices = array( '' => $placeholder ) + $choices;
} }
// clean up choices if using ajax // clean up choices if using ajax
if( $field['ajax'] ) { if( $field['ui'] && $field['ajax'] ) {
$minimal = array(); $minimal = array();
foreach( $value as $key ) { foreach( $value as $key ) {
if( isset($choices[ $key ]) ) { if( isset($choices[ $key ]) ) {

View File

@ -755,7 +755,7 @@ class acf_field_taxonomy extends acf_field {
'instructions' => __('Select the taxonomy to be displayed','acf'), 'instructions' => __('Select the taxonomy to be displayed','acf'),
'type' => 'select', 'type' => 'select',
'name' => 'taxonomy', 'name' => 'taxonomy',
'choices' => acf_get_taxonomies(), 'choices' => acf_get_taxonomy_labels(),
)); ));
@ -856,100 +856,79 @@ class acf_field_taxonomy extends acf_field {
function ajax_add_term() { function ajax_add_term() {
// vars // vars
$args = acf_parse_args($_POST, array( $args = wp_parse_args($_POST, array(
'nonce' => '', 'nonce' => '',
'field_key' => '', 'field_key' => '',
'term_name' => '', 'term_name' => '',
'term_parent' => '' 'term_parent' => ''
)); ));
// verify nonce // verify nonce
if( ! wp_verify_nonce($args['nonce'], 'acf_nonce') ) { if( !acf_verify_ajax() ) {
die(); die();
}
}
// load field // load field
$field = acf_get_field( $args['field_key'] ); $field = acf_get_field( $args['field_key'] );
if( !$field ) { if( !$field ) {
die(); die();
} }
// vars // vars
$taxonomy_obj = get_taxonomy($field['taxonomy']); $taxonomy_obj = get_taxonomy($field['taxonomy']);
$taxonomy_label = $taxonomy_obj->labels->singular_name; $taxonomy_label = $taxonomy_obj->labels->singular_name;
// validate cap // validate cap
// note: this situation should never occur due to condition of the add new button // note: this situation should never occur due to condition of the add new button
if( !current_user_can( $taxonomy_obj->cap->manage_terms) ) { if( !current_user_can( $taxonomy_obj->cap->manage_terms) ) {
wp_send_json_error(array(
echo '<p><strong>' . __("Error.", 'acf') . '</strong> ' . sprintf( __('User unable to add new %s', 'acf'), $taxonomy_label ) . '</p>'; 'error' => sprintf( __('User unable to add new %s', 'acf'), $taxonomy_label )
die; ));
} }
// save? // save?
if( $args['term_name'] ) { if( $args['term_name'] ) {
// exists // exists
if( term_exists($args['term_name'], $field['taxonomy']) ) { if( term_exists($args['term_name'], $field['taxonomy'], $args['term_parent']) ) {
wp_send_json_error(array( wp_send_json_error(array(
'error' => sprintf( __('%s already exists', 'acf'), $taxonomy_label ) 'error' => sprintf( __('%s already exists', 'acf'), $taxonomy_label )
)); ));
} }
// vars
$extra = array();
if( $args['term_parent'] ) {
$extra['parent'] = (int) $args['term_parent'];
}
// insert // insert
$extra = array();
if( $args['term_parent'] ) {
$extra['parent'] = $args['term_parent'];
}
$data = wp_insert_term( $args['term_name'], $field['taxonomy'], $extra ); $data = wp_insert_term( $args['term_name'], $field['taxonomy'], $extra );
// error
// error?
if( is_wp_error($data) ) { if( is_wp_error($data) ) {
wp_send_json_error(array( wp_send_json_error(array(
'error' => $data->get_error_message() 'error' => $data->get_error_message()
)); ));
} }
// load term
$term = get_term($data['term_id']);
// ancestors // prepend ancenstors count to term name
$prefix = ''; $prefix = '';
$ancestors = get_ancestors( $data['term_id'], $field['taxonomy'] ); $ancestors = get_ancestors( $term->term_id, $term->taxonomy );
if( !empty($ancestors) ) { if( !empty($ancestors) ) {
$prefix = str_repeat('- ', count($ancestors)); $prefix = str_repeat('- ', count($ancestors));
} }
// success // success
wp_send_json_success(array( wp_send_json_success(array(
'message' => sprintf( __('%s added', 'acf'), $taxonomy_label ), 'message' => sprintf( __('%s added', 'acf'), $taxonomy_label ),
'term_id' => $data['term_id'], 'term_id' => $term->term_id,
'term_name' => $args['term_name'], 'term_name' => $term->name,
'term_label' => $prefix . $args['term_name'], 'term_label' => $prefix . $term->name,
'term_parent' => $args['term_parent'] 'term_parent' => $term->parent
)); ));
} }

View File

@ -216,24 +216,21 @@ acf.unload.active = 0;
function save_attachment( $post, $attachment ) { function save_attachment( $post, $attachment ) {
// bail early if not valid nonce // bail early if not valid nonce
if( ! acf_verify_nonce('attachment') ) { if( !acf_verify_nonce('attachment') ) {
return $post; return $post;
} }
// bypass validation for ajax
// validate and save if( acf_is_ajax('save-attachment-compat') ) {
if( acf_validate_save_post(true) ) {
acf_save_post( $post['ID'] ); acf_save_post( $post['ID'] );
}
// validate and save
} elseif( acf_validate_save_post(true) ) {
acf_save_post( $post['ID'] );
}
// return // return
return $post; return $post;
} }

View File

@ -25,7 +25,7 @@ class acf_form_nav_menu {
add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts')); add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
add_action('wp_update_nav_menu', array($this, 'update_nav_menu')); add_action('wp_update_nav_menu', array($this, 'update_nav_menu'));
add_action('acf/validate_save_post', array($this, 'acf_validate_save_post'), 5); add_action('acf/validate_save_post', array($this, 'acf_validate_save_post'), 5);
add_action('wp_nav_menu_item_custom_fields', array($this, 'wp_nav_menu_item_custom_fields'), 10, 5);
// filters // filters
add_filter('wp_get_nav_menu_items', array($this, 'wp_get_nav_menu_items'), 10, 3); add_filter('wp_get_nav_menu_items', array($this, 'wp_get_nav_menu_items'), 10, 3);
@ -64,6 +64,65 @@ class acf_form_nav_menu {
} }
/**
* wp_nav_menu_item_custom_fields
*
* description
*
* @date 30/7/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function wp_nav_menu_item_custom_fields( $item_id, $item, $depth, $args, $id = '' ) {
// vars
$prefix = "menu-item-acf[$item_id]";
// get field groups
$field_groups = acf_get_field_groups(array(
'nav_menu_item' => $item->type
));
// render
if( !empty($field_groups) ) {
// open
echo '<div class="acf-menu-item-fields acf-fields -clear">';
// loop
foreach( $field_groups as $field_group ) {
// load fields
$fields = acf_get_fields( $field_group );
// bail if not fields
if( empty($fields) ) continue;
// change prefix
acf_prefix_fields( $fields, $prefix );
// render
acf_render_fields( $fields, $item_id, 'div', $field_group['instruction_placement'] );
}
// close
echo '</div>';
// Trigger append for newly created menu item (via AJAX)
if( acf_is_ajax('add-menu-item') ): ?>
<script type="text/javascript">
(function($) {
acf.doAction('append', $('#menu-item-settings-<?php echo $item_id; ?>') );
})(jQuery);
</script>
<?php endif;
}
}
/* /*
* update_nav_menu * update_nav_menu
* *

View File

@ -157,7 +157,7 @@ class ACF_Form_User {
// render // render
$this->render(array( $this->render(array(
'user_id' => 0, 'user_id' => 0,
'view' => 'new', 'view' => 'add',
'el' => 'tr' 'el' => 'tr'
)); ));
} }

View File

@ -256,7 +256,6 @@ class acf_form_widget {
*/ */
function admin_footer() { function admin_footer() {
?> ?>
<script type="text/javascript"> <script type="text/javascript">
(function($) { (function($) {
@ -264,11 +263,12 @@ class acf_form_widget {
// vars // vars
acf.set('post_id', 'widgets'); acf.set('post_id', 'widgets');
// restrict get fields // Only initialize visible fields.
// - check for #widgets-right as this does not exist in accessibility mode
acf.addFilter('find_fields_args', function( args ){ acf.addFilter('find_fields_args', function( args ){
// add parent // add parent
if( !args.parent ) { if( !args.parent && $('#widgets-right').length ) {
args.parent = $('#widgets-right'); args.parent = $('#widgets-right');
} }

View File

@ -77,7 +77,7 @@ class acf_location_taxonomy extends acf_location {
// vars // vars
$choices = array( 'all' => __('All', 'acf') ); $choices = array( 'all' => __('All', 'acf') );
$choices = array_merge( $choices, acf_get_taxonomies() ); $choices = array_merge( $choices, acf_get_taxonomy_labels() );
// return // return

View File

@ -2,56 +2,53 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_updates') ) : if( ! class_exists('ACF_Updates') ) :
class acf_updates { class ACF_Updates {
// vars /** @var string The ACF_Updates version */
var $version = '2.3', var $version = '2.4';
$plugins = array(),
$force_check = false,
$dev = 0;
/** @var array The array of registered plugins */
var $plugins = array();
/** @var boolean Dev mode */
var $dev = false;
/** @var int Counts the number of plugin update checks */
var $checked = 0;
/* /*
* __construct * __construct
* *
* This function will setup the class functionality * Sets up the class functionality.
* *
* @type function
* @date 5/03/2014 * @date 5/03/2014
* @since 5.0.0 * @since 5.0.0
* *
* @param n/a * @param void
* @return n/a * @return void
*/ */
function __construct() { function __construct() {
// vars
$this->force_check = !empty($_GET['force-check']);
// append update information to transient // append update information to transient
add_filter('pre_set_site_transient_update_plugins', array($this, 'modify_plugins_transient'), 10, 1); add_filter('pre_set_site_transient_update_plugins', array($this, 'modify_plugins_transient'), 10, 1);
// modify plugin data visible in the 'View details' popup // modify plugin data visible in the 'View details' popup
add_filter('plugins_api', array($this, 'modify_plugin_details'), 10, 3); add_filter('plugins_api', array($this, 'modify_plugin_details'), 10, 3);
} }
/* /*
* add_plugin * add_plugin
* *
* This function will register a plugin * Registeres a plugin for updates.
* *
* @type function
* @date 8/4/17 * @date 8/4/17
* @since 5.5.10 * @since 5.5.10
* *
* @param $plugin (array) * @param array $plugin The plugin array.
* @return n/a * @return void
*/ */
function add_plugin( $plugin ) { function add_plugin( $plugin ) {
@ -76,20 +73,40 @@ class acf_updates {
$this->plugins[ $plugin['basename'] ] = $plugin; $this->plugins[ $plugin['basename'] ] = $plugin;
} }
} }
/**
* get_plugin_by
*
* Returns a registered plugin for the give key and value.
*
* @date 3/8/18
* @since 5.7.2
*
* @param string $key The array key to compare
* @param string $value The value to compare against
* @return array|false
*/
function get_plugin_by( $key = '', $value = null ) {
foreach( $this->plugins as $plugin ) {
if( $plugin[$key] === $value ) {
return $plugin;
}
}
return false;
}
/* /*
* request * request
* *
* This function will make a request to the ACF update server * Makes a request to the ACF connect server.
* *
* @type function
* @date 8/4/17 * @date 8/4/17
* @since 5.5.10 * @since 5.5.10
* *
* @param $query (string) * @param string $query The api path. Defaults to 'index.php'
* @param $body (array) * @param array $body The body to post
* @return (mixed) * @return array|string|WP_Error
*/ */
function request( $query = 'index.php', $body = null ) { function request( $query = 'index.php', $body = null ) {
@ -130,33 +147,30 @@ class acf_updates {
return $json; return $json;
} }
/* /*
* get_plugin_info * get_plugin_info
* *
* This function will get plugin info and save as transient * Returns update information for the given plugin id.
* *
* @type function
* @date 9/4/17 * @date 9/4/17
* @since 5.5.10 * @since 5.5.10
* *
* @param $id (string) * @param string $id The plugin id such as 'pro'.
* @return (mixed) * @param boolean $force_check Bypasses cached result. Defaults to false.
* @return array|WP_Error
*/ */
function get_plugin_info( $id = '' ) { function get_plugin_info( $id = '', $force_check = false ) {
// var // var
$transient_name = 'acf_plugin_info_' . $id; $transient_name = 'acf_plugin_info_' . $id;
// ignore cache (only once) // check cache but allow for $force_check override
if( $this->force_check ) { if( !$force_check ) {
$this->force_check = false; $transient = get_transient( $transient_name );
if( $transient !== false ) {
// check cache return $transient;
} else { }
$transient = get_transient($transient_name);
if( $transient !== false ) return $transient;
} }
// connect // connect
@ -171,38 +185,78 @@ class acf_updates {
$expiration = $this->get_expiration($response, DAY_IN_SECONDS, MONTH_IN_SECONDS); $expiration = $this->get_expiration($response, DAY_IN_SECONDS, MONTH_IN_SECONDS);
// update transient // update transient
set_transient($transient_name, $response, $expiration ); set_transient( $transient_name, $response, $expiration );
// return // return
return $response; return $response;
} }
/**
* get_plugin_update
*
* Returns specific data from the 'update-check' response.
*
* @date 3/8/18
* @since 5.7.2
*
* @param string $basename The plugin basename.
* @param boolean $force_check Bypasses cached result. Defaults to false
* @return array
*/
function get_plugin_update( $basename = '', $force_check = false ) {
// get updates
$updates = $this->get_plugin_updates( $force_check );
// check for and return update
if( is_array($updates) && isset($updates['plugins'][ $basename ]) ) {
return $updates['plugins'][ $basename ];
}
return false;
}
/** /**
* get_plugin_updates * get_plugin_updates
* *
* description * Checks for plugin updates.
* *
* @date 8/7/18 * @date 8/7/18
* @since 5.6.9 * @since 5.6.9
* @since 5.7.2 Added 'checked' comparison
* *
* @param type $var Description. Default. * @param boolean $force_check Bypasses cached result. Defaults to false.
* @return type Description. * @return array|WP_Error.
*/ */
function get_plugin_updates() { function get_plugin_updates( $force_check = false ) {
// var // var
$transient_name = 'acf_plugin_updates'; $transient_name = 'acf_plugin_updates';
// ignore cache (only once) // construct array of 'checked' plugins
if( $this->force_check ) { // sort by key to avoid detecting change due to "include order"
$this->force_check = false; $checked = array();
foreach( $this->plugins as $basename => $plugin ) {
// check cache $checked[ $basename ] = $plugin['version'];
} else { }
ksort($checked);
// $force_check prevents transient lookup
if( !$force_check ) {
$transient = get_transient($transient_name); $transient = get_transient($transient_name);
if( $transient !== false ) return $transient;
// if cached response was found, compare $transient['checked'] against $checked and ignore if they don't match (plugins/versions have changed)
if( is_array($transient) ) {
$transient_checked = isset($transient['checked']) ? $transient['checked'] : array();
if( wp_json_encode($checked) !== wp_json_encode($transient_checked) ) {
$transient = false;
}
}
if( $transient !== false ) {
return $transient;
}
} }
// vars // vars
@ -224,6 +278,11 @@ class acf_updates {
// request // request
$response = $this->request('v2/plugins/update-check', $post); $response = $this->request('v2/plugins/update-check', $post);
// append checked reference
if( is_array($response) ) {
$response['checked'] = $checked;
}
// allow json to include expiration but force minimum and max for safety // allow json to include expiration but force minimum and max for safety
$expiration = $this->get_expiration($response, DAY_IN_SECONDS, MONTH_IN_SECONDS); $expiration = $this->get_expiration($response, DAY_IN_SECONDS, MONTH_IN_SECONDS);
@ -237,7 +296,7 @@ class acf_updates {
/** /**
* get_expiration * get_expiration
* *
* This function safely gets the expiration value from a response * This function safely gets the expiration value from a response.
* *
* @date 8/7/18 * @date 8/7/18
* @since 5.6.9 * @since 5.6.9
@ -275,40 +334,29 @@ class acf_updates {
/* /*
* refresh_plugins_transient * refresh_plugins_transient
* *
* This function will refresh plugin update info to the transient * Deletes transients and allows a fresh lookup.
* *
* @type function
* @date 11/4/17 * @date 11/4/17
* @since 5.5.10 * @since 5.5.10
* *
* @param n/a * @param void
* @return n/a * @return void
*/ */
function refresh_plugins_transient() { function refresh_plugins_transient() {
delete_site_transient('update_plugins');
// vars delete_transient('acf_plugin_updates');
$transient = get_site_transient('update_plugins');
// bail early if no transient
if( empty($transient) ) return;
// update (will trigger modify function)
$this->force_check = true;
set_site_transient( 'update_plugins', $transient );
} }
/* /*
* modify_plugins_transient * modify_plugins_transient
* *
* This function will connect to the ACF website and find update information * Called when WP updates the 'update_plugins' site transient. Used to inject ACF plugin update info.
* *
* @type function
* @date 16/01/2014 * @date 16/01/2014
* @since 5.0.0 * @since 5.0.0
* *
* @param $transient (object) * @param object $transient
* @return $transient * @return $transient
*/ */
@ -319,8 +367,11 @@ class acf_updates {
return $transient; return $transient;
} }
// force-check (only once)
$force_check = ($this->checked == 0) ? !empty($_GET['force-check']) : false;
// fetch updates (this filter is called multiple times during a single page load) // fetch updates (this filter is called multiple times during a single page load)
$updates = $this->get_plugin_updates(); $updates = $this->get_plugin_updates( $force_check );
// append // append
if( is_array($updates) ) { if( is_array($updates) ) {
@ -329,23 +380,24 @@ class acf_updates {
} }
} }
// increase
$this->checked++;
// return // return
return $transient; return $transient;
} }
/* /*
* modify_plugin_details * modify_plugin_details
* *
* This function will populate the plugin data visible in the 'View details' popup * Returns the plugin data visible in the 'View details' popup
* *
* @type function
* @date 17/01/2014 * @date 17/01/2014
* @since 5.0.0 * @since 5.0.0
* *
* @param $result (bool|object) * @param object $result
* @param $action (string) * @param string $action
* @param $args (object) * @param object $args
* @return $result * @return $result
*/ */
@ -354,39 +406,25 @@ class acf_updates {
// vars // vars
$plugin = false; $plugin = false;
// only for 'plugin_information' action // only for 'plugin_information' action
if( $action !== 'plugin_information' ) return $result; if( $action !== 'plugin_information' ) return $result;
// find plugin via slug // find plugin via slug
foreach( $this->plugins as $p ) { $plugin = $this->get_plugin_by('slug', $args->slug);
if( $args->slug == $p['slug'] ) $plugin = $p;
}
// bail early if plugin not found
if( !$plugin ) return $result; if( !$plugin ) return $result;
// connect // connect
$response = $this->get_plugin_info($plugin['id']); $response = $this->get_plugin_info($plugin['id']);
// bail early if no response // bail early if no response
if( !is_array($response) ) return $result; if( !is_array($response) ) return $result;
// remove tags (different context) // remove tags (different context)
unset($response['tags']); unset($response['tags']);
// convert to object // convert to object
$response = (object) $response; $response = (object) $response;
// sections // sections
$sections = array( $sections = array(
'description' => '', 'description' => '',
@ -394,21 +432,14 @@ class acf_updates {
'changelog' => '', 'changelog' => '',
'upgrade_notice' => '' 'upgrade_notice' => ''
); );
foreach( $sections as $k => $v ) { foreach( $sections as $k => $v ) {
$sections[ $k ] = $response->$k; $sections[ $k ] = $response->$k;
} }
$response->sections = $sections; $response->sections = $sections;
// return // return
return $response; return $response;
}
}
} }
@ -420,49 +451,39 @@ class acf_updates {
* *
* Example: <?php $acf_updates = acf_updates(); ?> * Example: <?php $acf_updates = acf_updates(); ?>
* *
* @type function
* @date 9/4/17 * @date 9/4/17
* @since 5.5.12 * @since 5.5.12
* *
* @param n/a * @param void
* @return (object) * @return object
*/ */
function acf_updates() { function acf_updates() {
global $acf_updates; global $acf_updates;
if( !isset($acf_updates) ) { if( !isset($acf_updates) ) {
$acf_updates = new ACF_Updates();
$acf_updates = new acf_updates();
} }
return $acf_updates; return $acf_updates;
} }
/* /*
* acf_register_plugin_update * acf_register_plugin_update
* *
* alias of acf_updates()->add_plugin() * Alias of acf_updates()->add_plugin().
* *
* @type function * @type function
* @date 12/4/17 * @date 12/4/17
* @since 5.5.10 * @since 5.5.10
* *
* @param $post_id (int) * @param array $plugin
* @return $post_id (int) * @return void
*/ */
function acf_register_plugin_update( $plugin ) { function acf_register_plugin_update( $plugin ) {
acf_updates()->add_plugin( $plugin );
acf_updates()->add_plugin( $plugin );
} }
endif; // class_exists check endif; // class_exists check
?> ?>

View File

@ -5,142 +5,70 @@ if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Walker_Nav_Menu_Edit') ) : if( ! class_exists('ACF_Walker_Nav_Menu_Edit') ) :
class ACF_Walker_Nav_Menu_Edit extends Walker_Nav_Menu_Edit { class ACF_Walker_Nav_Menu_Edit extends Walker_Nav_Menu_Edit {
/* /**
* __construct * Starts the element output.
* *
* This function will setup the class functionality * Calls the Walker_Nav_Menu_Edit start_el function and then injects the custom field HTML
* *
* @type function * @since 5.0.0
* @date 5/03/2014 * @since 5.7.2 Added preg_replace based on https://github.com/ineagu/wp-menu-item-custom-fields
* @since 5.0.0 *
* * @param string $output Used to append additional content (passed by reference).
* @param n/a * @param WP_Post $item Menu item data object.
* @return n/a * @param int $depth Depth of menu item. Used for padding.
*/ * @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $id Current item ID.
function __construct() { */
function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
/* do nothing */ // vars
$item_output = '';
// call parent function
parent::start_el( $item_output, $item, $depth, $args, $id );
// inject custom field HTML
$output .= preg_replace(
// NOTE: Check this regex from time to time!
'/(?=<(fieldset|p)[^>]+class="[^"]*field-move)/',
$this->get_fields( $item, $depth, $args, $id ),
$item_output
);
} }
/** /**
* Start the element output. * Get custom fields HTML
* *
* @see Walker_Nav_Menu::start_el() * @since 5.0.0
* @since 3.0.0 * @since 5.7.2 Added action based on https://github.com/ineagu/wp-menu-item-custom-fields
* *
* @global int $_wp_nav_menu_max_depth
*
* @param string $output Passed by reference. Used to append additional content.
* @param object $item Menu item data object. * @param object $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding. * @param int $depth Depth of menu item. Used for padding.
* @param array $args Not used. * @param array $args Menu item args.
* @param int $id Not used. * @param int $id Nav menu ID.
* @return string
*/ */
function get_fields( $item, $depth, $args = array(), $id = 0 ) {
function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
// get origional html
$html = '';
parent::start_el( $html, $item, $depth, $args, $id );
// explode at <fieldset>
$search = '<fieldset class="field-move';
$pos = strpos($html, $search);
$before = substr($html, 0, $pos);
$after = substr($html, $pos);
// inject
$html = $before . $this->get_fields($item) . $after;
// append
$output .= $html;
}
/*
* get_fields
*
* description
*
* @type function
* @date 26/5/17
* @since 5.6.0
*
* @param $post_id (int)
* @return $post_id (int)
*/
function get_fields( $item ) {
// ob
ob_start(); ob_start();
// vars
$prefix = 'menu-item-acf['.$item->ID.']';
$post_id = $item->ID;
/**
// get field groups * Get menu item custom fields from plugins/themes
$field_groups = acf_get_field_groups(array( *
'nav_menu_item' => $item->type * @since 5.7.2
)); *
* @param int $item_id post ID of menu
* @param object $item Menu item data object.
// render * @param int $depth Depth of menu item. Used for padding.
if( !empty($field_groups) ) { * @param array $args Menu item args.
* @param int $id Nav menu ID.
echo '<div class="acf-menu-item-fields acf-fields -clear">'; */
do_action( 'wp_nav_menu_item_custom_fields', $item->ID, $item, $depth, $args, $id );
// loop
foreach( $field_groups as $field_group ) {
// load fields
$fields = acf_get_fields( $field_group );
// bail if not fields
if( empty($fields) ) continue;
// change prefix
acf_prefix_fields( $fields, $prefix );
// render
acf_render_fields( $fields, $post_id, 'div', $field_group['instruction_placement'] );
}
echo '</div>';
// Trigger append for newly created menu item (via AJAX)
if( acf_is_ajax('add-menu-item') ): ?>
<script type="text/javascript">
(function($) {
acf.doAction('append', jQuery('#menu-item-settings-<?php echo $post_id; ?>') );
})(jQuery);
</script>
<?php endif;
}
// return
return ob_get_clean(); return ob_get_clean();
}
}
} }
endif; endif;
?> ?>

Binary file not shown.

View File

@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: Advanced Custom Fields Pro v5.2.9\n" "Project-Id-Version: Advanced Custom Fields Pro v5.2.9\n"
"Report-Msgid-Bugs-To: http://support.advancedcustomfields.com\n" "Report-Msgid-Bugs-To: http://support.advancedcustomfields.com\n"
"POT-Creation-Date: 2018-04-16 17:11+1000\n" "POT-Creation-Date: 2018-04-16 17:11+1000\n"
"PO-Revision-Date: 2018-04-30 05:17+0200\n" "PO-Revision-Date: 2018-07-16 09:34+1000\n"
"Last-Translator: Elliot Condon <e@elliotcondon.com>\n" "Last-Translator: Elliot Condon <e@elliotcondon.com>\n"
"Language-Team: Elliot Condon <e@elliotcondon.com>\n" "Language-Team: Elliot Condon <e@elliotcondon.com>\n"
"Language: it_IT\n" "Language: it_IT\n"
@ -11,7 +11,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.0.6\n" "X-Generator: Poedit 1.8.1\n"
"X-Loco-Target-Locale: it_IT\n" "X-Loco-Target-Locale: it_IT\n"
"X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;" "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
@ -864,7 +864,7 @@ msgstr "Formato"
#: includes/admin/views/field-group-options.php:125 #: includes/admin/views/field-group-options.php:125
msgid "Page Attributes" msgid "Page Attributes"
msgstr "Atrributi Pagina" msgstr "Attributi di Pagina"
#: includes/admin/views/field-group-options.php:126 #: includes/admin/views/field-group-options.php:126
#: includes/fields/class-acf-field-relationship.php:671 #: includes/fields/class-acf-field-relationship.php:671
@ -1497,7 +1497,8 @@ msgstr "Relazionale"
msgid "jQuery" msgid "jQuery"
msgstr "jQuery" msgstr "jQuery"
#: includes/fields.php:149 includes/fields/class-acf-field-button-group.php:177 #: includes/fields.php:149
#: includes/fields/class-acf-field-button-group.php:177
#: includes/fields/class-acf-field-checkbox.php:389 #: includes/fields/class-acf-field-checkbox.php:389
#: includes/fields/class-acf-field-group.php:474 #: includes/fields/class-acf-field-group.php:474
#: includes/fields/class-acf-field-radio.php:290 #: includes/fields/class-acf-field-radio.php:290
@ -2787,8 +2788,8 @@ msgstr "Modifica Field Group"
msgid "Validate Email" msgid "Validate Email"
msgstr "Valida Email" msgstr "Valida Email"
#: includes/forms/form-front.php:103 pro/fields/class-acf-field-gallery.php:573 #: includes/forms/form-front.php:103
#: pro/options-page.php:81 #: pro/fields/class-acf-field-gallery.php:573 pro/options-page.php:81
msgid "Update" msgid "Update"
msgstr "Aggiorna" msgstr "Aggiorna"

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: Advanced Custom Fields Pro v5.2.9\n" "Project-Id-Version: Advanced Custom Fields Pro v5.2.9\n"
"Report-Msgid-Bugs-To: http://support.advancedcustomfields.com\n" "Report-Msgid-Bugs-To: http://support.advancedcustomfields.com\n"
"POT-Creation-Date: 2017-10-24 23:11+0300\n" "POT-Creation-Date: 2017-10-24 23:11+0300\n"
"PO-Revision-Date: 2018-02-06 10:06+1000\n" "PO-Revision-Date: 2018-07-25 10:10+1000\n"
"Last-Translator: Elliot Condon <e@elliotcondon.com>\n" "Last-Translator: Elliot Condon <e@elliotcondon.com>\n"
"Language-Team: \n" "Language-Team: \n"
"Language: ru_RU\n" "Language: ru_RU\n"
@ -1384,7 +1384,7 @@ msgstr "red : Красный"
#: includes/fields/class-acf-field-taxonomy.php:793 #: includes/fields/class-acf-field-taxonomy.php:793
#: includes/fields/class-acf-field-user.php:408 #: includes/fields/class-acf-field-user.php:408
msgid "Allow Null?" msgid "Allow Null?"
msgstr "Разрешить пусто значение?" msgstr "Разрешить пустое значение?"
#: includes/fields/class-acf-field-button-group.php:168 #: includes/fields/class-acf-field-button-group.php:168
#: includes/fields/class-acf-field-checkbox.php:375 #: includes/fields/class-acf-field-checkbox.php:375
@ -2151,7 +2151,7 @@ msgstr "Все таксономии"
#: includes/fields/class-acf-field-page_link.php:523 #: includes/fields/class-acf-field-page_link.php:523
msgid "Allow Archives URLs" msgid "Allow Archives URLs"
msgstr "Рвзрешить ссылки на архивы" msgstr "Разрешить ссылки на архивы"
#: includes/fields/class-acf-field-page_link.php:533 #: includes/fields/class-acf-field-page_link.php:533
#: includes/fields/class-acf-field-post_object.php:422 #: includes/fields/class-acf-field-post_object.php:422

View File

@ -185,17 +185,13 @@ class acf_admin_settings_updates {
// activate // activate
if( acf_verify_nonce('activate_pro_licence') ) { if( acf_verify_nonce('activate_pro_licence') ) {
$this->activate_pro_licence(); $this->activate_pro_licence();
// deactivate // deactivate
} elseif( acf_verify_nonce('deactivate_pro_licence') ) { } elseif( acf_verify_nonce('deactivate_pro_licence') ) {
$this->deactivate_pro_licence(); $this->deactivate_pro_licence();
} }
// vars // vars
$license = acf_pro_get_license_key(); $license = acf_pro_get_license_key();
$this->view = array( $this->view = array(
@ -208,23 +204,18 @@ class acf_admin_settings_updates {
'upgrade_notice' => '' 'upgrade_notice' => ''
); );
// get plugin updates
// vars $force_check = !empty( $_GET['force-check'] );
$info = acf_updates()->get_plugin_info('pro'); $info = acf_updates()->get_plugin_info('pro', $force_check);
// error // error
if( is_wp_error($info) ) { if( is_wp_error($info) ) {
return $this->show_error( $info ); return $this->show_error( $info );
} }
// add info to view // add info to view
$this->view['remote_version'] = $info['version']; $this->view['remote_version'] = $info['version'];
// add changelog if the remote version is '>' than the current version // add changelog if the remote version is '>' than the current version
$version = acf_get_setting('version'); $version = acf_get_setting('version');
@ -236,50 +227,19 @@ class acf_admin_settings_updates {
$this->view['changelog'] = $this->get_changelog_section($info['changelog'], $info['version']); $this->view['changelog'] = $this->get_changelog_section($info['changelog'], $info['version']);
$this->view['upgrade_notice'] = $this->get_changelog_section($info['upgrade_notice'], $info['version']); $this->view['upgrade_notice'] = $this->get_changelog_section($info['upgrade_notice'], $info['version']);
// refresh transient if:
// refresh transient // a) A license is active (can get update)
// - avoids new version not available in plugin update list // b) No update exists, or the update version is stale
// - only request if license is active $basename = acf_get_setting('basename');
$update = acf_updates()->get_plugin_update( $basename );
if( $license ) { if( $license ) {
$this->refresh_plugins_transient(); if( !$update || $update['new_version'] !== $info['version'] ) {
acf_updates()->refresh_plugins_transient();
}
} }
} }
} }
/**
* refresh_plugins_transient
*
* Checks the site transient 'update_plugins' and compares the cached new_version against the plugin-info version.
* If the cached version is older, a new version is available, and the transient is refreshed.
*
* @date 12/7/18
* @since 5.6.9
*
* @param void
* @return void
*/
function refresh_plugins_transient() {
// vars
$remote_version = $this->view['remote_version'];
$basename = acf_get_setting('basename');
$transient = get_site_transient('update_plugins');
$transient_version = 0;
// get transient version
if( isset($transient->response[ $basename ]->new_version) ) {
$transient_version = $transient->response[ $basename ]->new_version;
}
// return true if a newer $remote_version exists
if( acf_version_compare($remote_version, '>', $transient_version) ) {
acf_updates()->refresh_plugins_transient();
}
}
/* /*
* activate_pro_licence * activate_pro_licence
* *

View File

@ -123,7 +123,7 @@
// disable clone // disable clone
acf.disable( this.$clone(), this.cid ); acf.disable( this.$clone(), this.cid );
// render // render
this.render(); this.render();
}, },
@ -200,33 +200,34 @@
return false; return false;
} }
// vars
var $clone = this.$clone();
// defaults // defaults
args = acf.parseArgs(args, { args = acf.parseArgs(args, {
before: $clone before: false
}); });
// add row // add row
var $el = acf.duplicate({ var $el = acf.duplicate({
target: $clone, target: this.$clone(),
append: function( $el, $el2 ){ append: this.proxy(function( $el, $el2 ){
// append
if( args.before ) {
args.before.before( $el2 );
} else {
$el.before( $el2 );
}
// remove clone class // remove clone class
$el2.removeClass('acf-clone'); $el2.removeClass('acf-clone');
// append // enable
args.before.before( $el2 ); acf.enable( $el2, this.cid );
}
// render
this.render();
})
}); });
// enable
acf.enable_form( $el, this.cid );
// update order
this.render();
// trigger change for validation errors // trigger change for validation errors
this.$input().trigger('change'); this.$input().trigger('change');
@ -336,7 +337,7 @@
} }
}, },
onShow: function( e, context ){ onShow: function( e, $el, context ){
// get sub fields // get sub fields
var fields = acf.getFields({ var fields = acf.getFields({
@ -670,7 +671,7 @@
} }
}, },
onShow: function( e, context ){ onShow: function( e, $el, context ){
// get sub fields // get sub fields
var fields = acf.getFields({ var fields = acf.getFields({
@ -764,9 +765,6 @@
before: false before: false
}); });
// append
args.append = this.$layoutsWrap();
// validate // validate
if( !this.allowAdd() ) { if( !this.allowAdd() ) {
return false; return false;
@ -775,22 +773,23 @@
// add row // add row
var $el = acf.duplicate({ var $el = acf.duplicate({
target: this.$clone( args.layout ), target: this.$clone( args.layout ),
append: function( $el, $el2 ){ append: this.proxy(function( $el, $el2 ){
// append
if( args.before ) { if( args.before ) {
args.before.before( $el2 ); args.before.before( $el2 );
} else { } else {
args.append.append( $el2 ); this.$layoutsWrap().append( $el2 );
} }
}
// enable
acf.enable( $el2, this.cid );
// render
this.render();
})
}); });
// enable
acf.enable_form( $el, this.cid );
// update order
this.render();
// trigger change for validation errors // trigger change for validation errors
this.$input().trigger('change'); this.$input().trigger('change');

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
=== Advanced Custom Fields Pro === === Advanced Custom Fields Pro ===
Contributors: elliotcondon Contributors: elliotcondon
Tags: acf, advanced, custom, field, fields, form, repeater, content Tags: acf, advanced, custom, field, fields, form, repeater, content
Requires at least: 3.6.0 Requires at least: 4.4.0
Tested up to: 4.9.9 Tested up to: 4.9.9
License: GPLv2 or later License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html License URI: http://www.gnu.org/licenses/gpl-2.0.html
@ -66,6 +66,23 @@ From your WordPress dashboard
== Changelog == == Changelog ==
= 5.7.2 =
*Release Date - 6 August 2018*
* Fix - Fixed bug preventing the Google Maps Field address from being customised.
* Fix - Improved logic to request and cache plugin update information.
* Fix - Fixed bug preventing JS initialization when editing widgets in accessibility mode.
* Fix - Added missing $parent argument to term_exists() function when adding a new term via taxonomy field popup.
* Fix - Fixed bug where nested Group Fields did not delete their values.
* Fix - Fixed JS error thrown by localStorage if cookies are not enabled.
* Dev - Bumped minimum WP version requirement to 4.4.
* Dev - Added action 'wp_nav_menu_item_custom_fields' for compatibility with other plugins modifying the menu walker class.
* Dev - Added 'multiple' to the allowed attributes for an email field.
* Dev - Added new ACF_Ajax class for upcoming features.
= 5.7.1 =
* Core: Minor fixes and improvements
= 5.7.0 = = 5.7.0 =
* Core: Major JavaScript updates * Core: Major JavaScript updates
* Core: Improved conditional logic with new types and more supported fields * Core: Improved conditional logic with new types and more supported fields