Merge branch 'release/5.9.1'

This commit is contained in:
Remco Tolsma 2020-10-01 13:49:04 +02:00
commit a2b8fc9aec
128 changed files with 31014 additions and 20372 deletions

52
acf.php
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.8.7
Version: 5.9.1
Author: Elliot Condon
Author URI: https://www.advancedcustomfields.com
Text Domain: acf
@ -17,7 +17,7 @@ if( ! class_exists('ACF') ) :
class ACF {
/** @var string The plugin version number. */
var $version = '5.8.7';
var $version = '5.9.1';
/** @var array The plugin settings array. */
var $settings = array();
@ -108,7 +108,8 @@ class ACF {
// Include classes.
acf_include('includes/class-acf-data.php');
acf_include('includes/fields/class-acf-field.php');
acf_include('includes/locations/class-acf-location.php');
acf_include('includes/locations/abstract-acf-legacy-location.php');
acf_include('includes/locations/abstract-acf-location.php');
// Include functions.
acf_include('includes/acf-helper-functions.php');
@ -121,6 +122,7 @@ class ACF {
acf_include('includes/acf-user-functions.php');
acf_include('includes/acf-value-functions.php');
acf_include('includes/acf-input-functions.php');
acf_include('includes/acf-wp-functions.php');
// Include core.
acf_include('includes/fields.php');
@ -128,10 +130,10 @@ class ACF {
acf_include('includes/assets.php');
acf_include('includes/compatibility.php');
acf_include('includes/deprecated.php');
acf_include('includes/json.php');
acf_include('includes/l10n.php');
acf_include('includes/local-fields.php');
acf_include('includes/local-meta.php');
acf_include('includes/local-json.php');
acf_include('includes/loop.php');
acf_include('includes/media.php');
acf_include('includes/revisions.php');
@ -144,6 +146,9 @@ class ACF {
acf_include('includes/ajax/class-acf-ajax-check-screen.php');
acf_include('includes/ajax/class-acf-ajax-user-setting.php');
acf_include('includes/ajax/class-acf-ajax-upgrade.php');
acf_include('includes/ajax/class-acf-ajax-query.php');
acf_include('includes/ajax/class-acf-ajax-query-users.php');
acf_include('includes/ajax/class-acf-ajax-local-json-diff.php');
// Include forms.
acf_include('includes/forms/form-attachment.php');
@ -167,6 +172,9 @@ class ACF {
acf_include('includes/admin/admin-upgrade.php');
}
// Include legacy.
acf_include('includes/legacy/legacy-locations.php');
// Include PRO.
acf_include('pro/acf-pro.php');
@ -413,12 +421,12 @@ class ACF {
// Register the Disabled post status.
register_post_status('acf-disabled', array(
'label' => __( 'Inactive', 'acf' ),
'label' => _x( 'Disabled', 'post status', 'acf' ),
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'Inactive <span class="count">(%s)</span>', 'Inactive <span class="count">(%s)</span>', 'acf' ),
'label_count' => _n_noop( 'Disabled <span class="count">(%s)</span>', 'Disabled <span class="count">(%s)</span>', 'acf' ),
));
}
@ -584,6 +592,38 @@ class ACF {
$this->instances[ $name ] = $instance;
return $instance;
}
/**
* Magic __isset method for backwards compatibility.
*
* @date 24/4/20
* @since 5.9.0
*
* @param string $key Key name.
* @return bool
*/
public function __isset( $key ) {
return in_array( $key, array( 'locations', 'json' ) );
}
/**
* Magic __get method for backwards compatibility.
*
* @date 24/4/20
* @since 5.9.0
*
* @param string $key Key name.
* @return mixed
*/
public function __get( $key ) {
switch ( $key ) {
case 'locations':
return acf_get_instance( 'ACF_Legacy_Locations' );
case 'json':
return acf_get_instance( 'ACF_Local_JSON' );
}
return null;
}
}
/*

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

View File

@ -1,48 +0,0 @@
Font license info
## Entypo
Copyright (C) 2012 by Daniel Bruce
Author: Daniel Bruce
License: SIL (http://scripts.sil.org/OFL)
Homepage: http://www.entypo.com
## Typicons
(c) Stephen Hutchings 2012
Author: Stephen Hutchings
License: SIL (http://scripts.sil.org/OFL)
Homepage: http://typicons.com/
## Font Awesome
Copyright (C) 2016 by Dave Gandy
Author: Dave Gandy
License: SIL ()
Homepage: http://fortawesome.github.com/Font-Awesome/
## Elusive
Copyright (C) 2013 by Aristeides Stathopoulos
Author: Aristeides Stathopoulos
License: SIL (http://scripts.sil.org/OFL)
Homepage: http://aristeides.com/
## Modern Pictograms
Copyright (c) 2012 by John Caserta. All rights reserved.
Author: John Caserta
License: SIL (http://scripts.sil.org/OFL)
Homepage: http://thedesignoffice.org/project/modern-pictograms/

View File

@ -1,75 +0,0 @@
This webfont is generated by http://fontello.com open source project.
================================================================================
Please, note, that you should obey original font licenses, used to make this
webfont pack. Details available in LICENSE.txt file.
- Usually, it's enough to publish content of LICENSE.txt file somewhere on your
site in "About" section.
- If your project is open-source, usually, it will be ok to make LICENSE.txt
file publicly available in your repository.
- Fonts, used in Fontello, don't require a clickable link on your site.
But any kind of additional authors crediting is welcome.
================================================================================
Comments on archive content
---------------------------
- /font/* - fonts in different formats
- /css/* - different kinds of css, for all situations. Should be ok with
twitter bootstrap. Also, you can skip <i> style and assign icon classes
directly to text elements, if you don't mind about IE7.
- demo.html - demo file, to show your webfont content
- LICENSE.txt - license info about source fonts, used to build your one.
- config.json - keeps your settings. You can import it back into fontello
anytime, to continue your work
Why so many CSS files ?
-----------------------
Because we like to fit all your needs :)
- basic file, <your_font_name>.css - is usually enough, it contains @font-face
and character code definitions
- *-ie7.css - if you need IE7 support, but still don't wish to put char codes
directly into html
- *-codes.css and *-ie7-codes.css - if you like to use your own @font-face
rules, but still wish to benefit from css generation. That can be very
convenient for automated asset build systems. When you need to update font -
no need to manually edit files, just override old version with archive
content. See fontello source code for examples.
- *-embedded.css - basic css file, but with embedded WOFF font, to avoid
CORS issues in Firefox and IE9+, when fonts are hosted on the separate domain.
We strongly recommend to resolve this issue by `Access-Control-Allow-Origin`
server headers. But if you ok with dirty hack - this file is for you. Note,
that data url moved to separate @font-face to avoid problems with <IE9, when
string is too long.
- animate.css - use it to get ideas about spinner rotation animation.
Attention for server setup
--------------------------
You MUST setup server to reply with proper `mime-types` for font files -
otherwise some browsers will fail to show fonts.
Usually, `apache` already has necessary settings, but `nginx` and other
webservers should be tuned. Here is list of mime types for our file extensions:
- `application/vnd.ms-fontobject` - eot
- `application/x-font-woff` - woff
- `application/x-font-ttf` - ttf
- `image/svg+xml` - svg

Binary file not shown.

View File

@ -1,48 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Copyright (C) 2017 by original authors @ fontello.com</metadata>
<defs>
<font id="acf" horiz-adv-x="1000" >
<font-face font-family="acf" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
<missing-glyph horiz-adv-x="1000" />
<glyph glyph-name="plus" unicode="&#xe800;" d="M550 400q30 0 30-50t-30-50l-210 0 0-210q0-30-50-30t-50 30l0 210-210 0q-30 0-30 50t30 50l210 0 0 210q0 30 50 30t50-30l0-210 210 0z" horiz-adv-x="580" />
<glyph glyph-name="minus" unicode="&#xe801;" d="M550 400q30 0 30-50t-30-50l-520 0q-30 0-30 50t30 50l520 0z" horiz-adv-x="580" />
<glyph glyph-name="cancel" unicode="&#xe802;" d="M452 194q18-18 18-43t-18-43q-18-16-43-16t-43 16l-132 152-132-152q-18-16-43-16t-43 16q-16 18-16 43t16 43l138 156-138 158q-16 18-16 43t16 43q18 16 43 16t43-16l132-152 132 152q18 16 43 16t43-16q18-18 18-43t-18-43l-138-158z" horiz-adv-x="470" />
<glyph glyph-name="pencil" unicode="&#xe803;" d="M938 605q22-22 22-55t-22-55l-570-570q-22-21-60-38t-73-17l-235 0 0 234q0 35 17 74t38 60l570 570q23 22 55 22t55-22z m-794-426l65-64 431 433-64 63z m91-205q14 0 33 8-10 10-27 26t-50 50-56 56l-22 22q-9-21-9-32l0-78 52-52 79 0z m74 40l432 432-63 64-433-431z m469 469l67 67-165 165-67-66z" horiz-adv-x="960" />
<glyph glyph-name="location" unicode="&#xe804;" d="M250 750q104 0 177-73t73-177q0-106-62-243t-126-223l-62-84q-10 12-27 35t-60 89-76 130-60 147-27 149q0 104 73 177t177 73z m0-388q56 0 96 40t40 96-40 95-96 39-95-39-39-95 39-96 95-40z" horiz-adv-x="500" />
<glyph glyph-name="down" unicode="&#xe805;" d="M564 422l-234-224q-18-18-40-18t-40 18l-234 224q-16 16-16 41t16 41q38 38 78 0l196-188 196 188q40 38 78 0 16-16 16-41t-16-41z" horiz-adv-x="580" />
<glyph glyph-name="left" unicode="&#xe806;" d="M242 626q14 16 39 16t41-16q38-36 0-80l-186-196 186-194q38-44 0-80-16-16-40-16t-40 16l-226 236q-16 16-16 38 0 24 16 40 206 214 226 236z" horiz-adv-x="341" />
<glyph glyph-name="right" unicode="&#xe807;" d="M98 626l226-236q16-16 16-40 0-22-16-38l-226-236q-16-16-40-16t-40 16q-36 36 0 80l186 194-186 196q-36 44 0 80 16 16 41 16t39-16z" horiz-adv-x="340" />
<glyph glyph-name="up" unicode="&#xe808;" d="M564 280q16-16 16-41t-16-41q-38-38-78 0l-196 188-196-188q-40-38-78 0-16 16-16 41t16 41l234 224q16 16 40 16t40-16z" horiz-adv-x="580" />
<glyph glyph-name="sync" unicode="&#xe809;" d="M843 261q0-3 0-4-36-150-150-243t-267-93q-81 0-157 31t-136 88l-72-72q-11-11-25-11t-25 11-11 25v250q0 14 11 25t25 11h250q14 0 25-11t10-25-10-25l-77-77q40-36 90-57t105-20q74 0 139 37t104 99q6 10 30 66 4 13 16 13h107q8 0 13-6t5-12z m14 446v-250q0-14-10-25t-26-11h-250q-14 0-25 11t-10 25 10 25l77 77q-82 77-194 77-75 0-140-37t-104-99q-6-10-29-66-5-13-17-13h-111q-7 0-13 6t-5 12v4q36 150 151 243t268 93q81 0 158-31t137-88l72 72q11 11 25 11t26-11 10-25z" horiz-adv-x="857.1" />
<glyph glyph-name="globe" unicode="&#xe80a;" d="M480 830q200 0 340-141t140-339q0-200-140-340t-340-140q-198 0-339 140t-141 340q0 198 141 339t339 141z m410-480q0 132-78 239t-202 149q-18-24-16-32 4-38 18-51t30-7l32 12t20 2q22-24 0-47t-45-56-1-77q34-64 96-64 28-2 43-36t17-66q10-80-14-140-22-44 14-76 86 112 86 250z m-466 404q-112-14-199-84t-127-174q6 0 22-2t28-3 26-4 24-8 12-13q4-12-14-45t-18-61q0-30 38-56t38-46q0-28 8-68t8-44q0-12 36-54t52-42q10 0 11 22t-2 54-3 40q0 32 14 74 12 42 59 70t55 46q16 34 9 61t-17 43-34 28-41 17-37 9-22 4q-16 6-42 7t-36-3-27 11-17 29q0 10 15 27t35 37 28 30q8 14 17 21t22 16 27 21q4 4 25 17t27 23z m-72-794q66-20 128-20 128 0 226 68-26 44-118 34-24-2-65-17t-47-17q-74-16-76-16-12-2-26-14t-22-18z" horiz-adv-x="960" />
<glyph glyph-name="picture" unicode="&#xe80b;" d="M0-68l0 836 1000 0 0-836-1000 0z m76 78l848 0 0 680-848 0 0-680z m90 80l0 59 150 195 102-86 193 291 223-228 0-231-668 0z m0 416q0 37 24 62t62 24q33 0 58-24t24-62q0-33-24-57t-58-25q-37 0-62 25t-24 57z" horiz-adv-x="1000" />
<glyph glyph-name="check" unicode="&#xe80c;" d="M249 0q-34 0-56 28l-180 236q-16 24-12 52t26 46 51 14 47-28l118-154 296 474q16 24 43 30t53-8q24-16 30-43t-8-53l-350-560q-20-32-56-32z" horiz-adv-x="667" />
<glyph glyph-name="dot-3" unicode="&#xe80d;" d="M110 460q46 0 78-32t32-78q0-44-32-77t-78-33-78 33-32 77q0 46 32 78t78 32z m350 0q46 0 78-32t32-78q0-44-33-77t-77-33-77 33-33 77q0 46 32 78t78 32z m350 0q46 0 78-32t32-78q0-44-32-77t-78-33-78 33-32 77q0 46 32 78t78 32z" horiz-adv-x="920" />
<glyph glyph-name="arrow-combo" unicode="&#xe80e;" d="M230 850l230-364-460 0z m0-1000l-230 366 460 0z" horiz-adv-x="460" />
<glyph glyph-name="arrow-down" unicode="&#xe80f;" d="M540 587l-269-473-271 473 540 0z" horiz-adv-x="540" />
<glyph glyph-name="arrow-up" unicode="&#xe810;" d="M0 114l269 473 271-473-540 0z" horiz-adv-x="540" />
<glyph glyph-name="search" unicode="&#xe811;" d="M772 78q30-34 6-62l-46-46q-36-32-68 0l-190 190q-74-42-156-42-128 0-223 95t-95 223 90 219 218 91 224-95 96-223q0-88-46-162z m-678 358q0-88 68-156t156-68 151 63 63 153q0 88-68 155t-156 67-151-63-63-151z" horiz-adv-x="789" />
<glyph glyph-name="link-ext" unicode="&#xf08e;" d="M786 332v-178q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h393q7 0 12-5t5-13v-36q0-8-5-13t-12-5h-393q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v178q0 8 5 13t13 5h36q8 0 13-5t5-13z m214 482v-285q0-15-11-25t-25-11-25 11l-98 98-364-364q-5-6-13-6t-12 6l-64 64q-6 5-6 12t6 13l364 364-98 98q-11 11-11 25t11 25 25 11h285q15 0 25-11t11-25z" horiz-adv-x="1000" />
</font>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,124 +0,0 @@
{
"name": "acf",
"css_prefix_text": "acf-icon-",
"css_use_suffix": false,
"hinting": true,
"units_per_em": 1000,
"ascent": 850,
"glyphs": [
{
"uid": "a73c5deb486c8d66249811642e5d719a",
"css": "sync",
"code": 59401,
"src": "fontawesome"
},
{
"uid": "7222571caa5c15f83dcfd447c58d68d9",
"css": "search",
"code": 59409,
"src": "entypo"
},
{
"uid": "14017aae737730faeda4a6fd8fb3a5f0",
"css": "check",
"code": 59404,
"src": "entypo"
},
{
"uid": "c709da589c923ba3c2ad48d9fc563e93",
"css": "cancel",
"code": 59394,
"src": "entypo"
},
{
"uid": "70370693ada58ef0a60fa0984fe8d52a",
"css": "plus",
"code": 59392,
"src": "entypo"
},
{
"uid": "1256e3054823e304d7e452a589cf8bb8",
"css": "minus",
"code": 59393,
"src": "entypo"
},
{
"uid": "a42b598e4298f3319b25a2702a02e7ff",
"css": "location",
"code": 59396,
"src": "entypo"
},
{
"uid": "0a3192de65a73ca1501b073ad601f87d",
"css": "arrow-combo",
"code": 59406,
"src": "entypo"
},
{
"uid": "8704cd847a47b64265b8bb110c8b4d62",
"css": "down",
"code": 59397,
"src": "entypo"
},
{
"uid": "c311c48d79488965b0fab7f9cd12b6b5",
"css": "left",
"code": 59398,
"src": "entypo"
},
{
"uid": "749e7d90a9182938180f1d2d8c33584e",
"css": "right",
"code": 59399,
"src": "entypo"
},
{
"uid": "9c7ff134960bb5a82404e4aeaab366d9",
"css": "up",
"code": 59400,
"src": "entypo"
},
{
"uid": "6a12c2b74456ea21cc984e11dec227a1",
"css": "globe",
"code": 59402,
"src": "entypo"
},
{
"uid": "d10920db2e79c997c5e783279291970c",
"css": "dot-3",
"code": 59405,
"src": "entypo"
},
{
"uid": "1e77a2yvsq3owssduo2lcgsiven57iv5",
"css": "pencil",
"code": 59395,
"src": "typicons"
},
{
"uid": "8ax1xqcbzz1hobyd4i7f0unwib1bztip",
"css": "arrow-down",
"code": 59407,
"src": "modernpics"
},
{
"uid": "6ipws8y9gej6vbloufvhi5qux7rluf64",
"css": "arrow-up",
"code": 59408,
"src": "modernpics"
},
{
"uid": "a1be363d4de9be39857893d4134f6215",
"css": "picture",
"code": 59403,
"src": "elusive"
},
{
"uid": "e15f0d620a7897e2035c18c80142f6d9",
"css": "link-ext",
"code": 61582,
"src": "fontawesome"
}
]
}

View File

@ -641,19 +641,24 @@
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 self = this;
var tooltip = acf.newTooltip({
confirmRemove: true,
target: $el,
context: this,
confirm: function(){
self.delete( true );
this.delete();
},
cancel: function(){
self.$el.removeClass('-hover');
this.$el.removeClass('-hover');
}
});
},
@ -1434,7 +1439,7 @@
conditionTypes.map(function( model ){
choices.push({
id: model.prototype.operator,
text: acf.strEscape(model.prototype.label)
text: model.prototype.label
});
});

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

4447
assets/js/acf.js Normal file

File diff suppressed because it is too large Load Diff

1
assets/js/acf.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1355,22 +1355,17 @@ function acf_get_field_ancestors( $field ) {
* @return array
*/
function acf_duplicate_fields( $fields = array(), $parent_id = 0 ) {
// Vars.
$duplicates = array();
// Loop over fields and pre-generate new field keys (needed for conditional logic).
// Generate keys for all new fields
// - Needed to alter conditional logic rules
// - Use usleep() to ensure unique keys.
$keys = array();
foreach( $fields as $field ) {
// Delay for a microsecond to ensure a unique ID.
usleep(1);
$keys[ $field['key'] ] = uniqid('field_');
}
// Store these keys for later use.
acf_set_data( 'duplicates', $keys );
acf_append_data( 'generated_keys', $keys );
// Duplicate fields.
foreach( $fields as $field ) {
$field_id = $field['ID'] ? $field['ID'] : $field['key'];
@ -1407,8 +1402,12 @@ function acf_duplicate_field( $id = 0, $parent_id = 0 ){
$field['ID'] = 0;
// Generate key.
$keys = acf_get_data( 'duplicates' );
$field['key'] = isset($keys[ $field['key'] ]) ? $keys[ $field['key'] ] : uniqid('field_');
$keys = acf_get_data( 'generated_keys' );
if( isset( $keys[ $field['key'] ] ) ) {
$field['key'] = $keys[ $field['key'] ];
} else {
$field['key'] = uniqid('field_');
}
// Set parent.
if( $parent_id ) {
@ -1486,10 +1485,7 @@ function acf_prepare_field_for_export( $field ) {
*
* @param array $field The field array.
*/
$field = apply_filters( "acf/prepare_field_for_export", $field );
// Return field.
return $field;
return apply_filters( "acf/prepare_field_for_export", $field );
}
// Register variation.
@ -1508,20 +1504,22 @@ acf_add_filter_variations( 'acf/prepare_field_for_export', array('type'), 0 );
*/
function acf_prepare_fields_for_import( $fields = array() ) {
// Ensure array indexes are clean.
// Ensure array is sequential.
$fields = array_values($fields);
// Loop through fields allowing for growth.
// Prepare each field for import making sure to detect additional sub fields.
$i = 0;
while( $i < count($fields) ) {
// Prepare for import.
// Prepare field.
$field = acf_prepare_field_for_import( $fields[ $i ] );
// Allow multiple fields to be returned (parent + children).
if( is_array($field) && !isset($field['key']) ) {
// Update single field.
if( isset($field['key']) ) {
$fields[ $i ] = $field;
// Replace this field ($i) with all returned fields.
// Insert multiple fields.
} else {
array_splice( $fields, $i, 1, $field );
}
@ -1535,12 +1533,9 @@ function acf_prepare_fields_for_import( $fields = array() ) {
* @date 12/02/2014
* @since 5.0.0
*
* @param array $field The field array.
* @param array $fields The array of fields.
*/
$fields = apply_filters( 'acf/prepare_fields_for_import', $fields );
// Return.
return $fields;
return apply_filters( 'acf/prepare_fields_for_import', $fields );
}
/**
@ -1565,10 +1560,7 @@ function acf_prepare_field_for_import( $field ) {
*
* @param array $field The field array.
*/
$field = apply_filters( "acf/prepare_field_for_import", $field );
// Return field.
return $field;
return apply_filters( "acf/prepare_field_for_import", $field );
}
// Register variation.

View File

@ -224,9 +224,10 @@ function acf_validate_field_group( $field_group = array() ) {
// Convert types.
$field_group['ID'] = (int) $field_group['ID'];
$field_group['menu_order'] = (int) $field_group['menu_order'];
$field_group['active'] = (bool) $field_group['active'];
// Field group is now valid.
$field_group['_valid'] = 1;
$field_group['_valid'] = true;
/**
* Filters the $field_group array to validate settings.
@ -951,6 +952,38 @@ function acf_prepare_field_group_for_export( $field_group = array() ) {
return apply_filters( 'acf/prepare_field_group_for_export', $field_group );
}
/**
* acf_prepare_field_group_for_import
*
* Prepares a field group for the import process.
*
* @date 21/11/19
* @since 5.8.8
*
* @param array $field_group The field group array.
* @return array
*/
function acf_prepare_field_group_for_import( $field_group ) {
// Update parent and menu_order properties for all fields.
if( $field_group['fields'] ) {
foreach( $field_group['fields'] as $i => &$field ) {
$field['parent'] = $field_group['key'];
$field['menu_order'] = $i;
}
}
/**
* Filters the $field_group array before being returned to the import tool.
*
* @date 21/11/19
* @since 5.8.8
*
* @param array $field_group The field group array.
*/
return apply_filters( "acf/prepare_field_group_for_import", $field_group );
}
/**
* acf_import_field_group
*
@ -967,24 +1000,23 @@ function acf_import_field_group( $field_group ) {
// Disable filters to ensure data is not modified by local, clone, etc.
$filters = acf_disable_filters();
// Validate field group.
// Validate field group (ensures all settings exist).
$field_group = acf_get_valid_field_group( $field_group );
// Prepare group for import (modifies settings).
$field_group = acf_prepare_field_group_for_import( $field_group );
// Prepare fields for import (modifies settings).
$fields = acf_prepare_fields_for_import( $field_group['fields'] );
// Stores a map of field "key" => "ID".
$ids = array();
// Stores a map of field "parent_key" => "child_count".
$count = array();
// Prepare fields for import.
$fields = acf_prepare_fields_for_import( $field_group['fields'] );
// If the field group has an ID, review and delete stale fields in the databse.
// If the field group has an ID, review and delete stale fields in the database.
if( $field_group['ID'] ) {
// Load database fields.
$db_fields = acf_get_fields( $field_group );
$db_fields = acf_prepare_fields_for_import( $db_fields );
$db_fields = acf_prepare_fields_for_import( acf_get_fields( $field_group ) );
// Generate map of "index" => "key" data.
$keys = wp_list_pluck( $fields, 'key' );
@ -1011,44 +1043,22 @@ function acf_import_field_group( $field_group ) {
// Add field group data to $ids map.
$ids[ $field_group['key'] ] = $field_group['ID'];
// Add count to map.
$count[ $field_group['ID'] ] = 0;
// Loop over and add fields.
if( $fields ) {
foreach( $fields as $field ) {
// Check $ids map for existing ID for this key.
// Replace any "key" references with "ID".
if( isset($ids[ $field['key'] ]) ) {
$field['ID'] = $ids[ $field['key'] ];
}
// Add field group as parent.
if( empty($field['parent']) ) {
$field['parent'] = $field_group['ID'];
// Check $ids map for existing parent
} elseif( isset($ids[ $field['parent'] ]) ) {
if( isset($ids[ $field['parent'] ]) ) {
$field['parent'] = $ids[ $field['parent'] ];
}
// Add field menu_order.
if( !isset($count[ $field['parent'] ]) ) {
$count[ $field['parent'] ] = 1;
} else {
$count[ $field['parent'] ]++;
}
// Only add menu order if doesn't already exist.
// Allows Flexible Content field to set custom order.
if( !isset($field['menu_order']) ) {
$field['menu_order'] = ($count[ $field['parent'] ] - 1);
}
// Save field.
$field = acf_update_field( $field );
// Add field data to $ids map.
// Add field data to $ids map for children.
$ids[ $field['key'] ] = $field['ID'];
}
}

View File

@ -303,7 +303,7 @@ function acf_maybe_idval( $value ) {
}
/**
* acf_numericval
* acf_numval
*
* Casts the provided value as eiter an int or float using a simple hack.
*
@ -341,10 +341,11 @@ function acf_idify( $str = '' ) {
* @since 5.6.5
*
* @param string $str The string to convert.
* @param string $glue The glue between each slug piece.
* @return string
*/
function acf_slugify( $str = '' ) {
return str_replace(array('_', '/', ' '), '-', strtolower($str));
function acf_slugify( $str = '', $glue = '-' ) {
return str_replace(array('_', '-', '/', ' '), $glue, strtolower($str));
}
/**
@ -384,4 +385,54 @@ function acf_did( $name ) {
acf_set_data("acf_did_$name", true);
return false;
}
}
/**
* Returns the length of a string that has been submitted via $_POST.
*
* Uses the following process:
* 1. Unslash the string because posted values will be slashed.
* 2. Decode special characters because wp_kses() will normalize entities.
* 3. Treat line-breaks as a single character instead of two.
* 4. Use mb_strlen() to accomodate special characters.
*
* @date 04/06/2020
* @since 5.9.0
*
* @param string $str The string to review.
* @return int
*/
function acf_strlen( $str ) {
return mb_strlen( str_replace("\r\n", "\n", wp_specialchars_decode( wp_unslash( $str ) ) ) );
}
/**
* Returns a value with default fallback.
*
* @date 6/4/20
* @since 5.9.0
*
* @param mixed $value The value.
* @param mixed $default_value The default value.
* @return mixed
*/
function acf_with_default( $value, $default_value ) {
return $value ? $value : $default_value;
}
/**
* Returns the current priority of a running action.
*
* @date 14/07/2020
* @since 5.9.0
*
* @param string $action The action name.
* @return int|bool
*/
function acf_doing_action( $action ) {
global $wp_filter;
if( isset( $wp_filter[ $action ] ) ) {
return $wp_filter[ $action ]->current_priority();
}
return false;
}

View File

@ -1,9 +1,7 @@
<?php
/**
* acf_get_post_templates
*
* Returns an array of post_type => templates data.
* Returns available templates for each post type.
*
* @date 29/8/17
* @since 5.6.2
@ -13,14 +11,19 @@
*/
function acf_get_post_templates() {
// Defaults.
$post_templates = array(
'page' => array()
);
// Check store.
$cache = acf_get_data( 'post_templates' );
if( $cache !== null ) {
return $cache;
}
// Initialize templates with default placeholder for pages.
$post_templates = array();
$post_templates['page'] = array();
// Loop over post types and append their templates.
if( method_exists('WP_Theme', 'get_page_templates') ) {
$post_types = acf_get_post_types();
$post_types = get_post_types();
foreach( $post_types as $post_type ) {
$templates = wp_get_theme()->get_page_templates( null, $post_type );
if( $templates ) {
@ -29,6 +32,9 @@ function acf_get_post_templates() {
}
}
// Return.
// Update store.
acf_set_data( 'post_templates', $post_templates );
// Return templates.
return $post_templates;
}

View File

@ -53,7 +53,7 @@ function acf_get_user_result( $user ) {
// Add name.
if( $user->first_name && $user->last_name ) {
$text .= " ({$user->first_name} {$user->last_name})";
} elseif( $user->last_name ) {
} elseif( $user->first_name ) {
$text .= " ({$user->first_name})";
}
return compact('id', 'text');
@ -72,16 +72,19 @@ function acf_get_user_result( $user ) {
* @return array
*/
function acf_get_user_role_labels( $roles = array() ) {
$all_roles = wp_roles()->get_names();
// Load all roles if none provided.
if( !$roles ) {
$roles = get_editable_roles();
if( empty($roles) ) {
$roles = array_keys( $all_roles );
}
// Loop over roles and populare labels.
$lables = array();
foreach( $roles as $role ) {
$lables[ $role ] = translate_user_role( $role );
if( isset($all_roles[ $role ]) ) {
$lables[ $role ] = translate_user_role( $all_roles[ $role ] );
}
}
// Return labels.

View File

@ -0,0 +1,108 @@
<?php
/**
* Returns a WordPress object type.
*
* @date 1/4/20
* @since 5.9.0
*
* @param string $object_type The object type (post, term, user, etc).
* @param string $object_subtype Optional object subtype (post type, taxonomy).
* @return object
*/
function acf_get_object_type( $object_type, $object_subtype = '' ) {
$props = array(
'type' => $object_type,
'subtype' => $object_subtype,
'name' => '',
'label' => '',
'icon' => ''
);
// Set unique identifier as name.
if( $object_subtype ) {
$props['name'] = "$object_type/$object_subtype";
} else {
$props['name'] = $object_type;
}
// Set label and icon.
switch ( $object_type ) {
case 'post':
if( $object_subtype ) {
$post_type = get_post_type_object( $object_subtype );
if( $post_type ) {
$props['label'] = $post_type->labels->name;
$props['icon'] = acf_with_default( $post_type->menu_icon, 'dashicons-admin-post' );
} else {
return false;
}
} else {
$props['label'] = __('Posts', 'acf');
$props['icon'] = 'dashicons-admin-post';
}
break;
case 'term':
if( $object_subtype ) {
$taxonomy = get_taxonomy( $object_subtype );
if( $taxonomy ) {
$props['label'] = $taxonomy->labels->name;
} else {
return false;
}
} else {
$props['label'] = __('Taxonomies', 'acf');
}
$props['icon'] = 'dashicons-tag';
break;
case 'attachment':
$props['label'] = __('Attachments', 'acf');
$props['icon'] = 'dashicons-admin-media';
break;
case 'comment':
$props['label'] = __('Comments', 'acf');
$props['icon'] = 'dashicons-admin-comments';
break;
case 'widget':
$props['label'] = __('Widgets', 'acf');
$props['icon'] = 'dashicons-screenoptions';
break;
case 'menu':
$props['label'] = __('Menus', 'acf');
$props['icon'] = 'dashicons-admin-appearance';
break;
case 'menu_item':
$props['label'] = __('Menu items', 'acf');
$props['icon'] = 'dashicons-admin-appearance';
break;
case 'user':
$props['label'] = __('Users', 'acf');
$props['icon'] = 'dashicons-admin-users';
break;
case 'option':
$props['label'] = __('Options', 'acf');
$props['icon'] = 'dashicons-admin-generic';
break;
case 'block':
$props['label'] = __('Blocks', 'acf');
$props['icon'] = acf_version_compare('wp', '>=', '5.5') ? 'dashicons-block-default' : 'dashicons-layout';
break;
default:
return false;
}
// Convert to object.
$object = (object) $props;
/**
* Filters the object type.
*
* @date 6/4/20
* @since 5.9.0
*
* @param object $object The object props.
* @param string $object_type The object type (post, term, user, etc).
* @param string $object_subtype Optional object subtype (post type, taxonomy).
*/
return apply_filters( 'acf/get_object_type', $object, $object_type, $object_subtype );
}

View File

@ -180,6 +180,18 @@ class acf_admin_field_group {
'copy' => __('copy', 'acf'),
'or' => __('or', 'acf'),
'Null' => __('Null', 'acf'),
// Conditions
'Has any value' => __('Has any value', 'acf'),
'Has no value' => __('Has no value', 'acf'),
'Value is equal to' => __('Value is equal to', 'acf'),
'Value is not equal to' => __('Value is not equal to', 'acf'),
'Value matches pattern' => __('Value matches pattern', 'acf'),
'Value contains' => __('Value contains', 'acf'),
'Value is greater than' => __('Value is greater than', 'acf'),
'Value is less than' => __('Value is less than', 'acf'),
'Selection is greater than' => __('Selection is greater than', 'acf'),
'Selection is less than' => __('Selection is less than', 'acf'),
));
// localize data
@ -407,11 +419,7 @@ class acf_admin_field_group {
// modify status
$('#post-status-display').html('<?php echo $status; ?>');
// remove edit links
$('#misc-publishing-actions a').remove();
})(jQuery);
</script>
<?php

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,9 @@ class ACF_Admin_Upgrade {
// actions
add_action( 'admin_menu', array($this,'admin_menu'), 20 );
add_action( 'network_admin_menu', array($this,'network_admin_menu'), 20 );
if( is_multisite() ) {
add_action( 'network_admin_menu', array($this,'network_admin_menu'), 20 );
}
}
/**
@ -131,8 +133,8 @@ class ACF_Admin_Upgrade {
// remove prompt
remove_action('admin_notices', array($this, 'admin_notices'));
// load acf scripts
acf_enqueue_scripts();
// Enqueue core script.
acf_enqueue_script( 'acf' );
}
/**
@ -151,8 +153,8 @@ class ACF_Admin_Upgrade {
// remove prompt
remove_action('network_admin_notices', array($this, 'network_admin_notices'));
// load acf scripts
acf_enqueue_scripts();
// Enqueue core script.
acf_enqueue_script( 'acf' );
}
/**

View File

@ -7,9 +7,7 @@ if( ! class_exists('ACF_Admin') ) :
class ACF_Admin {
/**
* __construct
*
* Sets up the class functionality.
* Constructor.
*
* @date 23/06/12
* @since 5.0.0
@ -17,17 +15,16 @@ class ACF_Admin {
* @param void
* @return void
*/
function __construct() {
// Add hooks.
function __construct() {
// Add actions.
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
add_action( 'admin_body_class', array( $this, 'admin_body_class' ) );
add_action( 'current_screen', array( $this, 'current_screen' ) );
}
/**
* admin_menu
*
* Adds the ACF menu item.
*
* @date 28/09/13
@ -36,7 +33,7 @@ class ACF_Admin {
* @param void
* @return void
*/
function admin_menu() {
function admin_menu() {
// Bail early if ACF is hidden.
if( !acf_get_setting('show_admin') ) {
@ -51,16 +48,9 @@ class ACF_Admin {
add_menu_page( __("Custom Fields",'acf'), __("Custom Fields",'acf'), $cap, $slug, false, 'dashicons-welcome-widgets-menus', '80.025' );
add_submenu_page( $slug, __('Field Groups','acf'), __('Field Groups','acf'), $cap, $slug );
add_submenu_page( $slug, __('Add New','acf'), __('Add New','acf'), $cap, 'post-new.php?post_type=acf-field-group' );
// Only register info page when needed.
if( isset($_GET['page']) && $_GET['page'] === 'acf-settings-info' ) {
add_submenu_page( $slug, __('Info','acf'), __('Info','acf'), $cap,'acf-settings-info', array($this,'info_page_html') );
}
}
/**
* admin_enqueue_scripts
*
* Enqueues global admin styling.
*
* @date 28/09/13
@ -70,15 +60,11 @@ class ACF_Admin {
* @return void
*/
function admin_enqueue_scripts() {
// Enqueue global style. To-do: Change to admin.
wp_enqueue_style( 'acf-global' );
}
/**
* admin_body_class
*
* Appends the determined body_class.
* Appends custom admin body classes.
*
* @date 5/11/19
* @since 5.8.7
@ -92,46 +78,126 @@ class ACF_Admin {
// Determine body class version.
$wp_minor_version = floatval( $wp_version );
if( $wp_minor_version >= 5.3 ) {
$body_class = 'acf-admin-5-3';
$classes .= ' acf-admin-5-3';
} else {
$body_class = 'acf-admin-3-8';
$classes .= ' acf-admin-3-8';
}
// Append and return.
return $classes . ' ' . $body_class;
// Add browser for specific CSS.
$classes .= ' acf-browser-' . acf_get_browser();
// Return classes.
return $classes;
}
/**
* info_page_html
* Adds custom functionality to "ACF" admin pages.
*
* Renders the Info page HTML.
*
* @date 5/11/19
* @since 5.8.7
* @date 7/4/20
* @since 5.9.0
*
* @param void
* @return void
*/
function info_page_html() {
function current_screen( $screen ) {
// Vars.
$view = array(
'version' => acf_get_setting('version'),
'have_pro' => acf_get_setting('pro'),
'tabs' => array(
'new' => __("What's New", 'acf'),
'changelog' => __("Changelog", 'acf')
),
'active' => 'new'
// Determine if the current page being viewed is "ACF" related.
if( isset( $screen->post_type ) && $screen->post_type === 'acf-field-group' ) {
add_action( 'in_admin_header', array( $this, 'in_admin_header' ) );
add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ) );
$this->setup_help_tab();
}
}
/**
* Sets up the admin help tab.
*
* @date 20/4/20
* @since 5.9.0
*
* @param void
* @return void
*/
public function setup_help_tab() {
$screen = get_current_screen();
// Overview tab.
$screen->add_help_tab(
array(
'id' => 'overview',
'title' => __( 'Overview', 'acf' ),
'content' =>
'<p><strong>' . __( 'Overview', 'acf' ) . '</strong></p>' .
'<p>' . __( 'The Advanced Custom Fields plugin provides a visual form builder to customize WordPress edit screens with extra fields, and an intuitive API to display custom field values in any theme template file.', 'acf' ) . '</p>' .
'<p>' . sprintf(
__( 'Before creating your first Field Group, we recommend first reading our <a href="%s" target="_blank">Getting started</a> guide to familiarize yourself with the plugin\'s philosophy and best practises.', 'acf' ),
'https://www.advancedcustomfields.com/resources/getting-started-with-acf/'
) . '</p>' .
'<p>' . __( 'Please use the Help & Support tab to get in touch should you find yourself requiring assistance.', 'acf' ) . '</p>' .
''
)
);
// Find active tab.
if( isset($_GET['tab']) && $_GET['tab'] === 'changelog' ) {
$view['active'] = 'changelog';
}
// Load view.
acf_get_view('settings-info', $view);
// Help tab.
$screen->add_help_tab(
array(
'id' => 'help',
'title' => __( 'Help & Support', 'acf' ),
'content' =>
'<p><strong>' . __( 'Help & Support', 'acf' ) . '</strong></p>' .
'<p>' . __( 'We are fanatical about support, and want you to get the best out of your website with ACF. If you run into any difficulties, there are several places you can find help:', 'acf' ) . '</p>' .
'<ul>' .
'<li>' . sprintf(
__( '<a href="%s" target="_blank">Documentation</a>. Our extensive documentation contains references and guides for most situations you may encounter.', 'acf' ),
'https://www.advancedcustomfields.com/resources/'
) . '</li>' .
'<li>' . sprintf(
__( '<a href="%s" target="_blank">Discussions</a>. We have an active and friendly community on our Community Forums who may be able to help you figure out the how-tos of the ACF world.', 'acf' ),
'https://support.advancedcustomfields.com/'
) . '</li>' .
'<li>' . sprintf(
__( '<a href="%s" target="_blank">Help Desk</a>. The support professionals on our Help Desk will assist with your more in depth, technical challenges.', 'acf' ),
'https://www.advancedcustomfields.com/support/'
) . '</li>' .
'</ul>'
)
);
// Sidebar.
$screen->set_help_sidebar(
'<p><strong>' . __( 'Information', 'acf' ) . '</strong></p>' .
'<p><span class="dashicons dashicons-admin-plugins"></span> ' . sprintf( __( 'Version %s', 'acf' ), ACF_VERSION ) . '</p>' .
'<p><span class="dashicons dashicons-wordpress"></span> <a href="https://wordpress.org/plugins/advanced-custom-fields/" target="_blank">' . __( 'View details', 'acf' ) . '</a></p>' .
'<p><span class="dashicons dashicons-admin-home"></span> <a href="https://www.advancedcustomfields.com/" target="_blank" target="_blank">' . __( 'Visit website', 'acf' ) . '</a></p>' .
''
);
}
/**
* Renders the admin navigation element.
*
* @date 27/3/20
* @since 5.9.0
*
* @param void
* @return void
*/
function in_admin_header() {
acf_get_view( 'html-admin-navigation' );
}
/**
* Modifies the admin footer text.
*
* @date 7/4/20
* @since 5.9.0
*
* @param string $text The admin footer text.
* @return string
*/
function admin_footer_text( $text ) {
// 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 );
}
}

View File

@ -0,0 +1,81 @@
<?php
/**
* The template for displaying admin navigation.
*
* @date 27/3/20
* @since 5.9.0
*/
if( ! defined( 'ABSPATH' ) ) exit;
global $submenu, $parent_file, $submenu_file, $plugin_page, $pagenow;
// Vars.
$parent_slug = 'edit.php?post_type=acf-field-group';
// Generate array of navigation items.
$tabs = array();
if( isset($submenu[ $parent_slug ]) ) {
foreach( $submenu[ $parent_slug ] as $i => $sub_item ) {
// Check user can access page.
if ( !current_user_can( $sub_item[1] ) ) {
continue;
}
// Ignore "Add New".
if( $i === 1 ) {
continue;
}
// Define tab.
$tab = array(
'text' => $sub_item[0],
'url' => $sub_item[2]
);
// Convert submenu slug "test" to "$parent_slug&page=test".
if( !strpos($sub_item[2], '.php') ) {
$tab['url'] = add_query_arg( array( 'page' => $sub_item[2] ), $parent_slug );
}
// Detect active state.
if( $submenu_file === $sub_item[2] || $plugin_page === $sub_item[2] ) {
$tab['is_active'] = true;
}
// Special case for "Add New" page.
if( $i === 0 && $submenu_file === 'post-new.php?post_type=acf-field-group' ) {
$tab['is_active'] = true;
}
$tabs[] = $tab;
}
}
/**
* Filters the admin navigation tabs.
*
* @date 27/3/20
* @since 5.9.0
*
* @param array $tabs The array of navigation tabs.
*/
$tabs = apply_filters( 'acf/admin/toolbar', $tabs );
// Bail early if set to false.
if( $tabs === false ) {
return;
}
?>
<div class="acf-admin-toolbar">
<h2><i class="acf-tab-icon dashicons dashicons-welcome-widgets-menus"></i> <?php echo acf_get_setting('name'); ?></h2>
<?php foreach( $tabs as $tab ) {
printf(
'<a class="acf-tab%s" href="%s">%s</a>',
!empty( $tab['is_active'] ) ? ' is-active' : '',
esc_url( $tab['url'] ),
acf_esc_html( $tab['text'] )
);
} ?>
</div>

View File

@ -153,38 +153,14 @@
blog_id: $input.val()
}),
success: function( json ){
// success
if( acf.isAjaxSuccess(json) ) {
// update
success = true;
// remove input
$input.remove();
// set response text
text = '<?php _e('Upgrade complete.', 'acf'); ?>';
if( jsonText = acf.getAjaxMessage(json) ) {
text = jsonText;
}
// error
} else {
// set response text
text = '<?php _e('Upgrade failed.', 'acf'); ?>';
if( jsonText = acf.getAjaxError(json) ) {
text += ' <pre>' + jsonText + '</pre>';
}
}
success = true;
$input.remove();
text = '<?php _e('Upgrade complete.', 'acf'); ?>';
},
error: function( jqXHR, textStatus, errorThrown ){
// set response text
text = '<?php _e('Upgrade failed.', 'acf'); ?>';
if( errorThrown) {
text += ' <pre>' + errorThrown + '</pre>';
if( error = acf.getXhrError(jqXHR) ) {
text += ' <code>' + error + '</code>';
}
},
complete: this.proxy(function(){

View File

@ -30,7 +30,7 @@
<p><?php _e('Reading upgrade tasks...', 'acf'); ?></p>
<p class="step-1"><i class="acf-loading"></i> <?php printf(__('Upgrading data to version %s', 'acf'), ACF_VERSION); ?></p>
<p class="step-2"></p>
<p class="step-3"><?php echo sprintf( __('Database upgrade complete. <a href="%s">See what\'s new</a>', 'acf' ), admin_url('edit.php?post_type=acf-field-group&page=acf-settings-info') ); ?></p>
<p class="step-3"><?php echo sprintf( __('Database upgrade complete. <a href="%s">See what\'s new</a>', 'acf' ), admin_url('edit.php?post_type=acf-field-group') ); ?></p>
<script type="text/javascript">
(function($) {
@ -59,34 +59,12 @@
action: 'acf/ajax/upgrade'
}),
success: function( json ){
// success
if( acf.isAjaxSuccess(json) ) {
// update
success = true;
// set response text
if( jsonText = acf.getAjaxMessage(json) ) {
response = jsonText;
}
// error
} else {
// set response text
response = '<?php _e('Upgrade failed.', 'acf'); ?>';
if( jsonText = acf.getAjaxError(json) ) {
response += ' <pre>' + jsonText + '</pre>';
}
}
success = true;
},
error: function( jqXHR, textStatus, errorThrown ){
// set response text
response = '<?php _e('Upgrade failed.', 'acf'); ?>';
if( errorThrown) {
response += ' <pre>' + errorThrown + '</pre>';
if( error = acf.getXhrError(jqXHR) ) {
response += ' <code>' + error + '</code>';
}
},
complete: this.proxy(function(){

View File

@ -1,157 +0,0 @@
<div class="wrap about-wrap acf-wrap">
<h1><?php _e("Welcome to Advanced Custom Fields",'acf'); ?> <?php echo $version; ?></h1>
<div class="about-text"><?php printf(__("Thank you for updating! ACF %s is bigger and better than ever before. We hope you like it.", 'acf'), $version); ?></div>
<h2 class="nav-tab-wrapper">
<?php foreach( $tabs as $tab_slug => $tab_title ): ?>
<a class="nav-tab<?php if( $active == $tab_slug ): ?> nav-tab-active<?php endif; ?>" href="<?php echo admin_url("edit.php?post_type=acf-field-group&page=acf-settings-info&tab={$tab_slug}"); ?>"><?php echo $tab_title; ?></a>
<?php endforeach; ?>
</h2>
<?php if( $active == 'new' ): ?>
<div class="feature-section">
<h2><?php _e("A Smoother Experience", 'acf'); ?> </h2>
<div class="acf-three-col">
<div>
<h3><?php _e("Improved Usability", 'acf'); ?></h3>
<p><?php _e("Including the popular Select2 library has improved both usability and speed across a number of field types including post object, page link, taxonomy and select.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Improved Design", 'acf'); ?></h3>
<p><?php _e("Many fields have undergone a visual refresh to make ACF look better than ever! Noticeable changes are seen on the gallery, relationship and oEmbed (new) fields!", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Improved Data", 'acf'); ?></h3>
<p><?php _e("Redesigning the data architecture has allowed sub fields to live independently from their parents. This allows you to drag and drop fields in and out of parent fields!", 'acf'); ?></p>
</div>
</div>
</div>
<hr />
<div class="feature-section">
<h2><?php _e("Goodbye Add-ons. Hello PRO", 'acf'); ?> 👋</h2>
<div class="acf-three-col">
<div>
<h3><?php _e("Introducing ACF PRO", 'acf'); ?></h3>
<p><?php _e("We're changing the way premium functionality is delivered in an exciting way!", 'acf'); ?></p>
<p><?php printf(__('All 4 premium add-ons have been combined into a new <a href="%s">Pro version of ACF</a>. With both personal and developer licenses available, premium functionality is more affordable and accessible than ever before!', 'acf'), esc_url('https://www.advancedcustomfields.com/pro')); ?></p>
</div>
<div>
<h3><?php _e("Powerful Features", 'acf'); ?></h3>
<p><?php _e("ACF PRO contains powerful features such as repeatable data, flexible content layouts, a beautiful gallery field and the ability to create extra admin options pages!", 'acf'); ?></p>
<p><?php printf(__('Read more about <a href="%s">ACF PRO features</a>.', 'acf'), esc_url('https://www.advancedcustomfields.com/pro')); ?></p>
</div>
<div>
<h3><?php _e("Easy Upgrading", 'acf'); ?></h3>
<p><?php _e('Upgrading to ACF PRO is easy. Simply purchase a license online and download the plugin!', 'acf'); ?></p>
<p><?php printf(__('We also wrote an <a href="%s">upgrade guide</a> to answer any questions, but if you do have one, please contact our support team via the <a href="%s">help desk</a>.', 'acf'), esc_url('https://www.advancedcustomfields.com/resources/upgrade-guide-acf-pro/'), esc_url('https://www.advancedcustomfields.com/support/')); ?></p>
</div>
</div>
</div>
<hr />
<div class="feature-section">
<h2><?php _e("New Features", 'acf'); ?> 🎉</h2>
<div class="acf-three-col">
<div>
<h3><?php _e("Link Field", 'acf'); ?></h3>
<p><?php _e("The Link field provides a simple way to select or define a link (url, title, target).", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Group Field", 'acf'); ?></h3>
<p><?php _e("The Group field provides a simple way to create a group of fields.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("oEmbed Field", 'acf'); ?></h3>
<p><?php _e("The oEmbed field allows an easy way to embed videos, images, tweets, audio, and other content.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Clone Field", 'acf'); ?> <span class="badge"><?php _e('Pro', 'acf'); ?></span></h3>
<p><?php _e("The clone field allows you to select and display existing fields.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("More AJAX", 'acf'); ?></h3>
<p><?php _e("More fields use AJAX powered search to speed up page loading.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Local JSON", 'acf'); ?></h3>
<p><?php _e("New auto export to JSON feature improves speed and allows for syncronisation.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Easy Import / Export", 'acf'); ?></h3>
<p><?php _e("Both import and export can easily be done through a new tools page.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("New Form Locations", 'acf'); ?></h3>
<p><?php _e("Fields can now be mapped to menus, menu items, comments, widgets and all user forms!", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("More Customization", 'acf'); ?></h3>
<p><?php _e("New PHP (and JS) actions and filters have been added to allow for more customization.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Fresh UI", 'acf'); ?></h3>
<p><?php _e("The entire plugin has had a design refresh including new field types, settings and design!", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("New Settings", 'acf'); ?></h3>
<p><?php _e("Field group settings have been added for Active, Label Placement, Instructions Placement and Description.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Better Front End Forms", 'acf'); ?></h3>
<p><?php _e("acf_form() can now create a new post on submission with lots of new settings.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Better Validation", 'acf'); ?></h3>
<p><?php _e("Form validation is now done via PHP + AJAX in favour of only JS.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Moving Fields", 'acf'); ?></h3>
<p><?php _e("New field group functionality allows you to move a field between groups & parents.", 'acf'); ?></p>
</div>
<div><?php // intentional empty div for flex alignment ?></div>
</div>
</div>
<?php elseif( $active == 'changelog' ): ?>
<p class="about-description"><?php printf(__("We think you'll love the changes in %s.", 'acf'), $version); ?></p>
<?php
// extract changelog and parse markdown
$readme = file_get_contents( acf_get_path('readme.txt') );
$changelog = '';
if( preg_match( '/(= '.$version.' =)(.+?)(=|$)/s', $readme, $match ) && $match[2] ) {
$changelog = acf_parse_markdown( $match[2] );
}
echo acf_parse_markdown($changelog);
endif; ?>
</div>

View File

@ -0,0 +1,80 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Ajax_Local_JSON_Diff') ) :
class ACF_Ajax_Local_JSON_Diff extends ACF_Ajax {
/** @var string The AJAX action name. */
var $action = 'acf/ajax/local_json_diff';
/** @var bool Prevents access for non-logged in users. */
var $public = false;
/**
* get_response
*
* Returns the response data to sent back.
*
* @date 31/7/18
* @since 5.7.2
*
* @param array $request The request args.
* @return mixed The response data or WP_Error.
*/
function get_response( $request ) {
$json = array();
// Extract props.
$id = isset( $request['id'] ) ? intval( $request['id'] ) : 0;
// Bail ealry if missing props.
if( !$id ) {
return new WP_Error( 'acf_invalid_param', __( 'Invalid field group parameter(s).', 'acf' ), array( 'status' => 404 ) );
}
// Disable filters and load field group directly from database.
acf_disable_filters();
$field_group = acf_get_field_group( $id );
if( !$field_group ) {
return new WP_Error( 'acf_invalid_id', __( 'Invalid field group ID.', 'acf' ), array( 'status' => 404 ) );
}
$field_group['fields'] = acf_get_fields( $field_group );
$field_group['modified'] = get_post_modified_time( 'U', true, $field_group['ID'] );
$field_group = acf_prepare_field_group_for_export( $field_group );
// Load local field group file.
$files = acf_get_local_json_files();
$key = $field_group['key'];
if( !isset( $files[ $key ] ) ) {
return new WP_Error( 'acf_cannot_compare', __( 'Sorry, this field group is unavailable for diff comparison.', 'acf' ), array( 'status' => 404 ) );
}
$local_field_group = json_decode( file_get_contents( $files[ $key ] ), true );
// Render diff HTML.
$date_format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' );
$date_template = __( 'Last updated: %s', 'acf' );
$json['html'] = '
<div class="acf-diff">
<div class="acf-diff-title">
<div class="acf-diff-title-left">
<strong>' . __( 'Original field group', 'acf' ) . '</strong>
<span>' . sprintf( $date_template, wp_date( $date_format, $field_group['modified'] ) ) . '</span>
</div>
<div class="acf-diff-title-right">
<strong>' . __( 'JSON field group (newer)', 'acf' ) . '</strong>
<span>' . sprintf( $date_template, wp_date( $date_format, $local_field_group['modified'] ) ) . '</span>
</div>
</div>
<div class="acf-diff-content">
' . wp_text_diff( acf_json_encode( $field_group ), acf_json_encode( $local_field_group ) ) . '
</div>
</div>';
return $json;
}
}
acf_new_instance('ACF_Ajax_Local_JSON_Diff');
endif; // class_exists check

View File

@ -0,0 +1,273 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Ajax_Query_Users') ) :
class ACF_Ajax_Query_Users extends ACF_Ajax_Query {
/** @var string The AJAX action name. */
var $action = 'acf/ajax/query_users';
/**
* init_request
*
* Called at the beginning of a request to setup properties.
*
* @date 23/5/19
* @since 5.8.1
*
* @param array $request The request args.
* @return void
*/
function init_request( $request ) {
parent::init_request( $request );
// Customize query.
add_filter( 'user_search_columns', array( $this, 'filter_search_columns' ), 10, 3 );
/**
* Fires when a request is made.
*
* @date 21/5/19
* @since 5.8.1
*
* @param array $request The query request.
* @param ACF_Ajax_Query $query The query object.
*/
do_action( "acf/ajax/query_users/init", $request, $this );
}
/**
* get_args
*
* Returns an array of args for this query.
*
* @date 31/7/18
* @since 5.7.2
*
* @param array $request The request args.
* @return array
*/
function get_args( $request ) {
$args = parent::get_args( $request );
$args['number'] = $this->per_page;
$args['paged'] = $this->page;
if( $this->is_search ) {
$args['search'] = "*{$this->search}*";
}
/**
* Filters the query args.
*
* @date 21/5/19
* @since 5.8.1
*
* @param array $args The query args.
* @param array $request The query request.
* @param ACF_Ajax_Query $query The query object.
*/
return apply_filters( "acf/ajax/query_users/args", $args, $request, $this );
}
/**
* Prepares args for the get_results() method.
*
* @date 23/3/20
* @since 5.8.9
*
* @param array args The query args.
* @return array
*/
function prepare_args( $args ) {
// Parse pagination args that may have been modified.
if( isset($args['users_per_page']) ) {
$this->per_page = intval($args['users_per_page']);
unset( $args['users_per_page'] );
} elseif( isset($args['number']) ) {
$this->per_page = intval($args['number']);
}
if( isset($args['paged']) ) {
$this->page = intval($args['paged']);
unset( $args['paged'] );
}
// Set pagination args for fine control.
$args['number'] = $this->per_page;
$args['offset'] = $this->per_page * ($this->page - 1);
$args['count_total'] = true;
return $args;
}
/**
* get_results
*
* Returns an array of results for the given args.
*
* @date 31/7/18
* @since 5.7.2
*
* @param array args The query args.
* @return array
*/
function get_results( $args ) {
$results = array();
// Prepare args for quey.
$args = $this->prepare_args( $args );
// Get result groups.
if( !empty( $args['role__in']) ) {
$roles = acf_get_user_role_labels( $args['role__in'] );
} else {
$roles = acf_get_user_role_labels();
}
// Return a flat array of results when searching or when queriying one group only.
if( $this->is_search || count($roles) === 1 ) {
// Query users and append to results.
$wp_user_query = new WP_User_Query( $args );
$users = (array) $wp_user_query->get_results();
$total_users = $wp_user_query->get_total();
foreach( $users as $user ) {
$results[] = $this->get_result( $user );
}
// Determine if more results exist.
// As this query does not return grouped results, the calculation can be exact (">").
$this->more = ( $total_users > count($users) + $args['offset'] );
// Otherwise, group results via role.
} else {
// Unset args that will interfer with query results.
unset( $args['role__in'], $args['role__not_in'] );
// Loop over each role.
foreach( $roles as $role => $role_label ) {
// Query users (for this role only).
$args['role'] = $role;
$wp_user_query = new WP_User_Query( $args );
$users = (array) $wp_user_query->get_results();
$total_users = $wp_user_query->get_total();
//acf_log( $args );
//acf_log( '- ', count($users) );
//acf_log( '- ', $total_users );
// If users were found for this query...
if( $users ) {
// Append optgroup of results.
$role_results = array();
foreach( $users as $user ) {
$role_results[] = $this->get_result( $user );
}
$results[] = array(
'text' => $role_label,
'children' => $role_results
);
// End loop when enough results have been found.
if( count($users) === $args['number'] ) {
// Determine if more results exist.
// As this query does return grouped results, the calculation is best left fuzzy to avoid querying the next group (">=").
$this->more = ( $total_users >= count($users) + $args['offset'] );
break;
// Otherwise, modify the args so that the next query can continue on correctly.
} else {
$args['offset'] = 0;
$args['number'] -= count($users);
}
// If no users were found (for the current pagination args), but there were users found for previous pages...
// Modify the args so that the next query is offset slightly less (the number of total users) and can continue on correctly.
} elseif( $total_users ) {
$args['offset'] -= $total_users;
continue;
// Ignore roles that will never return a result.
} else {
continue;
}
}
}
/**
* Filters the query results.
*
* @date 21/5/19
* @since 5.8.1
*
* @param array $results The query results.
* @param array $args The query args.
* @param ACF_Ajax_Query $query The query object.
*/
return apply_filters( "acf/ajax/query_users/results", $results, $args, $this );
}
/**
* get_result
*
* Returns a single result for the given item object.
*
* @date 31/7/18
* @since 5.7.2
*
* @param mixed $item A single item from the queried results.
* @return string
*/
function get_result( $user ) {
$item = acf_get_user_result( $user );
/**
* Filters the result item.
*
* @date 21/5/19
* @since 5.8.1
*
* @param array $item The choice id and text.
* @param ACF_User $user The user object.
* @param ACF_Ajax_Query $query The query object.
*/
return apply_filters( "acf/ajax/query_users/result", $item, $user, $this );
}
/**
* Filters the WP_User_Query search columns.
*
* @date 9/3/20
* @since 5.8.8
*
* @param array $columns An array of column names to be searched.
* @param string $search The search term.
* @param WP_User_Query $WP_User_Query The WP_User_Query instance.
* @return array
*/
function filter_search_columns( $columns, $search, $WP_User_Query ) {
/**
* Filters the column names to be searched.
*
* @date 21/5/19
* @since 5.8.1
*
* @param array $columns An array of column names to be searched.
* @param string $search The search term.
* @param WP_User_Query $WP_User_Query The WP_User_Query instance.
* @param ACF_Ajax_Query $query The query object.
*/
return apply_filters( "acf/ajax/query_users/search_columns", $columns, $search, $WP_User_Query, $this );
}
}
acf_new_instance('ACF_Ajax_Query_Users');
endif; // class_exists check

View File

@ -0,0 +1,150 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Ajax_Query') ) :
class ACF_Ajax_Query extends ACF_Ajax {
/** @var bool Prevents access for non-logged in users. */
var $public = true;
/** @var int The page of results to return. */
var $page = 1;
/** @var int The number of results per page. */
var $per_page = 20;
/** @var bool Signifies whether or not this AJAX query has more pages to load. */
var $more = false;
/** @var string The searched term. */
var $search = '';
/** @var bool Signifies whether the current query is a search. */
var $is_search = false;
/** @var (int|string) The post_id being edited. */
var $post_id = 0;
/** @var array The ACF field related to this query. */
var $field = false;
/**
* get_response
*
* Returns the response data to sent back.
*
* @date 31/7/18
* @since 5.7.2
*
* @param array $request The request args.
* @return (array|WP_Error) The response data or WP_Error.
*/
function get_response( $request ) {
// Init request.
$this->init_request( $request );
// Get query args.
$args = $this->get_args( $request );
// Get query results.
$results = $this->get_results( $args );
if( is_wp_error($results) ) {
return $results;
}
// Return response.
return array(
'results' => $results,
'more' => $this->more
);
}
/**
* init_request
*
* Called at the beginning of a request to setup properties.
*
* @date 23/5/19
* @since 5.8.1
*
* @param array $request The request args.
* @return void
*/
function init_request( $request ) {
// Get field for this query.
if( isset($request['field_key']) ) {
$this->field = acf_get_field( $request['field_key'] );
}
// Update query properties.
if( isset($request['page']) ) {
$this->page = intval($request['page']);
}
if( isset($request['per_page']) ) {
$this->per_page = intval($request['per_page']);
}
if( isset($request['search']) && acf_not_empty($request['search']) ) {
$this->search = sanitize_text_field($request['search']);
$this->is_search = true;
}
if( isset($request['post_id']) ) {
$this->post_id = $request['post_id'];
}
}
/**
* get_args
*
* Returns an array of args for this query.
*
* @date 31/7/18
* @since 5.7.2
*
* @param array $request The request args.
* @return array
*/
function get_args( $request ) {
// Allow for custom "query" arg.
if( isset($request['query']) ) {
return (array) $request['query'];
}
return array();
}
/**
* get_items
*
* Returns an array of results for the given args.
*
* @date 31/7/18
* @since 5.7.2
*
* @param array args The query args.
* @return array
*/
function get_results( $args ) {
return array();
}
/**
* get_item
*
* Returns a single result for the given item object.
*
* @date 31/7/18
* @since 5.7.2
*
* @param mixed $item A single item from the queried results.
* @return array An array containing "id" and "text".
*/
function get_result( $item ) {
return false;
}
}
endif; // class_exists check

View File

@ -128,18 +128,37 @@ class ACF_Ajax {
*/
function request() {
// Verify ajax request
if( !acf_verify_ajax() ) {
wp_send_json_error();
}
// Store data for has() and get() functions.
$this->request = wp_unslash($_REQUEST);
// Verify request and handle error.
$error = $this->verify_request( $this->request );
if( is_wp_error( $error ) ) {
$this->send( $error );
}
// Send response.
$this->send( $this->get_response( $this->request ) );
}
/**
* Verifies the request.
*
* @date 9/3/20
* @since 5.8.8
*
* @param array $request The request args.
* @return (bool|WP_Error) True on success, WP_Error on fail.
*/
function verify_request( $request ) {
// Verify nonce.
if( !acf_verify_ajax() ) {
return new WP_Error( 'acf_invalid_nonce', __( 'Invalid nonce.', 'acf' ), array( 'status' => 404 ) );
}
return true;
}
/**
* get_response
*
@ -170,13 +189,39 @@ class ACF_Ajax {
// Return error.
if( is_wp_error($response) ) {
wp_send_json_error(array( 'error' => $response->get_error_message() ));
$this->send_error( $response );
// Return success.
} else {
wp_send_json_success($response);
wp_send_json( $response );
}
}
/**
* Sends a JSON response for the given WP_Error object.
*
* @date 8/3/20
* @since 5.8.8
*
* @param WP_Error error The error object.
* @return void
*/
function send_error( $error ) {
// Get error status
$error_data = $error->get_error_data();
if( is_array($error_data) && isset($error_data['status']) ) {
$status_code = $error_data['status'];
} else {
$status_code = 500;
}
wp_send_json(array(
'code' => $error->get_error_code(),
'message' => $error->get_error_message(),
'data' => $error->get_error_data()
), $status_code);
}
}
endif; // class_exists check

View File

@ -191,6 +191,23 @@ function acf_set_data( $name, $value ) {
return acf()->set_data( $name, $value );
}
/**
* Appends data to an existing key.
*
* @date 11/06/2020
* @since 5.9.0
*
* @param string $name The data name.
* @return array $data The data array.
*/
function acf_append_data( $name, $data ) {
$prev_data = acf()->get_data( $name );
if( is_array($prev_data) ) {
$data = array_merge( $prev_data, $data );
}
acf()->set_data( $name, $data );
}
/*
* acf_init
*
@ -1216,6 +1233,22 @@ function acf_array( $val = array() ) {
return (array) $val;
}
/**
* Returns a non-array value.
*
* @date 11/05/2020
* @since 5.8.10
*
* @param mixed $val The value to review.
* @return mixed
*/
function acf_unarray( $val ) {
if( is_array( $val ) ) {
return reset( $val );
}
return $val;
}
/*
* acf_get_array
*
@ -3083,53 +3116,50 @@ function acf_maybe_get_GET( $key = '', $default = null ) {
}
/*
* acf_get_attachment
*
* This function will return an array of attachment data
*
* @type function
* @date 5/01/2015
* @since 5.1.5
*
* @param $post (mixed) either post ID or post object
* @return (array)
*/
/**
* Returns an array of attachment data.
*
* @date 05/01/2015
* @since 5.1.5
*
* @param int|WP_Post The attachment ID or object.
* @return array|false
*/
function acf_get_attachment( $attachment ) {
// get post
if( !$attachment = get_post($attachment) ) {
// Allow filter to short-circuit load attachment logic.
// Alternatively, this filter may be used to switch blogs for multisite media functionality.
$response = apply_filters( "acf/pre_load_attachment", null, $attachment );
if( $response !== null ) {
return $response;
}
// Get the attachment post object.
$attachment = get_post( $attachment );
if( !$attachment ) {
return false;
}
// validate post_type
if( $attachment->post_type !== 'attachment' ) {
return false;
}
// vars
$sizes_id = 0;
// Load various attachment details.
$meta = wp_get_attachment_metadata( $attachment->ID );
$attached_file = get_attached_file( $attachment->ID );
$attachment_url = wp_get_attachment_url( $attachment->ID );
// get mime types
if( strpos( $attachment->post_mime_type, '/' ) !== false ) {
list( $type, $subtype ) = explode( '/', $attachment->post_mime_type );
} else {
list( $type, $subtype ) = array( $attachment->post_mime_type, '' );
}
// vars
// Generate response.
$response = array(
'ID' => $attachment->ID,
'id' => $attachment->ID,
'title' => $attachment->post_title,
'filename' => wp_basename( $attached_file ),
'filesize' => 0,
'url' => $attachment_url,
'url' => wp_get_attachment_url( $attachment->ID ),
'link' => get_attachment_link( $attachment->ID ),
'alt' => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ),
'author' => $attachment->post_author,
@ -3147,67 +3177,63 @@ function acf_get_attachment( $attachment ) {
'icon' => wp_mime_type_icon( $attachment->ID )
);
// filesize
// Append filesize data.
if( isset($meta['filesize']) ) {
$response['filesize'] = $meta['filesize'];
} elseif( file_exists($attached_file) ) {
$response['filesize'] = filesize( $attached_file );
}
// image
if( $type === 'image' ) {
$sizes_id = $attachment->ID;
$src = wp_get_attachment_image_src( $attachment->ID, 'full' );
$response['url'] = $src[0];
$response['width'] = $src[1];
$response['height'] = $src[2];
// video
} elseif( $type === 'video' ) {
// dimensions
$response['width'] = acf_maybe_get($meta, 'width', 0);
$response['height'] = acf_maybe_get($meta, 'height', 0);
// featured image
if( $featured_id = get_post_thumbnail_id($attachment->ID) ) {
$sizes_id = $featured_id;
}
// audio
} elseif( $type === 'audio' ) {
// featured image
if( $featured_id = get_post_thumbnail_id($attachment->ID) ) {
$sizes_id = $featured_id;
}
// Restrict the loading of image "sizes".
$sizes_id = 0;
// Type specific logic.
switch( $type ) {
case 'image':
$sizes_id = $attachment->ID;
$src = wp_get_attachment_image_src( $attachment->ID, 'full' );
$response['url'] = $src[0];
$response['width'] = $src[1];
$response['height'] = $src[2];
break;
case 'video':
$response['width'] = acf_maybe_get( $meta, 'width', 0 );
$response['height'] = acf_maybe_get( $meta, 'height', 0 );
if( $featured_id = get_post_thumbnail_id( $attachment->ID ) ) {
$sizes_id = $featured_id;
}
break;
case 'audio':
if( $featured_id = get_post_thumbnail_id( $attachment->ID ) ) {
$sizes_id = $featured_id;
}
break;
}
// sizes
// Load array of image sizes.
if( $sizes_id ) {
// vars
$sizes = get_intermediate_image_sizes();
$data = array();
// loop
foreach( $sizes as $size ) {
$src = wp_get_attachment_image_src( $sizes_id, $size );
$data[ $size ] = $src[0];
$data[ $size . '-width' ] = $src[1];
$data[ $size . '-height' ] = $src[2];
$data[ $size ] = $src[ 0 ];
$data[ $size . '-width' ] = $src[ 1 ];
$data[ $size . '-height' ] = $src[ 2 ];
}
// append
$response['sizes'] = $data;
}
// return
return $response;
/**
* Filters the attachment $response after it has been loaded.
*
* @date 16/06/2020
* @since 5.9.0
*
* @param array $response Array of loaded attachment data.
* @param WP_Post $attachment Attachment object.
* @param array|false $meta Array of attachment meta data, or false if there is none.
*/
return apply_filters( "acf/load_attachment", $response, $attachment, $meta );
}
@ -3616,7 +3642,7 @@ function acf_validate_attachment( $attachment, $field, $context = 'prepare' ) {
} elseif( $max_size && $file['size'] > acf_get_filesize($max_size) ) {
// min width
$errors['max_size'] = sprintf(__('File size must must not exceed %s.', 'acf'), acf_format_filesize($max_size) );
$errors['max_size'] = sprintf(__('File size must not exceed %s.', 'acf'), acf_format_filesize($max_size) );
}

View File

@ -354,200 +354,140 @@ function get_field_objects( $post_id = false, $format_value = true, $load_value
}
/*
* have_rows
*
* This function will instantiate a global variable containing the rows of a repeater or flexible content field,
* after which, it will determine if another row exists to loop through
*
* @type function
* @date 2/09/13
* @since 4.3.0
*
* @param $field_name (string) the field name
* @param $post_id (mixed) the post_id of which the value is saved against
* @return (boolean)
*/
/**
* have_rows
*
* Checks if a field (such as Repeater or Flexible Content) has any rows of data to loop over.
* This function is intended to be used in conjunction with the_row() to step through available values.
*
* @date 2/09/13
* @since 4.3.0
*
* @param string $selector The field name or field key.
* @param mixed $post_id The post ID where the value is saved. Defaults to the current post.
* @return bool
*/
function have_rows( $selector, $post_id = false ) {
// reference
// Validate and backup $post_id.
$_post_id = $post_id;
// filter post_id
$post_id = acf_get_valid_post_id( $post_id );
// vars
// Vars.
$key = "selector={$selector}/post_id={$post_id}";
$active_loop = acf_get_loop('active');
$previous_loop = acf_get_loop('previous');
$new_parent_loop = false;
$new_child_loop = false;
$prev_loop = acf_get_loop('previous');
$new_loop = false;
$sub_field = false;
$sub_exists = false;
$change = false;
// no active loops
// Check if no active loop.
if( !$active_loop ) {
// create a new loop
$new_parent_loop = true;
$new_loop = 'parent';
// loop has changed
} elseif( $active_loop['key'] != $key ) {
// Detect "change" compared to the active loop.
} elseif( $key !== $active_loop['key'] ) {
// detect change
// Find sub field and check if a sub value exists.
$sub_field_exists = false;
$sub_field = acf_get_sub_field($selector, $active_loop['field']);
if( $sub_field ) {
$sub_field_exists = isset( $active_loop['value'][ $active_loop['i'] ][ $sub_field['key'] ] );
}
// Detect change in post_id.
if( $post_id != $active_loop['post_id'] ) {
$change = 'post_id';
// Case: Change in $post_id was due to this being a nested loop and not specifying the $post_id.
// Action: Move down one level into a new loop.
if( empty($_post_id) && $sub_field_exists ) {
$new_loop = 'child';
// Case: Change in $post_id was due to a nested loop ending.
// Action: move up one level through the loops.
} elseif( $prev_loop && $prev_loop['post_id'] == $post_id ) {
acf_remove_loop('active');
$active_loop = $prev_loop;
// Case: Chang in $post_id is the most obvious, used in an WP_Query loop with multiple $post objects.
// Action: leave this current loop alone and create a new parent loop.
} else {
$new_loop = 'parent';
}
// Detect change in selector.
} elseif( $selector != $active_loop['selector'] ) {
$change = 'selector';
} else {
// Case: Change in $field_name was due to this being a nested loop.
// Action: move down one level into a new loop.
if( $sub_field_exists ) {
$new_loop = 'child';
// key has changed due to a technicallity, however, the post_id and selector are the same
}
// attempt to find sub field
$sub_field = acf_get_sub_field($selector, $active_loop['field']);
if( $sub_field ) {
$sub_exists = isset( $active_loop['value'][ $active_loop['i'] ][ $sub_field['key'] ] );
}
// If post_id has changed, this is most likely an archive loop
if( $change == 'post_id' ) {
if( empty($_post_id) && $sub_exists ) {
// case: Change in $post_id was due to this being a nested loop and not specifying the $post_id
// action: move down one level into a new loop
$new_child_loop = true;
} elseif( $previous_loop && $previous_loop['post_id'] == $post_id ) {
// case: Change in $post_id was due to a nested loop ending
// action: move up one level through the loops
// Case: Change in $field_name was due to a nested loop ending.
// Action: move up one level through the loops.
} elseif( $prev_loop && $prev_loop['selector'] == $selector && $prev_loop['post_id'] == $post_id ) {
acf_remove_loop('active');
$active_loop = $previous_loop;
$active_loop = $prev_loop;
// Case: Change in $field_name is the most obvious, this is a new loop for a different field within the $post.
// Action: leave this current loop alone and create a new parent loop.
} else {
// case: Chang in $post_id is the most obvious, used in an WP_Query loop with multiple $post objects
// action: leave this current loop alone and create a new parent loop
$new_parent_loop = true;
$new_loop = 'parent';
}
} elseif( $change == 'selector' ) {
if( $sub_exists ) {
// case: Change in $field_name was due to this being a nested loop
// action: move down one level into a new loop
$new_child_loop = true;
} elseif( $previous_loop && $previous_loop['selector'] == $selector && $previous_loop['post_id'] == $post_id ) {
// case: Change in $field_name was due to a nested loop ending
// action: move up one level through the loops
acf_remove_loop('active');
$active_loop = $previous_loop;
} else {
// case: Chang in $field_name is the most obvious, this is a new loop for a different field within the $post
// action: leave this current loop alone and create a new parent loop
$new_parent_loop = true;
}
}
// loop is the same
} else {
// do nothing
}
// add loop
if( $new_parent_loop || $new_child_loop ) {
// vars
$field = null;
$value = null;
$name = '';
// parent loop
if( $new_parent_loop ) {
$field = get_field_object( $selector, $post_id, false );
$value = acf_extract_var( $field, 'value' );
$name = $field['name'];
// child loop
} else {
$field = $sub_field;
$value = $active_loop['value'][ $active_loop['i'] ][ $sub_field['key'] ];
$name = $active_loop['name'] . '_' . $active_loop['i'] . '_' . $sub_field['name'];
$post_id = $active_loop['post_id'];
}
// bail early if value is either empty or a non array
if( !acf_is_array($value) ) return false;
// allow for non repeatable data (group)
if( acf_get_field_type_prop($field['type'], 'have_rows') === 'single' ) {
$value = array( $value );
}
// add loop
$active_loop = acf_add_loop(array(
// Add loop if required.
if( $new_loop ) {
$args = array(
'key' => $key,
'selector' => $selector,
'name' => $name, // used by update_sub_field
'value' => $value,
'field' => $field,
'i' => -1,
'post_id' => $post_id,
'key' => $key
));
'name' => null,
'value' => null,
'field' => null,
'i' => -1,
);
// Case: Parent loop.
if( $new_loop === 'parent' ) {
$field = get_field_object( $selector, $post_id, false );
if( $field ) {
$args['field'] = $field;
$args['value'] = $field['value'];
$args['name'] = $field['name'];
unset( $args['field']['value'] );
}
// Case: Child loop ($sub_field must exist).
} else {
$args['field'] = $sub_field;
$args['value'] = $active_loop['value'][ $active_loop['i'] ][ $sub_field['key'] ];
$args['name'] = "{$active_loop['name']}_{$active_loop['i']}_{$sub_field['name']}";
$args['post_id'] = $active_loop['post_id'];
}
// Bail early if value is either empty or a non array.
if( !$args['value'] || !is_array($args['value']) ) {
return false;
}
// Allow for non repeatable data for Group and Clone fields.
if( acf_get_field_type_prop($args['field']['type'], 'have_rows') === 'single' ) {
$args['value'] = array( $args['value'] );
}
// Add loop.
$active_loop = acf_add_loop($args);
}
// return true if next row exists
// Return true if next row exists.
if( $active_loop && isset($active_loop['value'][ $active_loop['i']+1 ]) ) {
return true;
}
}
// no next row!
// Return false if no next row.
acf_remove_loop('active');
// return
return false;
}

View File

@ -359,10 +359,7 @@ function acf_encode_term( $term ) {
function acf_decode_term( $string ) {
if( is_string($string) && strpos($string, ':') ) {
list( $taxonomy, $slug ) = explode(':', $string);
return array(
'taxonomy' => $taxonomy,
'slug' => $slug
);
return compact( 'taxonomy', 'slug' );
}
return false;
}

View File

@ -6,401 +6,530 @@ if( ! class_exists('ACF_Assets') ) :
class ACF_Assets {
/** @var array Storage for translations */
var $text = array();
/** @var array Storage for data */
var $data = array();
/**
* Storage for i18n data.
*
* @since 5.6.9
* @var array
*/
public $text = array();
/**
* __construct
*
* description
*
* @date 10/4/18
* @since 5.6.9
*
* @param void
* @return void
*/
function __construct() {
// actions
add_action('init', array($this, 'register_scripts'));
* Storage for l10n data.
*
* @since 5.6.9
* @var array
*/
public $data = array();
/**
* List of enqueue flags.
*
* @since 5.9.0
* @var bool
*/
private $enqueue = array();
/**
* Constructor.
*
* @date 10/4/18
* @since 5.6.9
*
* @param void
* @return void
*/
public function __construct() {
add_action( 'init', array( $this, 'register_scripts' ) );
}
/**
* Magic __call method for backwards compatibility.
*
* @date 10/4/20
* @since 5.9.0
*
* @param string $name The method name.
* @param array $arguments The array of arguments.
* @return mixed
*/
public function __call( $name, $arguments ) {
switch ( $name ) {
case 'admin_enqueue_scripts':
case 'admin_print_scripts':
case 'admin_head':
case 'admin_footer':
case 'admin_print_footer_scripts':
_doing_it_wrong( __FUNCTION__, 'The ACF_Assets class should not be accessed directly.', '5.9.0' );
}
}
/**
* add_text
*
* description
*
* @date 13/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function add_text( $text ) {
* Appends an array of i18n data.
*
* @date 13/4/18
* @since 5.6.9
*
* @param array $text An array of text for i18n.
* @return void
*/
public function add_text( $text ) {
foreach( (array) $text as $k => $v ) {
$this->text[ $k ] = $v;
}
}
/**
* add_data
*
* description
*
* @date 13/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function add_data( $data ) {
* Appends an array of l10n data.
*
* @date 13/4/18
* @since 5.6.9
*
* @param array $data An array of data for l10n.
* @return void
*/
public function add_data( $data ) {
foreach( (array) $data as $k => $v ) {
$this->data[ $k ] = $v;
}
}
/**
* register_scripts
*
* description
*
* @date 13/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function register_scripts() {
* Registers the ACF scripts and styles.
*
* @date 10/4/18
* @since 5.6.9
*
* @param void
* @return void
*/
public function register_scripts() {
// vars
// Extract vars.
$suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
$version = acf_get_setting('version');
$min = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
// scripts
wp_register_script('acf-input', acf_get_url("assets/js/acf-input{$min}.js"), array('jquery', 'jquery-ui-sortable', 'jquery-ui-resizable'), $version );
wp_register_script('acf-field-group', acf_get_url("assets/js/acf-field-group{$min}.js"), array('acf-input'), $version );
// Register scripts.
wp_register_script( 'acf', acf_get_url( 'assets/js/acf' . $suffix . '.js' ), array( 'jquery' ), $version );
wp_register_script( 'acf-input', acf_get_url( 'assets/js/acf-input' . $suffix . '.js' ), array( 'jquery', 'jquery-ui-sortable', 'jquery-ui-resizable', 'acf' ), $version );
wp_register_script( 'acf-field-group', acf_get_url( 'assets/js/acf-field-group' . $suffix . '.js' ), array( 'acf-input' ), $version );
// styles
wp_register_style('acf-global', acf_get_url('assets/css/acf-global.css'), array(), $version );
wp_register_style('acf-input', acf_get_url('assets/css/acf-input.css'), array('acf-global'), $version );
wp_register_style('acf-field-group', acf_get_url('assets/css/acf-field-group.css'), array('acf-input'), $version );
// Register styles.
wp_register_style( 'acf-global', acf_get_url( 'assets/css/acf-global.css' ), array(), $version );
wp_register_style( 'acf-input', acf_get_url( 'assets/css/acf-input.css' ), array('acf-global'), $version );
wp_register_style( 'acf-field-group', acf_get_url( 'assets/css/acf-field-group.css' ), array('acf-input'), $version );
// action
do_action('acf/register_scripts', $version, $min);
/**
* Fires after core scripts and styles have been registered.
*
* @since 5.6.9
*
* @param string $version The ACF version.
* @param string $suffix The potential ".min" filename suffix.
*/
do_action( 'acf/register_scripts', $version, $suffix );
}
/**
* Enqueues a script and sets up actions for priting supplemental scripts.
*
* @date 27/4/20
* @since 5.9.0
*
* @param string $name The script name.
* @return void
*/
public function enqueue_script( $name ) {
wp_enqueue_script( $name );
$this->add_actions();
}
/**
* Enqueues a style.
*
* @date 27/4/20
* @since 5.9.0
*
* @param string $name The style name.
* @return void
*/
public function enqueue_style( $name ) {
wp_enqueue_style( $name );
}
/**
* enqueue_scripts
*
* Enqueue scripts for input
*
* @date 13/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function enqueue_scripts( $args = array() ) {
* Adds the actions needed to print supporting inline scripts.
*
* @date 27/4/20
* @since 5.9.0
*
* @param void
* @return void
*/
private function add_actions() {
// run only once
if( acf_has_done('enqueue_scripts') ) {
// Only run once.
if( acf_has_done('ACF_Assets::add_actions') ) {
return;
}
// defaults
$args = wp_parse_args($args, array(
// force tinymce editor to be enqueued
'uploader' => false,
// priority used for action callbacks, defaults to 20 which runs after defaults
'priority' => 20,
// action prefix
'context' => is_admin() ? 'admin' : 'wp'
));
// define actions
$actions = array(
'admin_enqueue_scripts' => $args['context'] . '_enqueue_scripts',
'admin_print_scripts' => $args['context'] . '_print_scripts',
'admin_head' => $args['context'] . '_head',
'admin_footer' => $args['context'] . '_footer',
'admin_print_footer_scripts' => $args['context'] . '_print_footer_scripts',
);
// fix customizer actions where head and footer are not available
if( $args['context'] == 'customize_controls' ) {
$actions['admin_head'] = $actions['admin_print_scripts'];
$actions['admin_footer'] = $actions['admin_print_footer_scripts'];
}
// add actions
foreach( $actions as $function => $action ) {
acf_maybe_add_action( $action, array($this, $function), $args['priority'] );
}
// enqueue uploader
// WP requires a lot of JS + inline scripes to create the media modal and should be avoioded when possible.
// - priority must be less than 10 to allow WP to enqueue
if( $args['uploader'] ) {
add_action($actions['admin_footer'], 'acf_enqueue_uploader', 5);
}
// Add actions.
$this->add_action( 'admin_enqueue_scripts', 'enqueue_scripts' , 20 );
$this->add_action( 'admin_print_scripts', 'print_scripts', 20 );
$this->add_action( 'admin_print_footer_scripts', 'print_footer_scripts', 20 );
}
/**
* Extends the add_action() function with two additional features:
* 1. Renames $action depending on the current page (customizer, login, front-end).
* 2. Alters the priotiry or calls the method directly if the action has already passed.
*
* @date 28/4/20
* @since 5.9.0
*
* @param string $action The action name.
* @param string $method The method name.
* @param int $priority See add_action().
* @param int $accepted_args See add_action().
* @return void
*/
public function add_action( $action, $method, $priority = 10, $accepted_args = 1 ) {
// Generate an array of action replacements.
$replacements = array(
'customizer' => array(
'admin_enqueue_scripts' => 'admin_enqueue_scripts',
'admin_print_scripts' => 'customize_controls_print_scripts',
'admin_head' => 'customize_controls_print_scripts',
'admin_footer' => 'customize_controls_print_footer_scripts',
'admin_print_footer_scripts' => 'customize_controls_print_footer_scripts'
),
'login' => array(
'admin_enqueue_scripts' => 'login_enqueue_scripts',
'admin_print_scripts' => 'login_head',
'admin_head' => 'login_head',
'admin_footer' => 'login_footer',
'admin_print_footer_scripts' => 'login_footer'
),
'wp' => array(
'admin_enqueue_scripts' => 'wp_enqueue_scripts',
'admin_print_scripts' => 'wp_print_scripts',
'admin_head' => 'wp_head',
'admin_footer' => 'wp_footer',
'admin_print_footer_scripts' => 'wp_print_footer_scripts'
)
);
// Determine the current context.
if( did_action('customize_controls_init') ) {
$context = 'customizer';
} elseif( did_action('login_form_register') ) {
$context = 'login';
} elseif( is_admin() ) {
$context = 'admin';
} else {
$context = 'wp';
}
// Replace action if possible.
if( isset( $replacements[ $context ][ $action ] ) ) {
$action = $replacements[ $context ][ $action ];
}
// Check if action is currently being or has already been run.
if( did_action($action) ) {
$doing = acf_doing_action( $action );
if( $doing && $doing < $priority ) {
// Allow action to be added as per usual.
} else {
// Call method directly.
return call_user_func( array( $this, $method ) );
}
}
// Add action.
add_action( $action, array( $this, $method ), $priority, $accepted_args );
}
/**
* admin_enqueue_scripts
*
* description
*
* @date 16/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function admin_enqueue_scripts() {
* Generic controller for enqueuing scripts and styles.
*
* @date 28/4/20
* @since 5.9.0
*
* @param array $args {
* @type bool $uploader Whether or not to enqueue uploader scripts.
* }
* @return void
*/
public function enqueue( $args = array() ) {
// Apply defaults.
$args = wp_parse_args($args, array(
'input' => true,
'uploader' => false
));
// Set enqueue flags and add actions.
if( $args['input'] ) {
$this->enqueue[] = 'input';
}
if( $args['uploader'] ) {
$this->enqueue[] = 'uploader';
}
$this->add_actions();
}
/**
* Enqueues the scripts and styles needed for the WP media uploader.
*
* @date 27/10/2014
* @since 5.0.9
*
* @param void
* @return void
*/
public function enqueue_uploader() {
// Only run once.
if( acf_has_done('ACF_Assets::enqueue_uploader') ) {
return;
}
// Enqueue media assets.
if( current_user_can('upload_files') ) {
wp_enqueue_media();
}
// Add actions.
$this->add_action( 'admin_footer', 'print_uploader_scripts', 1 );
/**
* Fires when enqueuing the uploader.
*
* @since 5.6.9
*
* @param void
*/
do_action( 'acf/enqueue_uploader' );
}
/**
* Enqueues and localizes scripts.
*
* @date 27/4/20
* @since 5.9.0
*
* @param void
* @return void
*/
public function enqueue_scripts() {
// Enqueue input scripts.
if( in_array('input', $this->enqueue) ) {
wp_enqueue_script( 'acf-input' );
wp_enqueue_style( 'acf-input' );
}
// Enqueue media scripts.
if( in_array('uploader', $this->enqueue) ) {
$this->enqueue_uploader();
}
// Localize text.
acf_localize_text(array(
// unload
'The changes you made will be lost if you navigate away from this page' => __('The changes you made will be lost if you navigate away from this page', 'acf'),
// media
'Select.verb' => _x('Select', 'verb', 'acf'),
'Edit.verb' => _x('Edit', 'verb', 'acf'),
'Update.verb' => _x('Update', 'verb', 'acf'),
'Uploaded to this post' => __('Uploaded to this post', 'acf'),
'Expand Details' => __('Expand Details', 'acf'),
'Collapse Details' => __('Collapse Details', 'acf'),
'Restricted' => __('Restricted', 'acf'),
'All images' => __('All images', 'acf'),
// validation
'Validation successful' => __('Validation successful', 'acf'),
'Validation failed' => __('Validation failed', 'acf'),
'1 field requires attention' => __('1 field requires attention', 'acf'),
'%d fields require attention' => __('%d fields require attention', 'acf'),
// tooltip
// Tooltip
'Are you sure?' => __('Are you sure?','acf'),
'Yes' => __('Yes','acf'),
'No' => __('No','acf'),
'Remove' => __('Remove','acf'),
'Cancel' => __('Cancel','acf'),
// conditions
'Has any value' => __('Has any value', 'acf'),
'Has no value' => __('Has no value', 'acf'),
'Value is equal to' => __('Value is equal to', 'acf'),
'Value is not equal to' => __('Value is not equal to', 'acf'),
'Value matches pattern' => __('Value matches pattern', 'acf'),
'Value contains' => __('Value contains', 'acf'),
'Value is greater than' => __('Value is greater than', 'acf'),
'Value is less than' => __('Value is less than', 'acf'),
'Selection is greater than' => __('Selection is greater than', 'acf'),
'Selection is less than' => __('Selection is less than', 'acf'),
// misc
'Edit field group' => __('Edit field group', 'acf'),
));
// enqueue
wp_enqueue_script('acf-input');
wp_enqueue_style('acf-input');
// Localize "input" text.
if( wp_script_is('acf-input') ) {
acf_localize_text(array(
// Unload
'The changes you made will be lost if you navigate away from this page' => __('The changes you made will be lost if you navigate away from this page', 'acf'),
// Validation
'Validation successful' => __('Validation successful', 'acf'),
'Validation failed' => __('Validation failed', 'acf'),
'1 field requires attention' => __('1 field requires attention', 'acf'),
'%d fields require attention' => __('%d fields require attention', 'acf'),
// Other
'Edit field group' => __('Edit field group', 'acf'),
));
/**
* Fires during "admin_enqueue_scripts" when ACF scripts are enqueued.
*
* @since 5.6.9
*
* @param void
*/
do_action( 'acf/input/admin_enqueue_scripts' );
}
// vars
/**
* Fires during "admin_enqueue_scripts" when ACF scripts are enqueued.
*
* @since 5.6.9
*
* @param void
*/
do_action( 'acf/admin_enqueue_scripts' );
do_action( 'acf/enqueue_scripts' );
// Filter i18n translations that differ from English and localize script.
$text = array();
// actions
do_action('acf/enqueue_scripts');
do_action('acf/admin_enqueue_scripts');
do_action('acf/input/admin_enqueue_scripts');
// only include translated strings
foreach( $this->text as $k => $v ) {
if( str_replace('.verb', '', $k) !== $v ) {
$text[ $k ] = $v;
}
}
// localize text
if( $text ) {
wp_localize_script( 'acf-input', 'acfL10n', $text );
wp_localize_script( 'acf', 'acfL10n', $text );
}
}
/**
* admin_print_scripts
*
* description
*
* @date 18/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function admin_print_scripts() {
do_action('acf/admin_print_scripts');
}
/**
* admin_head
*
* description
*
* @date 16/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function admin_head() {
* Prints scripts in head.
*
* @date 27/4/20
* @since 5.9.0
*
* @param void
* @return void
*/
public function print_scripts() {
if( wp_script_is('acf-input') ) {
/**
* Fires during "admin_head" when ACF scripts are enqueued.
*
* @since 5.6.9
*
* @param void
*/
do_action( 'acf/input/admin_head' );
do_action( 'acf/input/admin_print_scripts' );
}
// actions
do_action('acf/admin_head');
do_action('acf/input/admin_head');
/**
* Fires during "admin_head" when ACF scripts are enqueued.
*
* @since 5.6.9
*
* @param void
*/
do_action( 'acf/admin_head' );
do_action( 'acf/admin_print_scripts' );
}
/**
* admin_footer
*
* description
*
* @date 16/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function admin_footer() {
// global
* Prints scripts in footer.
*
* @date 27/4/20
* @since 5.9.0
*
* @param void
* @return void
*/
public function print_footer_scripts() {
global $wp_version;
// get data
$data = wp_parse_args($this->data, array(
'screen' => acf_get_form_data('screen'),
'post_id' => acf_get_form_data('post_id'),
'nonce' => wp_create_nonce( 'acf_nonce' ),
// Bail early if 'acf' script was never enqueued (fixes Elementor enqueue reset conflict).
if( !wp_script_is('acf') ) {
return;
}
// Localize data.
acf_localize_data(array(
'admin_url' => admin_url(),
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'validation' => acf_get_form_data('validation'),
'wp_version' => $wp_version,
'nonce' => wp_create_nonce( 'acf_nonce' ),
'acf_version' => acf_get_setting('version'),
'wp_version' => $wp_version,
'browser' => acf_get_browser(),
'locale' => acf_get_locale(),
'rtl' => is_rtl(),
'screen' => acf_get_form_data('screen'),
'post_id' => acf_get_form_data('post_id'),
'validation' => acf_get_form_data('validation'),
'editor' => acf_is_block_editor() ? 'block' : 'classic'
));
// get l10n (old)
$l10n = apply_filters( 'acf/input/admin_l10n', array() );
// Print inline script.
printf( "<script>\n%s\n</script>\n", 'acf.data = ' . wp_json_encode( $this->data ) . ';' );
// todo: force 'acf-input' script enqueue if not yet included
// - fixes potential timing issue if acf_enqueue_assest() was called during body
if( wp_script_is('acf-input') ) {
/**
* Filters an empty array for compat l10n data.
*
* @since 5.0.0
*
* @param array $data An array of data to append to.
*/
$compat_l10n = apply_filters( 'acf/input/admin_l10n', array() );
if( $compat_l10n ) {
printf( "<script>\n%s\n</script>\n", 'acf.l10n = ' . wp_json_encode( $compat_l10n ) . ';' );
}
/**
* Fires during "admin_footer" when ACF scripts are enqueued.
*
* @since 5.6.9
*
* @param void
*/
do_action( 'acf/input/admin_footer' );
do_action( 'acf/input/admin_print_footer_scripts' );
}
// localize data
?>
<script type="text/javascript">
acf.data = <?php echo wp_json_encode($data); ?>;
acf.l10n = <?php echo wp_json_encode($l10n); ?>;
</script>
<?php
/**
* Fires during "admin_footer" when ACF scripts are enqueued.
*
* @since 5.6.9
*
* @param void
*/
do_action( 'acf/admin_footer' );
do_action( 'acf/admin_print_footer_scripts' );
// actions
do_action('acf/admin_footer');
do_action('acf/input/admin_footer');
// trigger prepare
?>
<script type="text/javascript">
acf.doAction('prepare');
</script>
<?php
// Once all data is localized, trigger acf.prepare() to execute functionality before DOM ready.
printf( "<script>\n%s\n</script>\n", "acf.doAction( 'prepare' );" );
}
/**
* admin_print_footer_scripts
*
* description
*
* @date 18/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function admin_print_footer_scripts() {
do_action('acf/admin_print_footer_scripts');
}
/*
* enqueue_uploader
*
* This function will render a WP WYSIWYG and enqueue media
*
* @type function
* @date 27/10/2014
* @since 5.0.9
*
* @param n/a
* @return n/a
*/
function enqueue_uploader() {
// run only once
if( acf_has_done('enqueue_uploader') ) {
return;
}
// bail early if doing ajax
if( acf_is_ajax() ) {
return;
}
// enqueue media if user can upload
if( current_user_can('upload_files') ) {
wp_enqueue_media();
}
// create dummy editor
* Prints uploader scripts in footer.
*
* @date 11/06/2020
* @since 5.9.0
*
* @param void
* @return void
*/
public function print_uploader_scripts() {
// Todo: investigate output-buffer to hide HTML.
?>
<div id="acf-hidden-wp-editor" class="acf-hidden">
<div id="acf-hidden-wp-editor" style="display: none;">
<?php wp_editor( '', 'acf_content' ); ?>
</div>
<?php
// action
do_action('acf/enqueue_uploader');
/**
* Fires when printing uploader scripts.
*
* @since 5.6.9
*
* @param void
*/
do_action( 'acf/admin_print_uploader_scripts' );
}
}
@ -409,74 +538,67 @@ acf_new_instance('ACF_Assets');
endif; // class_exists check
/**
* acf_localize_text
*
* description
*
* @date 13/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
* Appends an array of i18n data for localization.
*
* @date 13/4/18
* @since 5.6.9
*
* @param array $text An array of text for i18n.
* @return void
*/
function acf_localize_text( $text ) {
return acf_get_instance('ACF_Assets')->add_text( $text );
}
/**
* acf_localize_data
*
* description
*
* @date 13/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
* Appends an array of l10n data for localization.
*
* @date 13/4/18
* @since 5.6.9
*
* @param array $data An array of data for l10n.
* @return void
*/
function acf_localize_data( $data ) {
return acf_get_instance('ACF_Assets')->add_data( $data );
}
/*
* acf_enqueue_scripts
*
*
*
* @type function
* @date 6/10/13
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function acf_enqueue_scripts( $args = array() ) {
return acf_get_instance('ACF_Assets')->enqueue_scripts( $args );
/**
* Enqueues a script with support for supplemental inline scripts.
*
* @date 27/4/20
* @since 5.9.0
*
* @param string $name The script name.
* @return void
*/
function acf_enqueue_script( $name ) {
return acf_get_instance('ACF_Assets')->enqueue_script( $name );
}
/**
* Enqueues the input scripts required for fields.
*
* @date 13/4/18
* @since 5.6.9
*
* @param array $args See ACF_Assets::enqueue_scripts() for a list of args.
* @return void
*/
function acf_enqueue_scripts( $args = array() ) {
return acf_get_instance('ACF_Assets')->enqueue( $args );
}
/*
* acf_enqueue_uploader
*
* This function will render a WP WYSIWYG and enqueue media
*
* @type function
* @date 27/10/2014
* @since 5.0.9
*
* @param n/a
* @return n/a
*/
/**
* Enqueues the WP media uploader scripts and styles.
*
* @date 27/10/2014
* @since 5.0.9
*
* @param void
* @return void
*/
function acf_enqueue_uploader() {
return acf_get_instance('ACF_Assets')->enqueue_uploader();
}
?>

View File

@ -442,8 +442,10 @@ class acf_field_checkbox extends acf_field {
function update_field( $field ) {
return acf_get_field_type('select')->update_field( $field );
// Decode choices (convert to array).
$field['choices'] = acf_decode_choices( $field['choices'] );
$field['default_value'] = acf_decode_choices( $field['default_value'], true );
return $field;
}
@ -479,7 +481,10 @@ class acf_field_checkbox extends acf_field {
// get raw $field (may have been changed via repeater field)
// if field is local, it won't have an ID
$selector = $field['ID'] ? $field['ID'] : $field['key'];
$field = acf_get_field( $selector, true );
$field = acf_get_field( $selector );
if( !$field ) {
return false;
}
// bail early if no ID (JSON only)

View File

@ -45,40 +45,20 @@ class acf_field_color_picker extends acf_field {
*/
function input_admin_enqueue_scripts() {
// globals
global $wp_scripts;
// register if not already (on front end)
// http://wordpress.stackexchange.com/questions/82718/how-do-i-implement-the-wordpress-iris-picker-into-my-plugin-on-the-front-end
if( !isset($wp_scripts->registered['iris']) ) {
// styles
wp_register_style('wp-color-picker', admin_url('css/color-picker.css'), array(), '', true);
// scripts
wp_register_script('iris', admin_url('js/iris.min.js'), array('jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch'), '1.0.7', true);
wp_register_script('wp-color-picker', admin_url('js/color-picker.min.js'), array('iris'), '', true);
// localize
wp_localize_script('wp-color-picker', 'wpColorPickerL10n', array(
'clear' => __('Clear', 'acf' ),
'defaultString' => __('Default', 'acf' ),
'pick' => __('Select Color', 'acf' ),
'current' => __('Current Color', 'acf' )
));
// Register scripts for non-admin.
// Applies logic from wp_default_scripts() function.
if( !is_admin() ) {
$suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
$scripts = wp_scripts();
$scripts->add( 'iris', '/wp-admin/js/iris.min.js', array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), '1.0.7', 1 );
$scripts->add( 'wp-color-picker', "/wp-admin/js/color-picker$suffix.js", array( 'iris' ), false, 1 );
$scripts->set_translations( 'wp-color-picker' );
}
// enqueue
wp_enqueue_style('wp-color-picker');
wp_enqueue_script('wp-color-picker');
// Enqueue.
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_script( 'wp-color-picker' );
}

View File

@ -147,11 +147,10 @@ class acf_field_file extends acf_field {
</p>
</div>
<div class="acf-actions -hover">
<?php
if( $uploader != 'basic' ):
?><a class="acf-icon -pencil dark" data-name="edit" href="#" title="<?php _e('Edit', 'acf'); ?>"></a><?php
endif;
?><a class="acf-icon -cancel dark" data-name="remove" href="#" title="<?php _e('Remove', 'acf'); ?>"></a>
<?php if( $uploader != 'basic' ): ?>
<a class="acf-icon -pencil dark" data-name="edit" href="#" title="<?php _e('Edit', 'acf'); ?>"></a>
<?php endif; ?>
<a class="acf-icon -cancel dark" data-name="remove" href="#" title="<?php _e('Remove', 'acf'); ?>"></a>
</div>
</div>
<div class="hide-if-value">

View File

@ -143,9 +143,9 @@ class acf_field_google_map extends acf_field {
<div class="title">
<div class="acf-actions -hover">
<a href="#" data-name="search" class="acf-icon -search grey" title="<?php _e("Search", 'acf'); ?>"></a><?php
?><a href="#" data-name="clear" class="acf-icon -cancel grey" title="<?php _e("Clear location", 'acf'); ?>"></a><?php
?><a href="#" data-name="locate" class="acf-icon -location grey" title="<?php _e("Find current location", 'acf'); ?>"></a>
<a href="#" data-name="search" class="acf-icon -search grey" title="<?php _e("Search", 'acf'); ?>"></a>
<a href="#" data-name="clear" class="acf-icon -cancel grey" title="<?php _e("Clear location", 'acf'); ?>"></a>
<a href="#" data-name="locate" class="acf-icon -location grey" title="<?php _e("Find current location", 'acf'); ?>"></a>
</div>
<input class="search" type="text" placeholder="<?php _e("Search for address...",'acf'); ?>" value="<?php echo esc_attr( $search ); ?>" />

View File

@ -571,78 +571,54 @@ class acf_field__group extends acf_field {
}
/*
* prepare_field_for_export
*
* description
*
* @type function
* @date 11/03/2014
* @since 5.0.0
*
* @param $post_id (int)
* @return $post_id (int)
*/
/**
* prepare_field_for_export
*
* Prepares the field for export.
*
* @date 11/03/2014
* @since 5.0.0
*
* @param array $field The field settings.
* @return array
*/
function prepare_field_for_export( $field ) {
// bail early if no sub fields
if( empty($field['sub_fields']) ) return $field;
// prepare
$field['sub_fields'] = acf_prepare_fields_for_export( $field['sub_fields'] );
// return
// Check for sub fields.
if( !empty($field['sub_fields']) ) {
$field['sub_fields'] = acf_prepare_fields_for_export( $field['sub_fields'] );
}
return $field;
}
/*
* prepare_field_for_import
*
* description
*
* @type function
* @date 11/03/2014
* @since 5.0.0
*
* @param $post_id (int)
* @return $post_id (int)
*/
/**
* prepare_field_for_import
*
* Returns a flat array of fields containing all sub fields ready for import.
*
* @date 11/03/2014
* @since 5.0.0
*
* @param array $field The field settings.
* @return array
*/
function prepare_field_for_import( $field ) {
// bail early if no sub fields
if( empty($field['sub_fields']) ) return $field;
// vars
$sub_fields = $field['sub_fields'];
// reset field setting
$field['sub_fields'] = array();
// loop
foreach( $sub_fields as &$sub_field ) {
// Check for sub fields.
if( !empty($field['sub_fields']) ) {
$sub_fields = acf_extract_var( $field, 'sub_fields' );
$sub_field['parent'] = $field['key'];
// Modify sub fields.
foreach( $sub_fields as $i => $sub_field ) {
$sub_fields[ $i ]['parent'] = $field['key'];
$sub_fields[ $i ]['menu_order'] = $i;
}
// Return array of [field, sub_1, sub_2, ...].
return array_merge( array($field), $sub_fields );
}
// merge
array_unshift($sub_fields, $field);
// return
return $sub_fields;
return $field;
}

View File

@ -67,99 +67,89 @@ class acf_field_image extends acf_field {
));
}
/*
* 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
*/
/**
* Renders the field HTML.
*
* @date 23/01/13
* @since 3.6.0
*
* @param array $field The field settings.
* @return void
*/
function render_field( $field ) {
// vars
$uploader = acf_get_setting('uploader');
// enqueue
if( $uploader == 'wp' ) {
// Enqueue uploader scripts
if( $uploader === 'wp' ) {
acf_enqueue_uploader();
}
// vars
$url = '';
$alt = '';
$div = array(
'class' => 'acf-image-uploader',
'data-preview_size' => $field['preview_size'],
'data-library' => $field['library'],
'data-mime_types' => $field['mime_types'],
'data-uploader' => $uploader
// Elements and attributes.
$value = '';
$div_attrs = array(
'class' => 'acf-image-uploader',
'data-preview_size' => $field['preview_size'],
'data-library' => $field['library'],
'data-mime_types' => $field['mime_types'],
'data-uploader' => $uploader
);
$img_attrs = array(
'src' => '',
'alt' => '',
'data-name' => 'image'
);
// has value?
if( $field['value'] ) {
// update vars
$url = wp_get_attachment_image_src($field['value'], $field['preview_size']);
$alt = get_post_meta($field['value'], '_wp_attachment_image_alt', true);
// url exists
if( $url ) $url = $url[0];
// url exists
if( $url ) {
$div['class'] .= ' has-value';
}
// Detect value.
if( $field['value'] && is_numeric($field['value']) ) {
$image = wp_get_attachment_image_src( $field['value'], $field['preview_size'] );
if( $image ) {
$value = $field['value'];
$img_attrs['src'] = $image[0];
$img_attrs['alt'] = get_post_meta( $field['value'], '_wp_attachment_image_alt', true );
$div_attrs['class'] .= ' has-value';
}
}
// get size of preview value
$size = acf_get_image_size($field['preview_size']);
?>
<div <?php acf_esc_attr_e( $div ); ?>>
<?php acf_hidden_input(array( 'name' => $field['name'], 'value' => $field['value'] )); ?>
<div class="show-if-value image-wrap" <?php if( $size['width'] ): ?>style="<?php echo esc_attr('max-width: '.$size['width'].'px'); ?>"<?php endif; ?>>
<img data-name="image" src="<?php echo esc_url($url); ?>" alt="<?php echo esc_attr($alt); ?>"/>
// Add "preview size" max width and height style.
// Apply max-width to wrap, and max-height to img for max compatibility with field widths.
$size = acf_get_image_size( $field['preview_size'] );
$size_w = $size['width'] ? $size['width'] . 'px' : '100%';
$size_h = $size['height'] ? $size['height'] . 'px' : '100%';
$img_attrs['style'] = sprintf( 'max-height: %s;', $size_h );
// Render HTML.
?>
<div <?php echo acf_esc_attrs( $div_attrs ); ?>>
<?php acf_hidden_input(array(
'name' => $field['name'],
'value' => $value
)); ?>
<div class="show-if-value image-wrap" style="max-width: <?php echo esc_attr( $size_w ); ?>">
<img <?php echo acf_esc_attrs( $img_attrs ); ?> />
<div class="acf-actions -hover">
<?php
if( $uploader != 'basic' ):
?><a class="acf-icon -pencil dark" data-name="edit" href="#" title="<?php _e('Edit', 'acf'); ?>"></a><?php
endif;
?><a class="acf-icon -cancel dark" data-name="remove" href="#" title="<?php _e('Remove', 'acf'); ?>"></a>
<?php if( $uploader !== 'basic' ): ?>
<a class="acf-icon -pencil dark" data-name="edit" href="#" title="<?php _e( 'Edit', 'acf' ); ?>"></a>
<?php endif; ?>
<a class="acf-icon -cancel dark" data-name="remove" href="#" title="<?php _e( 'Remove', 'acf' ); ?>"></a>
</div>
</div>
<div class="hide-if-value">
<?php if( $uploader == 'basic' ): ?>
<?php if( $uploader === 'basic' ): ?>
<?php if( $field['value'] && !is_numeric($field['value']) ): ?>
<div class="acf-error-message"><p><?php echo acf_esc_html($field['value']); ?></p></div>
<div class="acf-error-message"><p><?php echo acf_esc_html( $field['value'] ); ?></p></div>
<?php endif; ?>
<label class="acf-basic-uploader">
<?php acf_file_input(array( 'name' => $field['name'], 'id' => $field['id'] )); ?>
<?php acf_file_input(array(
'name' => $field['name'],
'id' => $field['id']
)); ?>
</label>
<?php else: ?>
<p><?php _e('No image selected','acf'); ?> <a data-name="add" class="acf-button button" href="#"><?php _e('Add Image','acf'); ?></a></p>
<p><?php _e( 'No image selected', 'acf' ); ?> <a data-name="add" class="acf-button button" href="#"><?php _e( 'Add Image', 'acf' ); ?></a></p>
<?php endif; ?>
</div>
</div>
<?php
<?php
}

View File

@ -143,41 +143,34 @@ class acf_field_page_link extends acf_field {
// add archives to $results
if( $field['allow_archives'] && $args['paged'] == 1 ) {
$archives = array();
$archives[] = array(
'id' => home_url(),
'text' => home_url()
);
// Generate unique list of URLs.
$links = array();
$links[] = home_url();
foreach( $args['post_type'] as $post_type ) {
// vars
$archive_link = get_post_type_archive_link( $post_type );
// bail ealry if no link
if( !$archive_link ) continue;
// bail early if no search match
if( $is_search && stripos($archive_link, $s) === false ) continue;
// append
$archives[] = array(
'id' => $archive_link,
'text' => $archive_link
);
$links[] = get_post_type_archive_link( $post_type );
}
$links = array_filter( $links );
$links = array_unique( $links );
// Convert list into choices.
$children = array();
foreach( $links as $link ) {
// Ignore if search does not match.
if( $is_search && stripos($link, $s) === false ) {
continue;
}
$children[] = array(
'id' => $link,
'text' => $link
);
}
if( $children ) {
$results[] = array(
'text' => __('Archives', 'acf'),
'children' => $children
);
}
// append
$results[] = array(
'text' => __('Archives', 'acf'),
'children' => $archives
);
}

View File

@ -100,10 +100,16 @@ class acf_field_range extends acf_field_number {
// range
$html .= acf_get_text_input( $atts );
// calculate input width based on character length (+1 char if using decimals)
$len = strlen( (string) $field['max'] );
if( $atts['step'] < 1 ) $len++;
// Calculate input width based on the largest possible input character length.
// Also take into account the step size for decimal steps minus - 1.5 chars for leading "0.".
$len = max(
strlen( strval($field['min']) ),
strlen( strval($field['max']) )
);
if( floatval($atts['step']) < 1 ) {
$len += strlen( strval($field['step']) ) - 1.5;
}
// input
$html .= acf_get_text_input(array(

View File

@ -473,9 +473,7 @@ class acf_field_relationship extends acf_field {
/* search */
if( in_array('search', $filters) ): ?>
<div class="filter -search">
<span>
<?php acf_text_input( array('placeholder' => __("Search...",'acf'), 'data-filter' => 's') ); ?>
</span>
<?php acf_text_input( array('placeholder' => __("Search...",'acf'), 'data-filter' => 's') ); ?>
</div>
<?php endif;
@ -483,9 +481,7 @@ class acf_field_relationship extends acf_field {
/* post_type */
if( in_array('post_type', $filters) ): ?>
<div class="filter -post_type">
<span>
<?php acf_select_input( array('choices' => $filter_post_type_choices, 'data-filter' => 'post_type') ); ?>
</span>
<?php acf_select_input( array('choices' => $filter_post_type_choices, 'data-filter' => 'post_type') ); ?>
</div>
<?php endif;
@ -493,9 +489,7 @@ class acf_field_relationship extends acf_field {
/* post_type */
if( in_array('taxonomy', $filters) ): ?>
<div class="filter -taxonomy">
<span>
<?php acf_select_input( array('choices' => $filter_taxonomy_choices, 'data-filter' => 'taxonomy') ); ?>
</span>
<?php acf_select_input( array('choices' => $filter_taxonomy_choices, 'data-filter' => 'taxonomy') ); ?>
</div>
<?php endif; ?>
</div>
@ -521,7 +515,7 @@ class acf_field_relationship extends acf_field {
<li>
<?php acf_hidden_input( array('name' => $field['name'].'[]', 'value' => $post->ID) ); ?>
<span data-id="<?php echo esc_attr($post->ID); ?>" class="acf-rel-item">
<?php echo $this->get_post_title( $post, $field ); ?>
<?php echo acf_esc_html( $this->get_post_title( $post, $field ) ); ?>
<a href="#" class="acf-icon -minus small dark" data-name="remove_item"></a>
</span>
</li>

View File

@ -452,15 +452,18 @@ class acf_field_select extends acf_field {
* @param $field (array) the field array holding all the field options
* @return $value
*/
function load_value( $value, $post_id, $field ) {
// ACF4 null
if( $value === 'null' ) return false;
// return
return $value;
// Return an array when field is set for multiple.
if( $field['multiple'] ) {
if( acf_is_empty( $value ) ) {
return array();
}
return acf_array( $value );
}
// Otherwise, return a single value.
return acf_unarray( $value );
}
@ -484,7 +487,11 @@ class acf_field_select extends acf_field {
// decode choices (convert to array)
$field['choices'] = acf_decode_choices($field['choices']);
$field['default_value'] = acf_decode_choices($field['default_value'], true);
// Convert back to string for single selects.
if( !$field['multiple'] ) {
$field['default_value'] = acf_unarray( $field['default_value'] );
}
// return
return $field;
@ -565,28 +572,15 @@ class acf_field_select extends acf_field {
*
* @return $value (mixed) the modified value
*/
function format_value( $value, $post_id, $field ) {
// array
if( acf_is_array($value) ) {
foreach( $value as $i => $v ) {
$value[ $i ] = $this->format_value_single( $v, $post_id, $field );
if( is_array( $value ) ) {
foreach( $value as $i => $val ) {
$value[ $i ] = $this->format_value_single( $val, $post_id, $field );
}
} else {
$value = $this->format_value_single( $value, $post_id, $field );
}
// return
return $value;
}

View File

@ -474,26 +474,23 @@ class acf_field_taxonomy extends acf_field {
function save_post( $post_id ) {
// bail ealry if no terms
if( empty($this->save_post_terms) ) return;
// vars
$info = acf_get_post_id_info($post_id);
// loop
foreach( $this->save_post_terms as $taxonomy => $term_ids ){
// Check for saved terms.
if( !empty($this->save_post_terms) ) {
// save
wp_set_object_terms( $info['id'], $term_ids, $taxonomy, false );
// 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.
$info = acf_get_post_id_info( $post_id );
// Loop over taxonomies and save terms.
foreach( $this->save_post_terms as $taxonomy => $term_ids ){
wp_set_object_terms( $info['id'], $term_ids, $taxonomy, false );
}
// Reset storage.
$this->save_post_terms = array();
}
// reset array ( WP saves twice )
$this->save_post_terms = array();
}

View File

@ -153,7 +153,7 @@ class acf_field_text extends acf_field {
function validate_value( $valid, $value, $field, $input ){
// Check maxlength
if( $field['maxlength'] && mb_strlen(wp_unslash($value)) > $field['maxlength'] ) {
if( $field['maxlength'] && (acf_strlen($value) > $field['maxlength']) ) {
return sprintf( __('Value must not exceed %d characters', 'acf'), $field['maxlength'] );
}

View File

@ -209,9 +209,7 @@ class acf_field_textarea extends acf_field {
function validate_value( $valid, $value, $field, $input ){
// Check maxlength.
// Note: Due to the way strlen (and mb_strlen) work, line breaks count as two characters in PHP, but not in Javascript (or HTML).
// To avoid incorrectly calculating the length, replace double line breaks.
if( $field['maxlength'] && mb_strlen(str_replace("\r\n", "\n", wp_unslash($value))) > $field['maxlength'] ) {
if( $field['maxlength'] && (acf_strlen($value) > $field['maxlength']) ) {
return sprintf( __('Value must not exceed %d characters', 'acf'), $field['maxlength'] );
}

View File

@ -100,8 +100,8 @@ class acf_field_time_picker extends acf_field {
function render_field_settings( $field ) {
// vars
$g_i_a = date('g:i a');
$H_i_s = date('H:i:s');
$g_i_a = date_i18n('g:i a');
$H_i_s = date_i18n('H:i:s');
// display_format

View File

@ -1,26 +1,21 @@
<?php
if( ! class_exists('acf_field_user') ) :
if( ! class_exists('ACF_Field_User') ) :
class acf_field_user extends acf_field {
/*
* __construct
*
* This function will setup the field type data
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
class ACF_Field_User extends ACF_Field {
/**
* Initializes the field type.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
function initialize() {
// vars
// Props.
$this->name = 'user';
$this->label = __("User",'acf');
$this->category = 'relational';
@ -31,302 +26,78 @@ class acf_field_user extends acf_field {
'return_format' => 'array',
);
// Register filter variations.
acf_add_filter_variations( 'acf/fields/user/query', array('name', 'key'), 1 );
acf_add_filter_variations( 'acf/fields/user/result', array('name', 'key'), 2 );
acf_add_filter_variations( 'acf/fields/user/search_columns', array('name', 'key'), 3 );
// extra
add_action('wp_ajax_acf/fields/user/query', array($this, 'ajax_query'));
add_action('wp_ajax_nopriv_acf/fields/user/query', array($this, 'ajax_query'));
}
/*
* ajax_query
*
* description
*
* @type function
* @date 24/10/13
* @since 5.0.0
*
* @param $post_id (int)
* @return $post_id (int)
*/
function ajax_query() {
// validate
if( !acf_verify_ajax() ) die();
// get choices
$response = $this->get_ajax_query( $_POST );
// return
acf_send_ajax_results($response);
// Add AJAX query.
add_action( 'wp_ajax_acf/fields/user/query', array( $this, 'ajax_query' ) );
add_action( 'wp_ajax_nopriv_acf/fields/user/query', array( $this, 'ajax_query' ) );
}
/*
* get_ajax_query
*
* This function will return an array of data formatted for use in a select2 AJAX response
*
* @type function
* @date 15/10/2014
* @since 5.0.9
*
* @param $options (array)
* @return (array)
*/
function get_ajax_query( $options = array() ) {
/**
* Renders the field settings HTML.
*
* @date 23/01/13
* @since 3.6.0
*
* @param array $field The ACF field.
* @return void
*/
function render_field_settings( $field ) {
// defaults
$options = acf_parse_args($options, array(
'post_id' => 0,
's' => '',
'field_key' => '',
'paged' => 1
acf_render_field_setting( $field, array(
'label' => __('Filter by role','acf'),
'instructions' => '',
'type' => 'select',
'name' => 'role',
'choices' => acf_get_user_role_labels(),
'multiple' => 1,
'ui' => 1,
'allow_null' => 1,
'placeholder' => __("All user roles",'acf'),
));
acf_render_field_setting( $field, array(
'label' => __('Allow Null?','acf'),
'instructions' => '',
'name' => 'allow_null',
'type' => 'true_false',
'ui' => 1,
));
// load field
$field = acf_get_field( $options['field_key'] );
if( !$field ) return false;
// vars
$results = array();
$args = array();
$s = false;
$is_search = false;
// paged
$args['users_per_page'] = 20;
$args['paged'] = $options['paged'];
// search
if( $options['s'] !== '' ) {
// strip slashes (search may be integer)
$s = wp_unslash( strval($options['s']) );
// update vars
$args['s'] = $s;
$is_search = true;
}
// role
if( !empty($field['role']) ) {
$args['role'] = acf_get_array( $field['role'] );
}
// search
if( $is_search ) {
// append to $args
$args['search'] = '*' . $options['s'] . '*';
// add reference
$this->field = $field;
// add filter to modify search colums
add_filter('user_search_columns', array($this, 'user_search_columns'), 10, 3);
}
// filters
$args = apply_filters("acf/fields/user/query", $args, $field, $options['post_id']);
$args = apply_filters("acf/fields/user/query/name={$field['_name']}", $args, $field, $options['post_id']);
$args = apply_filters("acf/fields/user/query/key={$field['key']}", $args, $field, $options['post_id']);
// get users
$groups = acf_get_grouped_users( $args );
// loop
if( !empty($groups) ) {
foreach( array_keys($groups) as $group_title ) {
// vars
$users = acf_extract_var( $groups, $group_title );
$data = array(
'text' => $group_title,
'children' => array()
);
// append users
foreach( array_keys($users) as $user_id ) {
$users[ $user_id ] = $this->get_result( $users[ $user_id ], $field, $options['post_id'] );
};
// order by search
if( $is_search && empty($args['orderby']) ) {
$users = acf_order_by_search( $users, $args['s'] );
}
// append to $data
foreach( $users as $id => $title ) {
$data['children'][] = array(
'id' => $id,
'text' => $title
);
}
// append to $r
$results[] = $data;
}
// optgroup or single
if( !empty($args['role']) && count($args['role']) == 1 ) {
$results = $results[0]['children'];
}
}
// vars
$response = array(
'results' => $results,
'limit' => $args['users_per_page']
);
// return
return $response;
acf_render_field_setting( $field, array(
'label' => __('Select multiple values?','acf'),
'instructions' => '',
'name' => 'multiple',
'type' => 'true_false',
'ui' => 1,
));
acf_render_field_setting( $field, array(
'label' => __('Return Format','acf'),
'instructions' => '',
'type' => 'radio',
'name' => 'return_format',
'choices' => array(
'array' => __("User Array",'acf'),
'object' => __("User Object",'acf'),
'id' => __("User ID",'acf'),
),
'layout' => 'horizontal',
));
}
/*
* get_result
*
* This function returns the HTML for a result
*
* @type function
* @date 1/11/2013
* @since 5.0.0
*
* @param $post (object)
* @param $field (array)
* @param $post_id (int) the post_id to which this value is saved to
* @return (string)
*/
function get_result( $user, $field, $post_id = 0 ) {
// get post_id
if( !$post_id ) $post_id = acf_get_form_data('post_id');
// vars
$result = $user->user_login;
// append name
if( $user->first_name ) {
$result .= ' (' . $user->first_name;
if( $user->last_name ) {
$result .= ' ' . $user->last_name;
}
$result .= ')';
}
// filters
$result = apply_filters("acf/fields/user/result", $result, $user, $field, $post_id);
$result = apply_filters("acf/fields/user/result/name={$field['_name']}", $result, $user, $field, $post_id);
$result = apply_filters("acf/fields/user/result/key={$field['key']}", $result, $user, $field, $post_id);
// return
return $result;
}
/*
* user_search_columns
*
* This function will modify the columns which the user AJAX search looks in
*
* @type function
* @date 17/06/2014
* @since 5.0.0
*
* @param $columns (array)
* @return $columns
*/
function user_search_columns( $columns, $search, $WP_User_Query ) {
// bail early if no field
if( empty($this->field) ) {
return $columns;
}
// vars
$field = $this->field;
// filter for 3rd party customization
$columns = apply_filters("acf/fields/user/search_columns", $columns, $search, $WP_User_Query, $field);
$columns = apply_filters("acf/fields/user/search_columns/name={$field['_name']}", $columns, $search, $WP_User_Query, $field);
$columns = apply_filters("acf/fields/user/search_columns/key={$field['key']}", $columns, $search, $WP_User_Query, $field);
// return
return $columns;
}
/*
* render_field()
*
* Create the HTML interface for your field
*
* @type action
* @since 3.6
* @date 23/01/13
*
* @param $field - an array holding all the field's data
*/
/**
* Renders the field input HTML.
*
* @date 23/01/13
* @since 3.6.0
*
* @param array $field The ACF field.
* @return void
*/
function render_field( $field ) {
// Change Field into a select.
@ -358,159 +129,69 @@ class acf_field_user extends acf_field {
acf_render_field( $field );
}
/*
* render_field_settings()
*
* Create extra options for your field. This is rendered when editing a field.
* The value of $field['name'] can be used (like bellow) to save extra data to the $field
*
* @type action
* @since 3.6
* @date 23/01/13
*
* @param $field - an array holding all the field's data
*/
function render_field_settings( $field ) {
/**
* Returns the result text for a fiven WP_User object.
*
* @date 1/11/2013
* @since 5.0.0
*
* @param WP_User $user The WP_User object.
* @param array $field The ACF field related to this query.
* @param (int|string) $post_id The post_id being edited.
* @return string
*/
function get_result( $user, $field, $post_id = 0 ) {
acf_render_field_setting( $field, array(
'label' => __('Filter by role','acf'),
'instructions' => '',
'type' => 'select',
'name' => 'role',
'choices' => acf_get_pretty_user_roles(),
'multiple' => 1,
'ui' => 1,
'allow_null' => 1,
'placeholder' => __("All user roles",'acf'),
));
// allow_null
acf_render_field_setting( $field, array(
'label' => __('Allow Null?','acf'),
'instructions' => '',
'name' => 'allow_null',
'type' => 'true_false',
'ui' => 1,
));
// multiple
acf_render_field_setting( $field, array(
'label' => __('Select multiple values?','acf'),
'instructions' => '',
'name' => 'multiple',
'type' => 'true_false',
'ui' => 1,
));
// return_format
acf_render_field_setting( $field, array(
'label' => __('Return Format','acf'),
'instructions' => '',
'type' => 'radio',
'name' => 'return_format',
'choices' => array(
'array' => __("User Array",'acf'),
'object' => __("User Object",'acf'),
'id' => __("User ID",'acf'),
),
'layout' => 'horizontal',
));
// Get user result item.
$item = acf_get_user_result( $user );
// Default $post_id to current post being edited.
$post_id = $post_id ? $post_id : acf_get_form_data('post_id');
/**
* Filters the result text.
*
* @date 21/5/19
* @since 5.8.1
*
* @param array $args The query args.
* @param array $field The ACF field related to this query.
* @param (int|string) $post_id The post_id being edited.
*/
return apply_filters( "acf/fields/user/result", $item['text'], $user, $field, $post_id );
}
/*
* update_value()
*
* This filter is appied 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;
}
// Format array of values.
// - ensure each value is an id.
// - Parse each id as string for SQL LIKE queries.
if( acf_is_sequential_array($value) ) {
$value = array_map('acf_idval', $value);
$value = array_map('strval', $value);
// Parse single value for id.
} else {
$value = acf_idval( $value );
}
// Return value.
return $value;
}
/*
* load_value()
*
* This filter is applied to the $value after it is loaded from the db
*
* @type filter
* @since 3.6
* @date 23/01/13
*
* @param $value (mixed) the value found in 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
*/
/**
* Filters the field value after it is loaded from the database.
*
* @date 23/01/13
* @since 3.6.0
*
* @param mixed $value The field value.
* @param mixed $post_id The post ID where the value is saved.
* @param array $field The field array containing all settings.
* @return mixed
*/
function load_value( $value, $post_id, $field ) {
// ACF4 null
// Add compatibility for version 4.
if( $value === 'null' ) {
return false;
}
// return
return $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
*/
/**
* Filters the field value after it is loaded from the database but before it is returned to the front-end API.
*
* @date 23/01/13
* @since 3.6.0
*
* @param mixed $value The field value.
* @param mixed $post_id The post ID where the value is saved.
* @param array $field The field array containing all settings.
* @return mixed
*/
function format_value( $value, $post_id, $field ) {
// Bail early if no value.
@ -571,13 +252,210 @@ class acf_field_user extends acf_field {
// Return.
return $value;
}
/**
* Filters the field value before it is saved into the database.
*
* @date 23/01/13
* @since 3.6.0
*
* @param mixed $value The field value.
* @param mixed $post_id The post ID where the value is saved.
* @param array $field The field array containing all settings.
* @return mixed
*/
function update_value( $value, $post_id, $field ) {
// Bail early if no value.
if( empty($value) ) {
return $value;
}
// Format array of values.
// - ensure each value is an id.
// - Parse each id as string for SQL LIKE queries.
if( acf_is_sequential_array($value) ) {
$value = array_map('acf_idval', $value);
$value = array_map('strval', $value);
// Parse single value for id.
} else {
$value = acf_idval( $value );
}
// Return value.
return $value;
}
/**
* Callback for the AJAX query request.
*
* @date 24/10/13
* @since 5.0.0
*
* @param void
* @return void
*/
function ajax_query() {
// Modify Request args.
if( isset($_REQUEST['s']) ) {
$_REQUEST['search'] = $_REQUEST['s'];
}
if( isset($_REQUEST['paged']) ) {
$_REQUEST['page'] = $_REQUEST['paged'];
}
// Add query hooks.
add_action( 'acf/ajax/query_users/init', array( $this, 'ajax_query_init' ), 10, 2 );
add_filter( 'acf/ajax/query_users/args', array( $this, 'ajax_query_args' ), 10, 3 );
add_filter( 'acf/ajax/query_users/result', array( $this, 'ajax_query_result' ), 10, 3 );
add_filter( 'acf/ajax/query_users/search_columns', array( $this, 'ajax_query_search_columns' ), 10, 4 );
// Simulate AJAX request.
acf_get_instance('ACF_Ajax_Query_Users')->request();
}
/**
* Runs during the AJAX query initialization.
*
* @date 9/3/20
* @since 5.8.8
*
* @param array $request The query request.
* @param ACF_Ajax_Query $query The query object.
* @return void
*/
function ajax_query_init( $request, $query ) {
// Require field.
if( !$query->field ) {
$query->send( new WP_Error( 'acf_missing_field', __( 'Error loading field.', 'acf' ), array( 'status' => 404 ) ) );
}
}
/**
* Filters the AJAX query args.
*
* @date 9/3/20
* @since 5.8.8
*
* @param array $args The query args.
* @param array $request The query request.
* @param ACF_Ajax_Query $query The query object.
* @return array
*/
function ajax_query_args( $args, $request, $query ) {
// Add specific roles.
if( $query->field['role'] ) {
$args['role__in'] = acf_array( $query->field['role'] );
}
/**
* Filters the query args.
*
* @date 21/5/19
* @since 5.8.1
*
* @param array $args The query args.
* @param array $field The ACF field related to this query.
* @param (int|string) $post_id The post_id being edited.
*/
return apply_filters( "acf/fields/user/query", $args, $query->field, $query->post_id );
}
/**
* Filters the WP_User_Query search columns.
*
* @date 9/3/20
* @since 5.8.8
*
* @param array $columns An array of column names to be searched.
* @param string $search The search term.
* @param WP_User_Query $WP_User_Query The WP_User_Query instance.
* @return array
*/
function ajax_query_search_columns( $columns, $search, $WP_User_Query, $query ) {
/**
* Filters the column names to be searched.
*
* @date 21/5/19
* @since 5.8.1
*
* @param array $columns An array of column names to be searched.
* @param string $search The search term.
* @param WP_User_Query $WP_User_Query The WP_User_Query instance.
* @param array $field The ACF field related to this query.
*/
return apply_filters( "acf/fields/user/search_columns", $columns, $search, $WP_User_Query, $query->field );
}
/**
* Filters the AJAX Query result.
*
* @date 9/3/20
* @since 5.8.8
*
* @param array $item The choice id and text.
* @param WP_User $user The user object.
* @param ACF_Ajax_Query $query The query object.
* @return array
*/
function ajax_query_result( $item, $user, $query ) {
/**
* Filters the result text.
*
* @date 21/5/19
* @since 5.8.1
*
* @param string The result text.
* @param WP_User $user The user object.
* @param array $field The ACF field related to this query.
* @param (int|string) $post_id The post_id being edited.
*/
$item['text'] = apply_filters( "acf/fields/user/result", $item['text'], $user, $query->field, $query->post_id );
return $item;
}
/**
* Return an array of data formatted for use in a select2 AJAX response.
*
* @date 15/10/2014
* @since 5.0.9
* @deprecated 5.8.9
*
* @param array $args An array of query args.
* @return array
*/
function get_ajax_query( $options = array() ) {
_deprecated_function( __FUNCTION__, '5.8.9' );
return array();
}
/**
* Filters the WP_User_Query search columns.
*
* @date 15/10/2014
* @since 5.0.9
* @deprecated 5.8.9
*
* @param array $columns An array of column names to be searched.
* @param string $search The search term.
* @param WP_User_Query $WP_User_Query The WP_User_Query instance.
* @return array
*/
function user_search_columns( $columns, $search, $WP_User_Query ) {
_deprecated_function( __FUNCTION__, '5.8.9' );
return $columns;
}
}
// initialize
acf_register_field_type( 'acf_field_user' );
acf_register_field_type( 'ACF_Field_User' );
endif; // class_exists check
?>

View File

@ -56,40 +56,25 @@ class acf_field_wysiwyg extends acf_field {
function add_filters() {
// wp-includes/class-wp-embed.php
if( !empty($GLOBALS['wp_embed']) ) {
add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'run_shortcode' ), 8 );
add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'autoembed' ), 8 );
}
// wp-includes/default-filters.php
// WordPress 5.5 introduced new function for applying image tags.
$wp_filter_content_tags = function_exists('wp_filter_content_tags') ? 'wp_filter_content_tags' : 'wp_make_content_images_responsive';
// Mimic filters added to "the_content" in "wp-includes/default-filters.php".
add_filter( 'acf_the_content', 'capital_P_dangit', 11 );
//add_filter( 'acf_the_content', 'do_blocks', 9 ); Not yet supported.
add_filter( 'acf_the_content', 'wptexturize' );
add_filter( 'acf_the_content', 'convert_smilies', 20 );
// Removed in 4.4
if( acf_version_compare('wp', '<', '4.4') ) {
add_filter( 'acf_the_content', 'convert_chars' );
}
add_filter( 'acf_the_content', 'wpautop' );
add_filter( 'acf_the_content', 'shortcode_unautop' );
// should only be for the_content (causes double image on attachment page)
//add_filter( 'acf_the_content', 'prepend_attachment' );
// Added in 4.4
if( function_exists('wp_make_content_images_responsive') ) {
add_filter( 'acf_the_content', 'wp_make_content_images_responsive' );
}
//add_filter( 'acf_the_content', 'prepend_attachment' ); Causes double image on attachment page.
add_filter( 'acf_the_content', $wp_filter_content_tags );
add_filter( 'acf_the_content', 'do_shortcode', 11);
// Mimic filters added to "the_content" in "wp-includes/class-wp-embed.php"
if( isset($GLOBALS['wp_embed']) ) {
add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'run_shortcode' ), 8 );
add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'autoembed' ), 8 );
}
}
@ -322,7 +307,12 @@ class acf_field_wysiwyg extends acf_field {
<div id="wp-<?php echo $id; ?>-editor-tools" class="wp-editor-tools hide-if-no-js">
<?php if( $field['media_upload'] ): ?>
<div id="wp-<?php echo $id; ?>-media-buttons" class="wp-media-buttons">
<?php do_action( 'media_buttons', $id ); ?>
<?php
if( !function_exists( 'media_buttons' ) ) {
require ABSPATH . 'wp-admin/includes/media.php';
}
do_action( 'media_buttons', $id );
?>
</div>
<?php endif; ?>
<?php if( user_can_richedit() && $show_tabs ): ?>

View File

@ -210,32 +210,30 @@ class acf_form_nav_menu {
return $items;
}
/*
* wp_edit_nav_menu_walker
*
* description
*
* @type function
* @date 26/5/17
* @since 5.6.0
*
* @param $post_id (int)
* @return $post_id (int)
*/
/**
* Called when WP renders a menu edit form.
* Used to set global data and customize the Walker class.
*
* @date 26/5/17
* @since 5.6.0
*
* @param string $class The walker class to use. Default 'Walker_Nav_Menu_Edit'.
* @param int $menu_id ID of the menu being rendered.
* @return string
*/
function wp_edit_nav_menu_walker( $class, $menu_id = 0 ) {
// update data (needed for ajax location rules to work)
acf_set_data('nav_menu_id', $menu_id);
// include walker
if( class_exists('Walker_Nav_Menu_Edit') ) {
// Use custom walker class to inject "wp_nav_menu_item_custom_fields" action prioir to WP 5.4.
if( acf_version_compare('wp', '<', '5.3.99') ) {
acf_include('includes/walkers/class-acf-walker-nav-menu-edit.php');
return 'ACF_Walker_Nav_Menu_Edit';
}
// return
return 'ACF_Walker_Nav_Menu_Edit';
// Return class.
return $class;
}

View File

@ -1,280 +0,0 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_json') ) :
class acf_json {
function __construct() {
// update setting
acf_update_setting('save_json', get_stylesheet_directory() . '/acf-json');
acf_append_setting('load_json', get_stylesheet_directory() . '/acf-json');
// actions
add_action('acf/update_field_group', array($this, 'update_field_group'), 10, 1);
add_action('acf/untrash_field_group', array($this, 'update_field_group'), 10, 1);
add_action('acf/trash_field_group', array($this, 'delete_field_group'), 10, 1);
add_action('acf/delete_field_group', array($this, 'delete_field_group'), 10, 1);
add_action('acf/include_fields', array($this, 'include_json_folders'), 10, 0);
}
/*
* update_field_group
*
* This function is hooked into the acf/update_field_group action and will save all field group data to a .json file
*
* @type function
* @date 10/03/2014
* @since 5.0.0
*
* @param $field_group (array)
* @return n/a
*/
function update_field_group( $field_group ) {
// validate
if( !acf_get_setting('json') ) return;
// get fields
$field_group['fields'] = acf_get_fields( $field_group );
// save file
acf_write_json_field_group( $field_group );
}
/*
* delete_field_group
*
* This function will remove the field group .json file
*
* @type function
* @date 10/03/2014
* @since 5.0.0
*
* @param $field_group (array)
* @return n/a
*/
function delete_field_group( $field_group ) {
// validate
if( !acf_get_setting('json') ) return;
// WP appends '__trashed' to end of 'key' (post_name)
$field_group['key'] = str_replace('__trashed', '', $field_group['key']);
// delete
acf_delete_json_field_group( $field_group['key'] );
}
/*
* include_json_folders
*
* This function will include all registered .json files
*
* @type function
* @date 10/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function include_json_folders() {
// validate
if( !acf_get_setting('json') ) return;
// vars
$paths = acf_get_setting('load_json');
// loop through and add to cache
foreach( $paths as $path ) {
$this->include_json_folder( $path );
}
}
/*
* include_json_folder
*
* This function will include all .json files within a folder
*
* @type function
* @date 1/5/17
* @since 5.5.13
*
* @param n/a
* @return n/a
*/
function include_json_folder( $path = '' ) {
// remove trailing slash
$path = untrailingslashit( $path );
// bail early if path does not exist
if( !is_dir($path) ) return false;
// open
$dir = opendir( $path );
// bail early if not valid
if( !$dir ) return false;
// loop over files
while(false !== ( $file = readdir($dir)) ) {
// validate type
if( pathinfo($file, PATHINFO_EXTENSION) !== 'json' ) continue;
// read json
$json = file_get_contents("{$path}/{$file}");
// validate json
if( empty($json) ) continue;
// decode
$json = json_decode($json, true);
// add local
$json['local'] = 'json';
// add field group
acf_add_local_field_group( $json );
}
// return
return true;
}
}
// initialize
acf()->json = new acf_json();
endif; // class_exists check
/*
* acf_write_json_field_group
*
* This function will save a field group to a json file within the current theme
*
* @type function
* @date 5/12/2014
* @since 5.1.5
*
* @param $field_group (array)
* @return (boolean)
*/
function acf_write_json_field_group( $field_group ) {
// vars
$path = acf_get_setting('save_json');
$file = $field_group['key'] . '.json';
// remove trailing slash
$path = untrailingslashit( $path );
// bail early if dir does not exist
if( !is_writable($path) ) return false;
// prepare for export
$id = acf_extract_var( $field_group, 'ID' );
$field_group = acf_prepare_field_group_for_export( $field_group );
// add modified time
$field_group['modified'] = get_post_modified_time('U', true, $id, true);
// write file
$f = fopen("{$path}/{$file}", 'w');
fwrite($f, acf_json_encode( $field_group ));
fclose($f);
// return
return true;
}
/*
* acf_delete_json_field_group
*
* This function will delete a json field group file
*
* @type function
* @date 5/12/2014
* @since 5.1.5
*
* @param $key (string)
* @return (boolean)
*/
function acf_delete_json_field_group( $key ) {
// vars
$path = acf_get_setting('save_json');
$file = $key . '.json';
// remove trailing slash
$path = untrailingslashit( $path );
// bail early if file does not exist
if( !is_readable("{$path}/{$file}") ) {
return false;
}
// remove file
unlink("{$path}/{$file}");
// return
return true;
}
?>

View File

@ -70,7 +70,7 @@ function acf_get_locale() {
// https://wpastra.com/docs/complete-list-wordpress-locale-codes/
$langs = array(
'az_TR' => 'az', // Azerbaijani (Turkey)
'zh_HK' => 'zh_CN', // Chinese (Hong Kong)
'zh_HK' => 'zh_TW', // Chinese (Hong Kong)
'nl_BE' => 'nl_NL', // Dutch (Belgium)
'fr_BE' => 'fr_FR', // French (Belgium)
'nn_NO' => 'nb_NO', // Norwegian (Nynorsk)

View File

@ -0,0 +1,70 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Legacy_Locations') ) :
class ACF_Legacy_Locations {
/**
* Magic __isset method for backwards compatibility.
*
* @date 10/4/20
* @since 5.9.0
*
* @param string $key Key name.
* @return bool
*/
public function __isset( $key ) {
//_doing_it_wrong( __FUNCTION__, __( 'The ACF_Locations class should not be accessed directly.', 'acf' ), '5.9.0' );
return (
$key === 'locations'
);
}
/**
* Magic __get method for backwards compatibility.
*
* @date 10/4/20
* @since 5.9.0
*
* @param string $key Key name.
* @return mixed
*/
public function __get( $key ) {
//_doing_it_wrong( __FUNCTION__, __( 'The ACF_Locations class should not be accessed directly.', 'acf' ), '5.9.0' );
switch ( $key ) {
case 'locations':
return call_user_func( 'acf_get_location_types' );
}
return null;
}
/**
* Magic __call method for backwards compatibility.
*
* @date 10/4/20
* @since 5.9.0
*
* @param string $name The method name.
* @param array $arguments The array of arguments.
* @return mixed
*/
public function __call( $name, $arguments ) {
//_doing_it_wrong( __FUNCTION__, __( 'The ACF_Locations class should not be accessed directly.', 'acf' ), '5.9.0' );
switch ( $name ) {
case 'register_location':
return call_user_func_array( 'acf_register_location_type', $arguments );
case 'get_location':
return call_user_func_array( 'acf_get_location_type', $arguments );
case 'get_locations':
return call_user_func_array( 'acf_get_location_rule_types', $arguments );
}
}
}
endif; // class_exists check

View File

@ -146,40 +146,44 @@ function acf_count_local_field_groups() {
* @since 5.7.10
*
* @param array $field_group The field group array.
* @return void
* @return bool
*/
function acf_add_local_field_group( $field_group ) {
// Validate field group.
$field_group = acf_get_valid_field_group( $field_group );
// Apply default properties needed for import.
$field_group = wp_parse_args($field_group, array(
'key' => '',
'title' => '',
'fields' => array(),
'local' => 'php'
));
// Generate key if only name is provided.
if( !$field_group['key'] ) {
$field_group['key'] = 'group_' . acf_slugify($field_group['title'], '_');
}
// Bail early if field group already exists.
if( acf_is_local_field_group($field_group['key']) ) {
return;
return false;
}
// Prepare field group for import (adds menu_order and parent properties to fields).
$field_group = acf_prepare_field_group_for_import( $field_group );
// Extract fields from group.
$fields = acf_extract_var( $field_group, 'fields' );
// Add local reference (may be set to "json").
if( empty($field_group['local']) ) {
$field_group['local'] = 'php';
}
// Add to store
acf_get_local_store( 'groups' )->set( $field_group['key'], $field_group );
// Add fields
if( $fields ) {
// Add parent reference
foreach( $fields as $i => $field ) {
$fields[ $i ]['parent'] = $field_group['key'];
}
// Add fields.
acf_add_local_fields( $fields );
}
// Return true on success.
return true;
}
/**
@ -348,17 +352,17 @@ function acf_count_local_fields( $parent = '' ) {
*/
function acf_add_local_field( $field, $prepared = false ) {
// Apply default args needed for import.
// Apply default properties needed for import.
$field = wp_parse_args($field, array(
'key' => '',
'name' => '',
'type' => '',
'parent' => ''
'parent' => '',
));
// Ensure field has a key.
// Generate key if only name is provided.
if( !$field['key'] ) {
$field['key'] = "field_{$field['name']}";
$field['key'] = 'field_' . $field['name'];
}
// If called directly, allow sub fields to be correctly prepared.
@ -366,11 +370,6 @@ function acf_add_local_field( $field, $prepared = false ) {
return acf_add_local_fields( array( $field ) );
}
// Set menu order.
if( !isset($field['menu_order']) ) {
$field['menu_order'] = acf_count_local_fields( $field['parent'] );
}
// Extract attributes.
$key = $field['key'];
$name = $field['name'];
@ -511,7 +510,7 @@ function _acf_apply_get_local_field_groups( $groups = array() ) {
}
// Hook into filter.
add_filter( 'acf/get_field_groups', '_acf_apply_get_local_field_groups', 20, 1 );
add_filter( 'acf/load_field_groups', '_acf_apply_get_local_field_groups', 20, 1 );
/**
* _acf_apply_is_local_field_key

319
includes/local-json.php Normal file
View File

@ -0,0 +1,319 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Local_JSON') ) :
class ACF_Local_JSON {
/**
* The found JSON field group files.
*
* @since 5.9.0
* @var array
*/
private $files = array();
/**
* Constructor.
*
* @date 14/4/20
* @since 5.9.0
*
* @param void
* @return void
*/
public function __construct() {
// Update settings.
acf_update_setting( 'save_json', get_stylesheet_directory() . '/acf-json' );
acf_append_setting( 'load_json', get_stylesheet_directory() . '/acf-json' );
// Add listeners.
add_action( 'acf/update_field_group', array( $this, 'update_field_group' ) );
add_action( 'acf/untrash_field_group', array( $this, 'update_field_group' ) );
add_action( 'acf/trash_field_group', array( $this, 'delete_field_group' ) );
add_action( 'acf/delete_field_group', array( $this, 'delete_field_group' ) );
// Include fields.
add_action( 'acf/include_fields', array( $this, 'include_fields' ) );
}
/**
* Returns true if this component is enabled.
*
* @date 14/4/20
* @since 5.9.0
*
* @param void
* @return bool.
*/
public function is_enabled() {
return (bool) acf_get_setting( 'json' );
}
/**
* Writes field group data to JSON file.
*
* @date 14/4/20
* @since 5.9.0
*
* @param array $field_group The field group.
* @return void
*/
public function update_field_group( $field_group ) {
// Bail early if disabled.
if( !$this->is_enabled() ) {
return false;
}
// Append fields.
$field_group['fields'] = acf_get_fields( $field_group );
// Save to file.
$this->save_file( $field_group['key'], $field_group );
}
/**
* Deletes a field group JSON file.
*
* @date 14/4/20
* @since 5.9.0
*
* @param array $field_group The field group.
* @return void
*/
public function delete_field_group( $field_group ) {
// Bail early if disabled.
if( !$this->is_enabled() ) {
return false;
}
// WP appends '__trashed' to end of 'key' (post_name).
$key = str_replace( '__trashed', '', $field_group['key'] );
// Delete file.
$this->delete_file( $key );
}
/**
* Includes all local JSON fields.
*
* @date 14/4/20
* @since 5.9.0
*
* @param void
* @return void
*/
public function include_fields() {
// Bail early if disabled.
if( !$this->is_enabled() ) {
return false;
}
// Get load paths.
$files = $this->scan_field_groups();
foreach( $files as $key => $file ) {
$json = json_decode( file_get_contents( $file ), true );
$json['local'] = 'json';
$json['local_file'] = $file;
acf_add_local_field_group( $json );
}
}
/**
* Scans for JSON field groups.
*
* @date 14/4/20
* @since 5.9.0
*
* @param void
* @return array
*/
function scan_field_groups() {
$json_files = array();
// Loop over "local_json" paths and parse JSON files.
$paths = (array) acf_get_setting( 'load_json' );
foreach( $paths as $path ) {
if( is_dir( $path ) ) {
$files = scandir( $path );
if( $files ) {
foreach( $files as $filename ) {
// Ignore hidden files.
if( $filename[0] === '.' ) {
continue;
}
// Ignore sub directories.
$file = untrailingslashit( $path ) . '/' . $filename;
if( is_dir($file) ) {
continue;
}
// Ignore non JSON files.
$ext = pathinfo( $filename, PATHINFO_EXTENSION );
if( $ext !== 'json' ) {
continue;
}
// Read JSON data.
$json = json_decode( file_get_contents( $file ), true );
if( !is_array($json) || !isset($json['key']) ) {
continue;
}
// Append data.
$json_files[ $json['key'] ] = $file;
}
}
}
}
// Store data and return.
$this->files = $json_files;
return $json_files;
}
/**
* Returns an array of found JSON field group files.
*
* @date 14/4/20
* @since 5.9.0
*
* @param void
* @return array
*/
public function get_files() {
return $this->files;
}
/**
* Saves a field group JSON file.
*
* @date 17/4/20
* @since 5.9.0
*
* @param string $key The field group key.
* @param array $field_group The field group.
* @return bool
*/
public function save_file( $key, $field_group ) {
$path = acf_get_setting( 'save_json' );
$file = untrailingslashit( $path ) . '/' . $key . '.json';
if( !is_writable($path) ) {
return false;
}
// Append modified time.
if( $field_group['ID'] ) {
$field_group['modified'] = get_post_modified_time( 'U', true, $field_group['ID'] );
} else {
$field_group['modified'] = strtotime();
}
// Prepare for export.
$field_group = acf_prepare_field_group_for_export( $field_group );
// Save and return true if bytes were written.
$result = file_put_contents( $file, acf_json_encode( $field_group ) );
return is_int( $result );
}
/**
* Deletes a field group JSON file.
*
* @date 17/4/20
* @since 5.9.0
*
* @param string $key The field group key.
* @return bool True on success.
*/
public function delete_file( $key ) {
$path = acf_get_setting( 'save_json' );
$file = untrailingslashit( $path ) . '/' . $key . '.json';
if( is_readable($file) ) {
unlink( $file );
return true;
}
return false;
}
/**
* Includes all local JSON files.
*
* @date 10/03/2014
* @since 5.0.0
* @deprecated 5.9.0
*
* @param void
* @return void
*/
public function include_json_folders() {
_deprecated_function( __METHOD__, '5.9.0', 'ACF_Local_JSON::include_fields()' );
$this->include_fields();
}
/**
* Includes local JSON files within a specific folder.
*
* @date 01/05/2017
* @since 5.5.13
* @deprecated 5.9.0
*
* @param string $path The path to a specific JSON folder.
* @return void
*/
public function include_json_folder( $path = '' ) {
_deprecated_function( __METHOD__, '5.9.0' );
// Do nothing.
}
}
// Initialize.
acf_new_instance('ACF_Local_JSON');
endif; // class_exists check
/**
* Returns an array of found JSON field group files.
*
* @date 14/4/20
* @since 5.9.0
*
* @param type $var Description. Default.
* @return type Description.
*/
function acf_get_local_json_files() {
return acf_get_instance( 'ACF_Local_JSON' )->get_files();
}
/**
* Saves a field group JSON file.
*
* @date 5/12/2014
* @since 5.1.5
*
* @param array $field_group The field group.
* @return bool
*/
function acf_write_json_field_group( $field_group ) {
return acf_get_instance( 'ACF_Local_JSON' )->save_file( $field_group['key'], $field_group );
}
/**
* Deletes a field group JSON file.
*
* @date 5/12/2014
* @since 5.1.5
*
* @param string $key The field group key.
* @return bool True on success.
*/
function acf_delete_json_field_group( $key ) {
return acf_get_instance( 'ACF_Local_JSON' )->delete_file( $key );
}

View File

@ -1,213 +1,148 @@
<?php
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_locations') ) :
class acf_locations {
/** @var array Contains an array of location rule instances */
var $locations = array();
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function __construct() {
/* do nothing */
}
/*
* register_location
*
* This function will store a location rule class
*
* @type function
* @date 6/07/2016
* @since 5.4.0
*
* @param $instance (object)
* @return n/a
*/
function register_location( $class ) {
$instance = new $class();
$this->locations[ $instance->name ] = $instance;
}
/*
* get_rule
*
* This function will return a location rule class
*
* @type function
* @date 6/07/2016
* @since 5.4.0
*
* @param $name (string)
* @return (mixed)
*/
function get_location( $name ) {
return isset( $this->locations[$name] ) ? $this->locations[$name] : null;
}
/*
* get_rules
*
* This function will return a grouped array of location rules (category => name => label)
*
* @type function
* @date 6/07/2016
* @since 5.4.0
*
* @param n/a
* @return (array)
*/
function get_locations() {
// vars
$groups = array();
$l10n = array(
'post' => __('Post', 'acf'),
'page' => __('Page', 'acf'),
'user' => __('User', 'acf'),
'forms' => __('Forms', 'acf'),
);
// loop
foreach( $this->locations as $location ) {
// bail ealry if not public
if( !$location->public ) continue;
// translate
$cat = $location->category;
$cat = isset( $l10n[$cat] ) ? $l10n[$cat] : $cat;
// append
$groups[ $cat ][ $location->name ] = $location->label;
}
// filter
$groups = apply_filters('acf/location/rule_types', $groups);
// return
return $groups;
}
}
// initialize
acf()->locations = new acf_locations();
endif; // class_exists check
/*
* acf_register_location_rule
*
* alias of acf()->locations->register_location()
*
* @type function
* @date 31/5/17
* @since 5.6.0
*
* @param n/a
* @return n/a
*/
function acf_register_location_rule( $class ) {
return acf()->locations->register_location( $class );
}
/*
* acf_get_location_rule
*
* alias of acf()->locations->get_location()
*
* @type function
* @date 31/5/17
* @since 5.6.0
*
* @param n/a
* @return n/a
*/
function acf_get_location_rule( $name ) {
return acf()->locations->get_location( $name );
}
/*
* acf_get_location_rule_types
*
* alias of acf()->locations->get_locations()
*
* @type function
* @date 31/5/17
* @since 5.6.0
*
* @param n/a
* @return n/a
*/
function acf_get_location_rule_types() {
return acf()->locations->get_locations();
}
// Exit if accessed directly.
if( ! defined( 'ABSPATH' ) ) exit;
// Register store.
acf_register_store( 'location-types' );
/**
* acf_validate_location_rule
*
* Returns a valid location rule array.
*
* @date 28/8/18
* @since 5.7.4
*
* @param $rule array The rule array.
* @return array
*/
function acf_validate_location_rule( $rule = false ) {
* Registers a location type.
*
* @date 8/4/20
* @since 5.9.0
*
* @param string $class_name The location class name.
* @return (ACF_Location|false)
*/
function acf_register_location_type( $class_name ) {
$store = acf_get_store( 'location-types' );
// defaults
$rule = wp_parse_args( $rule, array(
// Check class exists.
if( !class_exists($class_name) ) {
$message = sprintf( __( 'Class "%s" does not exist.', 'acf' ), $class_name );
_doing_it_wrong( __FUNCTION__, $message, '5.9.0' );
return false;
}
// Create instance.
$location_type = new $class_name();
$name = $location_type->name;
// Check location type is unique.
if( $store->has( $name ) ) {
$message = sprintf( __( 'Location type "%s" is already registered.' ), $name );
_doing_it_wrong( __FUNCTION__, $message, '5.9.0' );
return false;
}
// Add to store.
$store->set( $name, $location_type );
/**
* Fires after a location type is registered.
*
* @date 8/4/20
* @since 5.9.0
*
* @param string $name The location type name.
* @param ACF_Location $location_type The location type instance.
*/
do_action( 'acf/registered_location_type', $name, $location_type );
// Return location type instance.
return $location_type;
}
/**
* Returns an array of all registered location types.
*
* @date 8/4/20
* @since 5.9.0
*
* @param void
* @return array
*/
function acf_get_location_types() {
return acf_get_store( 'location-types' )->get();
}
/**
* Returns a location type for the given name.
*
* @date 18/2/19
* @since 5.7.12
*
* @param string $name The location type name.
* @return (ACF_Location|null)
*/
function acf_get_location_type( $name ) {
return acf_get_store( 'location-types' )->get( $name );
}
/**
* Returns a grouped array of all location rule types.
*
* @date 8/4/20
* @since 5.9.0
*
* @param void
* @return array
*/
function acf_get_location_rule_types() {
$types = array();
// Default categories.
$categories = array(
'post' => __('Post', 'acf'),
'page' => __('Page', 'acf'),
'user' => __('User', 'acf'),
'forms' => __('Forms', 'acf'),
);
// Loop over all location types and append to $type.
$location_types = acf_get_location_types();
foreach( $location_types as $location_type ) {
// Ignore if not public.
if( !$location_type->public ) {
continue;
}
// Find category label from category name.
$category = $location_type->category;
if( isset($categories[ $category ]) ) {
$category = $categories[ $category ];
}
// Append
$types[ $category ][ $location_type->name ] = esc_html( $location_type->label );
}
/**
* Filters the location rule types.
*
* @date 8/4/20
* @since 5.9.0
*
* @param array $types The location rule types.
*/
return apply_filters( 'acf/location/rule_types', $types );
}
/**
* Returns a validated location rule with all props.
*
* @date 8/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @return array
*/
function acf_validate_location_rule( $rule = array() ) {
// Apply defaults.
$rule = wp_parse_args($rule, array(
'id' => '',
'group' => '',
'param' => '',
@ -215,158 +150,186 @@ function acf_validate_location_rule( $rule = false ) {
'value' => '',
));
// filter
/**
* Filters the location rule to ensure is valid.
*
* @date 8/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
*/
$rule = apply_filters( "acf/location/validate_rule/type={$rule['param']}", $rule );
$rule = apply_filters( "acf/location/validate_rule", $rule);
// return
$rule = apply_filters( "acf/location/validate_rule", $rule );
return $rule;
}
/*
* acf_get_location_rule_operators
*
* This function will return the operators for a given rule
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param $rule (array)
* @return (array)
*/
/**
* Returns an array of operators for a given rule.
*
* @date 30/5/17
* @since 5.6.0
*
* @param array $rule The location rule.
* @return array
*/
function acf_get_location_rule_operators( $rule ) {
$operators = ACF_Location::get_operators( $rule );
// vars
$operators = array(
'==' => __("is equal to",'acf'),
'!=' => __("is not equal to",'acf'),
);
// Get operators from location type since 5.9.
$location_type = acf_get_location_type( $rule['param'] );
if( $location_type ) {
$operators = $location_type->get_operators( $rule );
}
// filter
/**
* Filters the location rule operators.
*
* @date 30/5/17
* @since 5.6.0
*
* @param array $types The location rule operators.
*/
$operators = apply_filters( "acf/location/rule_operators/type={$rule['param']}", $operators, $rule );
$operators = apply_filters( "acf/location/rule_operators/{$rule['param']}", $operators, $rule );
$operators = apply_filters( "acf/location/rule_operators", $operators, $rule );
// return
return $operators;
}
/*
* acf_get_location_rule_values
*
* This function will return the values for a given rule
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param $rule (array)
* @return (array)
*/
/**
* Returns an array of values for a given rule.
*
* @date 30/5/17
* @since 5.6.0
*
* @param array $rule The location rule.
* @return array
*/
function acf_get_location_rule_values( $rule ) {
// vars
$values = array();
// Get values from location type since 5.9.
$location_type = acf_get_location_type( $rule['param'] );
if( $location_type ) {
$values = $location_type->get_values( $rule );
}
// filter
/**
* Filters the location rule values.
*
* @date 30/5/17
* @since 5.6.0
*
* @param array $types The location rule values.
*/
$values = apply_filters( "acf/location/rule_values/type={$rule['param']}", $values, $rule );
$values = apply_filters( "acf/location/rule_values/{$rule['param']}", $values, $rule );
$values = apply_filters( "acf/location/rule_values", $values, $rule );
// return
return $values;
}
/*
* acf_match_location_rule
*
* This function will match a given rule to the $screen
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param $rule (array)
* @param $screen (array)
* @return (boolean)
*/
/**
* Returns true if the provided rule matches the screen args.
*
* @date 30/5/17
* @since 5.6.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field The field group array.
* @return bool
*/
function acf_match_location_rule( $rule, $screen, $field_group ) {
// vars
$result = false;
// Get result from location type since 5.9.
$location_type = acf_get_location_type( $rule['param'] );
if( $location_type ) {
$result = $location_type->match( $rule, $screen, $field_group );
}
// filter
/**
* Filters the result.
*
* @date 30/5/17
* @since 5.6.0
*
* @param bool $result The match result.
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group array.
*/
$result = apply_filters( "acf/location/match_rule/type={$rule['param']}", $result, $rule, $screen, $field_group );
$result = apply_filters( "acf/location/match_rule", $result, $rule, $screen, $field_group );
$result = apply_filters( "acf/location/rule_match/{$rule['param']}", $result, $rule, $screen, $field_group );
$result = apply_filters( "acf/location/rule_match", $result, $rule, $screen, $field_group );
// return
return $result;
}
/*
* acf_get_location_screen
*
* This function will return a valid location screen array
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param $screen (array)
* @param $field_group (array)
* @return (array)
*/
function acf_get_location_screen( $screen = array(), $field_group = false ) {
/**
* Returns ann array of screen args to be used against matching rules.
*
* @date 8/4/20
* @since 5.9.0
*
* @param array $screen The screen args.
* @param array $deprecated The field group array.
* @return array
*/
function acf_get_location_screen( $screen = array(), $deprecated = false ) {
// vars
// Apply defaults.
$screen = wp_parse_args($screen, array(
'lang' => acf_get_setting('current_language'),
'ajax' => false
));
// filter for 3rd party customization
$screen = apply_filters('acf/location/screen', $screen, $field_group);
// return
return $screen;
/**
* Filters the result.
*
* @date 30/5/17
* @since 5.6.0
*
* @param array $screen The screen args.
* @param array $deprecated The field group array.
*/
return apply_filters( 'acf/location/screen', $screen, $deprecated );
}
/**
* acf_get_valid_location_rule
*
* Deprecated in 5.7.4. Use acf_validate_location_rule() instead.
*
* @date 30/5/17
* @since 5.6.0
*
* @param $rule array The rule array.
* @return array
*/
* Alias of acf_register_location_type().
*
* @date 31/5/17
* @since 5.6.0
*
* @param string $class_name The location class name.
* @return (ACF_Location|false)
*/
function acf_register_location_rule( $class_name ) {
return acf_register_location_type( $class_name );
}
/**
* Alias of acf_get_location_type().
*
* @date 31/5/17
* @since 5.6.0
*
* @param string $class_name The location class name.
* @return (ACF_Location|false)
*/
function acf_get_location_rule( $name ) {
return acf_get_location_type( $name );
}
/**
* Alias of acf_validate_location_rule().
*
* @date 30/5/17
* @since 5.6.0
*
* @param array $rule The location rule.
* @return array
*/
function acf_get_valid_location_rule( $rule ) {
return acf_validate_location_rule( $rule );
}
?>

View File

@ -0,0 +1,62 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Legacy_Location') ) :
abstract class ACF_Legacy_Location {
/**
* Constructor.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function __construct() {
// Add legacy method filters.
if( method_exists($this, 'rule_match') ) {
add_filter( "acf/location/rule_match/{$this->name}", array( $this, 'rule_match' ), 5, 3 );
}
if( method_exists($this, 'rule_operators') ) {
add_filter( "acf/location/rule_operators/{$this->name}", array( $this, 'rule_operators' ), 5, 2 );
}
if( method_exists($this, 'rule_values') ) {
add_filter( "acf/location/rule_values/{$this->name}", array( $this, 'rule_values' ), 5, 2 );
}
}
/**
* Magic __call method for backwards compatibility.
*
* @date 10/4/20
* @since 5.9.0
*
* @param string $name The method name.
* @param array $arguments The array of arguments.
* @return mixed
*/
public function __call( $name, $arguments ) {
// Add backwards compatibility for legacy methods.
// - Combine 3x legacy filters cases together (remove first args).
switch( $name ) {
case 'rule_match':
$method = isset($method) ? $method : 'match';
$arguments[3] = isset($arguments[3]) ? $arguments[3] : false; // Add $field_group param.
case 'rule_operators':
$method = isset($method) ? $method : 'get_operators';
case 'rule_values':
$method = isset($method) ? $method : 'get_values';
array_shift( $arguments );
return call_user_func_array( array($this, $method), $arguments );
case 'compare':
return call_user_func_array( array($this, 'compare_to_rule'), $arguments );
}
}
}
endif; // class_exists check

View File

@ -0,0 +1,188 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Location') ) :
abstract class ACF_Location extends ACF_Legacy_Location {
/**
* The location rule name.
*
* @since 5.9.0
* @var string
*/
public $name = '';
/**
* The location rule label.
*
* @since 5.9.0
* @var string
*/
public $label = '';
/**
* The location rule category.
*
* Accepts "post", "page", "user", "forms" or a custom label.
*
* @since 5.9.0
* @var string
*/
public $category = 'post';
/**
* Whether or not the location rule is publicly accessible.
*
* @since 5.0.0
* @var bool
*/
public $public = true;
/**
* The object type related to this location rule.
*
* Accepts an object type discoverable by `acf_get_object_type()`.
*
* @since 5.9.0
* @var string
*/
public $object_type = '';
/**
* The object subtype related to this location rule.
*
* Accepts a custom post type or custom taxonomy.
*
* @since 5.9.0
* @var string
*/
public $object_subtype = '';
/**
* Constructor.
*
* @date 8/4/20
* @since 5.9.0
*
* @param void
* @return void
*/
public function __construct() {
$this->initialize();
// Call legacy constructor.
parent::__construct();
}
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
// Set props here.
}
/**
* Returns an array of operators for this location.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public static function get_operators( $rule ) {
return array(
'==' => __( "is equal to", 'acf' ),
'!=' => __( "is not equal to", 'acf' )
);
}
/**
* Returns an array of possible values for this location.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
return array();
}
/**
* Returns the object_type connected to this location.
*
* @date 1/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return string
*/
public function get_object_type( $rule ) {
return $this->object_type;
}
/**
* Returns the object_subtype connected to this location.
*
* @date 1/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return string|array
*/
public function get_object_subtype( $rule ) {
return $this->object_subtype;
}
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
return false;
}
/**
* Compares the given value and rule params returning true when they match.
*
* @date 17/9/19
* @since 5.8.1
*
* @param array $rule The location rule data.
* @param mixed $value The value to compare against.
* @return bool
*/
public function compare_to_rule( $value, $rule ) {
$result = ( $value == $rule['value'] );
// Allow "all" to match any value.
if( $rule['value'] === 'all' ) {
$result = true;
}
// Reverse result for "!=" operator.
if( $rule['operator'] === '!=' ) {
return !$result;
}
return $result;
}
}
endif; // class_exists check

View File

@ -2,126 +2,93 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_attachment') ) :
if( ! class_exists('ACF_Location_Attachment') ) :
class acf_location_attachment extends acf_location {
class ACF_Location_Attachment extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'attachment';
$this->label = __("Attachment",'acf');
$this->label = __( "Attachment", 'acf' );
$this->category = 'forms';
$this->object_type = 'attachment';
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// vars
$attachment = acf_maybe_get( $screen, 'attachment' );
// validate
if( !$attachment ) return false;
// get attachment mime type
$mime_type = get_post_mime_type( $attachment );
// no specific mime
if( !strpos($rule['value'], '/') ) {
// explode into [0] => type, [1] => mime
$bits = explode('/', $mime_type);
// if type matches, fake the $mime_type to match
if( $rule['value'] === $bits[0] ) {
$mime_type = $rule['value'];
}
// Check screen args.
if( isset($screen['attachment']) ) {
$attachment = $screen['attachment'];
} else {
return false;
}
// Get attachment mime type
$mime_type = get_post_mime_type( $attachment );
// match
return $this->compare( $mime_type, $rule );
// Allow for unspecific mim_type matching such as "image" or "video".
if( !strpos($rule['value'], '/') ) {
// Explode mime_type into bits ([0] => type, [1] => subtype) and match type.
$bits = explode( '/', $mime_type );
if( $bits[0] === $rule['value'] ) {
$mime_type = $rule['value'];
}
}
return $this->compare_to_rule( $mime_type, $rule );
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
// vars
$mimes = get_allowed_mime_types();
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
$choices = array(
'all' => __('All', 'acf')
);
// loop
foreach( $mimes as $type => $mime ) {
// Get mime types and append into optgroups.
$mime_types = get_allowed_mime_types();
foreach( $mime_types as $regex => $mime_type ) {
$group = current( explode('/', $mime) );
$choices[ $group ][ $group ] = sprintf( __('All %s formats', 'acf'), $group);
$choices[ $group ][ $mime ] = "$type ($mime)";
// Get type "image" from mime_type "image/jpeg".
$type = current( explode('/', $mime_type) );
// Append group and mimetype.
$choices[ $type ][ $type ] = sprintf( __('All %s formats', 'acf'), $type);
$choices[ $type ][ $mime_type ] = "$regex ($mime_type)";
}
// return
return $choices;
}
}
// initialize
acf_register_location_rule( 'acf_location_attachment' );
// Register.
acf_register_location_type( 'ACF_Location_Attachment' );
endif; // class_exists check
?>

View File

@ -2,94 +2,68 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_comment') ) :
if( ! class_exists('ACF_Location_Comment') ) :
class acf_location_comment extends acf_location {
class ACF_Location_Comment extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'comment';
$this->label = __("Comment",'acf');
$this->label = __( "Comment", 'acf' );
$this->category = 'forms';
$this->object_type = 'comment';
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
// vars
$comment = acf_maybe_get( $screen, 'comment' );
// bail early if not comment
if( !$comment ) return false;
// return
return $this->compare( $comment, $rule );
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// Check screen args.
if( isset($screen['comment']) ) {
$comment = $screen['comment'];
} else {
return false;
}
return $this->compare_to_rule( $comment, $rule );
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
// vars
$choices = array( 'all' => __('All', 'acf') );
$choices = array_merge( $choices, acf_get_pretty_post_types() );
// change this to post types that support comments
// return
return $choices;
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
return array_merge(
array(
'all' => __('All', 'acf')
),
acf_get_pretty_post_types() // Todo: Change to post types that support comments.
);
}
}
// initialize
acf_register_location_rule( 'acf_location_comment' );
// Register.
acf_register_location_type( 'ACF_Location_Comment' );
endif; // class_exists check
?>
endif; // class_exists check

View File

@ -2,127 +2,86 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_current_user_role') ) :
if( ! class_exists('ACF_Location_Current_User_Role') ) :
class acf_location_current_user_role extends acf_location {
class ACF_Location_Current_User_Role extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'current_user_role';
$this->label = __("Current User Role",'acf');
$this->label = __( "Current User Role", 'acf' );
$this->category = 'user';
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// bail early if not logged in
if( !is_user_logged_in() ) return false;
// vars
// Get current user.
$user = wp_get_current_user();
if( !$user ) {
return false;
}
// super_admin
// Check super_admin value.
if( $rule['value'] == 'super_admin' ) {
$result = is_super_admin( $user->ID );
// role
// Check role.
} else {
$result = in_array( $rule['value'], $user->roles );
}
// reverse if 'not equal to'
if( $rule['operator'] == '!=' ) {
$result = !$result;
// Reverse result for "!=" operator.
if( $rule['operator'] === '!=' ) {
return !$result;
}
// return
return $result;
return $result;
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
$choices = wp_roles()->get_names();
// global
global $wp_roles;
// specific roles
$choices = $wp_roles->get_names();
// multi-site
// Prepend Super Admin choice.
if( is_multisite() ) {
$prepend = array( 'super_admin' => __('Super Admin', 'acf') );
$choices = array_merge( $prepend, $choices );
return array_merge(
array(
'super_admin' => __( 'Super Admin', 'acf' )
),
$choices
);
}
// return
return $choices;
}
}
// initialize
acf_register_location_rule( 'acf_location_current_user_role' );
// Register.
acf_register_location_type( 'ACF_Location_Current_User_Role' );
endif; // class_exists check
?>
endif; // class_exists check

View File

@ -2,110 +2,78 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_current_user') ) :
if( ! class_exists('ACF_Location_Current_User') ) :
class acf_location_current_user extends acf_location {
class ACF_Location_Current_User extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'current_user';
$this->label = __("Current User",'acf');
$this->label = __( "Current User", 'acf' );
$this->category = 'user';
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
// logged in
if( $rule['value'] == 'logged_in' ) {
$result = is_user_logged_in();
// viewing_front
} elseif( $rule['value'] == 'viewing_front' ) {
$result = !is_admin();
// viewing_back
} elseif( $rule['value'] == 'viewing_back' ) {
$result = is_admin();
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
switch( $rule['value'] ) {
case 'logged_in':
$result = is_user_logged_in();
break;
case 'viewing_front':
$result = !is_admin();
break;
case 'viewing_back':
$result = is_admin();
break;
default:
$result = false;
break;
}
// reverse if 'not equal to'
if( $rule['operator'] == '!=' ) {
$result = !$result;
// Reverse result for "!=" operator.
if( $rule['operator'] === '!=' ) {
return !$result;
}
// return
return $result;
return $result;
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
return array(
'logged_in' => __('Logged in', 'acf'),
'viewing_front' => __('Viewing front end', 'acf'),
'viewing_back' => __('Viewing back end', 'acf')
'logged_in' => __( 'Logged in', 'acf' ),
'viewing_front' => __( 'Viewing front end', 'acf' ),
'viewing_back' => __( 'Viewing back end', 'acf' )
);
}
}
// initialize
acf_register_location_rule( 'acf_location_current_user' );
// Register.
acf_register_location_type( 'ACF_Location_Current_User' );
endif; // class_exists check
?>

View File

@ -2,103 +2,68 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_nav_menu_item') ) :
if( ! class_exists('ACF_Location_Nav_Menu_Item') ) :
class acf_location_nav_menu_item extends acf_location {
class ACF_Location_Nav_Menu_Item extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'nav_menu_item';
$this->label = __("Menu Item",'acf');
$this->label = __( "Menu Item", 'acf' );
$this->category = 'forms';
$this->object_type = 'menu_item';
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// vars
$nav_menu_item = acf_maybe_get( $screen, 'nav_menu_item' );
// Check screen args.
if( isset($screen['nav_menu_item']) ) {
$nav_menu_item = $screen['nav_menu_item'];
} else {
return false;
}
// bail early if not nav_menu_item
if( !$nav_menu_item ) return false;
// append nav_menu data
// Append "nav_menu" global data to $screen and call 'nav_menu' logic.
if( !isset($screen['nav_menu']) ) {
$screen['nav_menu'] = acf_get_data('nav_menu_id');
}
// return
return acf_get_location_rule('nav_menu')->rule_match( $result, $rule, $screen );
return acf_get_location_type( 'nav_menu' )->match( $rule, $screen, $field_group );
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
// get menu choices
$choices = acf_get_location_rule('nav_menu')->rule_values( $choices, $rule );
// append item types?
// dificult to get these details
// return
return $choices;
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
return acf_get_location_type( 'nav_menu' )->get_values( $rule );
}
}
// initialize
acf_register_location_rule( 'acf_location_nav_menu_item' );
// Register.
acf_register_location_type( 'ACF_Location_Nav_Menu_Item' );
endif; // class_exists check
?>

View File

@ -2,137 +2,100 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_nav_menu') ) :
if( ! class_exists('ACF_Location_Nav_Menu') ) :
class acf_location_nav_menu extends acf_location {
class ACF_Location_Nav_Menu extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'nav_menu';
$this->label = __("Menu",'acf');
$this->label = __( "Menu", 'acf' );
$this->category = 'forms';
}
$this->object_type = 'menu';
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// vars
$nav_menu = acf_maybe_get( $screen, 'nav_menu' );
// bail early if not nav_menu
if( !$nav_menu ) return false;
// location
if( substr($rule['value'], 0, 9) === 'location/' ) {
// vars
$location = substr($rule['value'], 9);
$menu_locations = get_nav_menu_locations();
// bail ealry if no location
if( !isset($menu_locations[$location]) ) return false;
// if location matches, update value
if( $menu_locations[$location] == $nav_menu ) {
$nav_menu = $rule['value'];
}
// Check screen args.
if( isset($screen['nav_menu']) ) {
$nav_menu = $screen['nav_menu'];
} else {
return false;
}
// Allow for "location/xxx" rule value.
$bits = explode('/', $rule['value']);
if( $bits[0] === 'location' ) {
$location = $bits[1];
// Get the map of menu locations [location => menu_id] and update $nav_menu to a location value.
$menu_locations = get_nav_menu_locations();
if( isset($menu_locations[ $location ]) ) {
$rule['value'] = $menu_locations[ $location ];
}
}
// return
return $this->compare( $nav_menu, $rule );
// Compare rule against $nav_menu.
return $this->compare_to_rule( $nav_menu, $rule );
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
// all
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
$choices = array(
'all' => __('All', 'acf'),
'all' => __( 'All', 'acf' )
);
// locations
// Append locations.
$nav_locations = get_registered_nav_menus();
if( !empty($nav_locations) ) {
$cat = __('Menu Locations', 'acf');
if( $nav_locations ) {
$cat = __( 'Menu Locations', 'acf' );
foreach( $nav_locations as $slug => $title ) {
$choices[ $cat ][ 'location/'.$slug ] = $title;
$choices[ $cat ][ "location/$slug" ] = $title;
}
}
// specific menus
// Append menu IDs.
$nav_menus = wp_get_nav_menus();
if( !empty($nav_menus) ) {
$cat = __('Menus', 'acf');
if( $nav_menus ) {
$cat = __( 'Menus', 'acf' );
foreach( $nav_menus as $nav_menu ) {
$choices[ $cat ][ $nav_menu->term_id ] = $nav_menu->name;
}
}
}
// return
// Return choices.
return $choices;
}
}
// initialize
acf_register_location_rule( 'acf_location_nav_menu' );
// Register.
acf_register_location_type( 'ACF_Location_Nav_Menu' );
endif; // class_exists check
?>

View File

@ -2,99 +2,69 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_page_parent') ) :
if( ! class_exists('ACF_Location_Page_Parent') ) :
class acf_location_page_parent extends acf_location {
class ACF_Location_Page_Parent extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'page_parent';
$this->label = __("Page Parent",'acf');
$this->label = __( "Page Parent", 'acf' );
$this->category = 'page';
$this->object_type = 'post';
$this->object_subtype = 'page';
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// vars
$post_id = acf_maybe_get( $screen, 'post_id' );
$page_parent = acf_maybe_get( $screen, 'page_parent' );
// no page parent
if( $page_parent === null ) {
// bail early if no post id
if( !$post_id ) return false;
// get post parent
$post = get_post( $post_id );
$page_parent = $post->post_parent;
// Check screen args.
if( isset($screen['page_parent']) ) {
$page_parent = $screen['page_parent'];
} elseif( isset($screen['post_id']) ) {
$post = get_post( $screen['post_id'] );
$page_parent = $post ? $post->post_parent : false;
} else {
return false;
}
// compare
return $this->compare( $page_parent, $rule );
// Compare rule against $page_parent.
return $this->compare_to_rule( $page_parent, $rule );
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
return acf_get_location_rule('page')->rule_values( $choices, $rule );
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
return acf_get_location_type( 'page' )->get_values( $rule );
}
}
// initialize
acf_register_location_rule( 'acf_location_page_parent' );
// Register.
acf_register_location_type( 'ACF_Location_Page_Parent' );
endif; // class_exists check
?>

View File

@ -2,52 +2,41 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_page_template') ) :
if( ! class_exists('ACF_Location_Page_Template') ) :
class acf_location_page_template extends acf_location {
class ACF_Location_Page_Template extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'page_template';
$this->label = __("Page Template",'acf');
$this->label = __( "Page Template", 'acf' );
$this->category = 'page';
$this->object_type = 'post';
$this->object_subtype = 'page';
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// Check if this rule is relevant to the current screen.
// Find $post_id in the process.
// Check screen args.
if( isset($screen['post_type']) ) {
$post_type = $screen['post_type'];
} elseif( isset($screen['post_id']) ) {
@ -56,52 +45,37 @@ class acf_location_page_template extends acf_location {
return false;
}
// If this rule is set to "default" template, avoid matching on non "page" post types.
// Fixes issue where post templates were added in WP 4.7 and field groups appeared on all post type edit screens.
// Page templates were extended in WordPress version 4.7 for all post types.
// Prevent this rule (which is scoped to the "page" post type) appearing on all post types without a template selected (default template).
if( $rule['value'] === 'default' && $post_type !== 'page' ) {
return false;
}
// Return.
return acf_get_location_rule('post_template')->rule_match( $result, $rule, $screen );
// Match rule using Post Template logic.
return acf_get_location_type( 'post_template' )->match( $rule, $screen, $field_group );
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
// Default choices.
$choices = array(
'default' => apply_filters( 'default_page_template_title', __('Default Template', 'acf') )
);
// Load all templates, and merge in 'page' templates.
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
$post_templates = acf_get_post_templates();
if( isset($post_templates['page']) ) {
$choices = array_merge($choices, $post_templates['page']);
}
// Return choices.
return $choices;
return array_merge(
array(
'default' => apply_filters( 'default_page_template_title', __('Default Template', 'acf') )
),
$post_templates[ 'page' ]
);
}
}
// initialize
acf_register_location_rule( 'acf_location_page_template' );
// Register.
acf_register_location_type( 'ACF_Location_Page_Template' );
endif; // class_exists check
?>
endif; // class_exists check.

View File

@ -2,146 +2,106 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_page_type') ) :
if( ! class_exists('ACF_Location_Page_Type') ) :
class acf_location_page_type extends acf_location {
class ACF_Location_Page_Type extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'page_type';
$this->label = __("Page Type",'acf');
$this->label = __( "Page Type", 'acf' );
$this->category = 'page';
}
$this->object_type = 'post';
$this->object_subtype = 'page';
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// vars
$post_id = acf_maybe_get( $screen, 'post_id' );
// Check screen args.
if( isset($screen['post_id']) ) {
$post_id = $screen['post_id'];
} else {
return false;
}
// bail early if no post id
if( !$post_id ) return false;
// get post
// Get post.
$post = get_post( $post_id );
if ( !$post ) {
return false;
}
// bail early if no post
if( !$post ) return false;
// Compare.
switch( $rule['value'] ) {
case 'front_page':
$front_page = (int) get_option('page_on_front');
$result = ( $front_page === $post->ID );
break;
case 'posts_page':
$posts_page = (int) get_option('page_for_posts');
$result = ( $posts_page === $post->ID );
break;
case 'top_level':
$page_parent = (int) ( isset($screen['page_parent']) ? $screen['page_parent'] : $post->post_parent );
$result = ( $page_parent === 0 );
break;
case 'parent':
$children = get_posts(array(
'post_type' => $post->post_type,
'post_parent' => $post->ID,
'posts_per_page' => 1,
'fields' => 'ids',
));
$result = !empty( $children );
break;
case 'child':
$page_parent = (int) ( isset($screen['page_parent']) ? $screen['page_parent'] : $post->post_parent );
$result = ( $page_parent !== 0 );
break;
default:
return false;
}
// compare
if( $rule['value'] == 'front_page') {
// vars
$front_page = (int) get_option('page_on_front');
// compare
$result = ( $front_page === $post->ID );
} elseif( $rule['value'] == 'posts_page') {
// vars
$posts_page = (int) get_option('page_for_posts');
// compare
$result = ( $posts_page === $post->ID );
} elseif( $rule['value'] == 'top_level') {
// vars
$page_parent = acf_maybe_get( $screen, 'page_parent', $post->post_parent );
// compare
$result = ( $page_parent == 0 );
} elseif( $rule['value'] == 'parent' ) {
// get children
$children = get_posts(array(
'post_type' => $post->post_type,
'post_parent' => $post->ID,
'posts_per_page' => 1,
'fields' => 'ids',
));
// compare
$result = !empty( $children );
} elseif( $rule['value'] == 'child') {
// vars
$page_parent = acf_maybe_get( $screen, 'page_parent', $post->post_parent );
// compare
$result = ( $page_parent > 0 );
// Reverse result for "!=" operator.
if( $rule['operator'] === '!=' ) {
return !$result;
}
// reverse if 'not equal to'
if( $rule['operator'] == '!=' ) {
$result = !$result;
}
// return
return $result;
}
return $result;
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
return array(
'front_page' => __("Front Page",'acf'),
'posts_page' => __("Posts Page",'acf'),
@ -149,14 +109,10 @@ class acf_location_page_type extends acf_location {
'parent' => __("Parent Page (has children)",'acf'),
'child' => __("Child Page (has parent)",'acf'),
);
}
}
// initialize
acf_register_location_rule( 'acf_location_page_type' );
acf_register_location_type( 'ACF_Location_Page_Type' );
endif; // class_exists check
?>

View File

@ -2,98 +2,73 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_page') ) :
if( ! class_exists('ACF_Location_Page') ) :
class acf_location_page extends acf_location {
class ACF_Location_Page extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'page';
$this->label = __("Page",'acf');
$this->label = __( "Page", 'acf' );
$this->category = 'page';
$this->object_type = 'post';
$this->object_subtype = 'page';
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
return acf_get_location_rule('post')->rule_match( $result, $rule, $screen );
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
return acf_get_location_type( 'post' )->match( $rule, $screen, $field_group );
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
$choices = array();
// get posts grouped by post type
// Get grouped posts.
$groups = acf_get_grouped_posts(array(
'post_type' => 'page'
'post_type' => array( 'page' )
));
// Get first group.
$posts = reset( $groups );
// pop
$choices = array_pop( $groups );
// convert posts to titles
foreach( $choices as &$item ) {
$item = acf_get_post_title( $item );
// Append to choices.
if( $posts ) {
foreach( $posts as $post ) {
$choices[ $post->ID ] = acf_get_post_title( $post );
}
}
// return
return $choices;
}
}
// initialize
acf_register_location_rule( 'acf_location_page' );
// Register.
acf_register_location_type( 'ACF_Location_Page' );
endif; // class_exists check
?>

View File

@ -2,87 +2,73 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_post_category') ) :
if( ! class_exists('ACF_Location_Post_Category') ) :
class acf_location_post_category extends acf_location {
class ACF_Location_Post_Category extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'post_category';
$this->label = __("Post Category",'acf');
$this->label = __( "Post Category", 'acf' );
$this->category = 'post';
$this->object_type = 'post';
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
return acf_get_location_rule('post_taxonomy')->rule_match( $result, $rule, $screen );
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
return acf_get_location_type( 'post_taxonomy' )->match( $rule, $screen, $field_group );
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
$terms = acf_get_taxonomy_terms( 'category' );
if( !empty($terms) ) {
$choices = array_pop($terms);
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
$choices = acf_get_taxonomy_terms(array( 'category' ));
if( $choices ) {
return reset( $choices );
}
return $choices;
return array();
}
/**
* Returns the object_subtype connected to this location.
*
* @date 1/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return string|array
*/
public function get_object_subtype( $rule ) {
return acf_get_location_type( 'post_taxonomy' )->get_object_subtype( $rule );
}
}
// initialize
acf_register_location_rule( 'acf_location_post_category' );
acf_register_location_rule( 'ACF_Location_Post_Category' );
endif; // class_exists check
?>

View File

@ -2,142 +2,73 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_post_format') ) :
if( ! class_exists('ACF_Location_Post_Format') ) :
class acf_location_post_format extends acf_location {
class ACF_Location_Post_Format extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'post_format';
$this->label = __("Post Format",'acf');
$this->label = __( "Post Format", 'acf' );
$this->category = 'post';
$this->object_type = 'post';
}
/*
* get_post_type
*
* This function will return the current post_type
*
* @type function
* @date 25/11/16
* @since 5.5.0
*
* @param $options (int)
* @return (mixed)
*/
function get_post_type( $screen ) {
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// vars
$post_id = acf_maybe_get( $screen, 'post_id' );
$post_type = acf_maybe_get( $screen, 'post_type' );
// post_type
if( $post_type ) return $post_type;
// $post_id
if( $post_id ) return get_post_type( $post_id );
// return
return false;
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
// vars
$post_format = acf_maybe_get( $screen, 'post_format' );
// find post format
if( !$post_format ) {
// Check screen args.
if( isset($screen['post_format']) ) {
$post_format = $screen['post_format'];
} elseif( isset($screen['post_id']) ) {
$post_type = get_post_type( $screen['post_id'] );
$post_format = get_post_format( $screen['post_id'] );
// get post id
$post_id = acf_maybe_get( $screen, 'post_id' );
$post_type = $this->get_post_type( $screen );
// bail early if not a post
if( !$post_id || !$post_type ) return false;
// does post_type support 'post-format'
if( post_type_supports($post_type, 'post-formats') ) {
// update
$post_format = get_post_format($post_id);
$post_format = $post_format ? $post_format : 'standard';
// Treat new posts (that support post-formats) without a saved format as "standard".
if( !$post_format && post_type_supports($post_type, 'post-formats') ) {
$post_format = 'standard';
}
} else {
return false;
}
// compare
return $this->compare( $post_format, $rule );
// Compare rule against $post_format.
return $this->compare_to_rule( $post_format, $rule );
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
return get_post_format_strings();
}
}
// initialize
acf_register_location_rule( 'acf_location_post_format' );
acf_register_location_type( 'ACF_Location_Post_Format' );
endif; // class_exists check
?>

View File

@ -2,160 +2,81 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_post_status') ) :
if( ! class_exists('ACF_Location_Post_Status') ) :
class acf_location_post_status extends acf_location {
class ACF_Location_Post_Status extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'post_status';
$this->label = __("Post Status",'acf');
$this->label = __( "Post Status", 'acf' );
$this->category = 'post';
$this->object_type = 'post';
}
/*
* get_post_type
*
* This function will return the current post_type
*
* @type function
* @date 25/11/16
* @since 5.5.0
*
* @param $options (int)
* @return (mixed)
*/
function get_post_type( $screen ) {
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// vars
$post_id = acf_maybe_get( $screen, 'post_id' );
$post_type = acf_maybe_get( $screen, 'post_type' );
// post_type
if( $post_type ) return $post_type;
// $post_id
if( $post_id ) return get_post_type( $post_id );
// return
return false;
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
// vars
$post_status = acf_maybe_get( $screen, 'post_status' );
// find post format
if( !$post_status ) {
// get post id
$post_id = acf_maybe_get( $screen, 'post_id' );
// bail early if not a post
if( !$post_id ) return false;
// update
$post_status = get_post_status( $post_id );
// Check screen args.
if( isset($screen['post_status']) ) {
$post_status = $screen['post_status'];
} elseif( isset($screen['post_id']) ) {
$post_status = get_post_status( $screen['post_id'] );
} else {
return false;
}
// auto-draft = draft
if( $post_status == 'auto-draft' ) {
// Treat "auto-draft" as "draft".
if( $post_status === 'auto-draft' ) {
$post_status = 'draft';
}
// match
return $this->compare( $post_status, $rule );
// Compare rule against $post_status.
return $this->compare_to_rule( $post_status, $rule );
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
// globals
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
global $wp_post_statuses;
// append
if( !empty($wp_post_statuses) ) {
// Append to choices.
$choices = array();
if( $wp_post_statuses ) {
foreach( $wp_post_statuses as $status ) {
$choices[ $status->name ] = $status->label;
}
}
// return choices
return $choices;
}
}
// initialize
acf_register_location_rule( 'acf_location_post_status' );
acf_register_location_type( 'ACF_Location_Post_Status' );
endif; // class_exists check
?>

View File

@ -2,134 +2,113 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_post_taxonomy') ) :
if( ! class_exists('ACF_Location_Post_Taxonomy') ) :
class acf_location_post_taxonomy extends acf_location {
class ACF_Location_Post_Taxonomy extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'post_taxonomy';
$this->label = __("Post Taxonomy",'acf');
$this->label = __( "Post Taxonomy", 'acf' );
$this->category = 'post';
$this->object_type = 'post';
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// vars
$post_id = acf_maybe_get( $screen, 'post_id' );
$post_terms = acf_maybe_get( $screen, 'post_terms' );
// Allow compatibility for attachments.
if( !$post_id ) {
$post_id = acf_maybe_get( $screen, 'attachment_id' );
// Check screen args.
if( isset($screen['post_id']) ) {
$post_id = $screen['post_id'];
} elseif( isset($screen['attachment_id']) ) {
$post_id = $screen['attachment_id'];
} else {
return false;
}
// bail early if not a post
if( !$post_id ) return false;
// get selected term from rule
// Get WP_Term from rule value.
$term = acf_get_term( $rule['value'] );
if( !$term || is_wp_error($term) ) {
return false;
}
// bail early if no term
if( !$term || is_wp_error($term) ) return false;
// if ajax, find the terms for the correct category
if( $post_terms !== null ) {
$post_terms = acf_maybe_get( $post_terms, $term->taxonomy, array() );
// if not ajax, load post's terms
// Get terms connected to post.
if( isset($screen['post_terms']) ) {
$post_terms = acf_maybe_get( $screen['post_terms'], $term->taxonomy, array() );
} else {
$post_terms = wp_get_post_terms( $post_id, $term->taxonomy, array('fields' => 'ids') );
}
// If no terms, this is a new post and should be treated as if it has the "Uncategorized" (1) category ticked
// If no post terms are found, and we are dealing with the "category" taxonomy, treat as default "Uncategorized" category.
if( !$post_terms && $term->taxonomy == 'category' ) {
$post_terms = array( 1 );
}
// compare term IDs and slugs
if( in_array($term->term_id, $post_terms) || in_array($term->slug, $post_terms) ) {
$result = true;
}
// Search $post_terms for a match.
$result = ( in_array($term->term_id, $post_terms) || in_array($term->slug, $post_terms) );
// reverse if 'not equal to'
if( $rule['operator'] == '!=' ) {
$result = !$result;
// Reverse result for "!=" operator.
if( $rule['operator'] === '!=' ) {
return !$result;
}
// return
return $result;
return $result;
}
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
return acf_get_taxonomy_terms();
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
// get
$choices = acf_get_taxonomy_terms();
// unset post_format
if( isset($choices['post_format']) ) {
unset( $choices['post_format']) ;
/**
* Returns the object_subtype connected to this location.
*
* @date 1/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return string|array
*/
public function get_object_subtype( $rule ) {
if( $rule['operator'] === '==' ) {
$term = acf_decode_term( $rule['value'] );
if( $term ) {
$taxonomy = get_taxonomy( $term['taxonomy'] );
if( $taxonomy ) {
return $taxonomy->object_type;
}
}
}
// return
return $choices;
return '';
}
}
// initialize
acf_register_location_rule( 'acf_location_post_taxonomy' );
acf_register_location_type( 'ACF_Location_Post_Taxonomy' );
endif; // class_exists check
?>

View File

@ -2,87 +2,40 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_post_template') ) :
if( ! class_exists('ACF_Location_Post_Template') ) :
class acf_location_post_template extends acf_location {
class ACF_Location_Post_Template extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'post_template';
$this->label = __("Post Template",'acf');
$this->label = __( "Post Template", 'acf' );
$this->category = 'post';
$this->public = acf_version_compare('wp', '>=', '4.7');
$this->object_type = 'post';
}
/*
* get_post_type
*
* This function will return the current post_type
*
* @type function
* @date 25/11/16
* @since 5.5.0
*
* @param $options (int)
* @return (mixed)
*/
function get_post_type( $screen ) {
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// vars
$post_id = acf_maybe_get( $screen, 'post_id' );
$post_type = acf_maybe_get( $screen, 'post_type' );
// post_type
if( $post_type ) return $post_type;
// $post_id
if( $post_id ) return get_post_type( $post_id );
// return
return false;
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
// Check if this rule is relevant to the current screen.
// Find $post_id in the process.
// Check screen args.
if( isset($screen['post_type']) ) {
$post_type = $screen['post_type'];
} elseif( isset($screen['post_id']) ) {
@ -97,11 +50,13 @@ class acf_location_post_template extends acf_location {
return false;
}
// get page template allowing for screen or database value.
$page_template = acf_maybe_get( $screen, 'page_template' );
$post_id = acf_maybe_get( $screen, 'post_id' );
if( $page_template === null ) {
$page_template = get_post_meta( $post_id, '_wp_page_template', true );
// Get page template allowing for screen or database value.
if( isset($screen['page_template']) ) {
$page_template = $screen['page_template'];
} elseif( isset($screen['post_id']) ) {
$page_template = get_post_meta( $screen['post_id'], '_wp_page_template', true );
} else {
$page_template = '';
}
// Treat empty value as default template.
@ -109,44 +64,61 @@ class acf_location_post_template extends acf_location {
$page_template = 'default';
}
// Compare.
return $this->compare( $page_template, $rule );
// Compare rule against $page_template.
return $this->compare_to_rule( $page_template, $rule );
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
// Default choices.
$choices = array(
'default' => apply_filters( 'default_page_template_title', __('Default Template', 'acf') )
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
return array_merge(
array(
'default' => apply_filters( 'default_page_template_title', __('Default Template', 'acf') )
),
acf_get_post_templates()
);
// Merge in all post templates.
$post_templates = acf_get_post_templates();
$choices = array_merge($choices, $post_templates);
// Return choices.
return $choices;
}
/**
* Returns the object_subtype connected to this location.
*
* @date 1/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return string|array
*/
public function get_object_subtype( $rule ) {
if( $rule['operator'] === '==' ) {
$post_templates = acf_get_post_templates();
// If "default", return array of all post types which have templates.
if( $rule['value'] === 'default' ) {
return array_keys( $post_templates );
// Otherwise, generate list of post types that have the selected template.
} else {
$post_types = array();
foreach( $post_templates as $post_type => $templates ) {
if( isset( $templates[ $rule['value'] ] ) ) {
$post_types[] = $post_type;
}
}
return $post_types;
}
}
return '';
}
}
// initialize
acf_register_location_rule( 'acf_location_post_template' );
acf_register_location_type( 'ACF_Location_Post_Template' );
endif; // class_exists check
?>

View File

@ -2,131 +2,92 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_post_type') ) :
if( ! class_exists('ACF_Location_Post_Type') ) :
class acf_location_post_type extends acf_location {
class ACF_Location_Post_Type extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'post_type';
$this->label = __("Post Type",'acf');
$this->label = __( "Post Type", 'acf' );
$this->category = 'post';
$this->object_type = 'post';
}
/*
* get_post_type
*
* This function will return the current post_type
*
* @type function
* @date 25/11/16
* @since 5.5.0
*
* @param $options (int)
* @return (mixed)
*/
function get_post_type( $screen ) {
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// vars
$post_id = acf_maybe_get( $screen, 'post_id' );
$post_type = acf_maybe_get( $screen, 'post_type' );
// post_type
if( $post_type ) return $post_type;
// $post_id
if( $post_id ) return get_post_type( $post_id );
// return
return false;
// Check screen args.
if( isset($screen['post_type']) ) {
$post_type = $screen['post_type'];
} elseif( isset($screen['post_id']) ) {
$post_type = get_post_type( $screen['post_id'] );
} else {
return false;
}
// Compare rule against $post_type.
return $this->compare_to_rule( $post_type, $rule );
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
// vars
$post_type = $this->get_post_type( $screen );
// bail early if no post_type found (not a post)
if( !$post_type ) return false;
// match
return $this->compare( $post_type, $rule );
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
// get post types
// - removed show_ui to allow 3rd party code to register a post type using a custom admin edit page
// Get post types.
$post_types = acf_get_post_types(array(
'show_ui' => 1,
'exclude' => array('attachment')
'exclude' => array( 'attachment' )
));
// return choices
// Return array of [type => label].
return acf_get_pretty_post_types( $post_types );
}
/**
* Returns the object_subtype connected to this location.
*
* @date 1/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return string|array
*/
public function get_object_subtype( $rule ) {
if( $rule['operator'] === '==' ) {
return $rule['value'];
}
return '';
}
}
// initialize
acf_register_location_rule( 'acf_location_post_type' );
acf_register_location_type( 'ACF_Location_Post_Type' );
endif; // class_exists check
?>

View File

@ -2,127 +2,87 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_post') ) :
if( ! class_exists('ACF_Location_Post') ) :
class acf_location_post extends acf_location {
class ACF_Location_Post extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'post';
$this->label = __("Post",'acf');
$this->label = __( "Post", 'acf' );
$this->category = 'post';
$this->object_type = 'post';
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// vars
$post_id = acf_maybe_get( $screen, 'post_id' );
// bail early if not post
if( !$post_id ) return false;
// compare
return $this->compare( $post_id, $rule );
// Check screen args.
if( isset($screen['post_id']) ) {
$post_id = $screen['post_id'];
} else {
return false;
}
// Compare rule against post_id.
return $this->compare_to_rule( $post_id, $rule );
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
$choices = array();
// get post types
// Get post types.
$post_types = acf_get_post_types(array(
'show_ui' => 1,
'exclude' => array('page', 'attachment')
));
// get posts grouped by post type
// Get grouped posts.
$groups = acf_get_grouped_posts(array(
'post_type' => $post_types
));
if( !empty($groups) ) {
foreach( array_keys($groups) as $group_title ) {
// vars
$posts = acf_extract_var( $groups, $group_title );
// override post data
foreach( array_keys($posts) as $post_id ) {
// update
$posts[ $post_id ] = acf_get_post_title( $posts[ $post_id ] );
};
// append to $choices
$choices[ $group_title ] = $posts;
// Append to choices.
if( $groups ) {
foreach( $groups as $label => $posts ) {
$choices[ $label ] = array();
foreach( $posts as $post ) {
$choices[ $label ][ $post->ID ] = acf_get_post_title( $post );
}
}
}
// return
return $choices;
}
}
// initialize
acf_register_location_rule( 'acf_location_post' );
acf_register_location_type( 'ACF_Location_Post' );
endif; // class_exists check
?>

View File

@ -2,94 +2,87 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_taxonomy') ) :
if( ! class_exists('ACF_Location_Taxonomy') ) :
class acf_location_taxonomy extends acf_location {
class ACF_Location_Taxonomy extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'taxonomy';
$this->label = __("Taxonomy",'acf');
$this->label = __( "Taxonomy", 'acf' );
$this->category = 'forms';
$this->object_type = 'term';
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// vars
$taxonomy = acf_maybe_get( $screen, 'taxonomy' );
// bail early if not taxonomy
if( !$taxonomy ) return false;
// return
return $this->compare( $taxonomy, $rule );
// Check screen args.
if( isset($screen['taxonomy']) ) {
$taxonomy = $screen['taxonomy'];
} else {
return false;
}
// Compare rule against $taxonomy.
return $this->compare_to_rule( $taxonomy, $rule );
}
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
return array_merge(
array(
'all' => __('All', 'acf')
),
acf_get_taxonomy_labels()
);
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
// vars
$choices = array( 'all' => __('All', 'acf') );
$choices = array_merge( $choices, acf_get_taxonomy_labels() );
// return
return $choices;
/**
* Returns the object_subtype connected to this location.
*
* @date 1/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return string|array
*/
function get_object_subtype( $rule ) {
if( $rule['operator'] === '==' ) {
return $rule['value'];
}
return '';
}
}
// initialize
acf_register_location_rule( 'acf_location_taxonomy' );
acf_register_location_type( 'ACF_Location_Taxonomy' );
endif; // class_exists check
?>

View File

@ -7,9 +7,7 @@ if( ! class_exists('ACF_Location_User_Form') ) :
class ACF_Location_User_Form extends ACF_Location {
/**
* initialize
*
* Sets up the class functionality.
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
@ -17,32 +15,30 @@ class ACF_Location_User_Form extends ACF_Location {
* @param void
* @return void
*/
function initialize() {
public function initialize() {
$this->name = 'user_form';
$this->label = __("User Form", 'acf');
$this->label = __( "User Form", 'acf' );
$this->category = 'user';
$this->object_type = 'user';
}
/**
* rule_match
* Matches the provided rule against the screen args returning a bool result.
*
* Determines if the given location $rule is a match for the current $screen.
* @date 9/4/20
* @since 5.9.0
*
* @date 17/9/19
* @since 5.8.1
*
* @param bool $result Whether or not this location rule is a match.
* @param array $rule The locatio rule data.
* @param array $screen The current screen data.
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
function rule_match( $result, $rule, $screen ) {
public function match( $rule, $screen, $field_group ) {
// Extract vars.
$user_form = acf_maybe_get($screen, 'user_form');
// Return false if no user_form data.
if( !$user_form ) {
// Check screen args.
if( isset($screen['user_form']) ) {
$user_form = $screen['user_form'];
} else {
return false;
}
@ -51,23 +47,20 @@ class ACF_Location_User_Form extends ACF_Location {
$user_form = 'edit';
}
// Compare and return.
return $this->compare( $user_form, $rule );
// Compare rule against $user_form.
return $this->compare_to_rule( $user_form, $rule );
}
/**
* rule_values
* Returns an array of possible values for this rule type.
*
* Returns an array of values for this location rule.
* @date 9/4/20
* @since 5.9.0
*
* @date 17/9/19
* @since 5.8.1
*
* @param array $choices An empty array.
* @param array $rule The locatio rule data.
* @return type Description.
* @param array $rule A location rule.
* @return array
*/
function rule_values( $choices, $rule ) {
public function get_values( $rule ) {
return array(
'all' => __('All', 'acf'),
'add' => __('Add', 'acf'),
@ -78,6 +71,6 @@ class ACF_Location_User_Form extends ACF_Location {
}
// Register.
acf_register_location_rule( 'ACF_Location_User_Form' );
acf_register_location_type( 'ACF_Location_User_Form' );
endif; // class_exists check

View File

@ -4,7 +4,7 @@ if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Location_User_Role') ) :
class ACF_Location_User_Role extends acf_location {
class ACF_Location_User_Role extends ACF_Location {
/**
* initialize
@ -19,78 +19,68 @@ class ACF_Location_User_Role extends acf_location {
*/
function initialize() {
$this->name = 'user_role';
$this->label = __("User Role", 'acf');
$this->label = __( "User Role", 'acf' );
$this->category = 'user';
$this->object_type = 'user';
}
/**
* rule_match
* Matches the provided rule against the screen args returning a bool result.
*
* Determines if the given location $rule is a match for the current $screen.
* @date 9/4/20
* @since 5.9.0
*
* @date 17/9/19
* @since 5.8.1
*
* @param bool $result Whether or not this location rule is a match.
* @param array $rule The locatio rule data.
* @param array $screen The current screen data.
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
function rule_match( $result, $rule, $screen ) {
public function match( $rule, $screen, $field_group ) {
// Extract vars.
$user_id = acf_maybe_get( $screen, 'user_id' );
$user_role = acf_maybe_get( $screen, 'user_role' );
// Allow $user_role to be supplied (third-party compatibility).
if( $user_role ) {
// Do nothing
// Determine $user_role from $user_id.
} elseif( $user_id ) {
// Check screen args.
if( isset($screen['user_role']) ) {
$user_role = $screen['user_role'];
} elseif( isset($screen['user_id']) ) {
$user_id = $screen['user_id'];
$user_role = '';
// Use default role for new user.
if( $user_id == 'new' ) {
$user_role = get_option('default_role');
// Determine $user_role from $user_id.
if( $user_id === 'new' ) {
$user_role = get_option( 'default_role' );
// Check if user can, and if so, set the value allowing them to match.
} elseif( user_can($user_id, $rule['value']) ) {
$user_role = $rule['value'];
}
// Return false if not a user.
} else {
return false;
}
// Compare and return.
return $this->compare( $user_role, $rule );
// Compare rule against $user_role.
return $this->compare_to_rule( $user_role, $rule );
}
/**
* rule_values
* Returns an array of possible values for this rule type.
*
* Returns an array of values for this location rule.
* @date 9/4/20
* @since 5.9.0
*
* @date 17/9/19
* @since 5.8.1
*
* @param array $choices An empty array.
* @param array $rule The locatio rule data.
* @param array $rule A location rule.
* @return array
*/
function rule_values( $choices, $rule ) {
public function get_values( $rule ) {
global $wp_roles;
// Merge roles with defaults and return.
return wp_parse_args($wp_roles->get_names(), array(
'all' => __('All', 'acf')
));
return array_merge(
array(
'all' => __( 'All', 'acf' )
),
$wp_roles->get_names()
);
}
}
// initialize
acf_register_location_rule( 'ACF_Location_User_Role' );
acf_register_location_type( 'ACF_Location_User_Role' );
endif; // class_exists check

View File

@ -2,109 +2,76 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_location_widget') ) :
if( ! class_exists('ACF_Location_Widget') ) :
class acf_location_widget extends acf_location {
class ACF_Location_Widget extends ACF_Location {
/*
* __construct
*
* This function will setup the class functionality
*
* @type function
* @date 5/03/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function initialize() {
// vars
/**
* Initializes props.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
public function initialize() {
$this->name = 'widget';
$this->label = __("Widget",'acf');
$this->label = __( "Widget", 'acf' );
$this->category = 'forms';
$this->object_type = 'widget';
}
/**
* Matches the provided rule against the screen args returning a bool result.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule The location rule.
* @param array $screen The screen args.
* @param array $field_group The field group settings.
* @return bool
*/
public function match( $rule, $screen, $field_group ) {
// Check screen args.
if( isset($screen['widget']) ) {
$widget = $screen['widget'];
} else {
return false;
}
// Compare rule against $widget.
return $this->compare_to_rule( $widget, $rule );
}
/*
* rule_match
*
* This function is used to match this location $rule to the current $screen
*
* @type function
* @date 3/01/13
* @since 3.5.7
*
* @param $match (boolean)
* @param $rule (array)
* @return $options (array)
*/
function rule_match( $result, $rule, $screen ) {
// vars
$widget = acf_maybe_get( $screen, 'widget' );
// bail early if not widget
if( !$widget ) return false;
// return
return $this->compare( $widget, $rule );
}
/*
* rule_operators
*
* This function returns the available values for this rule type
*
* @type function
* @date 30/5/17
* @since 5.6.0
*
* @param n/a
* @return (array)
*/
function rule_values( $choices, $rule ) {
// global
/**
* Returns an array of possible values for this rule type.
*
* @date 9/4/20
* @since 5.9.0
*
* @param array $rule A location rule.
* @return array
*/
public function get_values( $rule ) {
global $wp_widget_factory;
// vars
$choices = array( 'all' => __('All', 'acf') );
// loop
if( !empty( $wp_widget_factory->widgets ) ) {
// Populate choices.
$choices = array(
'all' => __( 'All', 'acf' )
);
if( $wp_widget_factory->widgets ) {
foreach( $wp_widget_factory->widgets as $widget ) {
$choices[ $widget->id_base ] = $widget->name;
}
}
// return
return $choices;
}
}
// initialize
acf_register_location_rule( 'acf_location_widget' );
acf_register_location_type( 'ACF_Location_Widget' );
endif; // class_exists check
?>

View File

@ -1,111 +0,0 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Location') ) :
class ACF_Location {
/** @var string The location rule name. */
public $name = '';
/** @var string The location rule label. */
public $label = '';
/** @var string The location rule category. */
public $category = 'post';
/** @var string The location rule visibility. */
public $public = true;
/**
* __construct
*
* Sets up the class functionality.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
function __construct() {
// Call initialize to setup props.
$this->initialize();
// Add filters.
$this->add_filter( 'acf/location/rule_match/' . $this->name, array($this, 'rule_match'), 5, 3 );
$this->add_filter( 'acf/location/rule_operators/' . $this->name, array($this, 'rule_operators'), 5, 2 );
$this->add_filter( 'acf/location/rule_values/' . $this->name, array($this, 'rule_values'), 5, 2 );
}
/**
* add_filter
*
* Maybe adds a filter callback.
*
* @date 17/9/19
* @since 5.8.1
*
* @param string $tag The filter name.
* @param callable $function_to_add The callback function.
* @param int $priority The filter priority.
* @param int $accepted_args The number of args to accept.
* @return void
*/
function add_filter( $tag = '', $function_to_add = '', $priority = 10, $accepted_args = 1 ) {
if( is_callable($function_to_add) ) {
add_filter( $tag, $function_to_add, $priority, $accepted_args );
}
}
/**
* initialize
*
* Sets up the class functionality.
*
* @date 5/03/2014
* @since 5.0.0
*
* @param void
* @return void
*/
function initialize() {
// Do nothing.
}
/**
* compare
*
* Compares the given value and rule params returning true when they match.
*
* @date 17/9/19
* @since 5.8.1
*
* @param mixed $value The value to compare against.
* @param array $rule The locatio rule data.
* @return bool
*/
function compare( $value, $rule ) {
// Allow "all" to match any value.
if( $rule['value'] === 'all' ) {
$match = true;
// Compare all other values.
} else {
$match = ( $value == $rule['value'] );
}
// Allow for "!=" operator.
if( $rule['operator'] == '!=' ) {
$match = !$match;
}
// Return.
return $match;
}
}
endif; // class_exists check

View File

@ -49,12 +49,22 @@ class ACF_Media {
*/
function enqueue_scripts(){
// localize
acf_localize_data(array(
'mimeTypeIcon' => wp_mime_type_icon(),
'mimeTypes' => get_allowed_mime_types()
));
if( wp_script_is('acf-input') ) {
acf_localize_text(array(
'Select.verb' => _x('Select', 'verb', 'acf'),
'Edit.verb' => _x('Edit', 'verb', 'acf'),
'Update.verb' => _x('Update', 'verb', 'acf'),
'Uploaded to this post' => __('Uploaded to this post', 'acf'),
'Expand Details' => __('Expand Details', 'acf'),
'Collapse Details' => __('Collapse Details', 'acf'),
'Restricted' => __('Restricted', 'acf'),
'All images' => __('All images', 'acf')
));
acf_localize_data(array(
'mimeTypeIcon' => wp_mime_type_icon(),
'mimeTypes' => get_allowed_mime_types()
));
}
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

BIN
lang/acf-ca.mo Normal file

Binary file not shown.

3310
lang/acf-ca.po Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

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