Merge tag '5.11.4' into develop

5.11.4
This commit is contained in:
Jean-Baptiste Bailly 2021-12-20 11:04:53 +01:00
commit 017258105b
117 changed files with 62266 additions and 41266 deletions

View File

@ -3,7 +3,7 @@
Plugin Name: Advanced Custom Fields PRO
Plugin URI: https://www.advancedcustomfields.com
Description: Customize WordPress with powerful, professional and intuitive fields.
Version: 5.10.2
Version: 5.11.4
Author: Delicious Brains
Author URI: https://www.advancedcustomfields.com
Text Domain: acf
@ -19,7 +19,7 @@ if ( ! class_exists( 'ACF' ) ) :
class ACF {
/** @var string The plugin version number. */
var $version = '5.10.2';
var $version = '5.11.4';
/** @var array The plugin settings array. */
var $settings = array();
@ -97,6 +97,9 @@ if ( ! class_exists( 'ACF' ) ) :
'select2_version' => 4,
'row_index_offset' => 1,
'remove_wp_meta_box' => true,
'rest_api_enabled' => true,
'rest_api_format' => 'light',
'rest_api_embed_links' => true,
);
// Include utility functions.
@ -142,6 +145,7 @@ if ( ! class_exists( 'ACF' ) ) :
acf_include( 'includes/updates.php' );
acf_include( 'includes/upgrades.php' );
acf_include( 'includes/validation.php' );
acf_include( 'includes/rest-api.php' );
// Include ajax.
acf_include( 'includes/ajax/class-acf-ajax.php' );

View File

@ -1,3 +1,6 @@
/*!***************************************************************************************************************************************************************************************************************!*\
!*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].use[1]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./src/advanced-custom-fields-pro/assets/src/sass/acf-dark.scss ***!
\***************************************************************************************************************************************************************************************************************/
/*--------------------------------------------------------------------------------------------
*
* Dark mode
@ -314,3 +317,5 @@
color: #fff;
background: transparent;
}
/*# sourceMappingURL=acf-dark.css.map*/

View File

@ -0,0 +1,6 @@
/******/ (function() { // webpackBootstrap
/******/ "use strict";
/******/
/******/
/******/ })()
;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,6 @@
/*!**********************************************************************************************************************************************************************************************************************!*\
!*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].use[1]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./src/advanced-custom-fields-pro/assets/src/sass/acf-field-group.scss ***!
\**********************************************************************************************************************************************************************************************************************/
/*--------------------------------------------------------------------------------------------
*
* Vars
@ -479,3 +482,5 @@ td.acf-input {
padding-bottom: 0 !important;
}
}
/*# sourceMappingURL=acf-field-group.css.map*/

View File

@ -0,0 +1,6 @@
/******/ (function() { // webpackBootstrap
/******/ "use strict";
/******/
/******/
/******/ })()
;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,6 @@
@charset "UTF-8";
/*!*****************************************************************************************************************************************************************************************************************!*\
!*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].use[1]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./src/advanced-custom-fields-pro/assets/src/sass/acf-global.scss ***!
\*****************************************************************************************************************************************************************************************************************/
/*--------------------------------------------------------------------------------------------
*
* Vars
@ -336,89 +338,89 @@
}
.acf-icon.-plus:before {
content: "";
content: "\f543";
}
.acf-icon.-minus:before {
content: "";
content: "\f460";
}
.acf-icon.-cancel:before {
content: "";
content: "\f335";
}
.acf-icon.-pencil:before {
content: "";
content: "\f464";
}
.acf-icon.-location:before {
content: "";
content: "\f230";
}
.acf-icon.-up:before {
content: "";
content: "\f343";
margin-top: -0.1em;
}
.acf-icon.-down:before {
content: "";
content: "\f347";
margin-top: 0.1em;
}
.acf-icon.-left:before {
content: "";
content: "\f341";
margin-left: -0.1em;
}
.acf-icon.-right:before {
content: "";
content: "\f345";
margin-left: 0.1em;
}
.acf-icon.-sync:before {
content: "";
content: "\f463";
}
.acf-icon.-globe:before {
content: "";
content: "\f319";
margin-top: 0.1em;
margin-left: 0.1em;
}
.acf-icon.-picture:before {
content: "";
content: "\f128";
}
.acf-icon.-check:before {
content: "";
content: "\f147";
margin-left: -0.1em;
}
.acf-icon.-dot-3:before {
content: "";
content: "\f533";
margin-top: -0.1em;
}
.acf-icon.-arrow-combo:before {
content: "";
content: "\f156";
}
.acf-icon.-arrow-up:before {
content: "";
content: "\f142";
margin-left: -0.1em;
}
.acf-icon.-arrow-down:before {
content: "";
content: "\f140";
margin-left: -0.1em;
}
.acf-icon.-search:before {
content: "";
content: "\f179";
}
.acf-icon.-link-ext:before {
content: "";
content: "\f504";
}
.acf-icon.-duplicate {
@ -443,12 +445,12 @@
}
.acf-icon.-collapse:before {
content: "";
content: "\f142";
margin-left: -0.1em;
}
.-collapsed .acf-icon.-collapse:before {
content: "";
content: "\f140";
margin-left: -0.1em;
}
@ -1660,3 +1662,5 @@ html[dir=rtl] .acf-table > tbody > tr > td.order + td {
background-size: 20px 20px;
}
}
/*# sourceMappingURL=acf-global.css.map*/

View File

@ -0,0 +1,6 @@
/******/ (function() { // webpackBootstrap
/******/ "use strict";
/******/
/******/
/******/ })()
;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,6 @@
/*!****************************************************************************************************************************************************************************************************************!*\
!*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].use[1]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./src/advanced-custom-fields-pro/assets/src/sass/acf-input.scss ***!
\****************************************************************************************************************************************************************************************************************/
/*--------------------------------------------------------------------------------------------
*
* Vars
@ -647,6 +650,9 @@ html[dir=rtl] .select2-container.-acf .select2-choice .select2-arrow {
.select2-container.-acf li {
margin-bottom: 0;
}
.select2-container.-acf[data-select2-id^=select2-data] .select2-selection--multiple {
overflow: hidden;
}
.select2-container.-acf .select2-selection {
border-color: #7e8993;
}
@ -662,6 +668,14 @@ html[dir=rtl] .select2-container.-acf .select2-choice .select2-arrow {
.select2-container.-acf .select2-selection--multiple .select2-selection__rendered {
padding-right: 0;
}
.select2-container.-acf .select2-selection--multiple .select2-selection__rendered[id^=select2-acf-field] {
display: inline;
padding: 0;
margin: 0;
}
.select2-container.-acf .select2-selection--multiple .select2-selection__rendered[id^=select2-acf-field] .select2-selection__choice {
margin-right: 0;
}
.select2-container.-acf .select2-selection--multiple .select2-selection__choice {
background-color: #f7f7f7;
border-color: #cccccc;
@ -679,6 +693,11 @@ html[dir=rtl] .select2-container.-acf .select2-choice .select2-arrow {
.select2-container.-acf .select2-selection--multiple .select2-selection__choice.ui-sortable-helper span {
visibility: hidden;
}
.select2-container.-acf .select2-selection--multiple .select2-selection__choice .select2-selection__choice__remove {
position: static;
border-right: none;
padding: 0;
}
.select2-container.-acf .select2-selection--multiple .select2-selection__choice.ui-sortable-placeholder {
background-color: #f7f7f7;
border-color: #f7f7f7;
@ -695,6 +714,10 @@ html[dir=rtl] .select2-container.-acf .select2-choice .select2-arrow {
white-space: normal;
}
.select2-dropdown .select2-results__option {
margin-bottom: 0;
}
.select2-container .select2-dropdown {
z-index: 900000;
}
@ -2930,3 +2953,5 @@ body.is-dragging-metaboxes #acf_after_title-sortables {
min-height: 60px;
margin-bottom: 3px !important;
}
/*# sourceMappingURL=acf-input.css.map*/

View File

@ -0,0 +1,6 @@
/******/ (function() { // webpackBootstrap
/******/ "use strict";
/******/
/******/
/******/ })()
;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,6 @@
/*!******************************************************************************************************************************************************************************************************************************!*\
!*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].use[1]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./src/advanced-custom-fields-pro/assets/src/sass/pro/acf-pro-field-group.scss ***!
\******************************************************************************************************************************************************************************************************************************/
/*--------------------------------------------------------------------------------------------
*
* Vars
@ -65,3 +68,5 @@
.acf-field-object-clone[data-display=seamless] .acf-field-setting-conditional_logic {
display: none;
}
/*# sourceMappingURL=acf-pro-field-group.css.map*/

View File

@ -0,0 +1,6 @@
/******/ (function() { // webpackBootstrap
/******/ "use strict";
/******/
/******/
/******/ })()
;

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
.acf-field-setting-fc_layout .acf-fc-meta{margin:0 0 10px;padding:0}.acf-field-setting-fc_layout .acf-fc-meta li{margin:0 0 10px;padding:0}.acf-field-setting-fc_layout .acf-fc-meta .acf-fc-meta-display,.acf-field-setting-fc_layout .acf-fc-meta .acf-fc-meta-min{float:left;width:33%;padding-right:10px}.acf-field-setting-fc_layout .acf-fc-meta .acf-fc-meta-display .acf-input-prepend,.acf-field-setting-fc_layout .acf-fc-meta .acf-fc-meta-label .acf-input-prepend,.acf-field-setting-fc_layout .acf-fc-meta .acf-fc-meta-name .acf-input-prepend{min-width:60px}.acf-field-setting-fc_layout .acf-fl-actions{visibility:hidden}.acf-field-setting-fc_layout .acf-fl-actions .reorder-layout{cursor:move}.acf-field-setting-fc_layout .acf-fl-actions a{padding:1px 0;font-size:13px;line-height:20px}.acf-field-setting-fc_layout.-hover .acf-fl-actions,.acf-field-setting-fc_layout:hover .acf-fl-actions{visibility:visible}.acf-field-object-clone[data-display=seamless] .acf-field-setting-conditional_logic,.acf-field-object-clone[data-display=seamless] .acf-field-setting-instructions,.acf-field-object-clone[data-display=seamless] .acf-field-setting-layout,.acf-field-object-clone[data-display=seamless] .acf-field-setting-wrapper{display:none}
.acf-field-setting-fc_layout .acf-fc-meta{margin:0 0 10px;padding:0}.acf-field-setting-fc_layout .acf-fc-meta li{margin:0 0 10px;padding:0}.acf-field-setting-fc_layout .acf-fc-meta .acf-fc-meta-display,.acf-field-setting-fc_layout .acf-fc-meta .acf-fc-meta-min{float:left;width:33%;padding-right:10px}.acf-field-setting-fc_layout .acf-fc-meta .acf-fc-meta-label .acf-input-prepend,.acf-field-setting-fc_layout .acf-fc-meta .acf-fc-meta-name .acf-input-prepend,.acf-field-setting-fc_layout .acf-fc-meta .acf-fc-meta-display .acf-input-prepend{min-width:60px}.acf-field-setting-fc_layout .acf-fl-actions{visibility:hidden}.acf-field-setting-fc_layout .acf-fl-actions .reorder-layout{cursor:move}.acf-field-setting-fc_layout .acf-fl-actions a{padding:1px 0;font-size:13px;line-height:20px}.acf-field-setting-fc_layout:hover .acf-fl-actions,.acf-field-setting-fc_layout.-hover .acf-fl-actions{visibility:visible}.acf-field-object-clone[data-display=seamless] .acf-field-setting-instructions,.acf-field-object-clone[data-display=seamless] .acf-field-setting-layout,.acf-field-object-clone[data-display=seamless] .acf-field-setting-wrapper,.acf-field-object-clone[data-display=seamless] .acf-field-setting-conditional_logic{display:none}

View File

@ -1,3 +1,6 @@
/*!************************************************************************************************************************************************************************************************************************!*\
!*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].use[1]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./src/advanced-custom-fields-pro/assets/src/sass/pro/acf-pro-input.scss ***!
\************************************************************************************************************************************************************************************************************************/
/*--------------------------------------------------------------------------------------------
*
* Vars
@ -681,3 +684,5 @@ html[dir=rtl] .acf-block-component .acf-block-fields {
.components-panel__body .acf-block-panel {
margin: 16px -16px -16px;
}
/*# sourceMappingURL=acf-pro-input.css.map*/

View File

@ -0,0 +1,6 @@
/******/ (function() { // webpackBootstrap
/******/ "use strict";
/******/
/******/
/******/ })()
;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4419
assets/build/js/pro/acf-pro-blocks-legacy.js Executable file → Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

2
assets/build/js/pro/acf-pro-blocks-legacy.min.js vendored Executable file → Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,480 +1,516 @@
(function($){
/******/ (function() { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/*
* Repeater
*
* This field type requires some extra logic for its settings
*
* @type function
* @date 24/10/13
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
/***/ "./src/advanced-custom-fields-pro/assets/src/js/pro/_acf-setting-clone.js":
/*!********************************************************************************!*\
!*** ./src/advanced-custom-fields-pro/assets/src/js/pro/_acf-setting-clone.js ***!
\********************************************************************************/
/***/ (function() {
var RepeaterCollapsedFieldSetting = acf.FieldSetting.extend({
type: 'repeater',
name: 'collapsed',
events: {
'focus select': 'onFocus',
},
onFocus: function( e, $el ){
(function ($) {
/**
* CloneDisplayFieldSetting
*
* Extra logic for this field setting
*
* @date 18/4/18
* @since 5.6.9
*
* @param void
* @return void
*/
var CloneDisplayFieldSetting = acf.FieldSetting.extend({
type: 'clone',
name: 'display',
render: function () {
// vars
var display = this.field.val(); // set data attribute used by CSS to hide/show
// vars
var $select = $el;
this.$fieldObject.attr('data-display', display);
}
});
acf.registerFieldSetting(CloneDisplayFieldSetting);
/**
* ClonePrefixLabelFieldSetting
*
* Extra logic for this field setting
*
* @date 18/4/18
* @since 5.6.9
*
* @param void
* @return void
*/
// collapsed
var choices = [];
var ClonePrefixLabelFieldSetting = acf.FieldSetting.extend({
type: 'clone',
name: 'prefix_label',
render: function () {
// vars
var prefix = ''; // if checked
// keep 'null' choice
choices.push({
label: $select.find('option[value=""]').text(),
value: ''
});
if (this.field.val()) {
prefix = this.fieldObject.prop('label') + ' ';
} // update HTML
// find sub fields
var $list = this.fieldObject.$('.acf-field-list:first');
var fields = acf.getFieldObjects({
list: $list
});
// loop
fields.map(function( field ){
choices.push({
label: field.prop('label'),
value: field.prop('key')
});
});
this.$('code').html(prefix + '%field_label%');
}
});
acf.registerFieldSetting(ClonePrefixLabelFieldSetting);
/**
* ClonePrefixNameFieldSetting
*
* Extra logic for this field setting
*
* @date 18/4/18
* @since 5.6.9
*
* @param void
* @return void
*/
// render
acf.renderSelect( $select, choices );
}
});
var ClonePrefixNameFieldSetting = acf.FieldSetting.extend({
type: 'clone',
name: 'prefix_name',
render: function () {
// vars
var prefix = ''; // if checked
acf.registerFieldSetting( RepeaterCollapsedFieldSetting );
if (this.field.val()) {
prefix = this.fieldObject.prop('name') + '_';
} // update HTML
this.$('code').html(prefix + '%field_name%');
}
});
acf.registerFieldSetting(ClonePrefixNameFieldSetting);
/**
* cloneFieldSelectHelper
*
* Customizes the clone field setting Select2 isntance
*
* @date 18/4/18
* @since 5.6.9
*
* @param void
* @return void
*/
var cloneFieldSelectHelper = new acf.Model({
filters: {
select2_args: 'select2Args'
},
select2Args: function (options, $select, data, $el, instance) {
// check
if (data.ajaxAction == 'acf/fields/clone/query') {
// remain open on select
options.closeOnSelect = false; // customize ajaxData function
instance.data.ajaxData = this.ajaxData;
} // return
return options;
},
ajaxData: function (data) {
// find current fields
data.fields = {}; // loop
acf.getFieldObjects().map(function (fieldObject) {
// append
data.fields[fieldObject.prop('key')] = {
key: fieldObject.prop('key'),
type: fieldObject.prop('type'),
label: fieldObject.prop('label'),
ancestors: fieldObject.getParents().length
};
}); // append title
data.title = $('#title').val(); // return
return data;
}
});
})(jQuery);
(function($){
/**
* CloneDisplayFieldSetting
*
* Extra logic for this field setting
*
* @date 18/4/18
* @since 5.6.9
*
* @param void
* @return void
*/
/***/ }),
var FlexibleContentLayoutFieldSetting = acf.FieldSetting.extend({
type: 'flexible_content',
name: 'fc_layout',
/***/ "./src/advanced-custom-fields-pro/assets/src/js/pro/_acf-setting-flexible-content.js":
/*!*******************************************************************************************!*\
!*** ./src/advanced-custom-fields-pro/assets/src/js/pro/_acf-setting-flexible-content.js ***!
\*******************************************************************************************/
/***/ (function() {
events: {
'blur .layout-label': 'onChangeLabel',
'click .add-layout': 'onClickAdd',
'click .duplicate-layout': 'onClickDuplicate',
'click .delete-layout': 'onClickDelete'
},
(function ($) {
/**
* CloneDisplayFieldSetting
*
* Extra logic for this field setting
*
* @date 18/4/18
* @since 5.6.9
*
* @param void
* @return void
*/
var FlexibleContentLayoutFieldSetting = acf.FieldSetting.extend({
type: 'flexible_content',
name: 'fc_layout',
events: {
'blur .layout-label': 'onChangeLabel',
'click .add-layout': 'onClickAdd',
'click .duplicate-layout': 'onClickDuplicate',
'click .delete-layout': 'onClickDelete'
},
$input: function (name) {
return $('#' + this.getInputId() + '-' + name);
},
$list: function () {
return this.$('.acf-field-list:first');
},
getInputId: function () {
return this.fieldObject.getInputId() + '-layouts-' + this.field.get('id');
},
// get all sub fields
getFields: function () {
return acf.getFieldObjects({
parent: this.$el
});
},
// get imediate children
getChildren: function () {
return acf.getFieldObjects({
list: this.$list()
});
},
initialize: function () {
// add sortable
var $tbody = this.$el.parent();
$input: function( name ){
return $('#' + this.getInputId() + '-' + name);
},
$list: function(){
return this.$('.acf-field-list:first');
},
getInputId: function(){
return this.fieldObject.getInputId() + '-layouts-' + this.field.get('id');
},
// get all sub fields
getFields: function(){
return acf.getFieldObjects({ parent: this.$el });
},
// get imediate children
getChildren: function(){
return acf.getFieldObjects({ list: this.$list() });
},
initialize: function(){
// add sortable
var $tbody = this.$el.parent();
if( !$tbody.hasClass('ui-sortable') ) {
$tbody.sortable({
items: '> .acf-field-setting-fc_layout',
handle: '.reorder-layout',
forceHelperSize: true,
forcePlaceholderSize: true,
scroll: true,
stop: this.proxy(function(event, ui) {
this.fieldObject.save();
})
});
}
// add meta to sub fields
this.updateFieldLayouts();
},
updateFieldLayouts: function(){
this.getChildren().map(this.updateFieldLayout, this);
},
updateFieldLayout: function( field ){
field.prop('parent_layout', this.get('id'));
},
onChangeLabel: function( e, $el ){
// vars
var label = $el.val();
var $name = this.$input('name');
// render name
if( $name.val() == '' ) {
acf.val($name, acf.strSanitize(label));
}
},
onClickAdd: function( e, $el ){
// vars
var prevKey = this.get('id');
var newKey = acf.uniqid('layout_');
// duplicate
$layout = acf.duplicate({
$el: this.$el,
search: prevKey,
replace: newKey,
after: function( $el, $el2 ){
// vars
var $list = $el2.find('.acf-field-list:first');
// remove sub fields
$list.children('.acf-field-object').remove();
// show empty
$list.addClass('-empty');
// reset layout meta values
$el2.find('.acf-fc-meta input').val('');
}
});
// get layout
var layout = acf.getFieldSetting( $layout );
// update hidden input
layout.$input('key').val( newKey );
// save
this.fieldObject.save();
},
onClickDuplicate: function( e, $el ){
// vars
var prevKey = this.get('id');
var newKey = acf.uniqid('layout_');
// duplicate
$layout = acf.duplicate({
$el: this.$el,
search: prevKey,
replace: newKey
});
// get all fields in new layout similar to fieldManager.onDuplicateField().
// important to run field.wipe() before making any changes to the "parent_layout" prop
// to ensure the correct input is modified.
var children = acf.getFieldObjects({ parent: $layout });
if( children.length ) {
// loop
children.map(function( child ){
// wipe field
child.wipe();
// update parent
child.updateParent();
});
// action
acf.doAction('duplicate_field_objects', children, this.fieldObject, this.fieldObject);
}
// get layout
var layout = acf.getFieldSetting( $layout );
// update hidden input
layout.$input('key').val( newKey );
// save
this.fieldObject.save();
},
onClickDelete: function( e, $el ){
// Bypass confirmation when holding down "shift" key.
if( e.shiftKey ) {
return this.delete();
}
// add class
this.$el.addClass('-hover');
// add tooltip
var tooltip = acf.newTooltip({
confirmRemove: true,
target: $el,
context: this,
confirm: function(){
this.delete();
},
cancel: function(){
this.$el.removeClass('-hover');
}
});
},
delete: function(){
// vars
var $siblings = this.$el.siblings('.acf-field-setting-fc_layout');
// validate
if( !$siblings.length ) {
alert( acf.__('Flexible Content requires at least 1 layout') );
return false;
}
// delete sub fields
this.getFields().map(function( child ){
child.delete({
animate: false
});
});
// remove tr
acf.remove( this.$el );
// save
this.fieldObject.save();
}
});
acf.registerFieldSetting( FlexibleContentLayoutFieldSetting );
if (!$tbody.hasClass('ui-sortable')) {
$tbody.sortable({
items: '> .acf-field-setting-fc_layout',
handle: '.reorder-layout',
forceHelperSize: true,
forcePlaceholderSize: true,
scroll: true,
stop: this.proxy(function (event, ui) {
this.fieldObject.save();
})
});
} // add meta to sub fields
/**
* flexibleContentHelper
*
* description
*
* @date 19/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
this.updateFieldLayouts();
},
updateFieldLayouts: function () {
this.getChildren().map(this.updateFieldLayout, this);
},
updateFieldLayout: function (field) {
field.prop('parent_layout', this.get('id'));
},
onChangeLabel: function (e, $el) {
// vars
var label = $el.val();
var $name = this.$input('name'); // render name
var flexibleContentHelper = new acf.Model({
actions: {
'sortstop_field_object': 'updateParentLayout',
'change_field_object_parent': 'updateParentLayout'
},
if ($name.val() == '') {
acf.val($name, acf.strSanitize(label));
}
},
onClickAdd: function (e, $el) {
// vars
var prevKey = this.get('id');
var newKey = acf.uniqid('layout_'); // duplicate
updateParentLayout: function( fieldObject ){
$layout = acf.duplicate({
$el: this.$el,
search: prevKey,
replace: newKey,
after: function ($el, $el2) {
// vars
var $list = $el2.find('.acf-field-list:first'); // remove sub fields
// vars
var parent = fieldObject.getParent();
$list.children('.acf-field-object').remove(); // show empty
// delete meta
if( !parent || parent.prop('type') !== 'flexible_content' ) {
fieldObject.prop('parent_layout', null);
return;
}
$list.addClass('-empty'); // reset layout meta values
// get layout
var $layout = fieldObject.$el.closest('.acf-field-setting-fc_layout');
var layout = acf.getFieldSetting($layout);
$el2.find('.acf-fc-meta input').val('');
}
}); // get layout
// check if previous prop exists
// - if not, set prop to allow following code to trigger 'change' and save the field
if( !fieldObject.has('parent_layout') ) {
fieldObject.prop('parent_layout', 0);
}
var layout = acf.getFieldSetting($layout); // update hidden input
// update meta
fieldObject.prop('parent_layout', layout.get('id'));
}
});
layout.$input('key').val(newKey); // save
this.fieldObject.save();
},
onClickDuplicate: function (e, $el) {
// vars
var prevKey = this.get('id');
var newKey = acf.uniqid('layout_'); // duplicate
$layout = acf.duplicate({
$el: this.$el,
search: prevKey,
replace: newKey
}); // get all fields in new layout similar to fieldManager.onDuplicateField().
// important to run field.wipe() before making any changes to the "parent_layout" prop
// to ensure the correct input is modified.
var children = acf.getFieldObjects({
parent: $layout
});
if (children.length) {
// loop
children.map(function (child) {
// wipe field
child.wipe(); // update parent
child.updateParent();
}); // action
acf.doAction('duplicate_field_objects', children, this.fieldObject, this.fieldObject);
} // get layout
var layout = acf.getFieldSetting($layout); // update hidden input
layout.$input('key').val(newKey); // save
this.fieldObject.save();
},
onClickDelete: function (e, $el) {
// Bypass confirmation when holding down "shift" key.
if (e.shiftKey) {
return this.delete();
} // add class
this.$el.addClass('-hover'); // add tooltip
var tooltip = acf.newTooltip({
confirmRemove: true,
target: $el,
context: this,
confirm: function () {
this.delete();
},
cancel: function () {
this.$el.removeClass('-hover');
}
});
},
delete: function () {
// vars
var $siblings = this.$el.siblings('.acf-field-setting-fc_layout'); // validate
if (!$siblings.length) {
alert(acf.__('Flexible Content requires at least 1 layout'));
return false;
} // delete sub fields
this.getFields().map(function (child) {
child.delete({
animate: false
});
}); // remove tr
acf.remove(this.$el); // save
this.fieldObject.save();
}
});
acf.registerFieldSetting(FlexibleContentLayoutFieldSetting);
/**
* flexibleContentHelper
*
* description
*
* @date 19/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
var flexibleContentHelper = new acf.Model({
actions: {
sortstop_field_object: 'updateParentLayout',
change_field_object_parent: 'updateParentLayout'
},
updateParentLayout: function (fieldObject) {
// vars
var parent = fieldObject.getParent(); // delete meta
if (!parent || parent.prop('type') !== 'flexible_content') {
fieldObject.prop('parent_layout', null);
return;
} // get layout
var $layout = fieldObject.$el.closest('.acf-field-setting-fc_layout');
var layout = acf.getFieldSetting($layout); // check if previous prop exists
// - if not, set prop to allow following code to trigger 'change' and save the field
if (!fieldObject.has('parent_layout')) {
fieldObject.prop('parent_layout', 0);
} // update meta
fieldObject.prop('parent_layout', layout.get('id'));
}
});
})(jQuery);
(function($){
/**
* CloneDisplayFieldSetting
*
* Extra logic for this field setting
*
* @date 18/4/18
* @since 5.6.9
*
* @param void
* @return void
*/
/***/ }),
var CloneDisplayFieldSetting = acf.FieldSetting.extend({
type: 'clone',
name: 'display',
render: function(){
/***/ "./src/advanced-custom-fields-pro/assets/src/js/pro/_acf-setting-repeater.js":
/*!***********************************************************************************!*\
!*** ./src/advanced-custom-fields-pro/assets/src/js/pro/_acf-setting-repeater.js ***!
\***********************************************************************************/
/***/ (function() {
// vars
var display = this.field.val();
(function ($) {
/*
* Repeater
*
* This field type requires some extra logic for its settings
*
* @type function
* @date 24/10/13
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
var RepeaterCollapsedFieldSetting = acf.FieldSetting.extend({
type: 'repeater',
name: 'collapsed',
events: {
'focus select': 'onFocus'
},
onFocus: function (e, $el) {
// vars
var $select = $el; // collapsed
// set data attribute used by CSS to hide/show
this.$fieldObject.attr('data-display', display);
}
});
var choices = []; // keep 'null' choice
acf.registerFieldSetting( CloneDisplayFieldSetting );
choices.push({
label: $select.find('option[value=""]').text(),
value: ''
}); // find sub fields
var $list = this.fieldObject.$('.acf-field-list:first');
var fields = acf.getFieldObjects({
list: $list
}); // loop
/**
* ClonePrefixLabelFieldSetting
*
* Extra logic for this field setting
*
* @date 18/4/18
* @since 5.6.9
*
* @param void
* @return void
*/
var ClonePrefixLabelFieldSetting = acf.FieldSetting.extend({
type: 'clone',
name: 'prefix_label',
render: function(){
// vars
var prefix = '';
// if checked
if( this.field.val() ) {
prefix = this.fieldObject.prop('label') + ' ';
}
// update HTML
this.$('code').html( prefix + '%field_label%' );
}
});
acf.registerFieldSetting( ClonePrefixLabelFieldSetting );
/**
* ClonePrefixNameFieldSetting
*
* Extra logic for this field setting
*
* @date 18/4/18
* @since 5.6.9
*
* @param void
* @return void
*/
var ClonePrefixNameFieldSetting = acf.FieldSetting.extend({
type: 'clone',
name: 'prefix_name',
render: function(){
// vars
var prefix = '';
// if checked
if( this.field.val() ) {
prefix = this.fieldObject.prop('name') + '_';
}
// update HTML
this.$('code').html( prefix + '%field_name%' );
}
});
acf.registerFieldSetting( ClonePrefixNameFieldSetting );
/**
* cloneFieldSelectHelper
*
* Customizes the clone field setting Select2 isntance
*
* @date 18/4/18
* @since 5.6.9
*
* @param void
* @return void
*/
var cloneFieldSelectHelper = new acf.Model({
filters: {
'select2_args': 'select2Args'
},
select2Args: function( options, $select, data, $el, instance ){
// check
if( data.ajaxAction == 'acf/fields/clone/query' ) {
// remain open on select
options.closeOnSelect = false;
// customize ajaxData function
instance.data.ajaxData = this.ajaxData;
}
// return
return options;
},
ajaxData: function( data ){
// find current fields
data.fields = {};
// loop
acf.getFieldObjects().map(function(fieldObject){
// append
data.fields[ fieldObject.prop('key') ] = {
key: fieldObject.prop('key'),
type: fieldObject.prop('type'),
label: fieldObject.prop('label'),
ancestors: fieldObject.getParents().length
};
});
// append title
data.title = $('#title').val();
// return
return data;
}
});
fields.map(function (field) {
choices.push({
label: field.prop('label'),
value: field.prop('key')
});
}); // render
acf.renderSelect($select, choices);
}
});
acf.registerFieldSetting(RepeaterCollapsedFieldSetting);
})(jQuery);
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/compat get default export */
/******/ !function() {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function() { return module['default']; } :
/******/ function() { return module; };
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ !function() {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = function(exports, definition) {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ !function() {
/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
/******/ }();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ !function() {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ }();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
!function() {
"use strict";
/*!*********************************************************************************!*\
!*** ./src/advanced-custom-fields-pro/assets/src/js/pro/acf-pro-field-group.js ***!
\*********************************************************************************/
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _acf_setting_repeater_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_acf-setting-repeater.js */ "./src/advanced-custom-fields-pro/assets/src/js/pro/_acf-setting-repeater.js");
/* harmony import */ var _acf_setting_repeater_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_acf_setting_repeater_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _acf_setting_flexible_content_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_acf-setting-flexible-content.js */ "./src/advanced-custom-fields-pro/assets/src/js/pro/_acf-setting-flexible-content.js");
/* harmony import */ var _acf_setting_flexible_content_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_acf_setting_flexible_content_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _acf_setting_clone_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_acf-setting-clone.js */ "./src/advanced-custom-fields-pro/assets/src/js/pro/_acf-setting-clone.js");
/* harmony import */ var _acf_setting_clone_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_acf_setting_clone_js__WEBPACK_IMPORTED_MODULE_2__);
}();
/******/ })()
;
//# sourceMappingURL=acf-pro-field-group.js.map

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
!function(){var e=acf.FieldSetting.extend({type:"repeater",name:"collapsed",events:{"focus select":"onFocus"},onFocus:function(e,t){var i=t,a=[];a.push({label:i.find('option[value=""]').text(),value:""});t=this.fieldObject.$(".acf-field-list:first");acf.getFieldObjects({list:t}).map(function(e){a.push({label:e.prop("label"),value:e.prop("key")})}),acf.renderSelect(i,a)}});acf.registerFieldSetting(e)}(jQuery),function(t){var e=acf.FieldSetting.extend({type:"flexible_content",name:"fc_layout",events:{"blur .layout-label":"onChangeLabel","click .add-layout":"onClickAdd","click .duplicate-layout":"onClickDuplicate","click .delete-layout":"onClickDelete"},$input:function(e){return t("#"+this.getInputId()+"-"+e)},$list:function(){return this.$(".acf-field-list:first")},getInputId:function(){return this.fieldObject.getInputId()+"-layouts-"+this.field.get("id")},getFields:function(){return acf.getFieldObjects({parent:this.$el})},getChildren:function(){return acf.getFieldObjects({list:this.$list()})},initialize:function(){var e=this.$el.parent();e.hasClass("ui-sortable")||e.sortable({items:"> .acf-field-setting-fc_layout",handle:".reorder-layout",forceHelperSize:!0,forcePlaceholderSize:!0,scroll:!0,stop:this.proxy(function(e,t){this.fieldObject.save()})}),this.updateFieldLayouts()},updateFieldLayouts:function(){this.getChildren().map(this.updateFieldLayout,this)},updateFieldLayout:function(e){e.prop("parent_layout",this.get("id"))},onChangeLabel:function(e,t){var i=t.val(),t=this.$input("name");""==t.val()&&acf.val(t,acf.strSanitize(i))},onClickAdd:function(e,t){var i=this.get("id"),a=acf.uniqid("layout_");$layout=acf.duplicate({$el:this.$el,search:i,replace:a,after:function(e,t){var i=t.find(".acf-field-list:first");i.children(".acf-field-object").remove(),i.addClass("-empty"),t.find(".acf-fc-meta input").val("")}}),acf.getFieldSetting($layout).$input("key").val(a),this.fieldObject.save()},onClickDuplicate:function(e,t){var i=this.get("id"),a=acf.uniqid("layout_");$layout=acf.duplicate({$el:this.$el,search:i,replace:a});i=acf.getFieldObjects({parent:$layout});i.length&&(i.map(function(e){e.wipe(),e.updateParent()}),acf.doAction("duplicate_field_objects",i,this.fieldObject,this.fieldObject)),acf.getFieldSetting($layout).$input("key").val(a),this.fieldObject.save()},onClickDelete:function(e,t){if(e.shiftKey)return this.delete();this.$el.addClass("-hover");acf.newTooltip({confirmRemove:!0,target:t,context:this,confirm:function(){this.delete()},cancel:function(){this.$el.removeClass("-hover")}})},delete:function(){if(!this.$el.siblings(".acf-field-setting-fc_layout").length)return alert(acf.__("Flexible Content requires at least 1 layout")),!1;this.getFields().map(function(e){e.delete({animate:!1})}),acf.remove(this.$el),this.fieldObject.save()}});acf.registerFieldSetting(e);new acf.Model({actions:{sortstop_field_object:"updateParentLayout",change_field_object_parent:"updateParentLayout"},updateParentLayout:function(e){var t=e.getParent();t&&"flexible_content"===t.prop("type")?(t=e.$el.closest(".acf-field-setting-fc_layout"),t=acf.getFieldSetting(t),e.has("parent_layout")||e.prop("parent_layout",0),e.prop("parent_layout",t.get("id"))):e.prop("parent_layout",null)}})}(jQuery),function(e){var t=acf.FieldSetting.extend({type:"clone",name:"display",render:function(){var e=this.field.val();this.$fieldObject.attr("data-display",e)}});acf.registerFieldSetting(t);t=acf.FieldSetting.extend({type:"clone",name:"prefix_label",render:function(){var e="";this.field.val()&&(e=this.fieldObject.prop("label")+" "),this.$("code").html(e+"%field_label%")}});acf.registerFieldSetting(t);t=acf.FieldSetting.extend({type:"clone",name:"prefix_name",render:function(){var e="";this.field.val()&&(e=this.fieldObject.prop("name")+"_"),this.$("code").html(e+"%field_name%")}});acf.registerFieldSetting(t);new acf.Model({filters:{select2_args:"select2Args"},select2Args:function(e,t,i,a,l){return"acf/fields/clone/query"==i.ajaxAction&&(e.closeOnSelect=!1,l.data.ajaxData=this.ajaxData),e},ajaxData:function(t){return t.fields={},acf.getFieldObjects().map(function(e){t.fields[e.prop("key")]={key:e.prop("key"),type:e.prop("type"),label:e.prop("label"),ancestors:e.getParents().length}}),t.title=e("#title").val(),t}})}(jQuery);
!function(){var e={436:function(){!function(e){var t=acf.FieldSetting.extend({type:"clone",name:"display",render:function(){var e=this.field.val();this.$fieldObject.attr("data-display",e)}});acf.registerFieldSetting(t);var i=acf.FieldSetting.extend({type:"clone",name:"prefix_label",render:function(){var e="";this.field.val()&&(e=this.fieldObject.prop("label")+" "),this.$("code").html(e+"%field_label%")}});acf.registerFieldSetting(i);var a=acf.FieldSetting.extend({type:"clone",name:"prefix_name",render:function(){var e="";this.field.val()&&(e=this.fieldObject.prop("name")+"_"),this.$("code").html(e+"%field_name%")}});acf.registerFieldSetting(a),new acf.Model({filters:{select2_args:"select2Args"},select2Args:function(e,t,i,a,l){return"acf/fields/clone/query"==i.ajaxAction&&(e.closeOnSelect=!1,l.data.ajaxData=this.ajaxData),e},ajaxData:function(t){return t.fields={},acf.getFieldObjects().map((function(e){t.fields[e.prop("key")]={key:e.prop("key"),type:e.prop("type"),label:e.prop("label"),ancestors:e.getParents().length}})),t.title=e("#title").val(),t}})}(jQuery)},309:function(){var e,t;e=jQuery,t=acf.FieldSetting.extend({type:"flexible_content",name:"fc_layout",events:{"blur .layout-label":"onChangeLabel","click .add-layout":"onClickAdd","click .duplicate-layout":"onClickDuplicate","click .delete-layout":"onClickDelete"},$input:function(t){return e("#"+this.getInputId()+"-"+t)},$list:function(){return this.$(".acf-field-list:first")},getInputId:function(){return this.fieldObject.getInputId()+"-layouts-"+this.field.get("id")},getFields:function(){return acf.getFieldObjects({parent:this.$el})},getChildren:function(){return acf.getFieldObjects({list:this.$list()})},initialize:function(){var e=this.$el.parent();e.hasClass("ui-sortable")||e.sortable({items:"> .acf-field-setting-fc_layout",handle:".reorder-layout",forceHelperSize:!0,forcePlaceholderSize:!0,scroll:!0,stop:this.proxy((function(e,t){this.fieldObject.save()}))}),this.updateFieldLayouts()},updateFieldLayouts:function(){this.getChildren().map(this.updateFieldLayout,this)},updateFieldLayout:function(e){e.prop("parent_layout",this.get("id"))},onChangeLabel:function(e,t){var i=t.val(),a=this.$input("name");""==a.val()&&acf.val(a,acf.strSanitize(i))},onClickAdd:function(e,t){var i=this.get("id"),a=acf.uniqid("layout_");$layout=acf.duplicate({$el:this.$el,search:i,replace:a,after:function(e,t){var i=t.find(".acf-field-list:first");i.children(".acf-field-object").remove(),i.addClass("-empty"),t.find(".acf-fc-meta input").val("")}}),acf.getFieldSetting($layout).$input("key").val(a),this.fieldObject.save()},onClickDuplicate:function(e,t){var i=this.get("id"),a=acf.uniqid("layout_");$layout=acf.duplicate({$el:this.$el,search:i,replace:a});var l=acf.getFieldObjects({parent:$layout});l.length&&(l.map((function(e){e.wipe(),e.updateParent()})),acf.doAction("duplicate_field_objects",l,this.fieldObject,this.fieldObject)),acf.getFieldSetting($layout).$input("key").val(a),this.fieldObject.save()},onClickDelete:function(e,t){if(e.shiftKey)return this.delete();this.$el.addClass("-hover"),acf.newTooltip({confirmRemove:!0,target:t,context:this,confirm:function(){this.delete()},cancel:function(){this.$el.removeClass("-hover")}})},delete:function(){if(!this.$el.siblings(".acf-field-setting-fc_layout").length)return alert(acf.__("Flexible Content requires at least 1 layout")),!1;this.getFields().map((function(e){e.delete({animate:!1})})),acf.remove(this.$el),this.fieldObject.save()}}),acf.registerFieldSetting(t),new acf.Model({actions:{sortstop_field_object:"updateParentLayout",change_field_object_parent:"updateParentLayout"},updateParentLayout:function(e){var t=e.getParent();if(t&&"flexible_content"===t.prop("type")){var i=e.$el.closest(".acf-field-setting-fc_layout"),a=acf.getFieldSetting(i);e.has("parent_layout")||e.prop("parent_layout",0),e.prop("parent_layout",a.get("id"))}else e.prop("parent_layout",null)}})},166:function(){var e;jQuery,e=acf.FieldSetting.extend({type:"repeater",name:"collapsed",events:{"focus select":"onFocus"},onFocus:function(e,t){var i=t,a=[];a.push({label:i.find('option[value=""]').text(),value:""});var l=this.fieldObject.$(".acf-field-list:first");acf.getFieldObjects({list:l}).map((function(e){a.push({label:e.prop("label"),value:e.prop("key")})})),acf.renderSelect(i,a)}}),acf.registerFieldSetting(e)}},t={};function i(a){var l=t[a];if(void 0!==l)return l.exports;var n=t[a]={exports:{}};return e[a](n,n.exports,i),n.exports}i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,{a:t}),t},i.d=function(e,t){for(var a in t)i.o(t,a)&&!i.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){"use strict";i(166),i(309),i(436)}()}();

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -9,14 +9,16 @@
* Licensed under the GPLv2 license or later.
*/
( function( $, undef ) {
( function ( $, undef ) {
var wpColorPickerAlpha = {
'version' : 300
version: 300,
};
// Always try to use the last version of this script.
if ( 'wpColorPickerAlpha' in window && 'version' in window.wpColorPickerAlpha ) {
if (
'wpColorPickerAlpha' in window &&
'version' in window.wpColorPickerAlpha
) {
var version = parseInt( window.wpColorPickerAlpha.version, 10 );
if ( ! isNaN( version ) && version >= wpColorPickerAlpha.version ) {
return;
@ -29,8 +31,8 @@
}
// Create new method to replace the `Color.toString()` inside the scripts.
Color.fn.to_s = function( type ) {
type = ( type || 'hex' );
Color.fn.to_s = function ( type ) {
type = type || 'hex';
// Change hex to rgba to return the correct color.
if ( 'hex' === type && this._alpha < 1 ) {
type = 'rgba';
@ -40,16 +42,19 @@
if ( 'hex' === type ) {
color = this.toString();
} else if ( ! this.error ) {
color = this.toCSS( type ).replace( /\(\s+/, '(' ).replace( /\s+\)/, ')' );
color = this.toCSS( type )
.replace( /\(\s+/, '(' )
.replace( /\s+\)/, ')' );
}
return color;
}
};
// Register the global variable.
window.wpColorPickerAlpha = wpColorPickerAlpha;
// Background image encoded
var backgroundImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAAHnlligAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHJJREFUeNpi+P///4EDBxiAGMgCCCAGFB5AADGCRBgYDh48CCRZIJS9vT2QBAggFBkmBiSAogxFBiCAoHogAKIKAlBUYTELAiAmEtABEECk20G6BOmuIl0CIMBQ/IEMkO0myiSSraaaBhZcbkUOs0HuBwDplz5uFJ3Z4gAAAABJRU5ErkJggg==';
var backgroundImage =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAAHnlligAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHJJREFUeNpi+P///4EDBxiAGMgCCCAGFB5AADGCRBgYDh48CCRZIJS9vT2QBAggFBkmBiSAogxFBiCAoHogAKIKAlBUYTELAiAmEtABEECk20G6BOmuIl0CIMBQ/IEMkO0myiSSraaaBhZcbkUOs0HuBwDplz5uFJ3Z4gAAAABJRU5ErkJggg==';
/**
* Iris
@ -75,7 +80,7 @@
*
* @return {string} The element's color.
*/
_getColor: function( color ) {
_getColor: function ( color ) {
if ( color === undef ) {
color = this._color;
}
@ -97,11 +102,13 @@
*
* @return {void}
*/
_create: function() {
_create: function () {
try {
// Try to get the wpColorPicker alpha options.
this.alphaOptions = this.element.wpColorPicker( 'instance' ).alphaOptions;
} catch( e ) {}
this.alphaOptions = this.element.wpColorPicker(
'instance'
).alphaOptions;
} catch ( e ) {}
// We make sure there are all options
$.extend( {}, this.alphaOptions, {
@ -122,10 +129,10 @@
*
* @return {void}
*/
_addInputListeners: function( input ) {
_addInputListeners: function ( input ) {
var self = this,
debounceTimeout = 100,
callback = function( event ){
callback = function ( event ) {
var val = input.val(),
color = new Color( val ),
val = val.replace( /^(#|(rgb|hsl)a?)/, '' ),
@ -135,10 +142,22 @@
if ( ! color.error ) {
// let's not do this on keyup for hex shortcodes
if ( 'hex' !== type || ! ( event.type === 'keyup' && val.match( /^[0-9a-fA-F]{3}$/ ) ) ) {
if (
'hex' !== type ||
! (
event.type === 'keyup' &&
val.match( /^[0-9a-fA-F]{3}$/ )
)
) {
// Compare color ( #AARRGGBB )
if ( color.toIEOctoHex() !== self._color.toIEOctoHex() ) {
self._setOption( 'color', self._getColor( color ) );
if (
color.toIEOctoHex() !==
self._color.toIEOctoHex()
) {
self._setOption(
'color',
self._getColor( color )
);
}
}
} else if ( val !== '' ) {
@ -146,13 +165,15 @@
}
};
input.on( 'change', callback ).on( 'keyup', self._debounce( callback, debounceTimeout ) );
input
.on( 'change', callback )
.on( 'keyup', self._debounce( callback, debounceTimeout ) );
// If we initialized hidden, show on first focus. The rest is up to you.
if ( self.options.hide ) {
input.one( 'focus', function() {
input.one( 'focus', function () {
self.show();
});
} );
}
},
/**
@ -163,17 +184,17 @@
*
* @return {void}
*/
_initControls: function() {
_initControls: function () {
this._super();
if ( this.alphaOptions.alphaEnabled ) {
// Create Alpha controls
var self = this,
stripAlpha = self.controls.strip.clone(false, false),
stripAlpha = self.controls.strip.clone( false, false ),
stripAlphaSlider = stripAlpha.find( '.iris-slider-offset' ),
controls = {
stripAlpha : stripAlpha,
stripAlphaSlider : stripAlphaSlider
stripAlpha: stripAlpha,
stripAlphaSlider: stripAlphaSlider,
};
stripAlpha.addClass( 'iris-strip-alpha' );
@ -181,23 +202,23 @@
stripAlpha.appendTo( self.picker.find( '.iris-picker-inner' ) );
// Push new controls
$.each( controls, function( k, v ) {
self.controls[k] = v;
$.each( controls, function ( k, v ) {
self.controls[ k ] = v;
} );
// Create slider
self.controls.stripAlphaSlider.slider( {
orientation : 'vertical',
min : 0,
max : 100,
step : 1,
value : parseInt( self._color._alpha * 100 ),
slide : function( event, ui ) {
orientation: 'vertical',
min: 0,
max: 100,
step: 1,
value: parseInt( self._color._alpha * 100 ),
slide: function ( event, ui ) {
self.active = 'strip';
// Update alpha value
self._color._alpha = parseFloat( ui.value / 100 );
self._change.apply( self, arguments );
}
},
} );
}
},
@ -211,7 +232,7 @@
*
* @return {void}
*/
_dimensions: function( reset ) {
_dimensions: function ( reset ) {
this._super( reset );
if ( this.alphaOptions.alphaEnabled ) {
@ -220,7 +241,11 @@
controls = self.controls,
square = controls.square,
strip = self.picker.find( '.iris-strip' ),
innerWidth, squareWidth, stripWidth, stripMargin, totalWidth;
innerWidth,
squareWidth,
stripWidth,
stripMargin,
totalWidth;
/**
* I use Math.round() to avoid possible size errors,
@ -232,7 +257,9 @@
* 20 for css left and right property
* 2 for css border
*/
innerWidth = Math.round( self.picker.outerWidth( true ) - ( opts.border ? 22 : 0 ) );
innerWidth = Math.round(
self.picker.outerWidth( true ) - ( opts.border ? 22 : 0 )
);
// The width of the draggable, aka square.
squareWidth = Math.round( square.outerWidth() );
// The width for the sliders
@ -240,18 +267,23 @@
// The margin for the sliders
stripMargin = Math.round( stripWidth / 2 );
// The total width of the elements.
totalWidth = Math.round( squareWidth + ( stripWidth * 2 ) + ( stripMargin * 2 ) );
totalWidth = Math.round(
squareWidth + stripWidth * 2 + stripMargin * 2
);
// Check and change if necessary.
while ( totalWidth > innerWidth ) {
stripWidth = Math.round( stripWidth - 2 );
stripMargin = Math.round( stripMargin - 1 );
totalWidth = Math.round( squareWidth + ( stripWidth * 2 ) + ( stripMargin * 2 ) );
totalWidth = Math.round(
squareWidth + stripWidth * 2 + stripMargin * 2
);
}
square.css( 'margin', '0' );
strip.width( stripWidth ).css( 'margin-left', stripMargin + 'px' );
strip
.width( stripWidth )
.css( 'margin-left', stripMargin + 'px' );
}
},
/**
@ -262,42 +294,67 @@
*
* @return {void}
*/
_change: function() {
var self = this,
_change: function () {
var self = this,
active = self.active;
self._super();
if ( self.alphaOptions.alphaEnabled ) {
var controls = self.controls,
alpha = parseInt( self._color._alpha * 100 ),
color = self._color.toRgb(),
gradient = [
'rgb(' + color.r + ',' + color.g + ',' + color.b + ') 0%',
'rgba(' + color.r + ',' + color.g + ',' + color.b + ', 0) 100%'
var controls = self.controls,
alpha = parseInt( self._color._alpha * 100 ),
color = self._color.toRgb(),
gradient = [
'rgb(' +
color.r +
',' +
color.g +
',' +
color.b +
') 0%',
'rgba(' +
color.r +
',' +
color.g +
',' +
color.b +
', 0) 100%',
],
target = self.picker.closest( '.wp-picker-container' ).find( '.wp-color-result' );
target = self.picker
.closest( '.wp-picker-container' )
.find( '.wp-color-result' );
self.options.color = self._getColor();
// Generate background slider alpha, only for CSS3.
controls.stripAlpha.css( { 'background' : 'linear-gradient(to bottom, ' + gradient.join( ', ' ) + '), url(' + backgroundImage + ')' } );
controls.stripAlpha.css( {
background:
'linear-gradient(to bottom, ' +
gradient.join( ', ' ) +
'), url(' +
backgroundImage +
')',
} );
// Update alpha value
if ( active ) {
controls.stripAlphaSlider.slider( 'value', alpha );
}
if ( ! self._color.error ) {
self.element.removeClass( 'iris-error' ).val( self.options.color );
self.element
.removeClass( 'iris-error' )
.val( self.options.color );
}
self.picker.find( '.iris-palette-container' ).on( 'click.palette', '.iris-palette', function() {
var color = $( this ).data( 'color' );
if ( self.alphaOptions.alphaReset ) {
self._color._alpha = 1;
color = self._getColor();
}
self._setOption( 'color', color );
} );
self.picker
.find( '.iris-palette-container' )
.on( 'click.palette', '.iris-palette', function () {
var color = $( this ).data( 'color' );
if ( self.alphaOptions.alphaReset ) {
self._color._alpha = 1;
color = self._getColor();
}
self._setOption( 'color', color );
} );
}
},
/**
@ -311,7 +368,7 @@
*
* @return {void}
*/
_paintDimension: function( origin, control ) {
_paintDimension: function ( origin, control ) {
var self = this,
color = false;
@ -339,14 +396,17 @@
*
* @return {void}
*/
_setOption: function( key, value ) {
_setOption: function ( key, value ) {
var self = this;
if ( 'color' === key && self.alphaOptions.alphaEnabled ) {
// cast to string in case we have a number
value = '' + value;
newColor = new Color( value ).setHSpace( self.options.mode );
// Check if error && Check the color to prevent callbacks with the same color.
if ( ! newColor.error && self._getColor( newColor ) !== self._getColor() ) {
if (
! newColor.error &&
self._getColor( newColor ) !== self._getColor()
) {
self._color = newColor;
self.options.color = self._getColor();
self.active = 'external';
@ -365,7 +425,7 @@
*
* @return {string} The element's color.
*/
color: function( newColor ) {
color: function ( newColor ) {
if ( newColor === true ) {
return this._color.clone();
}
@ -398,12 +458,12 @@
*
* @return {object} The current alpha options.
*/
_getAlphaOptions: function() {
_getAlphaOptions: function () {
var el = this.element,
type = ( el.data( 'type' ) || this.options.type ),
color = ( el.data( 'defaultColor' ) || el.val() ),
type = el.data( 'type' ) || this.options.type,
color = el.data( 'defaultColor' ) || el.val(),
options = {
alphaEnabled: ( el.data( 'alphaEnabled' ) || false ),
alphaEnabled: el.data( 'alphaEnabled' ) || false,
alphaCustomWidth: 130,
alphaReset: false,
alphaColorType: 'rgb',
@ -411,21 +471,21 @@
};
if ( options.alphaEnabled ) {
options.alphaEnabled = ( el.is( 'input' ) && 'full' === type );
options.alphaEnabled = el.is( 'input' ) && 'full' === type;
}
if ( ! options.alphaEnabled ) {
return options;
}
options.alphaColorWithSpace = ( color && color.match( /\s/ ) );
options.alphaColorWithSpace = color && color.match( /\s/ );
$.each( options, function( name, defaultValue ) {
var value = ( el.data( name ) || defaultValue );
$.each( options, function ( name, defaultValue ) {
var value = el.data( name ) || defaultValue;
switch ( name ) {
case 'alphaCustomWidth':
value = ( value ? parseInt( value, 10 ) : 0 );
value = ( isNaN( value ) ? defaultValue : value );
value = value ? parseInt( value, 10 ) : 0;
value = isNaN( value ) ? defaultValue : value;
break;
case 'alphaColorType':
if ( ! value.match( /^(hex|(rgb|hsl)a?)$/ ) ) {
@ -439,10 +499,10 @@
}
break;
default:
value = !!value;
value = !! value;
break;
}
options[name] = value;
options[ name ] = value;
} );
return options;
@ -455,7 +515,7 @@
*
* @return {void}
*/
_create: function() {
_create: function () {
// Return early if Iris support is missing.
if ( ! $.support.iris ) {
return;
@ -475,7 +535,7 @@
*
* @return {void}
*/
_addListeners: function() {
_addListeners: function () {
if ( ! this.alphaOptions.alphaEnabled ) {
return this._super();
}
@ -486,12 +546,18 @@
this.alphaOptions.defaultWidth = el.width();
if ( this.alphaOptions.alphaCustomWidth ) {
el.width( parseInt( this.alphaOptions.defaultWidth + this.alphaOptions.alphaCustomWidth, 10 ) );
el.width(
parseInt(
this.alphaOptions.defaultWidth +
this.alphaOptions.alphaCustomWidth,
10
)
);
}
self.toggler.css( {
'position': 'relative',
'background-image' : 'url(' + backgroundImage + ')'
position: 'relative',
'background-image': 'url(' + backgroundImage + ')',
} );
if ( isDeprecated ) {
@ -501,29 +567,28 @@
}
self.colorAlpha = self.toggler.find( 'span.color-alpha' ).css( {
'width' : '30px',
'height' : '100%',
'position' : 'absolute',
'top' : 0,
'background-color' : el.val(),
width: '30px',
height: '100%',
position: 'absolute',
top: 0,
'background-color': el.val(),
} );
// Define the correct position for ltr or rtl direction.
if ( 'ltr' === self.colorAlpha.css( 'direction' ) ) {
self.colorAlpha.css( {
'border-bottom-left-radius' : '2px',
'border-top-left-radius' : '2px',
'left' : 0
'border-bottom-left-radius': '2px',
'border-top-left-radius': '2px',
left: 0,
} );
} else {
self.colorAlpha.css( {
'border-bottom-right-radius' : '2px',
'border-top-right-radius' : '2px',
'right' : 0
'border-bottom-right-radius': '2px',
'border-top-right-radius': '2px',
right: 0,
} );
}
el.iris( {
/**
* @summary Handles the onChange event if one has been defined in the options.
@ -538,17 +603,20 @@
*
* @returns {void}
*/
change: function( event, ui ) {
self.colorAlpha.css( { 'background-color': ui.color.to_s( self.alphaOptions.alphaColorType ) } );
change: function ( event, ui ) {
self.colorAlpha.css( {
'background-color': ui.color.to_s(
self.alphaOptions.alphaColorType
),
} );
// fire change callback if we have one
if ( $.isFunction( self.options.change ) ) {
self.options.change.call( this, event, ui );
}
}
},
} );
/**
* Prevent any clicks inside this widget from leaking to the top and closing it.
*
@ -558,22 +626,22 @@
*
* @return {void}
*/
self.wrap.on( 'click.wpcolorpicker', function( event ) {
self.wrap.on( 'click.wpcolorpicker', function ( event ) {
event.stopPropagation();
});
} );
/**
* Open or close the color picker depending on the class.
*
* @since 3.0.0
*/
self.toggler.click( function() {
self.toggler.click( function () {
if ( self.toggler.hasClass( 'wp-picker-open' ) ) {
self.close();
} else {
self.open();
}
});
} );
/**
* Checks if value is empty when changing the color in the color picker.
@ -585,10 +653,14 @@
*
* @return {void}
*/
el.change( function( event ) {
el.change( function ( event ) {
var val = $( this ).val();
if ( el.hasClass( 'iris-error' ) || val === '' || val.match( /^(#|(rgb|hsl)a?)$/ ) ) {
if (
el.hasClass( 'iris-error' ) ||
val === '' ||
val.match( /^(#|(rgb|hsl)a?)$/ )
) {
if ( isDeprecated ) {
self.toggler.removeAttr( 'style' );
}
@ -611,7 +683,7 @@
*
* @return {void}
*/
self.button.click( function( event ) {
self.button.click( function ( event ) {
if ( $( this ).hasClass( 'wp-picker-default' ) ) {
el.val( self.options.defaultColor ).change();
} else if ( $( this ).hasClass( 'wp-picker-clear' ) ) {
@ -632,4 +704,4 @@
} );
},
} );
} ( jQuery ) );
} )( jQuery );

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -533,7 +533,7 @@ function acf_prepare_field( $field ) {
}
// Use field prefix to modify input name.
if ( $field['prefix'] ) {
if ( ! empty( $field['prefix'] ) ) {
$field['name'] = "{$field['prefix']}[{$field['name']}]";
}

View File

@ -223,6 +223,7 @@ function acf_validate_field_group( $field_group = array() ) {
'hide_on_screen' => array(),
'active' => true,
'description' => '',
'show_in_rest' => false,
)
);

View File

@ -316,6 +316,26 @@ function acf_maybe_idval( $value ) {
return $value;
}
/**
* Convert any numeric strings into their equivalent numeric type. This function will
* work with both single values and arrays.
*
* @param mixed $value Either a single value or an array of values.
* @return mixed
*/
function acf_format_numerics( $value ) {
if ( is_array( $value ) ) {
return array_map(
function ( $v ) {
return is_numeric( $v ) ? $v + 0 : $v;
},
$value
);
}
return is_numeric( $value ) ? $value + 0 : $value;
}
/**
* acf_numval
*
@ -347,8 +367,6 @@ function acf_idify( $str = '' ) {
}
/**
* acf_slugify
*
* Returns a slug friendly string.
*
* @date 24/12/17
@ -359,7 +377,20 @@ function acf_idify( $str = '' ) {
* @return string
*/
function acf_slugify( $str = '', $glue = '-' ) {
return str_replace( array( '_', '-', '/', ' ' ), $glue, strtolower( $str ) );
$raw = $str;
$slug = str_replace( array( '_', '-', '/', ' ' ), $glue, strtolower( remove_accents( $raw ) ) );
$slug = preg_replace( "/[^A-Za-z0-9" . preg_quote( $glue ) . "]/", '', $slug );
/**
* Filters the slug created by acf_slugify().
*
* @since 5.11.4
*
* @param string $slug The newly created slug.
* @param string $raw The original string.
* @param string $glue The separator used to join the string into a slug.
*/
return apply_filters( 'acf/slugify', $slug, $raw, $glue );
}
/**

View File

@ -66,7 +66,7 @@ function acf_add_action_variations( $action = '', $variations = array(), $index
/**
* _acf_apply_hook_variations
*
* Applys hook variations during apply_filters() or do_action().
* Applies hook variations during apply_filters() or do_action().
*
* @date 25/1/19
* @since 5.7.11
@ -84,7 +84,9 @@ function _acf_apply_hook_variations() {
// Get variation information.
$variations = acf_get_store( 'hook-variations' )->get( $filter );
extract( $variations );
$index = $variations['index'];
$type = $variations['type'];
$variations = $variations['variations'];
// Find field in args using index.
$field = $args[ $index ];
@ -145,7 +147,7 @@ function acf_add_deprecated_filter( $deprecated, $version, $replacement ) {
);
// Add generic handler.
// Use a priotiry of 10, and accepted args of 10 (ignored by WP).
// Use a priority of 10, and accepted args of 10 (ignored by WP).
add_filter( $replacement, '_acf_apply_deprecated_hook', 10, 10 );
}
@ -175,14 +177,12 @@ function acf_add_deprecated_action( $deprecated, $version, $replacement ) {
);
// Add generic handler.
// Use a priotiry of 10, and accepted args of 10 (ignored by WP).
// Use a priority of 10, and accepted args of 10 (ignored by WP).
add_filter( $replacement, '_acf_apply_deprecated_hook', 10, 10 );
}
/**
* _acf_apply_deprecated_hook
*
* Applys a deprecated filter during apply_filters() or do_action().
* Applies a deprecated filter during apply_filters() or do_action().
*
* @date 25/1/19
* @since 5.7.11
@ -191,35 +191,28 @@ function acf_add_deprecated_action( $deprecated, $version, $replacement ) {
* @return mixed
*/
function _acf_apply_deprecated_hook() {
// Get current hook.
$hook = current_filter();
$current_hook = current_filter();
// Get args provided.
$args = func_get_args();
// Get deprecated items for this hook.
$items = acf_get_store( 'deprecated-hooks' )->query( array( 'replacement' => $hook ) );
$deprecated_hooks = acf_get_store( 'deprecated-hooks' )->query( array( 'replacement' => $current_hook ) );
// Loop over results.
foreach ( $items as $item ) {
// Extract data.
extract( $item );
foreach ( $deprecated_hooks as $hook ) {
// Check if anyone is hooked into this deprecated hook.
if ( has_filter( $deprecated ) ) {
if ( isset( $hook['deprecated'] ) && has_filter( $hook['deprecated'] ) ) {
// Log warning.
// _deprecated_hook( $deprecated, $version, $hook );
// Apply filters.
if ( $type === 'filter' ) {
$args[0] = apply_filters_ref_array( $deprecated, $args );
// Or do action.
// Apply the item/do the action.
if ( $hook['type'] === 'filter' ) {
$args[0] = apply_filters_ref_array( $hook['deprecated'], $args );
} else {
do_action_ref_array( $deprecated, $args );
do_action_ref_array( $hook['deprecated'], $args );
}
}
}

View File

@ -1,15 +1,14 @@
<?php
/**
* acf_get_meta
*
* Returns an array of "ACF only" meta for the given post_id.
*
* @date 9/10/18
* @since 5.8.0
*
* @param mixed $post_id The post_id for this data.
* @return array
* @param mixed $post_id The post_id for this data.
*
* @return array
*/
function acf_get_meta( $post_id = 0 ) {
@ -20,15 +19,18 @@ function acf_get_meta( $post_id = 0 ) {
}
// Decode $post_id for $type and $id.
extract( acf_decode_post_id( $post_id ) );
$decoded = acf_decode_post_id( $post_id );
// Determine CRUD function.
// - Relies on decoded post_id result to identify option or meta types.
// - Uses xxx_metadata(type) instead of xxx_type_meta() to bypass additional logic that could alter the ID.
if ( $type === 'option' ) {
$allmeta = acf_get_option_meta( $id );
/**
* Determine CRUD function.
*
* - Relies on decoded post_id result to identify option or meta types.
* - Uses xxx_metadata(type) instead of xxx_type_meta() to bypass additional logic that could alter the ID.
*/
if ( $decoded['type'] === 'option' ) {
$allmeta = acf_get_option_meta( $decoded['id'] );
} else {
$allmeta = get_metadata( $type, $id, '' );
$allmeta = get_metadata( $decoded['type'], $decoded['id'], '' );
}
// Loop over meta and check that a reference exists for each value.
@ -53,8 +55,8 @@ function acf_get_meta( $post_id = 0 ) {
* @date 25/1/19
* @since 5.7.11
*
* @param array $meta The arary of loaded meta.
* @param string $post_id The $post_id for this meta.
* @param array $meta The array of loaded meta.
* @param string $post_id The $post_id for this meta.
*/
return apply_filters( 'acf/load_meta', $meta, $post_id );
}
@ -109,20 +111,18 @@ function acf_get_option_meta( $prefix = '' ) {
}
/**
* acf_get_metadata
*
* Retrieves specific metadata from the database.
*
* @date 16/10/2015
* @since 5.2.3
*
* @param (int|string) $post_id The post id.
* @param string $name The meta name.
* @param bool $hidden If the meta is hidden (starts with an underscore).
* @param int|string $post_id The post id.
* @param string $name The meta name.
* @param bool $hidden If the meta is hidden (starts with an underscore).
*
* @return mixed
*/
function acf_get_metadata( $post_id = 0, $name = '', $hidden = false ) {
// Allow filter to short-circuit logic.
$null = apply_filters( 'acf/pre_load_metadata', null, $post_id, $name, $hidden );
if ( $null !== null ) {
@ -130,7 +130,9 @@ function acf_get_metadata( $post_id = 0, $name = '', $hidden = false ) {
}
// Decode $post_id for $type and $id.
extract( acf_decode_post_id( $post_id ) );
$decoded = acf_decode_post_id( $post_id );
$id = $decoded['id'];
$type = $decoded['type'];
// Hidden meta uses an underscore prefix.
$prefix = $hidden ? '_' : '';
@ -152,21 +154,19 @@ function acf_get_metadata( $post_id = 0, $name = '', $hidden = false ) {
}
/**
* acf_update_metadata
*
* Updates metadata in the database.
*
* @date 16/10/2015
* @since 5.2.3
*
* @param (int|string) $post_id The post id.
* @param string $name The meta name.
* @param mixed $value The meta value.
* @param bool $hidden If the meta is hidden (starts with an underscore).
* @return (int|bool) Meta ID if the key didn't exist, true on successful update, false on failure.
* @param int|string $post_id The post id.
* @param string $name The meta name.
* @param mixed $value The meta value.
* @param bool $hidden If the meta is hidden (starts with an underscore).
*
* @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
*/
function acf_update_metadata( $post_id = 0, $name = '', $value = '', $hidden = false ) {
// Allow filter to short-circuit logic.
$pre = apply_filters( 'acf/pre_update_metadata', null, $post_id, $name, $value, $hidden );
if ( $pre !== null ) {
@ -174,7 +174,9 @@ function acf_update_metadata( $post_id = 0, $name = '', $value = '', $hidden = f
}
// Decode $post_id for $type and $id.
extract( acf_decode_post_id( $post_id ) );
$decoded = acf_decode_post_id( $post_id );
$id = $decoded['id'];
$type = $decoded['type'];
// Hidden meta uses an underscore prefix.
$prefix = $hidden ? '_' : '';
@ -197,20 +199,18 @@ function acf_update_metadata( $post_id = 0, $name = '', $value = '', $hidden = f
}
/**
* acf_delete_metadata
*
* Deletes metadata from the database.
*
* @date 16/10/2015
* @since 5.2.3
*
* @param (int|string) $post_id The post id.
* @param string $name The meta name.
* @param bool $hidden If the meta is hidden (starts with an underscore).
* @param int|string $post_id The post id.
* @param string $name The meta name.
* @param bool $hidden If the meta is hidden (starts with an underscore).
*
* @return bool
*/
function acf_delete_metadata( $post_id = 0, $name = '', $hidden = false ) {
// Allow filter to short-circuit logic.
$pre = apply_filters( 'acf/pre_delete_metadata', null, $post_id, $name, $hidden );
if ( $pre !== null ) {
@ -218,7 +218,9 @@ function acf_delete_metadata( $post_id = 0, $name = '', $hidden = false ) {
}
// Decode $post_id for $type and $id.
extract( acf_decode_post_id( $post_id ) );
$decoded = acf_decode_post_id( $post_id );
$id = $decoded['id'];
$type = $decoded['type'];
// Hidden meta uses an underscore prefix.
$prefix = $hidden ? '_' : '';

View File

@ -60,6 +60,18 @@ function acf_get_value( $post_id, $field ) {
// Get field name.
$field_name = $field['name'];
// If we still don't have a proper field array, the field doesn't exist currently.
if ( empty( $field['type'] ) && empty( $field['key'] ) ) {
// Get field ID & type.
$decoded = acf_decode_post_id( $post_id );
if ( apply_filters( 'acf/prevent_access_to_unknown_fields', false ) || ( 'option' === $decoded['type'] && 'options' !== $decoded['id'] ) ) {
return null;
}
do_action( 'acf/get_invalid_field_value', $field, __FUNCTION__ );
}
// Check store.
$store = acf_get_store( 'values' );
if ( $store->has( "$post_id:$field_name" ) ) {
@ -322,3 +334,26 @@ function acf_preview_value( $value, $post_id, $field ) {
// Register variation.
acf_add_filter_variations( 'acf/preview_value', array( 'type', 'name', 'key' ), 2 );
/**
* Potentially log an error if a field doesn't exist when we expect it to.
*
* @param array $field An array representing the field that a value was requested for.
* @param string $function The function that noticed the problem.
*
* @return void
*/
function acf_log_invalid_field_notice( $field, $function ) {
// If "init" has fired, ACF probably wasn't initialized early.
if ( did_action( 'init' ) ) {
return;
}
$error_text = sprintf(
__( '<strong>%1$s</strong> - We\'ve detected one or more calls to retrieve ACF field values before ACF has been initialized. This is not supported and can result in malformed or missing data. <a href="%2$s" target="_blank">Learn how to fix this</a>.', 'acf' ),
acf_get_setting( 'name' ),
'https://www.advancedcustomfields.com/resources/acf-field-functions/'
);
_doing_it_wrong( $function, $error_text, '5.11.1' );
}
add_action( 'acf/get_invalid_field_value', 'acf_log_invalid_field_notice', 10, 2 );

View File

@ -178,6 +178,7 @@ function acf_decode_post_id( $post_id = 0 ) {
$id = absint( $id );
break;
case 'block_%s':
case 'block_%d':
$type = 'block';
$id = $post_id;
break;
@ -216,3 +217,46 @@ function acf_decode_post_id( $post_id = 0 ) {
*/
return apply_filters( 'acf/decode_post_id', compact( 'type', 'id' ), $post_id );
}
/**
* Determine the REST base for a post type or taxonomy object. Note that this is not intended for use
* with term or post objects but is, instead, to be used with the underlying WP_Post_Type and WP_Taxonomy
* instances.
*
* @param WP_Post_Type|WP_Taxonomy $type_object
* @return string|null
*/
function acf_get_object_type_rest_base( $type_object ) {
if ( $type_object instanceof WP_Post_Type || $type_object instanceof WP_Taxonomy ) {
return ! empty( $type_object->rest_base ) ? $type_object->rest_base : $type_object->name;
}
return null;
}
/**
* Extract the ID of a given object/array. This supports all expected types handled by our update_fields() and
* load_fields() callbacks.
*
* @param WP_Post|WP_User|WP_Term|array $object
* @return int|mixed|null
*/
function acf_get_object_id( $object ) {
if ( is_object( $object ) ) {
switch ( get_class( $object ) ) {
case WP_User::class:
case WP_Post::class:
return (int) $object->ID;
case WP_Term::class:
return (int) $object->term_id;
}
} elseif ( isset( $object['id'] ) ) {
return (int) $object['id'];
} elseif ( isset( $object['ID'] ) ) {
return (int) $object['ID'];
}
return null;
}

View File

@ -128,13 +128,15 @@ add_action( 'admin_notices', 'acf_render_admin_notices', 99 );
*
* @param string $text The admin notice text.
* @param string $class The type of notice (warning, error, success, info).
* @param string $dismissable Is this notification dismissible (default true) (since 5.11.0)
* @return ACF_Admin_Notice
*/
function acf_add_admin_notice( $text = '', $type = 'info' ) {
function acf_add_admin_notice( $text = '', $type = 'info', $dismissible = true ) {
return acf_new_admin_notice(
array(
'text' => $text,
'type' => $type,
'text' => $text,
'type' => $type,
'dismissible' => $dismissible,
)
);
}

View File

@ -18,7 +18,6 @@ if ( ! class_exists( 'ACF_Admin' ) ) :
* @return void
*/
function __construct() {
// Add actions.
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
@ -201,6 +200,7 @@ if ( ! class_exists( 'ACF_Admin' ) ) :
// Use RegExp to append "ACF" after the <a> element allowing translations to read correctly.
return preg_replace( '/(<a[\S\s]+?\/a>)/', '$1 ' . __( 'and', 'acf' ) . ' <a href="https://www.advancedcustomfields.com" target="_blank">ACF</a>', $text, 1 );
}
}
// Instantiate.

View File

@ -20,6 +20,24 @@ acf_render_field_wrap(
);
// Show fields in REST API.
if ( acf_get_setting( 'rest_api_enabled' ) ) {
acf_render_field_wrap(
array(
'label' => __( 'Show in REST API', 'acf' ),
'instructions' => '',
'type' => 'true_false',
'name' => 'show_in_rest',
'prefix' => 'acf_field_group',
'value' => $field_group['show_in_rest'],
'ui' => 1,
// 'ui_on_text' => __('Active', 'acf'),
// 'ui_off_text' => __('Inactive', 'acf'),
)
);
}
// style
acf_render_field_wrap(
array(

View File

@ -57,12 +57,19 @@ if ( ! class_exists( 'ACF_Ajax_Check_Screen' ) ) :
'key' => $field_group['key'],
'title' => $field_group['title'],
'position' => $field_group['position'],
'classes' => postbox_classes( 'acf-' . $field_group['key'], $args['screen'] ),
'style' => $field_group['style'],
'label' => $field_group['label_placement'],
'edit' => acf_get_field_group_edit_link( $field_group['ID'] ),
'html' => '',
);
$hidden_metaboxes = get_hidden_meta_boxes( $args['screen'] );
if ( is_array( $hidden_metaboxes ) && in_array( $item['id'], $hidden_metaboxes ) ) {
$item['classes'] = trim( $item['classes'] . ' hide-if-js' );
}
// append html if doesnt already exist on page
if ( ! in_array( $field_group['key'], $args['exists'] ) ) {

View File

@ -419,37 +419,29 @@ function acf_parse_type( $v ) {
}
/*
* acf_get_view
*
* This function will load in a file from the 'admin/views' folder and allow variables to be passed through
*
* @type function
* @date 28/09/13
* @since 5.0.0
*
* @param $view_name (string)
* @param $args (array)
* @return n/a
*/
function acf_get_view( $path = '', $args = array() ) {
/**
* This function will load in a file from the 'admin/views' folder and allow variables to be passed through
*
* @date 28/09/13
* @since 5.0.0
*
* @param string $view_path
* @param array $view_args
*
* @return void
*/
function acf_get_view( $view_path = '', $view_args = array() ) {
// allow view file name shortcut
if ( substr( $path, -4 ) !== '.php' ) {
$path = acf_get_path( "includes/admin/views/{$path}.php" );
if ( substr( $view_path, -4 ) !== '.php' ) {
$view_path = acf_get_path( "includes/admin/views/{$view_path}.php" );
}
// include
if ( file_exists( $path ) ) {
extract( $args );
include $path;
if ( file_exists( $view_path ) ) {
// Use `EXTR_SKIP` here to prevent `$view_path` from being accidentally/maliciously overridden.
extract( $view_args, EXTR_SKIP );
include $view_path;
}
}
@ -4246,7 +4238,7 @@ function acf_remove_array_key_prefix( $array, $prefix ) {
* acf_strip_protocol
*
* This function will remove the proticol from a url
* Used to allow licences to remain active if a site is switched to https
* Used to allow licenses to remain active if a site is switched to https
*
* @type function
* @date 10/01/2017

View File

@ -86,59 +86,41 @@ function the_field( $selector, $post_id = false, $format_value = true ) {
}
/*
* get_field_object()
*
* This function will return an array containing all the field data for a given field_name
*
* @type function
* @since 3.6
* @date 3/02/13
*
* @param $selector (string) the field name or key
* @param $post_id (mixed) the post_id of which the value is saved against
* @param $format_value (boolean) whether or not to format the field value
* @param $load_value (boolean) whether or not to load the field value
* @return $field (array)
*/
/**
* This function will return an array containing all the field data for a given field_name.
*
* @since 3.6
* @date 3/02/13
*
* @param string $selector The field name or key.
* @param mixed $post_id The post_id of which the value is saved against.
* @param bool $format_value Whether to format the field value.
* @param bool $load_value Whether to load the field value.
*
* @return array $field
*/
function get_field_object( $selector, $post_id = false, $format_value = true, $load_value = true ) {
// compatibilty
if ( is_array( $format_value ) ) {
extract( $format_value );
// Compatibility with ACF ~4.
if ( is_array( $format_value ) && isset( $format_value['format_value'] ) ) {
$format_value = $format_value['format_value'];
}
// get valid post_id
$post_id = acf_get_valid_post_id( $post_id );
$field = acf_maybe_get_field( $selector, $post_id );
// get field key
$field = acf_maybe_get_field( $selector, $post_id );
// bail early if no field found
if ( ! $field ) {
return false;
}
// load value
if ( $load_value ) {
$field['value'] = acf_get_value( $post_id, $field );
}
// format value
if ( $format_value ) {
// get value for field
$field['value'] = acf_format_value( $field['value'], $post_id, $field );
}
// return
return $field;
}
/*
@ -864,56 +846,55 @@ function get_row_layout() {
}
/*
* acf_shortcode()
*
* This function is used to add basic shortcode support for the ACF plugin
* eg. [acf field="heading" post_id="123" format_value="1"]
*
* @type function
* @since 1.1.1
* @date 29/01/13
*
* @param $field (string) the field name or key
* @param $post_id (mixed) the post_id of which the value is saved against
* @param $format_value (boolean) whether or not to format the field value
* @return (string)
*/
/**
* This function is used to add basic shortcode support for the ACF plugin
* eg. [acf field="heading" post_id="123" format_value="1"]
*
* @since 1.1.1
* @date 29/01/13
*
* @param array $atts The shortcode attributes.
*
* @return string
*/
function acf_shortcode( $atts ) {
// Mitigate issue where some AJAX requests can return ACF field data.
if ( wp_doing_ajax() && ! current_user_can( 'edit_posts' ) ) {
$capability = apply_filters( 'acf/ajax/shortcode_capability', 'edit_posts' );
if ( wp_doing_ajax() && ( $capability !== false ) && ! current_user_can( $capability ) ) {
return;
}
// extract attributs
extract(
shortcode_atts(
array(
'field' => '',
'post_id' => false,
'format_value' => true,
),
$atts
)
$atts = shortcode_atts(
array(
'field' => '',
'post_id' => false,
'format_value' => true,
),
$atts,
'acf'
);
// get value and return it
$value = get_field( $field, $post_id, $format_value );
// array
if ( is_array( $value ) ) {
$value = @implode( ', ', $value );
$access_already_prevented = apply_filters( 'acf/prevent_access_to_unknown_fields', false );
$filter_applied = false;
if ( ! $access_already_prevented ) {
$filter_applied = true;
add_filter( 'acf/prevent_access_to_unknown_fields', '__return_true' );
}
// Try to get the field value.
$value = get_field( $atts['field'], $atts['post_id'], $atts['format_value'] );
if ( $filter_applied ) {
remove_filter( 'acf/prevent_access_to_unknown_fields', '__return_true' );
}
if ( is_array( $value ) ) {
$value = @implode( ', ', $value );
}
// return
return $value;
}
add_shortcode( 'acf', 'acf_shortcode' );

View File

@ -4,6 +4,7 @@ if ( ! class_exists( 'acf_field__accordion' ) ) :
class acf_field__accordion extends acf_field {
public $show_in_rest = false;
/**
* initialize

View File

@ -288,6 +288,40 @@ if ( ! class_exists( 'acf_field_button_group' ) ) :
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
function get_rest_schema( array $field ) {
$schema = parent::get_rest_schema( $field );
if ( isset( $field['default_value'] ) && '' !== $field['default_value'] ) {
$schema['default'] = $field['default_value'];
}
/**
* If a user has defined keys for the buttons,
* we should use the keys for the available options to POST to,
* since they are what is displayed in GET requests.
*/
$button_keys = array_diff(
array_keys( $field['choices'] ),
array_values( $field['choices'] )
);
$schema['enum'] = empty( $button_keys ) ? $field['choices'] : $button_keys;
$schema['enum'][] = null;
// Allow null via UI will value to empty string.
if ( ! empty( $field['allow_null'] ) ) {
$schema['enum'][] = '';
}
return $schema;
}
}

View File

@ -564,6 +564,45 @@ if ( ! class_exists( 'acf_field_checkbox' ) ) :
return acf_get_field_type( 'select' )->format_value( $value, $post_id, $field );
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
$schema = array(
'type' => array( 'string', 'array', 'null' ),
'required' => isset( $field['required'] ) && $field['required'],
'items' => array(
'type' => 'string',
),
);
if ( isset( $field['default_value'] ) && '' !== $field['default_value'] ) {
$schema['default'] = $field['default_value'];
}
// If we allow custom values, nothing else to do here.
if ( ! empty( $field['allow_custom'] ) ) {
return $schema;
}
/**
* If a user has defined keys for the checkboxes,
* we should use the keys for the available options to POST to,
* since they are what is displayed in GET requests.
*/
$checkbox_keys = array_diff(
array_keys( $field['choices'] ),
array_values( $field['choices'] )
);
$schema['items']['enum'] = empty( $checkbox_keys ) ? $field['choices'] : $checkbox_keys;
return $schema;
}
}

View File

@ -115,7 +115,7 @@ if ( ! class_exists( 'acf_field_date_picker' ) ) :
'value' => $hidden_value,
);
$text_input = array(
'class' => 'input',
'class' => $field['class'] . ' input',
'value' => $display_value,
);
@ -275,6 +275,61 @@ if ( ! class_exists( 'acf_field_date_picker' ) ) :
}
/**
* This filter is applied to the $field after it is loaded from the database
* and ensures the return and display values are set.
*
* @type filter
* @since 5.11.0
* @date 28/09/21
*
* @param array $field The field array holding all the field options.
*
* @return array
*/
function load_field( $field ) {
if ( empty( $field['display_format'] ) ) {
$field['display_format'] = $this->defaults['display_format'];
}
if ( empty( $field['return_format'] ) ) {
$field['return_format'] = $this->defaults['return_format'];
}
return $field;
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
return array(
'type' => array( 'string', 'null' ),
'description' => 'A `Ymd` formatted date string.',
'required' => ! empty( $field['required'] ),
);
}
/**
* Apply basic formatting to prepare the value for default REST output.
*
* @param mixed $value
* @param string|int $post_id
* @param array $field
* @return mixed
*/
public function format_value_for_rest( $value, $post_id, array $field ) {
if ( ! $value ) {
return null;
}
return (string) $value;
}
}

View File

@ -130,7 +130,7 @@ if ( ! class_exists( 'acf_field_date_and_time_picker' ) ) :
'value' => $hidden_value,
);
$text_input = array(
'class' => 'input',
'class' => $field['class'] . ' input',
'value' => $display_value,
);
foreach ( array( 'readonly', 'disabled' ) as $k ) {
@ -250,6 +250,45 @@ if ( ! class_exists( 'acf_field_date_and_time_picker' ) ) :
}
/**
* This filter is applied to the $field after it is loaded from the database
* and ensures the return and display values are set.
*
* @type filter
* @since 5.11.0
* @date 28/09/21
*
* @param array $field The field array holding all the field options.
*
* @return array
*/
function load_field( $field ) {
if ( empty( $field['display_format'] ) ) {
$field['display_format'] = $this->defaults['display_format'];
}
if ( empty( $field['return_format'] ) ) {
$field['return_format'] = $this->defaults['return_format'];
}
return $field;
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
return array(
'type' => array( 'string', 'null' ),
'description' => 'A `Y-m-d H:i:s` formatted date string.',
'required' => ! empty( $field['required'] ),
);
}
}

View File

@ -178,6 +178,19 @@ if ( ! class_exists( 'acf_field_email' ) ) :
return $valid;
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
$schema = parent::get_rest_schema( $field );
$schema['format'] = 'email';
return $schema;
}
}

View File

@ -393,21 +393,18 @@ if ( ! class_exists( 'acf_field_file' ) ) :
return $attachment_id;
}
/*
* validate_value
*
* This function will validate a basic file input
*
* @type function
* @date 11/02/2014
* @since 5.0.0
*
* @param $post_id (int)
* @return $post_id (int)
*/
/**
* validate_value
*
* This function will validate a basic file input
*
* @type function
* @date 11/02/2014
* @since 5.0.0
*
* @param $post_id (int)
* @return $post_id (int)
*/
function validate_value( $valid, $value, $field, $input ) {
// bail early if empty
@ -439,14 +436,103 @@ if ( ! class_exists( 'acf_field_file' ) ) :
// append error
if ( ! empty( $errors ) ) {
$valid = implode( "\n", $errors );
}
// return
return $valid;
}
/**
* Validates file fields updated via the REST API.
*
* @param bool $valid
* @param int $value
* @param array $field
*
* @return bool|WP_Error
*/
public function validate_rest_value( $valid, $value, $field ) {
/**
* A bit of a hack, but we use `wp_prepare_attachment_for_js()` here
* since it returns all the data we need to validate the file, and we use this anyways
* to validate fields updated via UI.
*/
$attachment = wp_prepare_attachment_for_js( $value );
$param = sprintf( '%s[%s]', $field['prefix'], $field['name'] );
$data = array(
'param' => $param,
'value' => (int) $value,
);
if ( ! $attachment ) {
$error = sprintf( __( '%s requires a valid attachment ID.', 'acf' ), $param );
return new WP_Error( 'rest_invalid_param', $error, $data );
}
$errors = acf_validate_attachment( $attachment, $field, 'prepare' );
if ( ! empty( $errors ) ) {
$error = $param . ' - ' . implode( ' ', $errors );
return new WP_Error( 'rest_invalid_param', $error, $data );
}
return $valid;
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
$schema = array(
'type' => array( 'integer', 'null' ),
'required' => isset( $field['required'] ) && $field['required'],
);
if ( ! empty( $field['min_width'] ) ) {
$schema['minWidth'] = (int) $field['min_width'];
}
if ( ! empty( $field['min_height'] ) ) {
$schema['minHeight'] = (int) $field['min_height'];
}
if ( ! empty( $field['min_size'] ) ) {
$schema['minSize'] = $field['min_size'];
}
if ( ! empty( $field['max_width'] ) ) {
$schema['maxWidth'] = (int) $field['max_width'];
}
if ( ! empty( $field['max_height'] ) ) {
$schema['maxHeight'] = (int) $field['max_height'];
}
if ( ! empty( $field['max_size'] ) ) {
$schema['maxSize'] = $field['max_size'];
}
if ( ! empty( $field['mime_types'] ) ) {
$schema['mimeTypes'] = $field['mime_types'];
}
return $schema;
}
/**
* Apply basic formatting to prepare the value for default REST output.
*
* @param mixed $value
* @param string|int $post_id
* @param array $field
* @return mixed
*/
public function format_value_for_rest( $value, $post_id, array $field ) {
return acf_format_numerics( $value );
}
}

View File

@ -301,6 +301,82 @@ if ( ! class_exists( 'acf_field_google_map' ) ) :
// Return default.
return false;
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
return array(
'type' => array( 'object', 'null' ),
'required' => ! empty( $field['required'] ),
'properties' => array(
'address' => array(
'type' => 'string',
),
'lat' => array(
'type' => array( 'string', 'float' ),
),
'lng' => array(
'type' => array( 'string', 'float' ),
),
'zoom' => array(
'type' => array( 'string', 'int' ),
),
'place_id' => array(
'type' => 'string',
),
'name' => array(
'type' => 'string',
),
'street_number' => array(
'type' => array( 'string', 'int' ),
),
'street_name' => array(
'type' => 'string',
),
'street_name_short' => array(
'type' => 'string',
),
'city' => array(
'type' => 'string',
),
'state' => array(
'type' => 'string',
),
'state_short' => array(
'type' => 'string',
),
'post_code' => array(
'type' => array( 'string', 'int' ),
),
'country' => array(
'type' => 'string',
),
'country_short' => array(
'type' => 'string',
),
),
);
}
/**
* Apply basic formatting to prepare the value for default REST output.
*
* @param mixed $value
* @param string|int $post_id
* @param array $field
* @return mixed
*/
public function format_value_for_rest( $value, $post_id, array $field ) {
if ( ! $value ) {
return null;
}
return acf_format_numerics( $value );
}
}

View File

@ -659,6 +659,56 @@ if ( ! class_exists( 'acf_field__group' ) ) :
}
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
$schema = array(
'type' => array( 'object', 'null' ),
'properties' => array(),
'required' => ! empty( $field['required'] ),
);
foreach ( $field['sub_fields'] as $sub_field ) {
if ( $sub_field_schema = acf_get_field_rest_schema( $sub_field ) ) {
$schema['properties'][ $sub_field['name'] ] = $sub_field_schema;
}
}
return $schema;
}
/**
* Apply basic formatting to prepare the value for default REST output.
*
* @param mixed $value
* @param int|string $post_id
* @param array $field
* @return array|mixed
*/
public function format_value_for_rest( $value, $post_id, array $field ) {
if ( empty( $value ) || ! is_array( $value ) || empty( $field['sub_fields'] ) ) {
return $value;
}
// Loop through each row and within that, each sub field to process sub fields individually.
foreach ( $field['sub_fields'] as $sub_field ) {
// Extract the sub field 'field_key'=>'value' pair from the $value and format it.
$sub_value = acf_extract_var( $value, $sub_field['key'] );
$sub_value = acf_format_value_for_rest( $sub_value, $post_id, $sub_field );
// Add the sub field value back to the $value but mapped to the field name instead
// of the key reference.
$value[ $sub_field['name'] ] = $sub_value;
}
return $value;
}
}

View File

@ -422,23 +422,55 @@ if ( ! class_exists( 'acf_field_image' ) ) :
}
/*
* validate_value
*
* This function will validate a basic file input
*
* @type function
* @date 11/02/2014
* @since 5.0.0
*
* @param $post_id (int)
* @return $post_id (int)
*/
/**
* validate_value
*
* This function will validate a basic file input
*
* @type function
* @date 11/02/2014
* @since 5.0.0
*
* @param $post_id (int)
* @return $post_id (int)
*/
function validate_value( $valid, $value, $field, $input ) {
return acf_get_field_type( 'file' )->validate_value( $valid, $value, $field, $input );
}
/**
* Additional validation for the image field when submitted via REST.
*
* @param bool $valid
* @param int $value
* @param array $field
*
* @return bool|WP_Error
*/
public function validate_rest_value( $valid, $value, $field ) {
return acf_get_field_type( 'file' )->validate_rest_value( $valid, $value, $field );
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
return acf_get_field_type( 'file' )->get_rest_schema( $field );
}
/**
* Apply basic formatting to prepare the value for default REST output.
*
* @param mixed $value
* @param string|int $post_id
* @param array $field
* @return mixed
*/
public function format_value_for_rest( $value, $post_id, array $field ) {
return acf_format_numerics( $value );
}
}

View File

@ -280,6 +280,32 @@ if ( ! class_exists( 'acf_field_link' ) ) :
// return
return $value;
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
return array(
'type' => array( 'object', 'null' ),
'required' => ! empty( $field['required'] ),
'properties' => array(
'title' => array(
'type' => 'string',
),
'url' => array(
'type' => 'string',
'required' => true,
'format' => 'uri',
),
'target' => array(
'type' => 'string',
),
),
);
}
}

View File

@ -4,6 +4,7 @@ if ( ! class_exists( 'acf_field_message' ) ) :
class acf_field_message extends acf_field {
public $show_in_rest = false;
/*
* __construct

View File

@ -295,6 +295,44 @@ if ( ! class_exists( 'acf_field_number' ) ) :
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
$schema = array(
'type' => array( 'number', 'null' ),
'required' => ! empty( $field['required'] ),
);
if ( ! empty( $field['min'] ) ) {
$schema['minimum'] = (float) $field['min'];
}
if ( ! empty( $field['max'] ) ) {
$schema['maximum'] = (float) $field['max'];
}
if ( isset( $field['default_value'] ) && is_numeric( $field['default_value'] ) ) {
$schema['default'] = (float) $field['default_value'];
}
return $schema;
}
/**
* Apply basic formatting to prepare the value for default REST output.
*
* @param mixed $value
* @param string|int $post_id
* @param array $field
* @return mixed
*/
public function format_value_for_rest( $value, $post_id, array $field ) {
return acf_format_numerics( $value );
}
}

View File

@ -299,24 +299,22 @@ if ( ! class_exists( 'acf_field_oembed' ) ) :
}
/*
* format_value()
*
* This filter is appied to the $value after it is loaded from the db and before it is returned to the template
*
* @type filter
* @since 3.6
* @date 23/01/13
*
* @param $value (mixed) the value which was loaded from the database
* @param $post_id (mixed) the $post_id from which the value was loaded
* @param $field (array) the field array holding all the field options
*
* @return $value (mixed) the modified value
*/
/**
* format_value()
*
* This filter is appied to the $value after it is loaded from the db and before it is returned to the template
*
* @type filter
* @since 3.6
* @date 23/01/13
*
* @param $value (mixed) the value which was loaded from the database
* @param $post_id (mixed) the $post_id from which the value was loaded
* @param $field (array) the field array holding all the field options
*
* @return $value (mixed) the modified value
*/
function format_value( $value, $post_id, $field ) {
// bail early if no value
if ( empty( $value ) ) {
return $value;
@ -330,9 +328,20 @@ if ( ! class_exists( 'acf_field_oembed' ) ) :
// return
return $value;
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
$schema = parent::get_rest_schema( $field );
$schema['format'] = 'uri';
return $schema;
}
}

View File

@ -619,6 +619,91 @@ if ( ! class_exists( 'acf_field_page_link' ) ) :
return $value;
}
/**
* Validates page link fields updated via the REST API.
*
* @param bool $valid
* @param int $value
* @param array $field
*
* @return bool|WP_Error
*/
public function validate_rest_value( $valid, $value, $field ) {
return acf_get_field_type( 'post_object' )->validate_rest_value( $valid, $value, $field );
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
$schema = array(
'type' => array( 'integer', 'array', 'null' ),
'required' => ! empty( $field['required'] ),
'items' => array(
'type' => array( 'integer' ),
),
);
if ( empty( $field['allow_null'] ) ) {
$schema['minItems'] = 1;
}
if ( ! empty( $field['allow_archives'] ) ) {
$schema['type'][] = 'string';
$schema['items']['type'][] = 'string';
}
if ( empty( $field['multiple'] ) ) {
$schema['maxItems'] = 1;
}
return $schema;
}
/**
* @see \acf_field::get_rest_links()
* @param mixed $value The raw (unformatted) field value.
* @param int|string $post_id
* @param array $field
* @return array
*/
public function get_rest_links( $value, $post_id, array $field ) {
$links = array();
if ( empty( $value ) ) {
return $links;
}
foreach ( (array) $value as $object_id ) {
if ( ! $post_type = get_post_type( $object_id ) or ! $post_type = get_post_type_object( $post_type ) ) {
continue;
}
$rest_base = acf_get_object_type_rest_base( $post_type );
$links[] = array(
'rel' => $post_type->name === 'attachment' ? 'acf:attachment' : 'acf:post',
'href' => rest_url( sprintf( '/wp/v2/%s/%s', $rest_base, $object_id ) ),
'embeddable' => true,
);
}
return $links;
}
/**
* Apply basic formatting to prepare the value for default REST output.
*
* @param mixed $value
* @param string|int $post_id
* @param array $field
* @return mixed
*/
public function format_value_for_rest( $value, $post_id, array $field ) {
return acf_format_numerics( $value );
}
}

View File

@ -580,6 +580,179 @@ if ( ! class_exists( 'acf_field_post_object' ) ) :
}
/**
* Validates post object fields updated via the REST API.
*
* @param bool $valid
* @param int $value
* @param array $field
*
* @return bool|WP_Error
*/
public function validate_rest_value( $valid, $value, $field ) {
if ( is_null( $value ) ) {
return $valid;
}
$param = sprintf( '%s[%s]', $field['prefix'], $field['name'] );
$data = array( 'param' => $param );
$value = is_array( $value ) ? $value : array( $value );
$invalid_posts = array();
$post_type_errors = array();
$taxonomy_errors = array();
foreach ( $value as $post_id ) {
if ( is_string( $post_id ) ) {
continue;
}
$post_type = get_post_type( $post_id );
if ( ! $post_type ) {
$invalid_posts[] = $post_id;
continue;
}
if (
is_array( $field['post_type'] ) &&
! empty( $field['post_type'] ) &&
! in_array( $post_type, $field['post_type'] )
) {
$post_type_errors[] = $post_id;
}
if ( is_array( $field['taxonomy'] ) && ! empty( $field['taxonomy'] ) ) {
$found = false;
foreach ( $field['taxonomy'] as $taxonomy_term ) {
$decoded = acf_decode_taxonomy_term( $taxonomy_term );
if ( $decoded && is_object_in_term( $post_id, $decoded['taxonomy'], $decoded['term'] ) ) {
$found = true;
break;
}
}
if ( ! $found ) {
$taxonomy_errors[] = $post_id;
}
}
}
if ( count( $invalid_posts ) ) {
$error = sprintf(
__( '%1$s must have a valid post ID.', 'acf' ),
$param
);
$data['value'] = $invalid_posts;
return new WP_Error( 'rest_invalid_param', $error, $data );
}
if ( count( $post_type_errors ) ) {
$error = sprintf(
_n(
'%1$s must be of post type %2$s.',
'%1$s must be of one of the following post types: %2$s',
count( $field['post_type'] ),
'acf'
),
$param,
count( $field['post_type'] ) > 1 ? implode( ', ', $field['post_type'] ) : $field['post_type'][0]
);
$data['value'] = $post_type_errors;
return new WP_Error( 'rest_invalid_param', $error, $data );
}
if ( count( $taxonomy_errors ) ) {
$error = sprintf(
_n(
'%1$s must have term %2$s.',
'%1$s must have one of the following terms: %2$s',
count( $field['taxonomy'] ),
'acf'
),
$param,
count( $field['taxonomy'] ) > 1 ? implode( ', ', $field['taxonomy'] ) : $field['taxonomy'][0]
);
$data['value'] = $taxonomy_errors;
return new WP_Error( 'rest_invalid_param', $error, $data );
}
return $valid;
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
$schema = array(
'type' => array( 'integer', 'array', 'null' ),
'required' => ! empty( $field['required'] ),
'items' => array(
'type' => 'integer',
),
);
if ( empty( $field['allow_null'] ) ) {
$schema['minItems'] = 1;
}
if ( empty( $field['multiple'] ) ) {
$schema['maxItems'] = 1;
}
return $schema;
}
/**
* @see \acf_field::get_rest_links()
* @param mixed $value The raw (unformatted) field value.
* @param int|string $post_id
* @param array $field
* @return array
*/
public function get_rest_links( $value, $post_id, array $field ) {
$links = array();
if ( empty( $value ) ) {
return $links;
}
foreach ( (array) $value as $object_id ) {
if ( ! $post_type = get_post_type( $object_id ) ) {
continue;
}
if ( ! $post_type_object = get_post_type_object( $post_type ) ) {
continue;
}
$rest_base = acf_get_object_type_rest_base( $post_type_object );
$links[] = array(
'rel' => $post_type_object->name === 'attachment' ? 'acf:attachment' : 'acf:post',
'href' => rest_url( sprintf( '/wp/v2/%s/%s', $rest_base, $object_id ) ),
'embeddable' => true,
);
}
return $links;
}
/**
* Apply basic formatting to prepare the value for default REST output.
*
* @param mixed $value
* @param string|int $post_id
* @param array $field
* @return mixed
*/
public function format_value_for_rest( $value, $post_id, array $field ) {
return acf_format_numerics( $value );
}
}

View File

@ -443,6 +443,42 @@ if ( ! class_exists( 'acf_field_radio' ) ) :
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
function get_rest_schema( array $field ) {
$schema = parent::get_rest_schema( $field );
if ( isset( $field['default_value'] ) && '' !== $field['default_value'] ) {
$schema['default'] = $field['default_value'];
}
// If other/custom choices are allowed, nothing else to do here.
if ( ! empty( $field['other_choice'] ) ) {
return $schema;
}
/**
* If a user has defined keys for the radio options,
* we should use the keys for the available options to POST to,
* since they are what is displayed in GET requests.
*/
$radio_keys = array_diff(
array_keys( $field['choices'] ),
array_values( $field['choices'] )
);
$schema['enum'] = empty( $radio_keys ) ? $field['choices'] : $radio_keys;
if ( ! empty( $field['allow_null'] ) ) {
$schema['enum'][] = null;
}
return $schema;
}
}

View File

@ -227,6 +227,39 @@ if ( ! class_exists( 'acf_field_range' ) ) :
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
$schema = array(
'type' => array( 'number', 'null' ),
'required' => ! empty( $field['required'] ),
'minimum' => empty( $field['min'] ) ? 0 : (int) $field['min'],
'maximum' => empty( $field['max'] ) ? 100 : (int) $field['max'],
);
if ( isset( $field['default_value'] ) && is_numeric( $field['default_value'] ) ) {
$schema['default'] = (int) $field['default_value'];
}
return $schema;
}
/**
* Apply basic formatting to prepare the value for default REST output.
*
* @param mixed $value
* @param string|int $post_id
* @param array $field
* @return mixed
*/
public function format_value_for_rest( $value, $post_id, array $field ) {
return acf_format_numerics( $value );
}
}

View File

@ -760,24 +760,22 @@ if ( ! class_exists( 'acf_field_relationship' ) ) :
}
/*
* update_value()
*
* This filter is applied to the $value before it is updated in the db
*
* @type filter
* @since 3.6
* @date 23/01/13
*
* @param $value - the value which will be saved in the database
* @param $post_id - the $post_id of which the value will be saved
* @param $field - the field array holding all the field options
*
* @return $value - the modified value
*/
/**
* update_value()
*
* This filter is applied to the $value before it is updated in the db
*
* @type filter
* @since 3.6
* @date 23/01/13
*
* @param $value - the value which will be saved in the database
* @param $post_id - the $post_id of which the value will be saved
* @param $field - the field array holding all the field options
*
* @return $value - the modified value
*/
function update_value( $value, $post_id, $field ) {
// Bail early if no value.
if ( empty( $value ) ) {
return $value;
@ -799,6 +797,90 @@ if ( ! class_exists( 'acf_field_relationship' ) ) :
return $value;
}
/**
* Validates relationship fields updated via the REST API.
*
* @param bool $valid
* @param int $value
* @param array $field
*
* @return bool|WP_Error
*/
public function validate_rest_value( $valid, $value, $field ) {
return acf_get_field_type( 'post_object' )->validate_rest_value( $valid, $value, $field );
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
$schema = array(
'type' => array( 'integer', 'array', 'null' ),
'required' => ! empty( $field['required'] ),
'items' => array(
'type' => 'integer',
),
);
if ( empty( $field['allow_null'] ) ) {
$schema['minItems'] = 1;
}
if ( ! empty( $field['min'] ) ) {
$schema['minItems'] = (int) $field['min'];
}
if ( ! empty( $field['max'] ) ) {
$schema['maxItems'] = (int) $field['max'];
}
return $schema;
}
/**
* @see \acf_field::get_rest_links()
* @param mixed $value The raw (unformatted) field value.
* @param int|string $post_id
* @param array $field
* @return array
*/
public function get_rest_links( $value, $post_id, array $field ) {
$links = array();
if ( empty( $value ) ) {
return $links;
}
foreach ( (array) $value as $object_id ) {
if ( ! $post_type = get_post_type( $object_id ) or ! $post_type = get_post_type_object( $post_type ) ) {
continue;
}
$rest_base = acf_get_object_type_rest_base( $post_type );
$links[] = array(
'rel' => $post_type->name === 'attachment' ? 'acf:attachment' : 'acf:post',
'href' => rest_url( sprintf( '/wp/v2/%s/%s', $rest_base, $object_id ) ),
'embeddable' => true,
);
}
return $links;
}
/**
* Apply basic formatting to prepare the value for default REST output.
*
* @param mixed $value
* @param string|int $post_id
* @param array $field
* @return mixed
*/
public function format_value_for_rest( $value, $post_id, array $field ) {
return acf_format_numerics( $value );
}
}

View File

@ -57,7 +57,7 @@ if ( ! class_exists( 'acf_field_select' ) ) :
function input_admin_enqueue_scripts() {
// bail ealry if no enqueue
// bail early if no enqueue
if ( ! acf_get_setting( 'enqueue_select2' ) ) {
return;
}
@ -83,7 +83,7 @@ if ( ! class_exists( 'acf_field_select' ) ) :
// v4
if ( $major == 4 ) {
$version = '4.0';
$version = '4.0.13';
$script = acf_get_url( "assets/inc/select2/4/select2.full{$min}.js" );
$style = acf_get_url( "assets/inc/select2/4/select2{$min}.css" );
@ -324,6 +324,10 @@ if ( ! class_exists( 'acf_field_select' ) ) :
);
}
if ( ! empty( $field['query_nonce'] ) ) {
$select['data-query-nonce'] = $field['query_nonce'];
}
// append
$select['value'] = $value;
$select['choices'] = $choices;
@ -627,6 +631,87 @@ if ( ! class_exists( 'acf_field_select' ) ) :
}
/**
* Validates select fields updated via the REST API.
*
* @param bool $valid
* @param int $value
* @param array $field
*
* @return bool|WP_Error
*/
public function validate_rest_value( $valid, $value, $field ) {
// rest_validate_request_arg() handles the other types, we just worry about strings.
if ( is_null( $value ) || is_array( $value ) ) {
return $valid;
}
$option_keys = array_diff(
array_keys( $field['choices'] ),
array_values( $field['choices'] )
);
$allowed = empty( $option_keys ) ? $field['choices'] : $option_keys;
if ( ! in_array( $value, $allowed ) ) {
$param = sprintf( '%s[%s]', $field['prefix'], $field['name'] );
$data = array(
'param' => $param,
'value' => $value,
);
$error = sprintf(
__( '%1$s is not one of %2$s', 'acf' ),
$param,
implode( ', ', $allowed )
);
return new WP_Error( 'rest_invalid_param', $error, $data );
}
return $valid;
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
/**
* If a user has defined keys for the select options,
* we should use the keys for the available options to POST to,
* since they are what is displayed in GET requests.
*/
$option_keys = array_diff(
array_keys( $field['choices'] ),
array_values( $field['choices'] )
);
$schema = array(
'type' => array( 'string', 'array', 'null' ),
'required' => ! empty( $field['required'] ),
'items' => array(
'type' => array( 'string' ),
'enum' => empty( $option_keys ) ? $field['choices'] : $option_keys,
),
);
if ( empty( $field['allow_null'] ) ) {
$schema['minItems'] = 1;
}
if ( empty( $field['multiple'] ) ) {
$schema['maxItems'] = 1;
}
if ( isset( $field['default_value'] ) && '' !== $field['default_value'] ) {
$schema['default'] = $field['default_value'];
}
return $schema;
}
}

View File

@ -4,6 +4,7 @@ if ( ! class_exists( 'acf_field_tab' ) ) :
class acf_field_tab extends acf_field {
public $show_in_rest = false;
/*
* __construct

View File

@ -315,7 +315,10 @@ if ( ! class_exists( 'acf_field_taxonomy' ) ) :
if ( $field['load_terms'] ) {
// Decode $post_id for $type and $id.
extract( acf_decode_post_id( $post_id ) );
$decoded = acf_decode_post_id( $post_id );
$type = $decoded['type'];
$id = $decoded['id'];
if ( $type === 'block' ) {
// Get parent block...
}
@ -426,30 +429,29 @@ if ( ! class_exists( 'acf_field_taxonomy' ) ) :
}
/*
* save_post
*
* This function will save any terms in the save_post_terms array
*
* @type function
* @date 26/11/2014
* @since 5.0.9
*
* @param $post_id (int)
* @return n/a
*/
/**
* This function will save any terms in the save_post_terms array
*
* @date 26/11/2014
* @since 5.0.9
*
* @param int $post_id
*
* @return void
*/
function save_post( $post_id ) {
// Check for saved terms.
if ( ! empty( $this->save_post_terms ) ) {
/**
* Determine object ID allowing for non "post" $post_id (user, taxonomy, etc).
* Although not fully supported by WordPress, non "post" objects may use the term relationships table.
* Sharing taxonomies across object types is discouraged, but unique taxonomies work well.
* Note: Do not attempt to restrict to "post" only. This has been attempted in 5.8.9 and later reverted.
*/
$decoded = acf_decode_post_id( $post_id );
$type = $decoded['type'];
$id = $decoded['id'];
// Determine object ID allowing for non "post" $post_id (user, taxonomy, etc).
// Although not fully supported by WordPress, non "post" objects may use the term relationships table.
// Sharing taxonomies across object types is discoraged, but unique taxonomies work well.
// Note: Do not attempt to restrict to "post" only. This has been attempted in 5.8.9 and later reverted.
extract( acf_decode_post_id( $post_id ) );
if ( $type === 'block' ) {
// Get parent block...
}
@ -464,7 +466,6 @@ if ( ! class_exists( 'acf_field_taxonomy' ) ) :
}
}
/*
* format_value()
*
@ -966,6 +967,67 @@ if ( ! class_exists( 'acf_field_taxonomy' ) ) :
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
$schema = array(
'type' => array( 'integer', 'array', 'null' ),
'required' => ! empty( $field['required'] ),
'items' => array(
'type' => 'integer',
),
);
if ( empty( $field['allow_null'] ) ) {
$schema['minItems'] = 1;
}
if ( in_array( $field['field_type'], array( 'radio', 'select' ) ) ) {
$schema['maxItems'] = 1;
}
return $schema;
}
/**
* @see \acf_field::get_rest_links()
* @param mixed $value The raw (unformatted) field value.
* @param int|string $post_id
* @param array $field
* @return array
*/
public function get_rest_links( $value, $post_id, array $field ) {
$links = array();
if ( empty( $value ) ) {
return $links;
}
foreach ( (array) $value as $object_id ) {
$term = get_term( $object_id );
if ( ! $term instanceof WP_Term ) {
continue;
}
$rest_base = acf_get_object_type_rest_base( get_taxonomy( $term->taxonomy ) );
if ( ! $rest_base ) {
continue;
}
$links[] = array(
'rel' => 'acf:term',
'href' => rest_url( sprintf( '/wp/v2/%s/%s', $rest_base, $object_id ) ),
'embeddable' => true,
'taxonomy' => $term->taxonomy,
);
}
return $links;
}
}

View File

@ -171,6 +171,22 @@ if ( ! class_exists( 'acf_field_text' ) ) :
// Return.
return $valid;
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
function get_rest_schema( array $field ) {
$schema = parent::get_rest_schema( $field );
if ( ! empty( $field['maxlength'] ) ) {
$schema['maxLength'] = (int) $field['maxlength'];
}
return $schema;
}
}

View File

@ -224,6 +224,22 @@ if ( ! class_exists( 'acf_field_textarea' ) ) :
// Return.
return $valid;
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
function get_rest_schema( array $field ) {
$schema = parent::get_rest_schema( $field );
if ( ! empty( $field['maxlength'] ) ) {
$schema['maxLength'] = (int) $field['maxlength'];
}
return $schema;
}
}

View File

@ -66,7 +66,7 @@ if ( ! class_exists( 'acf_field_time_picker' ) ) :
'value' => $field['value'],
);
$text_input = array(
'class' => 'input',
'class' => $field['class'] . ' input',
'type' => 'text',
'value' => $display_value,
);
@ -166,6 +166,43 @@ if ( ! class_exists( 'acf_field_time_picker' ) ) :
}
/**
* This filter is applied to the $field after it is loaded from the database
* and ensures the return and display values are set.
*
* @type filter
* @since 5.11.0
* @date 28/09/21
*
* @param array $field The field array holding all the field options.
*
* @return array
*/
function load_field( $field ) {
if ( empty( $field['display_format'] ) ) {
$field['display_format'] = $this->defaults['display_format'];
}
if ( empty( $field['return_format'] ) ) {
$field['return_format'] = $this->defaults['return_format'];
}
return $field;
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
return array(
'type' => array( 'string', 'null' ),
'description' => 'A `H:i:s` formatted time string.',
'required' => ! empty( $field['required'] ),
);
}
}

View File

@ -285,6 +285,37 @@ if ( ! class_exists( 'acf_field_true_false' ) ) :
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
$schema = array(
'type' => array( 'boolean', 'null' ),
'required' => ! empty( $field['required'] ),
);
if ( isset( $field['default_value'] ) && '' !== $field['default_value'] ) {
$schema['default'] = (bool) $field['default_value'];
}
return $schema;
}
/**
* Apply basic formatting to prepare the value for default REST output.
*
* @param mixed $value
* @param string|int $post_id
* @param array $field
* @return mixed
*/
public function format_value_for_rest( $value, $post_id, array $field ) {
return (bool) $value;
}
}

View File

@ -160,6 +160,19 @@ if ( ! class_exists( 'acf_field_url' ) ) :
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
$schema = parent::get_rest_schema( $field );
$schema['format'] = 'uri';
return $schema;
}
}

View File

@ -113,10 +113,11 @@ if ( ! class_exists( 'ACF_Field_User' ) ) :
function render_field( $field ) {
// Change Field into a select.
$field['type'] = 'select';
$field['ui'] = 1;
$field['ajax'] = 1;
$field['choices'] = array();
$field['type'] = 'select';
$field['ui'] = 1;
$field['ajax'] = 1;
$field['choices'] = array();
$field['query_nonce'] = wp_create_nonce( 'acf/fields/user/query' . $field['key'] );
// Populate choices.
if ( $field['value'] ) {
@ -344,11 +345,15 @@ if ( ! class_exists( 'ACF_Field_User' ) ) :
* @return void
*/
function ajax_query_init( $request, $query ) {
// Require field.
if ( ! $query->field ) {
// Require field and make sure it's a user field.
if ( ! $query->field || $query->field['type'] !== $this->name ) {
$query->send( new WP_Error( 'acf_missing_field', __( 'Error loading field.', 'acf' ), array( 'status' => 404 ) ) );
}
// Verify that this is a legitimate request using a separate nonce from the main AJAX nonce.
if ( ! isset( $_REQUEST['user_query_nonce'] ) || ! wp_verify_nonce( $_REQUEST['user_query_nonce'], 'acf/fields/user/query' . $query->field['key']) ) {
$query->send( new WP_Error( 'acf_invalid_request', __( 'Invalid request.', 'acf' ), array( 'status' => 404 ) ) );
}
}
/**
@ -468,6 +473,135 @@ if ( ! class_exists( 'ACF_Field_User' ) ) :
_deprecated_function( __FUNCTION__, '5.8.9' );
return $columns;
}
/**
* Validates user fields updated via the REST API.
*
* @param bool $valid
* @param int $value
* @param array $field
*
* @return bool|WP_Error
*/
public function validate_rest_value( $valid, $value, $field ) {
if ( is_null( $value ) ) {
return $valid;
}
$param = sprintf( '%s[%s]', $field['prefix'], $field['name'] );
$data = array( 'param' => $param );
$value = is_array( $value ) ? $value : array( $value );
$invalid_users = array();
$insufficient_roles = array();
foreach ( $value as $user_id ) {
$user_data = get_userdata( $user_id );
if ( ! $user_data ) {
$invalid_users[] = $user_id;
continue;
}
if ( empty( $field['role'] ) ) {
continue;
}
$has_roles = count( array_intersect( $field['role'], $user_data->roles ) );
if ( ! $has_roles ) {
$insufficient_roles[] = $user_id;
}
}
if ( count( $invalid_users ) ) {
$error = sprintf(
__( '%1$s must have a valid user ID.', 'acf' ),
$param
);
$data['value'] = $invalid_users;
return new WP_Error( 'rest_invalid_param', $error, $data );
}
if ( count( $insufficient_roles ) ) {
$error = sprintf(
_n(
'%1$s must have a user with the %2$s role.',
'%1$s must have a user with one of the following roles: %2$s',
count( $field['role'] ),
'acf'
),
$param,
count( $field['role'] ) > 1 ? implode( ', ', $field['role'] ) : $field['role'][0]
);
$data['value'] = $insufficient_roles;
return new WP_Error( 'rest_invalid_param', $error, $data );
}
return $valid;
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
$schema = array(
'type' => array( 'integer', 'array', 'null' ),
'required' => ! empty( $field['required'] ),
'items' => array(
'type' => 'integer',
),
);
if ( empty( $field['allow_null'] ) ) {
$schema['minItems'] = 1;
}
if ( empty( $field['multiple'] ) ) {
$schema['maxItems'] = 1;
}
return $schema;
}
/**
* @see \acf_field::get_rest_links()
* @param mixed $value The raw (unformatted) field value.
* @param int|string $post_id
* @param array $field
* @return array
*/
public function get_rest_links( $value, $post_id, array $field ) {
$links = array();
if ( empty( $value ) ) {
return $links;
}
foreach ( (array) $value as $object_id ) {
$links[] = array(
'rel' => 'acf:user',
'href' => rest_url( '/wp/v2/users/' . $object_id ),
'embeddable' => true,
);
}
return $links;
}
/**
* Apply basic formatting to prepare the value for default REST output.
*
* @param mixed $value
* @param string|int $post_id
* @param array $field
* @return mixed
*/
public function format_value_for_rest( $value, $post_id, array $field ) {
return acf_format_numerics( $value );
}
}

View File

@ -179,18 +179,15 @@ if ( ! class_exists( 'acf_field_wysiwyg' ) ) :
);
}
/*
* render_field()
*
* Create the HTML interface for your field
*
* @param $field - an array holding all the field's data
*
* @type action
* @since 3.6
* @date 23/01/13
*/
/**
* Create the HTML interface for your field
*
* @param array $field An array holding all the field's data
*
* @type action
* @since 3.6
* @date 23/01/13
*/
function render_field( $field ) {
// enqueue
@ -240,6 +237,8 @@ if ( ! class_exists( 'acf_field_wysiwyg' ) ) :
// filter
add_filter( 'acf_the_editor_content', 'format_for_editor', 10, 2 );
$field['value'] = is_string( $field['value'] ) ? $field['value'] : '';
$field['value'] = apply_filters( 'acf_the_editor_content', $field['value'], $default_editor );
// attr
@ -403,39 +402,29 @@ if ( ! class_exists( 'acf_field_wysiwyg' ) ) :
}
/*
* format_value()
*
* This filter is appied to the $value after it is loaded from the db and before it is returned to the template
*
* @type filter
* @since 3.6
* @date 23/01/13
*
* @param $value (mixed) the value which was loaded from the database
* @param $post_id (mixed) the $post_id from which the value was loaded
* @param $field (array) the field array holding all the field options
*
* @return $value (mixed) the modified value
*/
/**
* This filter is applied to the $value after it is loaded from the db, and before it is returned to the template
*
* @type filter
* @since 3.6
* @date 23/01/13
*
* @param mixed $value The value which was loaded from the database
* @param mixed $post_id The $post_id from which the value was loaded
* @param array $field The field array holding all the field options
*
* @return mixed $value The modified value
*/
function format_value( $value, $post_id, $field ) {
// bail early if no value
if ( empty( $value ) ) {
// Bail early if no value or not a string.
if ( empty( $value ) || ! is_string( $value ) ) {
return $value;
}
// apply filters
$value = apply_filters( 'acf_the_content', $value );
// follow the_content function in /wp-includes/post-template.php
$value = str_replace( ']]>', ']]&gt;', $value );
return $value;
// Follow the_content function in /wp-includes/post-template.php
return str_replace( ']]>', ']]&gt;', $value );
}
}

View File

@ -12,6 +12,7 @@ if ( ! class_exists( 'acf_field' ) ) :
$l10n = array(),
$public = true;
public $show_in_rest = true;
/*
* __construct
@ -49,6 +50,7 @@ if ( ! class_exists( 'acf_field' ) ) :
$this->add_field_action( 'acf/delete_value', array( $this, 'delete_value' ), 10, 3 );
// field
$this->add_field_filter( 'acf/validate_rest_value', array( $this, 'validate_rest_value' ), 10, 3 );
$this->add_field_filter( 'acf/validate_field', array( $this, 'validate_field' ), 10, 1 );
$this->add_field_filter( 'acf/load_field', array( $this, 'load_field' ), 10, 1 );
$this->add_field_filter( 'acf/update_field', array( $this, 'update_field' ), 10, 1 );
@ -268,6 +270,79 @@ if ( ! class_exists( 'acf_field' ) ) :
}
/**
* Add additional validation for fields being updated via the REST API.
*
* @param bool $valid
* @param mixed $value
* @param array $field
*
* @return bool|WP_Error
*/
public function validate_rest_value( $valid, $value, $field ) {
return $valid;
}
/**
* Return the schema array for the REST API.
*
* @param array $field
* @return array
*/
public function get_rest_schema( array $field ) {
$schema = array(
'type' => array( 'string', 'null' ),
'required' => ! empty( $field['required'] ),
);
if ( isset( $field['default_value'] ) && '' !== $field['default_value'] ) {
$schema['default'] = $field['default_value'];
}
return $schema;
}
/**
* Return an array of links for addition to the REST API response. Each link is an array and must have both `rel` and
* `href` keys. The `href` key must be a REST API resource URL. If a link is marked as `embeddable`, the `_embed` URL
* parameter will trigger WordPress to dispatch an internal sub request and load the object within the same request
* under the `_embedded` response property.
*
* e.g;
* [
* [
* 'rel' => 'acf:post',
* 'href' => 'https://example.com/wp-json/wp/v2/posts/497',
* 'embeddable' => true,
* ],
* [
* 'rel' => 'acf:user',
* 'href' => 'https://example.com/wp-json/wp/v2/users/2',
* 'embeddable' => true,
* ],
* ]
*
* @param mixed $value The raw (unformatted) field value.
* @param string|int $post_id
* @param array $field
* @return array
*/
public function get_rest_links( $value, $post_id, array $field ) {
return array();
}
/**
* Apply basic formatting to prepare the value for default REST output.
*
* @param mixed $value
* @param string|int $post_id
* @param array $field
* @return mixed
*/
public function format_value_for_rest( $value, $post_id, array $field ) {
return $value;
}
}
endif; // class_exists check

View File

@ -345,7 +345,9 @@ if ( ! class_exists( 'acf_form_nav_menu' ) ) :
(function($) {
// append html
$('#post-body-content').append( $('#tmpl-acf-menu-settings').html() );
var html = $('#tmpl-acf-menu-settings').html();
$('#tmpl-acf-menu-settings').remove();
$('#post-body-content').append( html );
// avoid WP over-writing $_POST data

View File

@ -36,6 +36,10 @@ if ( ! class_exists( 'ACF_Location_User_Form' ) ) :
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// REST API has no forms, so we should always allow it.
if ( ! empty( $screen['rest'] ) ) {
return true;
}
// Check screen args.
if ( isset( $screen['user_form'] ) ) {

14
includes/rest-api.php Normal file
View File

@ -0,0 +1,14 @@
<?php
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
acf_include( 'includes/rest-api/acf-rest-api-functions.php' );
acf_include( 'includes/rest-api/class-acf-rest-api.php' );
acf_include( 'includes/rest-api/class-acf-rest-embed-links.php' );
acf_include( 'includes/rest-api/class-acf-rest-request.php' );
// Initialize.
acf_new_instance( 'ACF_Rest_Api' );

Some files were not shown because too many files have changed in this diff Show More