From 58f0d87e051b587f2c41867159f163fd6e87c987 Mon Sep 17 00:00:00 2001 From: Elliot Condon Date: Fri, 5 Apr 2019 09:26:51 +0200 Subject: [PATCH] 5.7.13 --- acf.php | 27 +- assets/js/acf-input.js | 179 +- assets/js/acf-input.min.js | 8 +- includes/acf-data-functions.php | 92 +- includes/acf-deprecated-functions.php | 116 + includes/acf-field-functions.php | 1570 ++++++++++ includes/acf-field-group-functions.php | 1071 +++++++ includes/acf-form-functions.php | 15 +- includes/acf-helper-functions.php | 201 ++ includes/acf-hook-functions.php | 220 ++ includes/acf-meta-functions.php | 439 +++ includes/acf-post-functions.php | 34 + includes/acf-value-functions.php | 329 +++ includes/admin/admin-field-group.php | 4 +- includes/admin/admin-field-groups.php | 44 +- .../tools/class-acf-admin-tool-import.php | 173 +- includes/api/api-field-group.php | 1238 -------- includes/api/api-field.php | 2177 -------------- includes/api/api-helpers.php | 280 +- includes/api/api-template.php | 103 + includes/api/api-value.php | 715 ----- includes/cache.php | 445 --- includes/class-acf-data.php | 218 +- includes/compatibility.php | 30 +- includes/fields/class-acf-field-text.php | 24 + includes/fields/class-acf-field-textarea.php | 24 + includes/forms/form-gutenberg.php | 13 +- includes/forms/form-taxonomy.php | 12 +- includes/json.php | 1 - includes/l10n.php | 37 +- includes/local-fields.php | 574 ++++ includes/local.php | 1045 ------- includes/locations.php | 2 +- .../class-acf-location-page-template.php | 52 +- .../class-acf-location-post-template.php | 84 +- lang/acf-ar.mo | Bin 57049 -> 58483 bytes lang/acf-ar.po | 437 ++- lang/acf-de_CH.mo | Bin 52835 -> 53137 bytes lang/acf-de_CH.po | 2582 +++++++++-------- lang/acf-de_DE.mo | Bin 53153 -> 53300 bytes lang/acf-de_DE.po | 599 ++-- lang/acf-de_DE_formal.mo | Bin 53330 -> 53488 bytes lang/acf-de_DE_formal.po | 602 ++-- lang/acf-fa_IR.mo | Bin 60311 -> 61177 bytes lang/acf-fa_IR.po | 1811 ++++++------ lang/acf-pt_PT.mo | Bin 52428 -> 52215 bytes lang/acf-pt_PT.po | 499 ++-- lang/acf-tr_TR.mo | Bin 51514 -> 51705 bytes lang/acf-tr_TR.po | 663 ++--- lang/acf.pot | 120 +- pro/assets/js/acf-pro-input.js | 5 +- pro/assets/js/acf-pro-input.min.js | 2 +- .../class-acf-field-flexible-content.php | 116 +- readme.txt | 43 + 54 files changed, 9208 insertions(+), 9867 deletions(-) create mode 100644 includes/acf-deprecated-functions.php create mode 100644 includes/acf-field-functions.php create mode 100644 includes/acf-field-group-functions.php create mode 100644 includes/acf-hook-functions.php create mode 100644 includes/acf-meta-functions.php create mode 100644 includes/acf-post-functions.php create mode 100644 includes/acf-value-functions.php delete mode 100644 includes/api/api-field-group.php delete mode 100644 includes/api/api-field.php delete mode 100644 includes/api/api-value.php delete mode 100644 includes/cache.php create mode 100644 includes/local-fields.php delete mode 100644 includes/local.php diff --git a/acf.php b/acf.php index 8b36b43..1a2358a 100644 --- a/acf.php +++ b/acf.php @@ -3,7 +3,7 @@ Plugin Name: Advanced Custom Fields PRO Plugin URI: https://www.advancedcustomfields.com/ Description: Customize WordPress with powerful, professional and intuitive fields. -Version: 5.7.10 +Version: 5.7.13 Author: Elliot Condon Author URI: http://www.elliotcondon.com/ Copyright: Elliot Condon @@ -18,7 +18,7 @@ if( ! class_exists('ACF') ) : class ACF { /** @var string The plugin version number */ - var $version = '5.7.10'; + var $version = '5.7.13'; /** @var array The plugin settings array */ var $settings = array(); @@ -118,27 +118,31 @@ class ACF { $this->define( 'ACF', true ); $this->define( 'ACF_VERSION', $version ); $this->define( 'ACF_PATH', $path ); - //$this->define( 'ACF_DEV', true ); // api include_once( ACF_PATH . 'includes/api/api-helpers.php'); acf_include('includes/api/api-input.php'); - acf_include('includes/api/api-value.php'); - acf_include('includes/api/api-field.php'); - acf_include('includes/api/api-field-group.php'); acf_include('includes/api/api-template.php'); acf_include('includes/api/api-term.php'); // Include models. acf_include('includes/class-acf-data.php'); - // Include functions. - acf_include('includes/acf-helper-functions.php'); + // Include core functions. acf_include('includes/acf-data-functions.php'); - acf_include('includes/acf-form-functions.php'); - acf_include('includes/acf-user-functions.php'); + acf_include('includes/acf-helper-functions.php'); + acf_include('includes/acf-hook-functions.php'); + // Include functions. + acf_include('includes/acf-deprecated-functions.php'); + acf_include('includes/acf-field-functions.php'); + acf_include('includes/acf-field-group-functions.php'); + acf_include('includes/acf-form-functions.php'); + acf_include('includes/acf-meta-functions.php'); + acf_include('includes/acf-post-functions.php'); + acf_include('includes/acf-user-functions.php'); + acf_include('includes/acf-value-functions.php'); // fields acf_include('includes/fields.php'); @@ -152,12 +156,11 @@ class ACF { // core acf_include('includes/assets.php'); - acf_include('includes/cache.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.php'); + acf_include('includes/local-fields.php'); acf_include('includes/loop.php'); acf_include('includes/media.php'); acf_include('includes/revisions.php'); diff --git a/assets/js/acf-input.js b/assets/js/acf-input.js index 998ffc6..48f7798 100644 --- a/assets/js/acf-input.js +++ b/assets/js/acf-input.js @@ -1991,7 +1991,7 @@ // option } else { - itemsHtml += ''; + itemsHtml += ''; } }); @@ -2097,7 +2097,7 @@ * @return bool */ acf.isGutenberg = function(){ - return ( window.wp && wp.blocks ); + return ( window.wp && wp.data && wp.data.select && wp.data.select( 'core/editor' ) ); }; /** @@ -5934,6 +5934,10 @@ // render this.renderVal( val ); + + // action + var latLng = this.newLatLng( val.lat, val.lng ); + acf.doAction('google_map_change', latLng, this.map, this); }, renderVal: function( val ){ @@ -5965,9 +5969,6 @@ // show marker this.map.marker.setVisible( true ); - // action - acf.doAction('google_map_change', latLng, this.map, this); - // center this.center(); @@ -11037,16 +11038,20 @@ copyEvents( $submitdiv.children('.hndle'), $postbox.children('.hndle') ); } + // Initalize it (modifies HTML). + postbox = acf.newPostbox( result ); + // Trigger action. acf.doAction('append', $postbox); - - // Initalize it. - postbox = acf.newPostbox( result ); + acf.doAction('append_postbox', postbox); } // show postbox postbox.showEnable(); + // Do action. + acf.doAction('show_postbox', postbox); + // append visible.push( result.id ); }); @@ -11055,6 +11060,9 @@ acf.getPostboxes().map(function( postbox ){ if( visible.indexOf( postbox.get('id') ) === -1 ) { postbox.hideDisable(); + + // Do action. + acf.doAction('hide_postbox', postbox); } }); @@ -11099,6 +11107,9 @@ acf.screen.getPostType = this.getPostType; acf.screen.getPostFormat = this.getPostFormat; acf.screen.getPostCoreTerms = this.getPostCoreTerms; + + // Add actions. + this.addAction( 'append_postbox', acf.screen.refreshAvailableMetaBoxesPerLocation ); }, onChange: function(){ @@ -11121,7 +11132,7 @@ // Filter out attributes that have not changed. attributes = attributes.filter(this.proxy(function( attr ){ - return ( edits[attr] && edits[attr] !== this.get(attr) ); + return ( edits[attr] !== undefined && edits[attr] !== this.get(attr) ); })); // Trigger change if has attributes. @@ -11175,8 +11186,62 @@ // return return terms; - }, + } }); + + /** + * acf.screen.refreshAvailableMetaBoxesPerLocation + * + * Refreshes the WP data state based on metaboxes found in the DOM. + * + * @date 6/3/19 + * @since 5.7.13 + * + * @param void + * @return void + */ + acf.screen.refreshAvailableMetaBoxesPerLocation = function() { + + // Extract vars. + var select = wp.data.select( 'core/edit-post' ); + var dispatch = wp.data.dispatch( 'core/edit-post' ); + + // Load current metabox locations and data. + var data = {}; + select.getActiveMetaBoxLocations().map(function( location ){ + data[ location ] = select.getMetaBoxesPerLocation( location ); + }); + + // Generate flat array of existing ids. + var ids = []; + for( var k in data ) { + ids = ids.concat( data[k].map(function(m){ return m.id; }) ); + } + + // Append ACF metaboxes. + acf.getPostboxes().map(function( postbox ){ + + // Ignore if already exists in data. + if( ids.indexOf( postbox.get('id') ) !== -1 ) { + return; + } + + // Get metabox location looking at parent form. + var location = postbox.$el.closest('form').attr('class').replace('metabox-location-', ''); + + // Ensure location exists. + data[ location ] = data[ location ] || []; + + // Append. + data[ location ].push({ + id: postbox.get('id'), + title: postbox.get('title') + }); + }); + + // Update state. + dispatch.setAvailableMetaBoxesPerLocation(data); + }; })(jQuery); @@ -13074,7 +13139,7 @@ 'click button[type="submit"]': 'onClickSubmit', //'click #editor .editor-post-publish-button': 'onClickSubmitGutenberg', 'click #save-post': 'onClickSave', - 'mousedown #post-preview': 'onClickPreview', // use mousedown to hook in before WP click event + 'submit form#post': 'onSubmitPost', 'submit form': 'onSubmit', }, @@ -13237,27 +13302,6 @@ this.set('ignore', true); }, - /** - * onClickPreview - * - * Set ignore to true when previewing a post. - * - * @date 4/9/18 - * @since 5.7.5 - * - * @param object e The event object. - * @param jQuery $el The input element. - * @return void - */ - onClickPreview: function( e, $el ) { - this.set('ignore', true); - - // if post has previously been published but prevented by an error, WP core has - // added a custom 'submit.edit-post' event which causes the input buttons to become disabled. - // remove this event to prevent UX issues. - $('form#post').off('submit.edit-post'); - }, - /** * onClickSubmitGutenberg * @@ -13291,6 +13335,31 @@ } }, + /** + * onSubmitPost + * + * Callback when the 'post' form is submit. + * + * @date 5/3/19 + * @since 5.7.13 + * + * @param object e The event object. + * @param jQuery $el The input element. + * @return void + */ + onSubmitPost: function( e, $el ) { + + // Check if is preview. + if( $('input#wp-preview').val() === 'dopreview' ) { + + // Ignore validation. + this.set('ignore', true); + + // Unlock form to fix conflict with core "submit.edit-post" event causing all submit buttons to be disabled. + acf.unlockForm( $el ) + } + }, + /** * onSubmit * @@ -13305,27 +13374,51 @@ */ onSubmit: function( e, $el ){ - // bail early if is disabled - if( !this.active ) { - return; + // Allow form to submit if... + if( + // Validation has been disabled. + !this.active + + // Or this event is to be ignored. + || this.get('ignore') + + // Or this event has already been prevented. + || e.isDefaultPrevented() + ) { + // Return early and call reset function. + return this.allowSubmit(); } - // bail early if is ignore - if( this.get('ignore') ) { - this.set('ignore', false); - return; - } - - // validate + // Validate form. var valid = acf.validateForm({ form: $el, event: this.get('originalEvent') }); - // if not valid, stop event and allow validation to continue + // If not valid, stop event to prevent form submit. if( !valid ) { e.preventDefault(); } + }, + + /** + * allowSubmit + * + * Resets data during onSubmit when the form is allowed to submit. + * + * @date 5/3/19 + * @since 5.7.13 + * + * @param void + * @return void + */ + allowSubmit: function(){ + + // Reset "ignore" state. + this.set('ignore', false); + + // Reset "originalEvent" object. + this.set('originalEvent', false) } }); diff --git a/assets/js/acf-input.min.js b/assets/js/acf-input.min.js index 3ef6113..d74dac4 100644 --- a/assets/js/acf-input.min.js +++ b/assets/js/acf-input.min.js @@ -1,4 +1,4 @@ -!function(r,s){var c={};(window.acf=c).data={},c.get=function(t){return this.data[t]||null},c.has=function(t){return null!==this.get(t)},c.set=function(t,e){return this.data[t]=e,this};var i=0;c.uniqueId=function(t){var e=++i+"";return t?t+e:e},c.uniqueArray=function(t){function e(t,e,i){return i.indexOf(t)===e}return t.filter(e)};var a="";c.uniqid=function(t,e){var i;void 0===t&&(t="");var n=function(t,e){return e<(t=parseInt(t,10).toString(16)).length?t.slice(t.length-e):e>t.length?Array(e-t.length+1).join("0")+t:t};return a||(a=Math.floor(123456789*Math.random())),a++,i=t,i+=n(parseInt((new Date).getTime()/1e3,10),8),i+=n(a,5),e&&(i+=(10*Math.random()).toFixed(8).toString()),i},c.strReplace=function(t,e,i){return i.split(t).join(e)},c.strCamelCase=function(t){return t=(t=t.replace(/[_-]/g," ")).replace(/(?:^\w|\b\w|\s+)/g,function(t,e){return 0==+t?"":0==e?t.toLowerCase():t.toUpperCase()})},c.strPascalCase=function(t){var e=c.strCamelCase(t);return e.charAt(0).toUpperCase()+e.slice(1)},c.strSlugify=function(t){return c.strReplace("_","-",t.toLowerCase())},c.strSanitize=function(t){var e={"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","ß":"s","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"c","Ĉ":"C","ĉ":"c","Ċ":"C","ċ":"c","Č":"C","č":"c","Ď":"D","ď":"d","Đ":"D","đ":"d","Ē":"E","ē":"e","Ĕ":"E","ĕ":"e","Ė":"E","ė":"e","Ę":"E","ę":"e","Ě":"E","ě":"e","Ĝ":"G","ĝ":"g","Ğ":"G","ğ":"g","Ġ":"G","ġ":"g","Ģ":"G","ģ":"g","Ĥ":"H","ĥ":"h","Ħ":"H","ħ":"h","Ĩ":"I","ĩ":"i","Ī":"I","ī":"i","Ĭ":"I","ĭ":"i","Į":"I","į":"i","İ":"I","ı":"i","IJ":"IJ","ij":"ij","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","Ĺ":"L","ĺ":"l","Ļ":"L","ļ":"l","Ľ":"L","ľ":"l","Ŀ":"L","ŀ":"l","Ł":"l","ł":"l","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","ʼn":"n","Ō":"O","ō":"o","Ŏ":"O","ŏ":"o","Ő":"O","ő":"o","Œ":"OE","œ":"oe","Ŕ":"R","ŕ":"r","Ŗ":"R","ŗ":"r","Ř":"R","ř":"r","Ś":"S","ś":"s","Ŝ":"S","ŝ":"s","Ş":"S","ş":"s","Š":"S","š":"s","Ţ":"T","ţ":"t","Ť":"T","ť":"t","Ŧ":"T","ŧ":"t","Ũ":"U","ũ":"u","Ū":"U","ū":"u","Ŭ":"U","ŭ":"u","Ů":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","ź":"z","Ż":"Z","ż":"z","Ž":"Z","ž":"z","ſ":"s","ƒ":"f","Ơ":"O","ơ":"o","Ư":"U","ư":"u","Ǎ":"A","ǎ":"a","Ǐ":"I","ǐ":"i","Ǒ":"O","ǒ":"o","Ǔ":"U","ǔ":"u","Ǖ":"U","ǖ":"u","Ǘ":"U","ǘ":"u","Ǚ":"U","ǚ":"u","Ǜ":"U","ǜ":"u","Ǻ":"A","ǻ":"a","Ǽ":"AE","ǽ":"ae","Ǿ":"O","ǿ":"o"," ":"_","'":"","?":"","/":"","\\":"",".":"",",":"","`":"",">":"","<":"",'"':"","[":"","]":"","|":"","{":"","}":"","(":"",")":""},i=/\W/g,n=function(t){return e[t]!==s?e[t]:t};return t=(t=t.replace(i,n)).toLowerCase()},c.strMatch=function(t,e){for(var i=0,n=Math.min(t.length,e.length),a=0;a").html(t).text()},c.strEscape=function(t){var e={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};return String(t).replace(/[&<>"'`=\/]/g,function(t){return e[t]})},c.parseArgs=function(t,e){return"object"!=typeof t&&(t={}),"object"!=typeof e&&(e={}),r.extend({},e,t)},window.acfL10n==s&&(acfL10n={}),c.__=function(t){return acfL10n[t]||t},c._x=function(t,e){return acfL10n[t+"."+e]||acfL10n[t]||t},c._n=function(t,e,i){return 1==i?c.__(t):c.__(e)},c.isArray=function(t){return Array.isArray(t)},c.isObject=function(t){return"object"==typeof t};var o=function(t,e,i){var n=(e=e.replace("[]","[%%index%%]")).match(/([^\[\]])+/g);if(n)for(var a=n.length,r=t,s=0;s');var o=e.parent();e.css({height:i,width:n,margin:a,position:"absolute"}),setTimeout(function(){o.css({opacity:0,height:t.endHeight})},50),setTimeout(function(){e.attr("style",s),o.remove(),t.complete()},301)},d=function(t){var e=t.target,i=e.height(),n=e.children().length,a=r('');e.addClass("acf-remove-element"),setTimeout(function(){e.html(a)},251),setTimeout(function(){e.removeClass("acf-remove-element"),a.css({height:t.endHeight})},300),setTimeout(function(){e.remove(),t.complete()},451)};c.duplicate=function(t){t instanceof jQuery&&(t={target:t});var i=0;(t=c.parseArgs(t,{target:!1,search:"",replace:"",before:function(t){},after:function(t,e){},append:function(t,e){t.after(e),i=1}})).target=t.target||t.$el;var e=t.target;t.search=t.search||e.attr("data-id"),t.replace=t.replace||c.uniqid(),t.before(e),c.doAction("before_duplicate",e);var n=e.clone();return c.rename({target:n,search:t.search,replace:t.replace}),n.removeClass("acf-clone"),n.find(".ui-sortable").removeClass("ui-sortable"),t.after(e,n),c.doAction("after_duplicate",e,n),t.append(e,n),c.doAction("append",n),n},c.rename=function(t){t instanceof jQuery&&(t={target:t});var e=(t=c.parseArgs(t,{target:!1,destructive:!1,search:"",replace:""})).target,i=t.search||e.attr("data-id"),n=t.replace||c.uniqid("acf"),a=function(t,e){return e.replace(i,n)};if(t.destructive){var r=e.outerHTML();r=c.strReplace(i,n,r),e.replaceWith(r)}else e.attr("data-id",n),e.find('[id*="'+i+'"]').attr("id",a),e.find('[for*="'+i+'"]').attr("for",a),e.find('[name*="'+i+'"]').attr("name",a);return e},c.prepareForAjax=function(t){return t.nonce=c.get("nonce"),t.post_id=c.get("post_id"),c.has("language")&&(t.lang=c.get("language")),t=c.applyFilters("prepare_for_ajax",t)},c.startButtonLoading=function(t){t.prop("disabled",!0),t.after(' ')},c.stopButtonLoading=function(t){t.prop("disabled",!1),t.next(".acf-loading").remove()},c.showLoading=function(t){t.append('
')},c.hideLoading=function(t){t.children(".acf-loading-overlay").remove()},c.updateUserSetting=function(t,e){var i={action:"acf/ajax/user_setting",name:t,value:e};r.ajax({url:c.get("ajaxurl"),data:c.prepareForAjax(i),type:"post",dataType:"html"})},c.val=function(t,e,i){var n=t.val();return e!==n&&(t.val(e),t.is("select")&&null===t.val()?(t.val(n),!1):(!0!==i&&t.trigger("change"),!0))},c.show=function(t,e){return e&&c.unlock(t,"hidden",e),!c.isLocked(t,"hidden")&&(!!t.hasClass("acf-hidden")&&(t.removeClass("acf-hidden"),!0))},c.hide=function(t,e){return e&&c.lock(t,"hidden",e),!t.hasClass("acf-hidden")&&(t.addClass("acf-hidden"),!0)},c.isHidden=function(t){return t.hasClass("acf-hidden")},c.isVisible=function(t){return!c.isHidden(t)};var f=function(t,e){return!t.hasClass("acf-disabled")&&(e&&c.unlock(t,"disabled",e),!c.isLocked(t,"disabled")&&(!!t.prop("disabled")&&(t.prop("disabled",!1),!0)))};c.enable=function(t,e){if(t.attr("name"))return f(t,e);var i=!1;return t.find("[name]").each(function(){var t;f(r(this),e)&&(i=!0)}),i};var h=function(t,e){return e&&c.lock(t,"disabled",e),!t.prop("disabled")&&(t.prop("disabled",!0),!0)};c.disable=function(t,e){if(t.attr("name"))return h(t,e);var i=!1;return t.find("[name]").each(function(){var t;h(r(this),e)&&(i=!0)}),i},c.isset=function(t){for(var e=1;e'+r(t.children)+"":n+='"}),n};return t.html(r(e)),-1e.priority;)t[i]=t[i-1],--i;t[i]=e}return t}function u(t,e,i){var n=f[t][e];if(!n)return"filters"===t&&i[0];var a=0,r=n.length;if("filters"===t)for(;a','
','

','
','
',"
",'
',""].join("")},render:function(){var t=this.get("title"),e=this.get("content"),i=this.get("loading"),n=this.get("width"),a=this.get("height");this.title(t),this.content(e),n&&this.$(".acf-popup-box").css("width",n),a&&this.$(".acf-popup-box").css("min-height",a),this.loading(i),acf.doAction("append",this.$el)},update:function(t){this.data=acf.parseArgs(t,this.data),this.render()},title:function(t){this.$(".title:first h3").html(t)},content:function(t){this.$(".inner:first").html(t)},loading:function(t){var e=this.$(".loading:first");t?e.show():e.hide()},open:function(){e("body").append(this.$el)},close:function(){this.remove()},onClickClose:function(t,e){t.preventDefault(),this.close()}}),acf.newPopup=function(t){return new acf.models.Popup(t)}}(jQuery),function(t,e){acf.unload=new acf.Model({wait:"load",active:!0,changed:!1,actions:{validation_failure:"startListening",validation_success:"stopListening"},events:{"change form .acf-field":"startListening","submit form":"stopListening"},enable:function(){this.active=!0},disable:function(){this.active=!1},reset:function(){this.stopListening()},startListening:function(){!this.changed&&this.active&&(this.changed=!0,t(window).on("beforeunload",this.onUnload))},stopListening:function(){this.changed=!1,t(window).off("beforeunload",this.onUnload)},onUnload:function(){return acf.__("The changes you made will be lost if you navigate away from this page")}})}(jQuery),function(t,e){var i=new acf.Model({events:{"click .acf-panel-title":"onClick"},onClick:function(t,e){t.preventDefault(),this.toggle(e.parent())},isOpen:function(t){return t.hasClass("-open")},toggle:function(t){this.isOpen(t)?this.close(t):this.open(t)},open:function(t){t.addClass("-open"),t.find(".acf-panel-title i").attr("class","dashicons dashicons-arrow-down")},close:function(t){t.removeClass("-open"),t.find(".acf-panel-title i").attr("class","dashicons dashicons-arrow-right")}})}(jQuery),function(e,t){var i=acf.Model.extend({data:{text:"",type:"",timeout:0,dismiss:!0,target:!1,close:function(){}},events:{"click .acf-notice-dismiss":"onClickClose"},tmpl:function(){return'
'},setup:function(t){e.extend(this.data,t),this.$el=e(this.tmpl())},initialize:function(){this.render(),this.show()},render:function(){this.type(this.get("type")),this.html("

"+this.get("text")+"

"),this.get("dismiss")&&(this.$el.append(''),this.$el.addClass("-dismiss"));var t=this.get("timeout");t&&this.away(t)},update:function(t){e.extend(this.data,t),this.initialize(),this.removeEvents(),this.addEvents()},show:function(){var t=this.get("target");t&&t.prepend(this.$el)},hide:function(){this.$el.remove()},away:function(t){this.setTimeout(function(){acf.remove(this.$el)},t)},type:function(t){var e=this.get("type");e&&this.$el.removeClass("-"+e),this.$el.addClass("-"+t),"error"==t&&this.$el.addClass("acf-error-message")},html:function(t){this.$el.html(t)},text:function(t){this.$("p").html(t)},onClickClose:function(t,e){t.preventDefault(),this.get("close").apply(this,arguments),this.remove()}});acf.newNotice=function(t){return"object"!=typeof t&&(t={text:t}),new i(t)};var n=new acf.Model({wait:"prepare",priority:1,initialize:function(){var t=e(".acf-admin-notice");t.length&&e("h1:first").after(t)}})}(jQuery),function(e,t){acf.getPostbox=function(t){return"string"==typeof t&&(t=e("#"+t)),acf.getInstance(t)},acf.getPostboxes=function(){return acf.getInstances(e(".acf-postbox"))},acf.newPostbox=function(t){return new acf.models.Postbox(t)},acf.models.Postbox=acf.Model.extend({data:{id:"",key:"",style:"default",label:"top",edit:""},setup:function(t){t.editLink&&(t.edit=t.editLink),e.extend(this.data,t),this.$el=this.$postbox()},$postbox:function(){return e("#"+this.get("id"))},$hide:function(){return e("#"+this.get("id")+"-hide")},$hideLabel:function(){return this.$hide().parent()},$hndle:function(){return this.$("> .hndle")},$inside:function(){return this.$("> .inside")},isVisible:function(){return this.$el.hasClass("acf-hidden")},initialize:function(){this.$el.addClass("acf-postbox"),this.$el.removeClass("hide-if-js");var t=this.get("style");"default"!==t&&this.$el.addClass(t),this.$inside().addClass("acf-fields").addClass("-"+this.get("label"));var e=this.get("edit");e&&this.$hndle().append(''),this.show()},show:function(){this.$hideLabel().show(),this.$hide().prop("checked",!0),this.$el.show().removeClass("acf-hidden")},enable:function(){acf.enable(this.$el,"postbox")},showEnable:function(){this.show(),this.enable()},hide:function(){this.$hideLabel().hide(),this.$el.hide().addClass("acf-hidden")},disable:function(){acf.disable(this.$el,"postbox")},hideDisable:function(){this.hide(),this.disable()},html:function(t){this.$inside().html(t),acf.doAction("append",this.$el)}})}(jQuery),function(f,e){acf.newTooltip=function(t){return"object"!=typeof t&&(t={text:t}),t.confirmRemove!==e?(t.textConfirm=acf.__("Remove"),t.textCancel=acf.__("Cancel"),new n(t)):t.confirm!==e?new n(t):new i(t)};var i=acf.Model.extend({data:{text:"",timeout:0,target:null},tmpl:function(){return'
'},setup:function(t){f.extend(this.data,t),this.$el=f(this.tmpl())},initialize:function(){this.render(),this.show(),this.position();var t=this.get("timeout");t&&setTimeout(f.proxy(this.fade,this),t)},update:function(t){f.extend(this.data,t),this.initialize()},render:function(){this.html(this.get("text"))},show:function(){f("body").append(this.$el)},hide:function(){this.$el.remove()},fade:function(){this.$el.addClass("acf-fade-up"),this.setTimeout(function(){this.remove()},250)},html:function(t){this.$el.html(t)},position:function(){var t=this.$el,e=this.get("target");if(e){t.removeClass("right left bottom top").css({top:0,left:0});var i=10,n=e.outerWidth(),a=e.outerHeight(),r=e.offset().top,s=e.offset().left,o=t.outerWidth(),c=t.outerHeight(),l=t.offset().top,u=r-c-l,d=s+n/2-o/2;d<10?(t.addClass("right"),d=s+n,u=r+a/2-c/2-l):d+o+10>f(window).width()?(t.addClass("left"),d=s-o,u=r+a/2-c/2-l):u-f(window).scrollTop()<10?(t.addClass("bottom"),u=r+a-l):t.addClass("top"),t.css({top:u,left:d})}}}),n=i.extend({data:{text:"",textConfirm:"",textCancel:"",target:null,targetConfirm:!0,confirm:function(){},cancel:function(){},context:!1},events:{'click [data-event="cancel"]':"onCancel",'click [data-event="confirm"]':"onConfirm"},addEvents:function(){acf.Model.prototype.addEvents.apply(this);var t=f(document),e=this.get("target");this.setTimeout(function(){this.on(t,"click","onCancel")}),this.get("targetConfirm")&&this.on(e,"click","onConfirm")},removeEvents:function(){acf.Model.prototype.removeEvents.apply(this);var t=f(document),e=this.get("target");this.off(t,"click"),this.off(e,"click")},render:function(){var t,e,i,n=[this.get("text")||acf.__("Are you sure?"),''+(this.get("textConfirm")||acf.__("Yes"))+"",''+(this.get("textCancel")||acf.__("No"))+""].join(" ");this.html(n),this.$el.addClass("-confirm")},onCancel:function(t,e){t.preventDefault(),t.stopImmediatePropagation();var i=this.get("cancel"),n=this.get("context")||this;i.apply(n,arguments),this.remove()},onConfirm:function(t,e){t.preventDefault(),t.stopImmediatePropagation();var i=this.get("confirm"),n=this.get("context")||this;i.apply(n,arguments),this.remove()}});acf.models.Tooltip=i,acf.models.TooltipConfirm=n;var t=new acf.Model({tooltip:!1,events:{"mouseenter .acf-js-tooltip":"showTitle","mouseup .acf-js-tooltip":"hideTitle","mouseleave .acf-js-tooltip":"hideTitle"},showTitle:function(t,e){var i=e.attr("title");i&&(e.attr("title",""),this.tooltip?this.tooltip.update({text:i,target:e}):this.tooltip=acf.newTooltip({text:i,target:e}))},hideTitle:function(t,e){this.tooltip.hide(),e.attr("title",this.tooltip.get("text"))}})}(jQuery),function(e,i){var r=[];acf.Field=acf.Model.extend({type:"",eventScope:".acf-field",wait:"ready",setup:function(t){this.$el=t,this.inherit(t),this.inherit(this.$control())},val:function(t){return t!==i?this.setValue(t):this.prop("disabled")?null:this.getValue()},getValue:function(){return this.$input().val()},setValue:function(t){return acf.val(this.$input(),t)},__:function(t){return acf._e(this.type,t)},$control:function(){return!1},$input:function(){return this.$("[name]:first")},$inputWrap:function(){return this.$(".acf-input:first")},$labelWrap:function(){return this.$(".acf-label:first")},getInputName:function(){return this.$input().attr("name")||""},parent:function(){var t=this.parents();return!!t.length&&t[0]},parents:function(){var t=this.$el.parents(".acf-field"),e;return acf.getFields(t)},show:function(t,e){var i=acf.show(this.$el,t);return i&&(this.prop("hidden",!1),acf.doAction("show_field",this,e)),i},hide:function(t,e){var i=acf.hide(this.$el,t);return i&&(this.prop("hidden",!0),acf.doAction("hide_field",this,e)),i},enable:function(t,e){var i=acf.enable(this.$el,t);return i&&(this.prop("disabled",!1),acf.doAction("enable_field",this,e)),i},disable:function(t,e){var i=acf.disable(this.$el,t);return i&&(this.prop("disabled",!0),acf.doAction("disable_field",this,e)),i},showEnable:function(t,e){return this.enable.apply(this,arguments),this.show.apply(this,arguments)},hideDisable:function(t,e){return this.disable.apply(this,arguments),this.hide.apply(this,arguments)},showNotice:function(t){"object"!=typeof t&&(t={text:t}),this.notice&&this.notice.remove(),t.target=this.$inputWrap(),this.notice=acf.newNotice(t)},removeNotice:function(t){this.notice&&(this.notice.away(t||0),this.notice=!1)},showError:function(t){this.$el.addClass("acf-error"),t!==i&&this.showNotice({text:t,type:"error",dismiss:!1}),acf.doAction("invalid_field",this),this.$el.one("focus change","input, select, textarea",e.proxy(this.removeError,this))},removeError:function(){this.$el.removeClass("acf-error"),this.removeNotice(250),acf.doAction("valid_field",this)},trigger:function(t,e,i){return"invalidField"==t&&(i=!0),acf.Model.prototype.trigger.apply(this,[t,e,i])}}),acf.newField=function(t){var e=t.data("type"),i=s(e),n,a=new(acf.models[i]||acf.Field)(t);return acf.doAction("new_field",a),a};var s=function(t){return acf.strPascalCase(t||"")+"Field"};acf.registerFieldType=function(t){var e,i=t.prototype.type,n=s(i);acf.models[n]=t,r.push(i)},acf.getFieldType=function(t){var e=s(t);return acf.models[e]||!1},acf.getFieldTypes=function(n){n=acf.parseArgs(n,{category:""});var a=[];return r.map(function(t){var e=acf.getFieldType(t),i=e.prototype;n.category&&i.category!==n.category||a.push(e)}),a}}(jQuery),function(n,t){acf.findFields=function(t){var e=".acf-field",i=!1;return(t=acf.parseArgs(t,{key:"",name:"",type:"",is:"",parent:!1,sibling:!1,limit:!1,visible:!1,suppressFilters:!1})).suppressFilters||(t=acf.applyFilters("find_fields_args",t)),t.key&&(e+='[data-key="'+t.key+'"]'),t.type&&(e+='[data-type="'+t.type+'"]'),t.name&&(e+='[data-name="'+t.name+'"]'),t.is&&(e+=t.is),t.visible&&(e+=":visible"),i=t.parent?t.parent.find(e):t.sibling?t.sibling.siblings(e):n(e),t.suppressFilters||(i=i.not(".acf-clone .acf-field"),i=acf.applyFilters("find_fields",i)),t.limit&&(i=i.slice(0,t.limit)),i},acf.findField=function(t,e){return acf.findFields({key:t,limit:1,parent:e,suppressFilters:!0})},acf.getField=function(t){t instanceof jQuery||(t=acf.findField(t));var e=t.data("acf");return e||(e=acf.newField(t)),e},acf.getFields=function(t){t instanceof jQuery||(t=acf.findFields(t));var e=[];return t.each(function(){var t=acf.getField(n(this));e.push(t)}),e},acf.findClosestField=function(t){return t.closest(".acf-field")},acf.getClosestField=function(t){var e=acf.findClosestField(t);return this.getField(e)};var e=function(t){var e=t,r=t+"_fields",a=t+"_field",i=function(t){var e,i=acf.arrayArgs(arguments).slice(1),n=acf.getFields({parent:t});if(n.length){var a=[r,n].concat(i);acf.doAction.apply(null,a)}},n=function(t){var e,n=acf.arrayArgs(arguments).slice(1);t.map(function(t,e){var i=[a,t].concat(n);acf.doAction.apply(null,i)})};acf.addAction(e,i),acf.addAction(r,n),s(t)},s=function(e){var r=e+"_field",s=e+"Field",t=function(i){var n=acf.arrayArgs(arguments),a=n.slice(1),t;["type","name","key"].map(function(t){var e="/"+t+"="+i.get(t);n=[r+e,i].concat(a),acf.doAction.apply(null,n)}),-1'),o=f('
'),c=f(''),l=f("");s.append(e.html()),c.append(l),o.append(c),i.append(s),i.append(o),e.remove(),n.remove(),i.attr("colspan",2),e=s,i=o,n=l}t.addClass("acf-accordion"),e.addClass("acf-accordion-title"),i.addClass("acf-accordion-content"),p++,this.get("multi_expand")&&t.attr("multi-expand",1);var u=acf.getPreference("this.accordions")||[];u[p-1]!==h&&this.set("open",u[p-1]),this.get("open")&&(t.addClass("-open"),i.css("display","block")),e.prepend(g.iconHtml({open:this.get("open")}));var d=t.parent();n.addClass(d.hasClass("-left")?"-left":""),n.addClass(d.hasClass("-clear")?"-clear":""),n.append(t.nextUntil(".acf-field-accordion",".acf-field")),n.removeAttr("data-open data-multi_expand data-endpoint")}}});acf.registerFieldType(t);var g=new acf.Model({actions:{unload:"onUnload"},events:{"click .acf-accordion-title":"onClick","invalidField .acf-accordion":"onInvalidField"},isOpen:function(t){return t.hasClass("-open")},toggle:function(t){this.isOpen(t)?this.close(t -):this.open(t)},iconHtml:function(t){var e;return''},open:function(t){t.find(".acf-accordion-content:first").slideDown().css("display","block"),t.find(".acf-accordion-icon:first").replaceWith(this.iconHtml({open:!0})),t.addClass("-open"),acf.doAction("show",t),t.attr("multi-expand")||t.siblings(".acf-accordion.-open").each(function(){g.close(f(this))})},close:function(t){t.find(".acf-accordion-content:first").slideUp(),t.find(".acf-accordion-icon:first").replaceWith(this.iconHtml({open:!1})),t.removeClass("-open"),acf.doAction("hide",t)},onClick:function(t,e){t.preventDefault(),this.toggle(e.parent())},onInvalidField:function(t,e){this.busy||(this.busy=!0,this.setTimeout(function(){this.busy=!1},1e3),this.open(e))},onUnload:function(t){var e=[];f(".acf-accordion").each(function(){var t=f(this).hasClass("-open")?1:0;e.push(t)}),e.length&&acf.setPreference("this.accordions",e)}})}(jQuery),function(t,e){var i=acf.Field.extend({type:"button_group",events:{'click input[type="radio"]':"onClick"},$control:function(){return this.$(".acf-button-group")},$input:function(){return this.$("input:checked")},setValue:function(t){this.$('input[value="'+t+'"]').prop("checked",!0).trigger("change")},onClick:function(t,e){var i=e.parent("label"),n=i.hasClass("selected");this.$(".selected").removeClass("selected"),i.addClass("selected"),this.get("allow_null")&&n&&(i.removeClass("selected"),e.prop("checked",!1).trigger("change"))}});acf.registerFieldType(i)}(jQuery),function(e,t){var i=acf.Field.extend({type:"checkbox",events:{"change input":"onChange","click .acf-add-checkbox":"onClickAdd","click .acf-checkbox-toggle":"onClickToggle","click .acf-checkbox-custom":"onClickCustom"},$control:function(){return this.$(".acf-checkbox-list")},$toggle:function(){return this.$(".acf-checkbox-toggle")},$input:function(){return this.$('input[type="hidden"]')},$inputs:function(){return this.$('input[type="checkbox"]').not(".acf-checkbox-toggle")},getValue:function(){var t=[];return this.$(":checked").each(function(){t.push(e(this).val())}),!!t.length&&t},onChange:function(t,e){var i=e.prop("checked"),n=this.$toggle(),a;(i?e.parent().addClass("selected"):e.parent().removeClass("selected"),n.length)&&(0==this.$inputs().not(":checked").length?n.prop("checked",!0):n.prop("checked",!1))},onClickAdd:function(t,e){var i='
  • ';e.parent("li").before(i)},onClickToggle:function(t,e){var i=e.prop("checked"),n;this.$inputs().prop("checked",i)},onClickCustom:function(t,e){var i=e.prop("checked"),n=e.next('input[type="text"]');i?n.prop("disabled",!1):(n.prop("disabled",!0),""==n.val()&&e.parent("li").remove())}});acf.registerFieldType(i)}(jQuery),function(t,e){var i=acf.Field.extend({type:"color_picker",wait:"load",$control:function(){return this.$(".acf-color-picker")},$input:function(){return this.$('input[type="hidden"]')},$inputText:function(){return this.$('input[type="text"]')},setValue:function(t){acf.val(this.$input(),t),this.$inputText().iris("color",t)},initialize:function(){var e=this.$input(),i=this.$inputText(),t=function(t){setTimeout(function(){acf.val(e,i.val())},1)},n={defaultColor:!1,palettes:!0,hide:!0,change:t,clear:t},n=acf.applyFilters("color_picker_args",n,this);i.wpColorPicker(n)}});acf.registerFieldType(i)}(jQuery),function(n,t){var e=acf.Field.extend({type:"date_picker",events:{'blur input[type="text"]':"onBlur"},$control:function(){return this.$(".acf-date-picker")},$input:function(){return this.$('input[type="hidden"]')},$inputText:function(){return this.$('input[type="text"]')},initialize:function(){if(this.has("save_format"))return this.initializeCompatibility();var t=this.$input(),e=this.$inputText(),i={dateFormat:this.get("date_format"),altField:t,altFormat:"yymmdd",changeYear:!0,yearRange:"-100:+100",changeMonth:!0,showButtonPanel:!0,firstDay:this.get("first_day")};i=acf.applyFilters("date_picker_args",i,this),acf.newDatePicker(e,i),acf.doAction("date_picker_init",e,i,this)},initializeCompatibility:function(){var t=this.$input(),e=this.$inputText();e.val(t.val());var i={dateFormat:this.get("date_format"),altField:t,altFormat:this.get("save_format"),changeYear:!0,yearRange:"-100:+100",changeMonth:!0,showButtonPanel:!0,firstDay:this.get("first_day")},n=(i=acf.applyFilters("date_picker_args",i,this)).dateFormat;i.dateFormat=this.get("save_format"),acf.newDatePicker(e,i),e.datepicker("option","dateFormat",n),acf.doAction("date_picker_init",e,i,this)},onBlur:function(){this.$inputText().val()||acf.val(this.$input(),"")}});acf.registerFieldType(e);var i=new acf.Model({priority:5,wait:"ready",initialize:function(){var t=acf.get("locale"),e=acf.get("rtl"),i=acf.get("datePickerL10n");return!!i&&(void 0!==n.datepicker&&(i.isRTL=e,n.datepicker.regional[t]=i,void n.datepicker.setDefaults(i)))}});acf.newDatePicker=function(t,e){if(void 0===n.datepicker)return!1;e=e||{},t.datepicker(e),n("body > #ui-datepicker-div").exists()&&n("body > #ui-datepicker-div").wrap('
    ')}}(jQuery),function(n,t){var e=acf.models.DatePickerField.extend({type:"date_time_picker",$control:function(){return this.$(".acf-date-time-picker")},initialize:function(){var t=this.$input(),e=this.$inputText(),i={dateFormat:this.get("date_format"),timeFormat:this.get("time_format"),altField:t,altFieldTimeOnly:!1,altFormat:"yy-mm-dd",altTimeFormat:"HH:mm:ss",changeYear:!0,yearRange:"-100:+100",changeMonth:!0,showButtonPanel:!0,firstDay:this.get("first_day"),controlType:"select",oneLine:!0};i=acf.applyFilters("date_time_picker_args",i,this),acf.newDateTimePicker(e,i),acf.doAction("date_time_picker_init",e,i,this)}});acf.registerFieldType(e);var i=new acf.Model({priority:5,wait:"ready",initialize:function(){var t=acf.get("locale"),e=acf.get("rtl"),i=acf.get("dateTimePickerL10n");return!!i&&(void 0!==n.timepicker&&(i.isRTL=e,n.timepicker.regional[t]=i,void n.timepicker.setDefaults(i)))}});acf.newDateTimePicker=function(t,e){if(void 0===n.timepicker)return!1;e=e||{},t.datetimepicker(e),n("body > #ui-datepicker-div").exists()&&n("body > #ui-datepicker-div").wrap('
    ')}}(jQuery),function(s,t){var e=acf.Field.extend({type:"google_map",map:!1,wait:"load",events:{'click a[data-name="clear"]':"onClickClear",'click a[data-name="locate"]':"onClickLocate",'click a[data-name="search"]':"onClickSearch","keydown .search":"onKeydownSearch","keyup .search":"onKeyupSearch","focus .search":"onFocusSearch","blur .search":"onBlurSearch",showField:"onShow"},$control:function(){return this.$(".acf-google-map")},$input:function(t){return this.$('input[data-name="'+(t||"address")+'"]')},$search:function(){return this.$(".search")},$canvas:function(){return this.$(".canvas")},addClass:function(t){this.$control().addClass(t)},removeClass:function(t){this.$control().removeClass(t)},getValue:function(){var t={lat:"",lng:"",address:""};return this.$('input[type="hidden"]').each(function(){t[s(this).data("name")]=s(this).val()}),t.lat&&t.lng||(t=!1),t},setValue:function(t){for(var e in t=acf.parseArgs(t,{lat:"",lng:"",address:""}))acf.val(this.$input(e),t[e]);t.lat&&t.lng||(t=!1),this.renderVal(t)},renderVal:function(t){t?(this.addClass("-value"),this.setPosition(t.lat,t.lng),this.map.marker.setVisible(!0)):(this.removeClass("-value"),this.map.marker.setVisible(!1)),this.$search().val(t.address)},setPosition:function(t,e){var i=this.newLatLng(t,e);return this.map.marker.setPosition(i),this.map.marker.setVisible(!0),acf.doAction("google_map_change",i,this.map,this),this.center(),this},center:function(){var t=this.map.marker.getPosition(),e=this.get("lat"),i=this.get("lng");t&&(e=t.lat(),i=t.lng());var n=this.newLatLng(e,i);this.map.setCenter(n)},getSearchVal:function(){return this.$search().val()},initialize:function(){o.isReady()?this.initializeMap():o.ready(this.initializeMap,this)},newLatLng:function(t,e){return new google.maps.LatLng(parseFloat(t),parseFloat(e))},initializeMap:function(){var t=this.get("zoom"),e=this.get("lat"),i=this.get("lng"),n={scrollwheel:!1,zoom:parseInt(t),center:this.newLatLng(e,i),mapTypeId:google.maps.MapTypeId.ROADMAP,marker:{draggable:!0,raiseOnDrag:!0},autocomplete:{}};n=acf.applyFilters("google_map_args",n,this);var a=new google.maps.Map(this.$canvas()[0],n),r=acf.parseArgs(n.marker,{draggable:!0,raiseOnDrag:!0,map:a});r=acf.applyFilters("google_map_marker_args",r,this);var s=new google.maps.Marker(r),o=!1;if(acf.isset(google,"maps","places","Autocomplete")){var c=n.autocomplete||{};c=acf.applyFilters("google_map_autocomplete_args",c,this),(o=new google.maps.places.Autocomplete(this.$search()[0],c)).bindTo("bounds",a)}this.addMapEvents(this,a,s,o),a.acf=this,a.marker=s,a.autocomplete=o,this.map=a,acf.doAction("google_map_init",a,s,this);var l=this.getValue();this.renderVal(l)},addMapEvents:function(n,t,e,i){google.maps.event.addListener(t,"click",function(t){var e=t.latLng.lat(),i=t.latLng.lng();n.searchPosition(e,i)}),google.maps.event.addListener(e,"dragend",function(){var t=this.getPosition(),e=t.lat(),i=t.lng();n.searchPosition(e,i)}),i&&google.maps.event.addListener(i,"place_changed",function(){var t=this.getPlace();t.address=n.getSearchVal(),n.setPlace(t)})},searchPosition:function(n,a){var t=this.newLatLng(n,a),r=this.$control();this.setPosition(n,a),r.addClass("-loading");var e=s.proxy(function(t,e){r.removeClass("-loading");var i="";e!=google.maps.GeocoderStatus.OK?console.log("Geocoder failed due to: "+e):t[0]?i=t[0].formatted_address:console.log("No results found"),this.val({lat:n,lng:a,address:i})},this);o.geocoder.geocode({latLng:t},e)},setPlace:function(t){if(!t)return this;if(t.name&&!t.geometry)return this.searchAddress(t.name),this;var e=t.geometry.location.lat(),i=t.geometry.location.lng(),n=t.address||t.formatted_address;return this.setValue({lat:e,lng:i,address:n}),this},searchAddress:function(a){var t=a.split(",");if(2==t.length){var e=t[0],i=t[1];if(s.isNumeric(e)&&s.isNumeric(i))return this.searchPosition(e,i)}var r=this.$control();r.addClass("-loading");var n=this.proxy(function(t,e){r.removeClass("-loading");var i="",n="";e!=google.maps.GeocoderStatus.OK?console.log("Geocoder failed due to: "+e):t[0]?(i=t[0].geometry.location.lat(),n=t[0].geometry.location.lng()):console.log("No results found"),this.val({lat:i,lng:n,address:a})});o.geocoder.geocode({address:a},n)},searchLocation:function(){if(!navigator.geolocation)return alert(acf.__("Sorry, this browser does not support geolocation"));var a=this.$control();a.addClass("-loading");var t=s.proxy(function(t,e){a.removeClass("-loading");var i=t.coords.latitude,n=t.coords.longitude;this.searchPosition(i,n)},this),e=function(t){a.removeClass("-loading")};navigator.geolocation.getCurrentPosition(t,e)},onClickClear:function(t,e){this.val(!1)},onClickLocate:function(t,e){this.searchLocation()},onClickSearch:function(t,e){this.searchAddress(this.$search().val())},onFocusSearch:function(t,e){this.removeClass("-value"),this.onKeyupSearch.apply(this,arguments)},onBlurSearch:function(t,e){this.setTimeout(function(){this.removeClass("-search"),e.val()&&this.addClass("-value")},100)},onKeyupSearch:function(t,e){e.val()?this.addClass("-search"):this.removeClass("-search")},onKeydownSearch:function(t,e){13==t.which&&t.preventDefault()},onMousedown:function(){},onShow:function(){if(!this.map)return!1;this.setTimeout(this.center,10)}});acf.registerFieldType(e);var o=new acf.Model({geocoder:!1,data:{status:!1},getStatus:function(){return this.get("status")},setStatus:function(t){return this.set("status",t)},isReady:function(){if("ready"==this.getStatus())return!0;if("loading"==this.getStatus())return!1;if(acf.isset(window,"google","maps","places"))return this.setStatus("ready"),!0;var t=acf.get("google_map_api");return t&&(this.setStatus("loading"),s.ajax({url:t,dataType:"script",cache:!0,context:this,success:function(){this.setStatus("ready"),this.geocoder=new google.maps.Geocoder,acf.doAction("google_map_api_loaded")}})),!1},ready:function(t,e){acf.addAction("google_map_api_loaded",t,10,e)}})}(jQuery),function(n,i){var t=acf.Field.extend({type:"image",$control:function(){return this.$(".acf-image-uploader")},$input:function(){return this.$('input[type="hidden"]')},events:{'click a[data-name="add"]':"onClickAdd",'click a[data-name="edit"]':"onClickEdit",'click a[data-name="remove"]':"onClickRemove",'change input[type="file"]':"onChange"},initialize:function(){"basic"===this.get("uploader")&&this.$el.closest("form").attr("enctype","multipart/form-data")},validateAttachment:function(t){(t=t||{}).id!==i&&(t=t.attributes),t=acf.parseArgs(t,{url:"",alt:"",title:"",caption:"",description:"",width:0,height:0});var e=acf.isget(t,"sizes",this.get("preview_size"),"url");return null!==e&&(t.url=e),t},render:function(t){t=this.validateAttachment(t),this.$("img").attr({src:t.url,alt:t.alt,title:t.title});var e=t.id||"";this.val(e),e?this.$control().addClass("has-value"):this.$control().removeClass("has-value")},append:function(t,e){var i=function(t,e){for(var i=acf.getFields({key:t.get("key"),parent:e.$el}),n=0;n
    '):this.$el=a('
      '),i.before(this.$el),this.set("index",r,!0),r++},initializeTabs:function(){var t=this.getVisible().shift(),e,i,n=(acf.getPreference("this.tabs")||[])[this.get("index")];this.tabs[n]&&this.tabs[n].isVisible()&&(t=this.tabs[n]),t?this.selectTab(t):this.closeTabs(),this.set("initialized",!0)},getVisible:function(){return this.tabs.filter(function(t){return t.isVisible()})},getActive:function(){return this.active},setActive:function(t){return this.active=t},hasActive:function(){return!1!==this.active},isActive:function(t){var e=this.getActive();return e&&e.cid===t.cid},closeActive:function(){this.hasActive()&&this.closeTab(this.getActive())},openTab:function(t){this.closeActive(),t.open(),this.setActive(t)},closeTab:function(t){t.close(),this.setActive(!1)},closeTabs:function(){this.tabs.map(this.closeTab,this)},selectTab:function(e){this.tabs.map(function(t){e.cid!==t.cid&&this.closeTab(t)},this),this.openTab(e)},addTab:function(t,e){var i=a("
    • ");i.append(t),this.$("ul").append(i);var n=new s({$el:i,field:e,group:this});return this.tabs.push(n),n},reset:function(){return this.closeActive(),this.refresh()},refresh:function(){if(this.hasActive())return!1;var t=this.getVisible().shift();return t&&this.openTab(t),t},onRefresh:function(){if("left"===this.get("placement")){var t=this.$el.parent(),e=this.$el.children("ul"),i=t.is("td")?"height":"min-height",n=e.position().top+e.outerHeight(!0)-1;t.css(i,n)}}}),s=acf.Model.extend({group:!1,field:!1,events:{"click a":"onClick"},index:function(){return this.$el.index()},isVisible:function(){return acf.isVisible(this.$el)},isActive:function(){return this.$el.hasClass("active")},open:function(){this.$el.addClass("active"),this.field.showFields()},close:function(){this.$el.removeClass("active"),this.field.hideFields()},onClick:function(t,e){t.preventDefault(),this.toggle()},toggle:function(){this.isActive()||this.group.openTab(this)}}),o=new acf.Model({priority:50,actions:{prepare:"render",append:"render",unload:"onUnload",invalid_field:"onInvalidField"},findTabs:function(){return a(".acf-tab-wrap")},getTabs:function(){return acf.getInstances(this.findTabs())},render:function(t){this.getTabs().map(function(t){t.get("initialized")||t.initializeTabs()})},onInvalidField:function(t){this.busy||t.hiddenByTab&&(t.hiddenByTab.toggle(),this.busy=!0,this.setTimeout(function(){this.busy=!1},100))},onUnload:function(){var i=[];this.getTabs().map(function(t){var e=t.hasActive()?t.getActive().index():0;i.push(e)}),i.length&&acf.setPreference("this.tabs",i)}})}(jQuery),function(t,e){var i=acf.models.SelectField.extend({type:"post_object"});acf.registerFieldType(i)}(jQuery),function(t,e){var i=acf.models.SelectField.extend({type:"page_link"});acf.registerFieldType(i)}(jQuery),function(t,e){var i=acf.models.SelectField.extend({type:"user"});acf.registerFieldType(i)}(jQuery),function(g,t){var e=acf.Field.extend({type:"taxonomy",data:{ftype:"select"},select2:!1,wait:"load",events:{'click a[data-name="add"]':"onClickAdd",'click input[type="radio"]':"onClickRadio"},$control:function(){return this.$(".acf-taxonomy-field")},$input:function(){return this.getRelatedPrototype().$input.apply(this,arguments)},getRelatedType:function(){var t=this.get("ftype");return"multi_select"==t&&(t="select"),t},getRelatedPrototype:function(){return acf.getFieldType(this.getRelatedType()).prototype},getValue:function(){return this.getRelatedPrototype().getValue.apply(this,arguments)},setValue:function(){return this.getRelatedPrototype().setValue.apply(this,arguments)},initialize:function(){this.getRelatedPrototype().initialize.apply(this,arguments)},onRemove:function(){this.select2&&this.select2.destroy()},onClickAdd:function(t,e){var n=this,i=!1,a=!1,r=!1,s=!1,o=!1,c=!1,l=!1,u=function(){i=acf.newPopup({title:e.attr("title"),loading:!0,width:"300px"});var t={action:"acf/fields/taxonomy/add_term",field_key:n.get("key")};g.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(t),type:"post",dataType:"html",success:d})},d=function(t){i.loading(!1),i.content(t),a=i.$("form"),r=i.$('input[name="term_name"]'),s=i.$('select[name="term_parent"]'),o=i.$(".acf-submit-button"),r.focus(),i.on("submit","form",f)},f=function(t,e){if(t.preventDefault(),t.stopImmediatePropagation(),""===r.val())return r.focus(),!1;acf.startButtonLoading(o);var i={action:"acf/fields/taxonomy/add_term",field_key:n.get("key"),term_name:r.val(),term_parent:s.length?s.val():0};g.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(i),type:"post",dataType:"json",success:h})},h=function(t){acf.stopButtonLoading(o),l&&l.remove(), -l=acf.isAjaxSuccess(t)?(r.val(""),p(t.data),acf.newNotice({type:"success",text:acf.getAjaxMessage(t),target:a,timeout:2e3,dismiss:!1})):acf.newNotice({type:"error",text:acf.getAjaxError(t),target:a,timeout:2e3,dismiss:!1}),r.focus()},p=function(e){var t=g('"),i;e.term_parent?s.children('option[value="'+e.term_parent+'"]').after(t):s.append(t),acf.getFields({type:"taxonomy"}).map(function(t){t.get("taxonomy")==n.get("taxonomy")&&t.appendTerm(e)}),n.selectTerm(e.term_id)};u()},appendTerm:function(t){"select"==this.getRelatedType()?this.appendTermSelect(t):this.appendTermCheckbox(t)},appendTermSelect:function(t){this.select2.addOption({id:t.term_id,text:t.term_label})},appendTermCheckbox:function(t){var e=this.$("[name]:first").attr("name"),i=this.$("ul:first");"checkbox"==this.getRelatedType()&&(e+="[]");var n=g(['
    • ',"","
    • "].join(""));if(t.term_parent){var a=i.find('li[data-id="'+t.term_parent+'"]');(i=a.children("ul")).exists()||(i=g('
        '),a.append(i))}i.append(n)},selectTerm:function(t){var e;"select"==this.getRelatedType()?this.select2.selectOption(t):this.$('input[value="'+t+'"]').prop("checked",!0).trigger("change")},onClickRadio:function(t,e){var i=e.parent("label"),n=i.hasClass("selected");this.$(".selected").removeClass("selected"),i.addClass("selected"),this.get("allow_null")&&n&&(i.removeClass("selected"),e.prop("checked",!1).trigger("change"))}});acf.registerFieldType(e)}(jQuery),function(i,t){var e=acf.models.DatePickerField.extend({type:"time_picker",$control:function(){return this.$(".acf-time-picker")},initialize:function(){var t=this.$input(),e=this.$inputText(),i={timeFormat:this.get("time_format"),altField:t,altFieldTimeOnly:!1,altTimeFormat:"HH:mm:ss",showButtonPanel:!0,controlType:"select",oneLine:!0,closeText:acf.get("dateTimePickerL10n").selectText,timeOnly:!0,onClose:function(t,e,i){var n=e.dpDiv.find(".ui-datepicker-close");!t&&n.is(":hover")&&i._updateDateTime()}};i=acf.applyFilters("time_picker_args",i,this),acf.newTimePicker(e,i),acf.doAction("time_picker_init",e,i,this)}});acf.registerFieldType(e),acf.newTimePicker=function(t,e){if(void 0===i.timepicker)return!1;e=e||{},t.timepicker(e),i("body > #ui-datepicker-div").exists()&&i("body > #ui-datepicker-div").wrap('
        ')}}(jQuery),function(t,e){var i=acf.Field.extend({type:"true_false",events:{"change .acf-switch-input":"onChange","focus .acf-switch-input":"onFocus","blur .acf-switch-input":"onBlur","keypress .acf-switch-input":"onKeypress"},$input:function(){return this.$('input[type="checkbox"]')},$switch:function(){return this.$(".acf-switch")},getValue:function(){return this.$input().prop("checked")?1:0},initialize:function(){this.render()},render:function(){var t=this.$switch();if(t.length){var e=t.children(".acf-switch-on"),i=t.children(".acf-switch-off"),n=Math.max(e.width(),i.width());n&&(e.css("min-width",n),i.css("min-width",n))}},switchOn:function(){this.$input().prop("checked",!0),this.$switch().addClass("-on")},switchOff:function(){this.$input().prop("checked",!1),this.$switch().removeClass("-on")},onChange:function(t,e){e.prop("checked")?this.switchOn():this.switchOff()},onFocus:function(t,e){this.$switch().addClass("-focus")},onBlur:function(t,e){this.$switch().removeClass("-focus")},onKeypress:function(t,e){return 37===t.keyCode?this.switchOff():39===t.keyCode?this.switchOn():void 0}});acf.registerFieldType(i)}(jQuery),function(t,e){var i=acf.Field.extend({type:"url",events:{'keyup input[type="url"]':"onkeyup"},$control:function(){return this.$(".acf-input-wrap")},$input:function(){return this.$('input[type="url"]')},initialize:function(){this.render()},isValid:function(){var t=this.val();return!!t&&(-1!==t.indexOf("://")||0===t.indexOf("//"))},render:function(){this.isValid()?this.$control().addClass("-valid"):this.$control().removeClass("-valid")},onkeyup:function(t,e){this.render()}});acf.registerFieldType(i)}(jQuery),function(t,e){var i=acf.Field.extend({type:"wysiwyg",wait:"load",events:{"mousedown .acf-editor-wrap.delay":"onMousedown",sortstartField:"disableEditor",sortstopField:"enableEditor",removeField:"disableEditor"},$control:function(){return this.$(".acf-editor-wrap")},$input:function(){return this.$("textarea")},getMode:function(){return this.$control().hasClass("tmce-active")?"visual":"text"},initialize:function(){this.$control().hasClass("delay")||this.initializeEditor()},initializeEditor:function(){var t=this.$control(),e=this.$input(),i={tinymce:!0,quicktags:!0,toolbar:this.get("toolbar"),mode:this.getMode(),field:this},n=e.attr("id"),a=acf.uniqueId("acf-editor-"),r=e.data();acf.rename({target:t,search:n,replace:a,destructive:!0}),this.set("id",a,!0),acf.tinymce.initialize(a,i),this.$input().data(r)},onMousedown:function(t){t.preventDefault();var e=this.$control();e.removeClass("delay"),e.find(".acf-editor-toolbar").remove(),this.initializeEditor()},enableEditor:function(){"visual"==this.getMode()&&acf.tinymce.enable(this.get("id"))},disableEditor:function(){acf.tinymce.destroy(this.get("id"))}});acf.registerFieldType(i)}(jQuery),function(e,t){var s=[];acf.Condition=acf.Model.extend({type:"",operator:"==",label:"",choiceType:"input",fieldTypes:[],data:{conditions:!1,field:!1,rule:{}},events:{change:"change",keyup:"change",enableField:"change",disableField:"change"},setup:function(t){e.extend(this.data,t)},getEventTarget:function(t,e){return t||this.get("field").$el},change:function(t,e){this.get("conditions").change(t)},match:function(t,e){return!1},calculate:function(){return this.match(this.get("rule"),this.get("field"))},choices:function(t){return''}}),acf.newCondition=function(t,e){var i=e.get("field"),n=i.getField(t.field);if(!i||!n)return!1;var a={rule:t,target:i,conditions:e,field:n},r=n.get("type"),s=t.operator,o,c,l;return new(acf.getConditionTypes({fieldType:r,operator:s})[0]||acf.Condition)(a)};var a=function(t){return acf.strPascalCase(t||"")+"Condition"};acf.registerConditionType=function(t){var e,i=t.prototype.type,n=a(i);acf.models[n]=t,s.push(i)},acf.getConditionType=function(t){var e=a(t);return acf.models[e]||!1},acf.registerConditionForFieldType=function(t,e){var i=acf.getConditionType(t);i&&i.prototype.fieldTypes.push(e)},acf.getConditionTypes=function(a){a=acf.parseArgs(a,{fieldType:"",operator:""});var r=[];return s.map(function(t){var e=acf.getConditionType(t),i=e.prototype.fieldTypes,n=e.prototype.operator;a.fieldType&&-1===i.indexOf(a.fieldType)||a.operator&&n!==a.operator||r.push(e)}),r}}(jQuery),function(t,e){var i="conditional_logic",n=new acf.Model({id:"conditionsManager",priority:20,actions:{new_field:"onNewField"},onNewField:function(t){t.has("conditions")&&t.getConditions().render()}}),a=function(t,e){var i=acf.getFields({key:e,sibling:t.$el,suppressFilters:!0});return i.length||(i=acf.getFields({key:e,parent:t.$el.parent(),suppressFilters:!0})),!!i.length&&i[0]};acf.Field.prototype.getField=function(t){var e=a(this,t);if(e)return e;for(var i=this.parents(),n=0;nparseFloat(e)},c=function(t,e){return parseFloat(t)'}});acf.registerConditionType(f);var e=f.extend({type:"hasNoValue",operator:"==empty",label:a("Has no value"),match:function(t,e){return!f.prototype.match.apply(this,arguments)}});acf.registerConditionType(e);var h=acf.Condition.extend({type:"equalTo",operator:"==",label:a("Value is equal to"),fieldTypes:["text","textarea","number","range","email","url","password"],match:function(t,e){return n.isNumeric(t.value)?i(t.value,e.val()):s(t.value,e.val())},choices:function(t){return''}});acf.registerConditionType(h);var p=h.extend({type:"notEqualTo",operator:"!=",label:a("Value is not equal to"),match:function(t,e){return!h.prototype.match.apply(this,arguments)}});acf.registerConditionType(p);var g=acf.Condition.extend({type:"patternMatch",operator:"==pattern",label:a("Value matches pattern"),fieldTypes:["text","textarea","email","url","password","wysiwyg"],match:function(t,e){return d(e.val(),t.value)},choices:function(t){return''}});acf.registerConditionType(g);var m=acf.Condition.extend({type:"contains",operator:"==contains",label:a("Value contains"),fieldTypes:["text","textarea","number","email","url","password","wysiwyg","oembed","select"],match:function(t,e){return u(e.val(),t.value)},choices:function(t){return''}});acf.registerConditionType(m);var v=h.extend({type:"trueFalseEqualTo",choiceType:"select",fieldTypes:["true_false"],choices:function(t){return[{id:1,text:a("Checked")}]}});acf.registerConditionType(v);var y=p.extend({type:"trueFalseNotEqualTo",choiceType:"select",fieldTypes:["true_false"],choices:function(t){return[{id:1,text:a("Checked")}]}});acf.registerConditionType(y);var b=acf.Condition.extend({type:"selectEqualTo",operator:"==",label:a("Value is equal to"),fieldTypes:["select","checkbox","radio","button_group"],match:function(t,e){var i=e.val();return i instanceof Array?l(t.value,i):s(t.value,i)},choices:function(t){var e=[],i=t.$setting("choices textarea").val().split("\n");return t.$input("allow_null").prop("checked")&&e.push({id:"",text:a("Null")}),i.map(function(t){(t=t.split(":"))[1]=t[1]||t[0],e.push({id:n.trim(t[0]),text:n.trim(t[1])})}),e}});acf.registerConditionType(b);var x=b.extend({type:"selectNotEqualTo",operator:"!=",label:a("Value is not equal to"),match:function(t,e){return!b.prototype.match.apply(this,arguments)}});acf.registerConditionType(x);var w=acf.Condition.extend({type:"greaterThan",operator:">",label:a("Value is greater than"),fieldTypes:["number","range"],match:function(t,e){var i=e.val();return i instanceof Array&&(i=i.length),o(i,t.value)},choices:function(t){return''}});acf.registerConditionType(w);var _=w.extend({type:"lessThan",operator:"<",label:a("Value is less than"),match:function(t,e){var i=e.val();return i instanceof Array&&(i=i.length),c(i,t.value)},choices:function(t){return''}});acf.registerConditionType(_);var $=w.extend({type:"selectionGreaterThan",label:a("Selection is greater than"),fieldTypes:["checkbox","select","post_object","page_link","relationship","taxonomy","user"]});acf.registerConditionType($);var k=_.extend({type:"selectionLessThan",label:a("Selection is less than"),fieldTypes:["checkbox","select","post_object","page_link","relationship","taxonomy","user"]});acf.registerConditionType(k)}(jQuery),function(s,n){acf.newMediaPopup=function(t){var e=null,t=acf.parseArgs(t,{mode:"select",title:"",button:"",type:"",field:!1,allowedTypes:"",library:"all",multiple:!1,attachment:0,autoOpen:!0,open:function(){},select:function(){},close:function(){}});return e="edit"==t.mode?new acf.models.EditMediaPopup(t):new acf.models.SelectMediaPopup(t),t.autoOpen&&setTimeout(function(){e.open()},1),acf.doAction("new_media_popup",e),e};var e=function(){var t=acf.get("post_id");return s.isNumeric(t)?t:0};acf.getMimeTypes=function(){return this.get("mimeTypes")},acf.getMimeType=function(t){var e=acf.getMimeTypes();if(e[t]!==n)return e[t];for(var i in e)if(-1!==i.indexOf(t))return e[i];return!1};var i=acf.Model.extend({id:"MediaPopup",data:{},defaults:{},frame:!1,setup:function(t){s.extend(this.data,t)},initialize:function(){var t=this.getFrameOptions();this.addFrameStates(t);var e=wp.media(t);(e.acf=this).addFrameEvents(e,t),this.frame=e},open:function(){this.frame.open()},close:function(){this.frame.close()},remove:function(){this.frame.detach(),this.frame.remove()},getFrameOptions:function(){var t={title:this.get("title"),multiple:this.get("multiple"),library:{},states:[]};return this.get("type")&&(t.library.type=this.get("type")),"uploadedTo"===this.get("library")&&(t.library.uploadedTo=e()),this.get("attachment")&&(t.library.post__in=[this.get("attachment")]),this.get("button")&&(t.button={text:this.get("button")}),t},addFrameStates:function(t){var e=wp.media.query(t.library);this.get("field")&&acf.isset(e,"mirroring","args")&&(e.mirroring.args._acfuploader=this.get("field")),t.states.push(new wp.media.controller.Library({library:e,multiple:this.get("multiple"),title:this.get("title"),priority:20,filterable:"all",editable:!0,allowLocalEdits:!0})),acf.isset(wp,"media","controller","EditImage")&&t.states.push(new wp.media.controller.EditImage)},addFrameEvents:function(i,t){i.on("open",function(){this.$el.closest(".media-modal").addClass("acf-media-modal -"+this.acf.get("mode"))},i),i.on("content:render:edit-image",function(){var t=this.state().get("image"),e=new wp.media.view.EditImage({model:t,controller:this}).render();this.content.set(e),e.loadEditor()},i),i.on("select",function(){var t=i.state().get("selection");t&&t.each(function(t,e){i.acf.get("select").apply(i.acf,[t,e])})}),i.on("close",function(){setTimeout(function(){i.acf.get("close").apply(i.acf),i.acf.remove()},1)})}});acf.models.SelectMediaPopup=i.extend({id:"SelectMediaPopup",setup:function(t){t.button||(t.button=acf._x("Select","verb")),i.prototype.setup.apply(this,arguments)},addFrameEvents:function(e,t){acf.isset(_wpPluploadSettings,"defaults","multipart_params")&&(_wpPluploadSettings.defaults.multipart_params._acfuploader=this.get("field"),e.on("open",function(){delete _wpPluploadSettings.defaults.multipart_params._acfuploader})),e.on("content:activate:browse",function(){var t=!1;try{t=e.content.get().toolbar}catch(t){return void console.log(t)}e.acf.customizeFilters.apply(e.acf,[t])}),i.prototype.addFrameEvents.apply(this,arguments)},customizeFilters:function(t){var n=t.get("filters"),e;("image"==this.get("type")&&(n.filters.all.text=acf.__("All images"),delete n.filters.audio,delete n.filters.video,delete n.filters.image,s.each(n.filters,function(t,e){e.props.type=e.props.type||"image"})),this.get("allowedTypes"))&&this.get("allowedTypes").split(" ").join("").split(".").join("").split(",").map(function(t){var e=acf.getMimeType(t);if(e){var i={text:e,props:{status:null,type:e,uploadedTo:null,orderby:"date",order:"DESC"},priority:20};n.filters[e]=i}});if("uploadedTo"===this.get("library")){var i=this.frame.options.library.uploadedTo;delete n.filters.unattached,delete n.filters.uploaded,s.each(n.filters,function(t,e){e.text+=" ("+acf.__("Uploaded to this post")+")",e.props.uploadedTo=i})}var a=this.get("field"),r;s.each(n.filters,function(t,e){e.props._acfuploader=a}),t.get("search").model.attributes._acfuploader=a,n.renderFilters&&n.renderFilters()}}),acf.models.EditMediaPopup=i.extend({id:"SelectMediaPopup",setup:function(t){t.button||(t.button=acf._x("Update","verb")),i.prototype.setup.apply(this,arguments)},addFrameEvents:function(n,t){n.on("open",function(){this.$el.closest(".media-modal").addClass("acf-expanded"),"browse"!=this.content.mode()&&this.content.mode("browse");var t,e=this.state().get("selection"),i=wp.media.attachment(n.acf.get("attachment"));e.add(i)},n),i.prototype.addFrameEvents.apply(this,arguments)}});var t=new acf.Model({id:"customizePrototypes",wait:"ready",initialize:function(){if(acf.isset(window,"wp","media","view")){var t=e();t&&acf.isset(wp,"media","view","settings","post")&&(wp.media.view.settings.post.id=t),this.customizeAttachmentsRouter(),this.customizeAttachmentFilters(),this.customizeAttachmentCompat(),this.customizeAttachmentLibrary()}},customizeAttachmentsRouter:function(){if(acf.isset(wp,"media","view","Router")){var t=wp.media.view.Router;wp.media.view.Router=t.extend({addExpand:function(){var t=s(['',''+acf.__("Expand Details")+"",''+acf.__("Collapse Details")+"",""].join(""));t.on("click",function(t){t.preventDefault();var e=s(this).closest(".media-modal");e.hasClass("acf-expanded")?e.removeClass("acf-expanded"):e.addClass("acf-expanded")}),this.$el.append(t)},initialize:function(){return t.prototype.initialize.apply(this,arguments),this.addExpand(),this}})}},customizeAttachmentFilters:function(){var t;acf.isset(wp,"media","view","AttachmentFilters","All")&&(wp.media.view.AttachmentFilters.All.prototype.renderFilters=function(){this.$el.html(_.chain(this.filters).map(function(t,e){return{el:s("").val(e).html(t.text)[0],priority:t.priority||50}},this).sortBy("priority").pluck("el").value())})},customizeAttachmentCompat:function(){if(acf.isset(wp,"media","view","AttachmentCompat")){var t=wp.media.view.AttachmentCompat,e=!1;wp.media.view.AttachmentCompat=t.extend({render:function(){return this.rendered?this:(t.prototype.render.apply(this,arguments),this.$("#acf-form-data").length&&(clearTimeout(e),e=setTimeout(s.proxy(function(){this.rendered=!0,acf.doAction("append",this.$el)},this),50)),this)},save:function(t){var e={};t&&t.preventDefault(),e=acf.serializeForAjax(this.$el),this.controller.trigger("attachment:compat:waiting",["waiting"]),this.model.saveCompat(e).always(_.bind(this.postSave,this))}})}},customizeAttachmentLibrary:function(){if(acf.isset(wp,"media","view","Attachment","Library")){var l=wp.media.view.Attachment.Library;wp.media.view.Attachment.Library=l.extend({render:function(){var t=acf.isget(this,"controller","acf"),e=acf.isget(this,"model","attributes");if(t&&e){e.acf_errors&&this.$el.addClass("acf-disabled");var i=t.get("selected");i&&-1',''+acf.__("Restricted")+"",''+c+"",''+s+"","
        "].join("")),i.reset(),void i.single(n)}return l.prototype.toggleSelection.apply(this,arguments)}})}}})}(jQuery),function(h,e){acf.screen=new acf.Model({active:!0,xhr:!1,timeout:!1,wait:"load",events:{"change #page_template":"onChange","change #parent_id":"onChange","change #post-formats-select":"onChange","change .categorychecklist":"onChange","change .tagsdiv":"onChange",'change .acf-taxonomy-field[data-save="1"]':"onChange","change #product-type":"onChange"},isPost:function(){return"post"===acf.get("screen")},isUser:function(){return"user"===acf.get("screen")},isTaxonomy:function(){return"taxonomy"===acf.get("screen")},isAttachment:function(){return"attachment"===acf.get("screen")},isNavMenu:function(){return"nav_menu"===acf.get("screen")},isWidget:function(){return"widget"===acf.get("screen")},isComment:function(){return"comment"===acf.get("screen")},getPageTemplate:function(){var t=h("#page_template");return t.length?t.val():null},getPageParent:function(t,e){var e;return(e=h("#parent_id")).length?e.val():null},getPageType:function(t,e){return this.getPageParent()?"child":"parent"},getPostType:function(){return h("#post_type").val()},getPostFormat:function(t,e){var e;if((e=h("#post-formats-select input:checked")).length){var i=e.val();return"0"==i?"standard":i}return null},getPostCoreTerms:function(){var t={},e=acf.serialize(h(".categorydiv, .tagsdiv"));for(var i in e.tax_input&&(t=e.tax_input),e.post_category&&(t.category=e.post_category),t)acf.isArray(t[i])||(t[i]=t[i].split(", "));return t},getPostTerms:function(){var n=this.getPostCoreTerms();for(var t in acf.getFields({type:"taxonomy"}).map(function(t){if(t.get("save")){var e=t.val(),i=t.get("taxonomy");e&&(n[i]=n[i]||[],e=acf.isArray(e)?e:[e],n[i]=n[i].concat(e))}}),null!==(productType=this.getProductType())&&(n.product_type=[productType]),n)n[t]=acf.uniqueArray(n[t]);return n},getProductType:function(){var t=h("#product-type");return t.length?t.val():null},check:function(){if("post"===acf.get("screen")){this.xhr&&this.xhr.abort();var e=acf.parseArgs(this.data,{action:"acf/ajax/check_screen",screen:acf.get("screen"),exists:[]});this.isPost()&&(e.post_id=acf.get("post_id")),null!==(postType=this.getPostType())&&(e.post_type=postType),null!==(pageTemplate=this.getPageTemplate())&&(e.page_template=pageTemplate),null!==(pageParent=this.getPageParent())&&(e.page_parent=pageParent),null!==(pageType=this.getPageType())&&(e.page_type=pageType),null!==(postFormat=this.getPostFormat())&&(e.post_format=postFormat),null!==(postTerms=this.getPostTerms())&&(e.post_terms=postTerms),acf.getPostboxes().map(function(t){e.exists.push(t.get("key"))}),e=acf.applyFilters("check_screen_args",e);var t=function(t){acf.isAjaxSuccess(t)&&("post"==acf.get("screen")?this.renderPostScreen(t.data):"user"==acf.get("screen")&&this.renderUserScreen(t.data)),acf.doAction("check_screen_complete",t.data,e)};this.xhr=h.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(e),type:"post",dataType:"json",context:this,success:t})}},onChange:function(t,e){this.setTimeout(this.check,1)},renderPostScreen:function(l){var u=[],d=function(t,e){var i=h._data(t[0]).events;for(var n in i)for(var a=0;a','",'

        ',""+e.title+"","

        ",'
        ',e.html,"
        ",""].join(""));if(h("#adv-settings").length){var a=h("#adv-settings .metabox-prefs"),r=h(['"].join(""));d(a.find("input").first(),r.find("input")),a.append(r)}"side"===e.position?h("#"+e.position+"-sortables").append(n):h("#"+e.position+"-sortables").prepend(n);var s=[];if(l.results.map(function(t){e.position===t.position&&h("#"+e.position+"-sortables #"+t.id).length&&s.push(t.id)}),f(e.id,s),l.sorted)for(var o in l.sorted){var s=l.sorted[o].split(",");if(f(e.id,s))break}var c=h("#submitdiv");h("#submitdiv").length&&(d(c.children(".handlediv"),n.children(".handlediv")),d(c.children(".hndle"),n.children(".hndle"))),acf.doAction("append",n),i=acf.newPostbox(e)}i.showEnable(),u.push(e.id)}),acf.getPostboxes().map(function(t){-1===u.indexOf(t.get("id"))&&t.hideDisable()}),h("#acf-style").html(l.style)},renderUserScreen:function(t){}});var t=new acf.Model({wait:"load",initialize:function(){acf.isGutenberg()&&(wp.data.subscribe(this.proxy(this.onChange)),acf.screen.getPageTemplate=this.getPageTemplate,acf.screen.getPageParent=this.getPageParent,acf.screen.getPostType=this.getPostType,acf.screen.getPostFormat=this.getPostFormat,acf.screen.getPostCoreTerms=this.getPostCoreTerms)},onChange:function(){var e=wp.data.select("core/editor").getPostEdits(),i=["template","parent","format"],t;(wp.data.select("core").getTaxonomies()||[]).map(function(t){i.push(t.rest_base)}),(i=i.filter(this.proxy(function(t){return e[t]&&e[t]!==this.get(t)}))).length&&this.triggerChange(e)},triggerChange:function(t){t!==e&&(this.data=t),acf.screen.check()},getPageTemplate:function(){return wp.data.select("core/editor").getEditedPostAttribute("template")},getPageParent:function(t,e){return wp.data.select("core/editor").getEditedPostAttribute("parent")},getPostType:function(){return wp.data.select("core/editor").getEditedPostAttribute("type")},getPostFormat:function(t,e){return wp.data.select("core/editor").getEditedPostAttribute("format")},getPostCoreTerms:function(){var i={},t;return(wp.data.select("core").getTaxonomies()||[]).map(function(t){var e=wp.data.select("core/editor").getEditedPostAttribute(t.rest_base);e&&(i[t.slug]=e)}),i}})}(jQuery),function(l,t){function a(){return acf.isset(window,"jQuery","fn","select2","amd")?4:!!acf.isset(window,"Select2")&&3}acf.newSelect2=function(t,e){if(e=acf.parseArgs(e,{allowNull:!1,placeholder:"",multiple:!1,field:!1,ajax:!1,ajaxAction:"",ajaxData:function(t){return t},ajaxResults:function(t){return t}}),4==a())var i=new r(t,e);else var i=new s(t,e);return acf.doAction("new_select2",i),i};var n=acf.Model.extend({setup:function(t,e){l.extend(this.data,e),this.$el=t},initialize:function(){},selectOption:function(t){var e=this.getOption(t);e.prop("selected")||e.prop("selected",!0).trigger("change")},unselectOption:function(t){var e=this.getOption(t);e.prop("selected")&&e.prop("selected",!1).trigger("change")},getOption:function(t){return this.$('option[value="'+t+'"]')},addOption:function(t){t=acf.parseArgs(t,{id:"",text:"",selected:!1});var e=this.getOption(t.id);return e.length||((e=l("")).html(t.text),e.attr("value",t.id),e.prop("selected",t.selected),this.$el.append(e)),e},getValue:function(){var e=[],t=this.$el.find("option:selected");return t.exists()&&(t=t.sort(function(t,e){return+t.getAttribute("data-i")-+e.getAttribute("data-i")})).each(function(){var t=l(this);e.push({$el:t,id:t.attr("value"),text:t.text()})}),e},mergeOptions:function(){},getChoices:function(){var i=function(t){var e=[];return t.children().each(function(){var t=l(this);t.is("optgroup")?e.push({text:t.attr("label"),children:i(t)}):e.push({id:t.attr("value"),text:t.text()})}),e};return i(this.$el)},decodeChoices:function(t){var e=function(t){return t.map(function(t){return t.text=acf.decode(t.text),t.children&&(t.children=e(t.children)),t}),t};return e(t)},getAjaxData:function(t){var e={action:this.get("ajaxAction"),s:t.term||"",paged:t.page||1},i=this.get("field");i&&(e.field_key=i.get("key"));var n=this.get("ajaxData");return n&&(e=n.apply(this,[e,t])),e=acf.applyFilters("select2_ajax_data",e,this.data,this.$el,i||!1,this),acf.prepareForAjax(e)},getAjaxResults:function(t,e){(t=acf.parseArgs(t,{results:!1,more:!1})).results&&(t.results=this.decodeChoices(t.results));var i=this.get("ajaxResults");return i&&(t=i.apply(this,[t,e])),t=acf.applyFilters("select2_ajax_results",t,e,this)},processAjaxResults:function(t,e){var t;return(t=this.getAjaxResults(t,e)).more&&(t.pagination={more:!0}),setTimeout(l.proxy(this.mergeOptions,this),1),t},destroy:function(){this.$el.data("select2")&&this.$el.select2("destroy"),this.$el.siblings(".select2-container").remove()}}),r=n.extend({initialize:function(){var e=this.$el,t={width:"100%",allowClear:this.get("allowNull"),placeholder:this.get("placeholder"),multiple:this.get("multiple"),data:[],escapeMarkup:function(t){return t}};t.multiple&&this.getValue().map(function(t){t.$el.detach().appendTo(e)}),e.removeData("ajax"),e.removeAttr("data-ajax"),this.get("ajax")&&(t.ajax={url:acf.get("ajaxurl"),delay:250,dataType:"json",type:"post",cache:!1,data:l.proxy(this.getAjaxData,this),processResults:l.proxy(this.processAjaxResults,this)});var i=this.get("field");t=acf.applyFilters("select2_args",t,e,this.data,i||!1,this),e.select2(t);var n=e.next(".select2-container");if(t.multiple){var a=n.find("ul");a.sortable({stop:function(t){a.find(".select2-selection__choice").each(function(){var t;l(l(this).data("data").element).detach().appendTo(e)}),e.trigger("change")}}),e.on("select2:select",this.proxy(function(t){this.getOption(t.params.data.id).detach().appendTo(this.$el)}))}n.addClass("-acf"),acf.doAction("select2_init",e,t,this.data,i||!1,this)},mergeOptions:function(){var i=!1,n=!1;l('.select2-results__option[role="group"]').each(function(){var t=l(this).children("ul"),e=l(this).children("strong");if(n&&n.text()===e.text())return i.append(t.children()),void l(this).remove();i=t,n=e})}}),s=n.extend({initialize:function(){var n=this.$el,i=this.getValue(),a=this.get("multiple"),t={width:"100%",allowClear:this.get("allowNull"),placeholder:this.get("placeholder"),separator:"||",multiple:this.get("multiple"),data:this.getChoices(),escapeMarkup:function(t){return t},dropdownCss:{"z-index":"999999999"},initSelection:function(t,e){e(a?i:i.shift())}},e=n.siblings("input");e.length||(e=l(''),n.before(e)),inputValue=i.map(function(t){return t.id}).join("||"),e.val(inputValue),t.multiple&&i.map(function(t){t.$el.detach().appendTo(n)}),t.allowClear&&(t.data=t.data.filter(function(t){return""!==t.id})),n.removeData("ajax"),n.removeAttr("data-ajax"),this.get("ajax")&&(t.ajax={url:acf.get("ajaxurl"),quietMillis:250,dataType:"json",type:"post",cache:!1,data:l.proxy(this.getAjaxData,this),results:l.proxy(this.processAjaxResults,this)});var r=this.get("field");t=acf.applyFilters("select2_args",t,n,this.data,r||!1,this),e.select2(t);var s=e.select2("container"),o=l.proxy(this.getOption,this);if(t.multiple){var c=s.find("ul");c.sortable({stop:function(){c.find(".select2-search-choice").each(function(){var t=l(this).data("select2Data"),e;o(t.id).detach().appendTo(n)}),n.trigger("change")}})}e.on("select2-selecting",function(t){var e=t.choice,i=o(e.id);i.length||(i=l( -'")),i.detach().appendTo(n)}),s.addClass("-acf"),acf.doAction("select2_init",n,t,this.data,r||!1,this),e.on("change",function(){var t=e.val();t.indexOf("||")&&(t=t.split("||")),n.val(t).trigger("change")}),n.hide()},mergeOptions:function(){var i=!1,n=!1;l("#select2-drop .select2-result-with-children").each(function(){var t=l(this).children("ul"),e=l(this).children(".select2-result-label");if(n&&n.text()===e.text())return n.append(t.children()),void l(this).remove();i=t,n=e})},getAjaxData:function(t,e){var i={term:t,page:e};return n.prototype.getAjaxData.apply(this,[i])}}),e=new acf.Model({priority:5,wait:"prepare",initialize:function(){var t=acf.get("locale"),e=acf.get("rtl"),i=acf.get("select2L10n"),n=a();return!!i&&(0!==t.indexOf("en")&&void(4==n?this.addTranslations4():3==n&&this.addTranslations3()))},addTranslations4:function(){var i=acf.get("select2L10n"),t=acf.get("locale");t=t.replace("_","-");var e={errorLoading:function(){return i.load_fail},inputTooLong:function(t){var e=t.input.length-t.maximum;return 1'),t.addClass("acf-sortable-tr-helper"),t.children().each(function(){l(this).width(l(this).width())}),e.height(t.height()+"px"),t.removeClass("acf-sortable-tr-helper"))}}),n=new acf.Model({actions:{after_duplicate:"onAfterDuplicate"},onAfterDuplicate:function(t,e){var i=[];t.find("select").each(function(t){i.push(l(this).val())}),e.find("select").each(function(t){l(this).val(i[t])})}}),a=new acf.Model({id:"tableHelper",priority:20,actions:{refresh:"renderTables"},renderTables:function(t){var e=this;l(".acf-table:visible").each(function(){e.renderTable(l(this))})},renderTable:function(t){var e=t.find("> thead > tr:visible > th[data-key]"),r=t.find("> tbody > tr:visible > td[data-key]");if(!e.length||!r.length)return!1;e.each(function(t){var e=l(this),i=e.data("key"),n=r.filter('[data-key="'+i+'"]'),a=n.filter(".acf-hidden");n.removeClass("acf-empty"),n.length===a.length?acf.hide(e):(acf.show(e),a.addClass("acf-empty"))}),e.css("width","auto"),e=e.not(".acf-hidden");var i=100,n=e.length,a;e.filter("[data-width]").each(function(){var t=l(this).data("width");l(this).css("width",t+"%"),i-=t});var s=e.not("[data-width]");if(s.length){var o=i/s.length;s.css("width",o+"%"),i=0}0t.length?Array(e-t.length+1).join("0")+t:t};return a||(a=Math.floor(123456789*Math.random())),a++,i=t,i+=n(parseInt((new Date).getTime()/1e3,10),8),i+=n(a,5),e&&(i+=(10*Math.random()).toFixed(8).toString()),i},c.strReplace=function(t,e,i){return i.split(t).join(e)},c.strCamelCase=function(t){return t=(t=t.replace(/[_-]/g," ")).replace(/(?:^\w|\b\w|\s+)/g,function(t,e){return 0==+t?"":0==e?t.toLowerCase():t.toUpperCase()})},c.strPascalCase=function(t){var e=c.strCamelCase(t);return e.charAt(0).toUpperCase()+e.slice(1)},c.strSlugify=function(t){return c.strReplace("_","-",t.toLowerCase())},c.strSanitize=function(t){var e={"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","ß":"s","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"c","Ĉ":"C","ĉ":"c","Ċ":"C","ċ":"c","Č":"C","č":"c","Ď":"D","ď":"d","Đ":"D","đ":"d","Ē":"E","ē":"e","Ĕ":"E","ĕ":"e","Ė":"E","ė":"e","Ę":"E","ę":"e","Ě":"E","ě":"e","Ĝ":"G","ĝ":"g","Ğ":"G","ğ":"g","Ġ":"G","ġ":"g","Ģ":"G","ģ":"g","Ĥ":"H","ĥ":"h","Ħ":"H","ħ":"h","Ĩ":"I","ĩ":"i","Ī":"I","ī":"i","Ĭ":"I","ĭ":"i","Į":"I","į":"i","İ":"I","ı":"i","IJ":"IJ","ij":"ij","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","Ĺ":"L","ĺ":"l","Ļ":"L","ļ":"l","Ľ":"L","ľ":"l","Ŀ":"L","ŀ":"l","Ł":"l","ł":"l","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","ʼn":"n","Ō":"O","ō":"o","Ŏ":"O","ŏ":"o","Ő":"O","ő":"o","Œ":"OE","œ":"oe","Ŕ":"R","ŕ":"r","Ŗ":"R","ŗ":"r","Ř":"R","ř":"r","Ś":"S","ś":"s","Ŝ":"S","ŝ":"s","Ş":"S","ş":"s","Š":"S","š":"s","Ţ":"T","ţ":"t","Ť":"T","ť":"t","Ŧ":"T","ŧ":"t","Ũ":"U","ũ":"u","Ū":"U","ū":"u","Ŭ":"U","ŭ":"u","Ů":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","ź":"z","Ż":"Z","ż":"z","Ž":"Z","ž":"z","ſ":"s","ƒ":"f","Ơ":"O","ơ":"o","Ư":"U","ư":"u","Ǎ":"A","ǎ":"a","Ǐ":"I","ǐ":"i","Ǒ":"O","ǒ":"o","Ǔ":"U","ǔ":"u","Ǖ":"U","ǖ":"u","Ǘ":"U","ǘ":"u","Ǚ":"U","ǚ":"u","Ǜ":"U","ǜ":"u","Ǻ":"A","ǻ":"a","Ǽ":"AE","ǽ":"ae","Ǿ":"O","ǿ":"o"," ":"_","'":"","?":"","/":"","\\":"",".":"",",":"","`":"",">":"","<":"",'"':"","[":"","]":"","|":"","{":"","}":"","(":"",")":""},i=/\W/g,n=function(t){return e[t]!==s?e[t]:t};return t=(t=t.replace(i,n)).toLowerCase()},c.strMatch=function(t,e){for(var i=0,n=Math.min(t.length,e.length),a=0;a").html(t).text()},c.strEscape=function(t){var e={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};return String(t).replace(/[&<>"'`=\/]/g,function(t){return e[t]})},c.parseArgs=function(t,e){return"object"!=typeof t&&(t={}),"object"!=typeof e&&(e={}),r.extend({},e,t)},window.acfL10n==s&&(acfL10n={}),c.__=function(t){return acfL10n[t]||t},c._x=function(t,e){return acfL10n[t+"."+e]||acfL10n[t]||t},c._n=function(t,e,i){return 1==i?c.__(t):c.__(e)},c.isArray=function(t){return Array.isArray(t)},c.isObject=function(t){return"object"==typeof t};var o=function(t,e,i){var n=(e=e.replace("[]","[%%index%%]")).match(/([^\[\]])+/g);if(n)for(var a=n.length,r=t,s=0;s');var o=e.parent();e.css({height:i,width:n,margin:a,position:"absolute"}),setTimeout(function(){o.css({opacity:0,height:t.endHeight})},50),setTimeout(function(){e.attr("style",s),o.remove(),t.complete()},301)},d=function(t){var e=t.target,i=e.height(),n=e.children().length,a=r('
        ');e.addClass("acf-remove-element"),setTimeout(function(){e.html(a)},251),setTimeout(function(){e.removeClass("acf-remove-element"),a.css({height:t.endHeight})},300),setTimeout(function(){e.remove(),t.complete()},451)};c.duplicate=function(t){t instanceof jQuery&&(t={target:t});var i=0;(t=c.parseArgs(t,{target:!1,search:"",replace:"",before:function(t){},after:function(t,e){},append:function(t,e){t.after(e),i=1}})).target=t.target||t.$el;var e=t.target;t.search=t.search||e.attr("data-id"),t.replace=t.replace||c.uniqid(),t.before(e),c.doAction("before_duplicate",e);var n=e.clone();return c.rename({target:n,search:t.search,replace:t.replace}),n.removeClass("acf-clone"),n.find(".ui-sortable").removeClass("ui-sortable"),t.after(e,n),c.doAction("after_duplicate",e,n),t.append(e,n),c.doAction("append",n),n},c.rename=function(t){t instanceof jQuery&&(t={target:t});var e=(t=c.parseArgs(t,{target:!1,destructive:!1,search:"",replace:""})).target,i=t.search||e.attr("data-id"),n=t.replace||c.uniqid("acf"),a=function(t,e){return e.replace(i,n)};if(t.destructive){var r=e.outerHTML();r=c.strReplace(i,n,r),e.replaceWith(r)}else e.attr("data-id",n),e.find('[id*="'+i+'"]').attr("id",a),e.find('[for*="'+i+'"]').attr("for",a),e.find('[name*="'+i+'"]').attr("name",a);return e},c.prepareForAjax=function(t){return t.nonce=c.get("nonce"),t.post_id=c.get("post_id"),c.has("language")&&(t.lang=c.get("language")),t=c.applyFilters("prepare_for_ajax",t)},c.startButtonLoading=function(t){t.prop("disabled",!0),t.after(' ')},c.stopButtonLoading=function(t){t.prop("disabled",!1),t.next(".acf-loading").remove()},c.showLoading=function(t){t.append('
        ')},c.hideLoading=function(t){t.children(".acf-loading-overlay").remove()},c.updateUserSetting=function(t,e){var i={action:"acf/ajax/user_setting",name:t,value:e};r.ajax({url:c.get("ajaxurl"),data:c.prepareForAjax(i),type:"post",dataType:"html"})},c.val=function(t,e,i){var n=t.val();return e!==n&&(t.val(e),t.is("select")&&null===t.val()?(t.val(n),!1):(!0!==i&&t.trigger("change"),!0))},c.show=function(t,e){return e&&c.unlock(t,"hidden",e),!c.isLocked(t,"hidden")&&(!!t.hasClass("acf-hidden")&&(t.removeClass("acf-hidden"),!0))},c.hide=function(t,e){return e&&c.lock(t,"hidden",e),!t.hasClass("acf-hidden")&&(t.addClass("acf-hidden"),!0)},c.isHidden=function(t){return t.hasClass("acf-hidden")},c.isVisible=function(t){return!c.isHidden(t)};var f=function(t,e){return!t.hasClass("acf-disabled")&&(e&&c.unlock(t,"disabled",e),!c.isLocked(t,"disabled")&&(!!t.prop("disabled")&&(t.prop("disabled",!1),!0)))};c.enable=function(t,e){if(t.attr("name"))return f(t,e);var i=!1;return t.find("[name]").each(function(){var t;f(r(this),e)&&(i=!0)}),i};var h=function(t,e){return e&&c.lock(t,"disabled",e),!t.prop("disabled")&&(t.prop("disabled",!0),!0)};c.disable=function(t,e){if(t.attr("name"))return h(t,e);var i=!1;return t.find("[name]").each(function(){var t;h(r(this),e)&&(i=!0)}),i},c.isset=function(t){for(var e=1;e'+r(t.children)+"":n+='"}),n};return t.html(r(e)),-1e.priority;)t[i]=t[i-1],--i;t[i]=e}return t}function u(t,e,i){var n=f[t][e];if(!n)return"filters"===t&&i[0];var a=0,r=n.length;if("filters"===t)for(;a','
        ','

        ','
        ','
        ',"
        ",'
        ',""].join("")},render:function(){var t=this.get("title"),e=this.get("content"),i=this.get("loading"),n=this.get("width"),a=this.get("height");this.title(t),this.content(e),n&&this.$(".acf-popup-box").css("width",n),a&&this.$(".acf-popup-box").css("min-height",a),this.loading(i),acf.doAction("append",this.$el)},update:function(t){this.data=acf.parseArgs(t,this.data),this.render()},title:function(t){this.$(".title:first h3").html(t)},content:function(t){this.$(".inner:first").html(t)},loading:function(t){var e=this.$(".loading:first");t?e.show():e.hide()},open:function(){e("body").append(this.$el)},close:function(){this.remove()},onClickClose:function(t,e){t.preventDefault(),this.close()}}),acf.newPopup=function(t){return new acf.models.Popup(t)}}(jQuery),function(t,e){acf.unload=new acf.Model({wait:"load",active:!0,changed:!1,actions:{validation_failure:"startListening",validation_success:"stopListening"},events:{"change form .acf-field":"startListening","submit form":"stopListening"},enable:function(){this.active=!0},disable:function(){this.active=!1},reset:function(){this.stopListening()},startListening:function(){!this.changed&&this.active&&(this.changed=!0,t(window).on("beforeunload",this.onUnload))},stopListening:function(){this.changed=!1,t(window).off("beforeunload",this.onUnload)},onUnload:function(){return acf.__("The changes you made will be lost if you navigate away from this page")}})}(jQuery),function(t,e){var i=new acf.Model({events:{"click .acf-panel-title":"onClick"},onClick:function(t,e){t.preventDefault(),this.toggle(e.parent())},isOpen:function(t){return t.hasClass("-open")},toggle:function(t){this.isOpen(t)?this.close(t):this.open(t)},open:function(t){t.addClass("-open"),t.find(".acf-panel-title i").attr("class","dashicons dashicons-arrow-down")},close:function(t){t.removeClass("-open"),t.find(".acf-panel-title i").attr("class","dashicons dashicons-arrow-right")}})}(jQuery),function(e,t){var i=acf.Model.extend({data:{text:"",type:"",timeout:0,dismiss:!0,target:!1,close:function(){}},events:{"click .acf-notice-dismiss":"onClickClose"},tmpl:function(){return'
        '},setup:function(t){e.extend(this.data,t),this.$el=e(this.tmpl())},initialize:function(){this.render(),this.show()},render:function(){this.type(this.get("type")),this.html("

        "+this.get("text")+"

        "),this.get("dismiss")&&(this.$el.append(''),this.$el.addClass("-dismiss"));var t=this.get("timeout");t&&this.away(t)},update:function(t){e.extend(this.data,t),this.initialize(),this.removeEvents(),this.addEvents()},show:function(){var t=this.get("target");t&&t.prepend(this.$el)},hide:function(){this.$el.remove()},away:function(t){this.setTimeout(function(){acf.remove(this.$el)},t)},type:function(t){var e=this.get("type");e&&this.$el.removeClass("-"+e),this.$el.addClass("-"+t),"error"==t&&this.$el.addClass("acf-error-message")},html:function(t){this.$el.html(t)},text:function(t){this.$("p").html(t)},onClickClose:function(t,e){t.preventDefault(),this.get("close").apply(this,arguments),this.remove()}});acf.newNotice=function(t){return"object"!=typeof t&&(t={text:t}),new i(t)};var n=new acf.Model({wait:"prepare",priority:1,initialize:function(){var t=e(".acf-admin-notice");t.length&&e("h1:first").after(t)}})}(jQuery),function(e,t){acf.getPostbox=function(t){return"string"==typeof t&&(t=e("#"+t)),acf.getInstance(t)},acf.getPostboxes=function(){return acf.getInstances(e(".acf-postbox"))},acf.newPostbox=function(t){return new acf.models.Postbox(t)},acf.models.Postbox=acf.Model.extend({data:{id:"",key:"",style:"default",label:"top",edit:""},setup:function(t){t.editLink&&(t.edit=t.editLink),e.extend(this.data,t),this.$el=this.$postbox()},$postbox:function(){return e("#"+this.get("id"))},$hide:function(){return e("#"+this.get("id")+"-hide")},$hideLabel:function(){return this.$hide().parent()},$hndle:function(){return this.$("> .hndle")},$inside:function(){return this.$("> .inside")},isVisible:function(){return this.$el.hasClass("acf-hidden")},initialize:function(){this.$el.addClass("acf-postbox"),this.$el.removeClass("hide-if-js");var t=this.get("style");"default"!==t&&this.$el.addClass(t),this.$inside().addClass("acf-fields").addClass("-"+this.get("label"));var e=this.get("edit");e&&this.$hndle().append(''),this.show()},show:function(){this.$hideLabel().show(),this.$hide().prop("checked",!0),this.$el.show().removeClass("acf-hidden")},enable:function(){acf.enable(this.$el,"postbox")},showEnable:function(){this.show(),this.enable()},hide:function(){this.$hideLabel().hide(),this.$el.hide().addClass("acf-hidden")},disable:function(){acf.disable(this.$el,"postbox")},hideDisable:function(){this.hide(),this.disable()},html:function(t){this.$inside().html(t),acf.doAction("append",this.$el)}})}(jQuery),function(f,e){acf.newTooltip=function(t){return"object"!=typeof t&&(t={text:t}),t.confirmRemove!==e?(t.textConfirm=acf.__("Remove"),t.textCancel=acf.__("Cancel"),new n(t)):t.confirm!==e?new n(t):new i(t)};var i=acf.Model.extend({data:{text:"",timeout:0,target:null},tmpl:function(){return'
        '},setup:function(t){f.extend(this.data,t),this.$el=f(this.tmpl())},initialize:function(){this.render(),this.show(),this.position();var t=this.get("timeout");t&&setTimeout(f.proxy(this.fade,this),t)},update:function(t){f.extend(this.data,t),this.initialize()},render:function(){this.html(this.get("text"))},show:function(){f("body").append(this.$el)},hide:function(){this.$el.remove()},fade:function(){this.$el.addClass("acf-fade-up"),this.setTimeout(function(){this.remove()},250)},html:function(t){this.$el.html(t)},position:function(){var t=this.$el,e=this.get("target");if(e){t.removeClass("right left bottom top").css({top:0,left:0});var i=10,n=e.outerWidth(),a=e.outerHeight(),r=e.offset().top,s=e.offset().left,o=t.outerWidth(),c=t.outerHeight(),l=t.offset().top,u=r-c-l,d=s+n/2-o/2;d<10?(t.addClass("right"),d=s+n,u=r+a/2-c/2-l):d+o+10>f(window).width()?(t.addClass("left"),d=s-o,u=r+a/2-c/2-l):u-f(window).scrollTop()<10?(t.addClass("bottom"),u=r+a-l):t.addClass("top"),t.css({top:u,left:d})}}}),n=i.extend({data:{text:"",textConfirm:"",textCancel:"",target:null,targetConfirm:!0,confirm:function(){},cancel:function(){},context:!1},events:{'click [data-event="cancel"]':"onCancel",'click [data-event="confirm"]':"onConfirm"},addEvents:function(){acf.Model.prototype.addEvents.apply(this);var t=f(document),e=this.get("target");this.setTimeout(function(){this.on(t,"click","onCancel")}),this.get("targetConfirm")&&this.on(e,"click","onConfirm")},removeEvents:function(){acf.Model.prototype.removeEvents.apply(this);var t=f(document),e=this.get("target");this.off(t,"click"),this.off(e,"click")},render:function(){var t,e,i,n=[this.get("text")||acf.__("Are you sure?"),''+(this.get("textConfirm")||acf.__("Yes"))+"",''+(this.get("textCancel")||acf.__("No"))+""].join(" ");this.html(n),this.$el.addClass("-confirm")},onCancel:function(t,e){t.preventDefault(),t.stopImmediatePropagation();var i=this.get("cancel"),n=this.get("context")||this;i.apply(n,arguments),this.remove()},onConfirm:function(t,e){t.preventDefault(),t.stopImmediatePropagation();var i=this.get("confirm"),n=this.get("context")||this;i.apply(n,arguments),this.remove()}});acf.models.Tooltip=i,acf.models.TooltipConfirm=n;var t=new acf.Model({tooltip:!1,events:{"mouseenter .acf-js-tooltip":"showTitle","mouseup .acf-js-tooltip":"hideTitle","mouseleave .acf-js-tooltip":"hideTitle"},showTitle:function(t,e){var i=e.attr("title");i&&(e.attr("title",""),this.tooltip?this.tooltip.update({text:i,target:e}):this.tooltip=acf.newTooltip({text:i,target:e}))},hideTitle:function(t,e){this.tooltip.hide(),e.attr("title",this.tooltip.get("text"))}})}(jQuery),function(e,i){var r=[];acf.Field=acf.Model.extend({type:"",eventScope:".acf-field",wait:"ready",setup:function(t){this.$el=t,this.inherit(t),this.inherit(this.$control())},val:function(t){return t!==i?this.setValue(t):this.prop("disabled")?null:this.getValue()},getValue:function(){return this.$input().val()},setValue:function(t){return acf.val(this.$input(),t)},__:function(t){return acf._e(this.type,t)},$control:function(){return!1},$input:function(){return this.$("[name]:first")},$inputWrap:function(){return this.$(".acf-input:first")},$labelWrap:function(){return this.$(".acf-label:first")},getInputName:function(){return this.$input().attr("name")||""},parent:function(){var t=this.parents();return!!t.length&&t[0]},parents:function(){var t=this.$el.parents(".acf-field"),e;return acf.getFields(t)},show:function(t,e){var i=acf.show(this.$el,t);return i&&(this.prop("hidden",!1),acf.doAction("show_field",this,e)),i},hide:function(t,e){var i=acf.hide(this.$el,t);return i&&(this.prop("hidden",!0),acf.doAction("hide_field",this,e)),i},enable:function(t,e){var i=acf.enable(this.$el,t);return i&&(this.prop("disabled",!1),acf.doAction("enable_field",this,e)),i},disable:function(t,e){var i=acf.disable(this.$el,t);return i&&(this.prop("disabled",!0),acf.doAction("disable_field",this,e)),i},showEnable:function(t,e){return this.enable.apply(this,arguments),this.show.apply(this,arguments)},hideDisable:function(t,e){return this.disable.apply(this,arguments),this.hide.apply(this,arguments)},showNotice:function(t){"object"!=typeof t&&(t={text:t}),this.notice&&this.notice.remove(),t.target=this.$inputWrap(),this.notice=acf.newNotice(t)},removeNotice:function(t){this.notice&&(this.notice.away(t||0),this.notice=!1)},showError:function(t){this.$el.addClass("acf-error"),t!==i&&this.showNotice({text:t,type:"error",dismiss:!1}),acf.doAction("invalid_field",this),this.$el.one("focus change","input, select, textarea",e.proxy(this.removeError,this))},removeError:function(){this.$el.removeClass("acf-error"),this.removeNotice(250),acf.doAction("valid_field",this)},trigger:function(t,e,i){return"invalidField"==t&&(i=!0),acf.Model.prototype.trigger.apply(this,[t,e,i])}}),acf.newField=function(t){var e=t.data("type"),i=s(e),n,a=new(acf.models[i]||acf.Field)(t);return acf.doAction("new_field",a),a};var s=function(t){return acf.strPascalCase(t||"")+"Field"};acf.registerFieldType=function(t){var e,i=t.prototype.type,n=s(i);acf.models[n]=t,r.push(i)},acf.getFieldType=function(t){var e=s(t);return acf.models[e]||!1},acf.getFieldTypes=function(n){n=acf.parseArgs(n,{category:""});var a=[];return r.map(function(t){var e=acf.getFieldType(t),i=e.prototype;n.category&&i.category!==n.category||a.push(e)}),a}}(jQuery),function(n,t){acf.findFields=function(t){var e=".acf-field",i=!1;return(t=acf.parseArgs(t,{key:"",name:"",type:"",is:"",parent:!1,sibling:!1,limit:!1,visible:!1,suppressFilters:!1})).suppressFilters||(t=acf.applyFilters("find_fields_args",t)),t.key&&(e+='[data-key="'+t.key+'"]'),t.type&&(e+='[data-type="'+t.type+'"]'),t.name&&(e+='[data-name="'+t.name+'"]'),t.is&&(e+=t.is),t.visible&&(e+=":visible"),i=t.parent?t.parent.find(e):t.sibling?t.sibling.siblings(e):n(e),t.suppressFilters||(i=i.not(".acf-clone .acf-field"),i=acf.applyFilters("find_fields",i)),t.limit&&(i=i.slice(0,t.limit)),i},acf.findField=function(t,e){return acf.findFields({key:t,limit:1,parent:e,suppressFilters:!0})},acf.getField=function(t){t instanceof jQuery||(t=acf.findField(t));var e=t.data("acf");return e||(e=acf.newField(t)),e},acf.getFields=function(t){t instanceof jQuery||(t=acf.findFields(t));var e=[];return t.each(function(){var t=acf.getField(n(this));e.push(t)}),e},acf.findClosestField=function(t){return t.closest(".acf-field")},acf.getClosestField=function(t){var e=acf.findClosestField(t);return this.getField(e)};var e=function(t){var e=t,r=t+"_fields",a=t+"_field",i=function(t){var e,i=acf.arrayArgs(arguments).slice(1),n=acf.getFields({parent:t});if(n.length){var a=[r,n].concat(i);acf.doAction.apply(null,a)}},n=function(t){var e,n=acf.arrayArgs(arguments).slice(1);t.map(function(t,e){var i=[a,t].concat(n);acf.doAction.apply(null,i)})};acf.addAction(e,i),acf.addAction(r,n),s(t)},s=function(e){var r=e+"_field",s=e+"Field",t=function(i){var n=acf.arrayArgs(arguments),a=n.slice(1),t;["type","name","key"].map(function(t){var e="/"+t+"="+i.get(t);n=[r+e,i].concat(a),acf.doAction.apply(null,n)}),-1'),o=f('
        '),c=f('
          '),l=f("");s.append(e.html()),c.append(l),o.append(c),i.append(s),i.append(o),e.remove(),n.remove(),i.attr("colspan",2),e=s,i=o,n=l}t.addClass("acf-accordion"),e.addClass("acf-accordion-title"),i.addClass("acf-accordion-content"),p++,this.get("multi_expand")&&t.attr("multi-expand",1);var u=acf.getPreference("this.accordions")||[];u[p-1]!==h&&this.set("open",u[p-1]),this.get("open")&&(t.addClass("-open"),i.css("display","block")),e.prepend(g.iconHtml({open:this.get("open")}));var d=t.parent();n.addClass(d.hasClass("-left")?"-left":""),n.addClass(d.hasClass("-clear")?"-clear":""),n.append(t.nextUntil(".acf-field-accordion",".acf-field")),n.removeAttr("data-open data-multi_expand data-endpoint")}}});acf.registerFieldType(t);var g=new acf.Model({actions:{unload:"onUnload"},events:{"click .acf-accordion-title":"onClick","invalidField .acf-accordion":"onInvalidField"},isOpen:function(t){return t.hasClass("-open")}, +toggle:function(t){this.isOpen(t)?this.close(t):this.open(t)},iconHtml:function(t){var e;return''},open:function(t){t.find(".acf-accordion-content:first").slideDown().css("display","block"),t.find(".acf-accordion-icon:first").replaceWith(this.iconHtml({open:!0})),t.addClass("-open"),acf.doAction("show",t),t.attr("multi-expand")||t.siblings(".acf-accordion.-open").each(function(){g.close(f(this))})},close:function(t){t.find(".acf-accordion-content:first").slideUp(),t.find(".acf-accordion-icon:first").replaceWith(this.iconHtml({open:!1})),t.removeClass("-open"),acf.doAction("hide",t)},onClick:function(t,e){t.preventDefault(),this.toggle(e.parent())},onInvalidField:function(t,e){this.busy||(this.busy=!0,this.setTimeout(function(){this.busy=!1},1e3),this.open(e))},onUnload:function(t){var e=[];f(".acf-accordion").each(function(){var t=f(this).hasClass("-open")?1:0;e.push(t)}),e.length&&acf.setPreference("this.accordions",e)}})}(jQuery),function(t,e){var i=acf.Field.extend({type:"button_group",events:{'click input[type="radio"]':"onClick"},$control:function(){return this.$(".acf-button-group")},$input:function(){return this.$("input:checked")},setValue:function(t){this.$('input[value="'+t+'"]').prop("checked",!0).trigger("change")},onClick:function(t,e){var i=e.parent("label"),n=i.hasClass("selected");this.$(".selected").removeClass("selected"),i.addClass("selected"),this.get("allow_null")&&n&&(i.removeClass("selected"),e.prop("checked",!1).trigger("change"))}});acf.registerFieldType(i)}(jQuery),function(e,t){var i=acf.Field.extend({type:"checkbox",events:{"change input":"onChange","click .acf-add-checkbox":"onClickAdd","click .acf-checkbox-toggle":"onClickToggle","click .acf-checkbox-custom":"onClickCustom"},$control:function(){return this.$(".acf-checkbox-list")},$toggle:function(){return this.$(".acf-checkbox-toggle")},$input:function(){return this.$('input[type="hidden"]')},$inputs:function(){return this.$('input[type="checkbox"]').not(".acf-checkbox-toggle")},getValue:function(){var t=[];return this.$(":checked").each(function(){t.push(e(this).val())}),!!t.length&&t},onChange:function(t,e){var i=e.prop("checked"),n=this.$toggle(),a;(i?e.parent().addClass("selected"):e.parent().removeClass("selected"),n.length)&&(0==this.$inputs().not(":checked").length?n.prop("checked",!0):n.prop("checked",!1))},onClickAdd:function(t,e){var i='
        • ';e.parent("li").before(i)},onClickToggle:function(t,e){var i=e.prop("checked"),n;this.$inputs().prop("checked",i)},onClickCustom:function(t,e){var i=e.prop("checked"),n=e.next('input[type="text"]');i?n.prop("disabled",!1):(n.prop("disabled",!0),""==n.val()&&e.parent("li").remove())}});acf.registerFieldType(i)}(jQuery),function(t,e){var i=acf.Field.extend({type:"color_picker",wait:"load",$control:function(){return this.$(".acf-color-picker")},$input:function(){return this.$('input[type="hidden"]')},$inputText:function(){return this.$('input[type="text"]')},setValue:function(t){acf.val(this.$input(),t),this.$inputText().iris("color",t)},initialize:function(){var e=this.$input(),i=this.$inputText(),t=function(t){setTimeout(function(){acf.val(e,i.val())},1)},n={defaultColor:!1,palettes:!0,hide:!0,change:t,clear:t},n=acf.applyFilters("color_picker_args",n,this);i.wpColorPicker(n)}});acf.registerFieldType(i)}(jQuery),function(n,t){var e=acf.Field.extend({type:"date_picker",events:{'blur input[type="text"]':"onBlur"},$control:function(){return this.$(".acf-date-picker")},$input:function(){return this.$('input[type="hidden"]')},$inputText:function(){return this.$('input[type="text"]')},initialize:function(){if(this.has("save_format"))return this.initializeCompatibility();var t=this.$input(),e=this.$inputText(),i={dateFormat:this.get("date_format"),altField:t,altFormat:"yymmdd",changeYear:!0,yearRange:"-100:+100",changeMonth:!0,showButtonPanel:!0,firstDay:this.get("first_day")};i=acf.applyFilters("date_picker_args",i,this),acf.newDatePicker(e,i),acf.doAction("date_picker_init",e,i,this)},initializeCompatibility:function(){var t=this.$input(),e=this.$inputText();e.val(t.val());var i={dateFormat:this.get("date_format"),altField:t,altFormat:this.get("save_format"),changeYear:!0,yearRange:"-100:+100",changeMonth:!0,showButtonPanel:!0,firstDay:this.get("first_day")},n=(i=acf.applyFilters("date_picker_args",i,this)).dateFormat;i.dateFormat=this.get("save_format"),acf.newDatePicker(e,i),e.datepicker("option","dateFormat",n),acf.doAction("date_picker_init",e,i,this)},onBlur:function(){this.$inputText().val()||acf.val(this.$input(),"")}});acf.registerFieldType(e);var i=new acf.Model({priority:5,wait:"ready",initialize:function(){var t=acf.get("locale"),e=acf.get("rtl"),i=acf.get("datePickerL10n");return!!i&&(void 0!==n.datepicker&&(i.isRTL=e,n.datepicker.regional[t]=i,void n.datepicker.setDefaults(i)))}});acf.newDatePicker=function(t,e){if(void 0===n.datepicker)return!1;e=e||{},t.datepicker(e),n("body > #ui-datepicker-div").exists()&&n("body > #ui-datepicker-div").wrap('
          ')}}(jQuery),function(n,t){var e=acf.models.DatePickerField.extend({type:"date_time_picker",$control:function(){return this.$(".acf-date-time-picker")},initialize:function(){var t=this.$input(),e=this.$inputText(),i={dateFormat:this.get("date_format"),timeFormat:this.get("time_format"),altField:t,altFieldTimeOnly:!1,altFormat:"yy-mm-dd",altTimeFormat:"HH:mm:ss",changeYear:!0,yearRange:"-100:+100",changeMonth:!0,showButtonPanel:!0,firstDay:this.get("first_day"),controlType:"select",oneLine:!0};i=acf.applyFilters("date_time_picker_args",i,this),acf.newDateTimePicker(e,i),acf.doAction("date_time_picker_init",e,i,this)}});acf.registerFieldType(e);var i=new acf.Model({priority:5,wait:"ready",initialize:function(){var t=acf.get("locale"),e=acf.get("rtl"),i=acf.get("dateTimePickerL10n");return!!i&&(void 0!==n.timepicker&&(i.isRTL=e,n.timepicker.regional[t]=i,void n.timepicker.setDefaults(i)))}});acf.newDateTimePicker=function(t,e){if(void 0===n.timepicker)return!1;e=e||{},t.datetimepicker(e),n("body > #ui-datepicker-div").exists()&&n("body > #ui-datepicker-div").wrap('
          ')}}(jQuery),function(s,t){var e=acf.Field.extend({type:"google_map",map:!1,wait:"load",events:{'click a[data-name="clear"]':"onClickClear",'click a[data-name="locate"]':"onClickLocate",'click a[data-name="search"]':"onClickSearch","keydown .search":"onKeydownSearch","keyup .search":"onKeyupSearch","focus .search":"onFocusSearch","blur .search":"onBlurSearch",showField:"onShow"},$control:function(){return this.$(".acf-google-map")},$input:function(t){return this.$('input[data-name="'+(t||"address")+'"]')},$search:function(){return this.$(".search")},$canvas:function(){return this.$(".canvas")},addClass:function(t){this.$control().addClass(t)},removeClass:function(t){this.$control().removeClass(t)},getValue:function(){var t={lat:"",lng:"",address:""};return this.$('input[type="hidden"]').each(function(){t[s(this).data("name")]=s(this).val()}),t.lat&&t.lng||(t=!1),t},setValue:function(t){for(var e in t=acf.parseArgs(t,{lat:"",lng:"",address:""}))acf.val(this.$input(e),t[e]);t.lat&&t.lng||(t=!1),this.renderVal(t);var i=this.newLatLng(t.lat,t.lng);acf.doAction("google_map_change",i,this.map,this)},renderVal:function(t){t?(this.addClass("-value"),this.setPosition(t.lat,t.lng),this.map.marker.setVisible(!0)):(this.removeClass("-value"),this.map.marker.setVisible(!1)),this.$search().val(t.address)},setPosition:function(t,e){var i=this.newLatLng(t,e);return this.map.marker.setPosition(i),this.map.marker.setVisible(!0),this.center(),this},center:function(){var t=this.map.marker.getPosition(),e=this.get("lat"),i=this.get("lng");t&&(e=t.lat(),i=t.lng());var n=this.newLatLng(e,i);this.map.setCenter(n)},getSearchVal:function(){return this.$search().val()},initialize:function(){o.isReady()?this.initializeMap():o.ready(this.initializeMap,this)},newLatLng:function(t,e){return new google.maps.LatLng(parseFloat(t),parseFloat(e))},initializeMap:function(){var t=this.get("zoom"),e=this.get("lat"),i=this.get("lng"),n={scrollwheel:!1,zoom:parseInt(t),center:this.newLatLng(e,i),mapTypeId:google.maps.MapTypeId.ROADMAP,marker:{draggable:!0,raiseOnDrag:!0},autocomplete:{}};n=acf.applyFilters("google_map_args",n,this);var a=new google.maps.Map(this.$canvas()[0],n),r=acf.parseArgs(n.marker,{draggable:!0,raiseOnDrag:!0,map:a});r=acf.applyFilters("google_map_marker_args",r,this);var s=new google.maps.Marker(r),o=!1;if(acf.isset(google,"maps","places","Autocomplete")){var c=n.autocomplete||{};c=acf.applyFilters("google_map_autocomplete_args",c,this),(o=new google.maps.places.Autocomplete(this.$search()[0],c)).bindTo("bounds",a)}this.addMapEvents(this,a,s,o),a.acf=this,a.marker=s,a.autocomplete=o,this.map=a,acf.doAction("google_map_init",a,s,this);var l=this.getValue();this.renderVal(l)},addMapEvents:function(n,t,e,i){google.maps.event.addListener(t,"click",function(t){var e=t.latLng.lat(),i=t.latLng.lng();n.searchPosition(e,i)}),google.maps.event.addListener(e,"dragend",function(){var t=this.getPosition(),e=t.lat(),i=t.lng();n.searchPosition(e,i)}),i&&google.maps.event.addListener(i,"place_changed",function(){var t=this.getPlace();t.address=n.getSearchVal(),n.setPlace(t)})},searchPosition:function(n,a){var t=this.newLatLng(n,a),r=this.$control();this.setPosition(n,a),r.addClass("-loading");var e=s.proxy(function(t,e){r.removeClass("-loading");var i="";e!=google.maps.GeocoderStatus.OK?console.log("Geocoder failed due to: "+e):t[0]?i=t[0].formatted_address:console.log("No results found"),this.val({lat:n,lng:a,address:i})},this);o.geocoder.geocode({latLng:t},e)},setPlace:function(t){if(!t)return this;if(t.name&&!t.geometry)return this.searchAddress(t.name),this;var e=t.geometry.location.lat(),i=t.geometry.location.lng(),n=t.address||t.formatted_address;return this.setValue({lat:e,lng:i,address:n}),this},searchAddress:function(a){var t=a.split(",");if(2==t.length){var e=t[0],i=t[1];if(s.isNumeric(e)&&s.isNumeric(i))return this.searchPosition(e,i)}var r=this.$control();r.addClass("-loading");var n=this.proxy(function(t,e){r.removeClass("-loading");var i="",n="";e!=google.maps.GeocoderStatus.OK?console.log("Geocoder failed due to: "+e):t[0]?(i=t[0].geometry.location.lat(),n=t[0].geometry.location.lng()):console.log("No results found"),this.val({lat:i,lng:n,address:a})});o.geocoder.geocode({address:a},n)},searchLocation:function(){if(!navigator.geolocation)return alert(acf.__("Sorry, this browser does not support geolocation"));var a=this.$control();a.addClass("-loading");var t=s.proxy(function(t,e){a.removeClass("-loading");var i=t.coords.latitude,n=t.coords.longitude;this.searchPosition(i,n)},this),e=function(t){a.removeClass("-loading")};navigator.geolocation.getCurrentPosition(t,e)},onClickClear:function(t,e){this.val(!1)},onClickLocate:function(t,e){this.searchLocation()},onClickSearch:function(t,e){this.searchAddress(this.$search().val())},onFocusSearch:function(t,e){this.removeClass("-value"),this.onKeyupSearch.apply(this,arguments)},onBlurSearch:function(t,e){this.setTimeout(function(){this.removeClass("-search"),e.val()&&this.addClass("-value")},100)},onKeyupSearch:function(t,e){e.val()?this.addClass("-search"):this.removeClass("-search")},onKeydownSearch:function(t,e){13==t.which&&t.preventDefault()},onMousedown:function(){},onShow:function(){if(!this.map)return!1;this.setTimeout(this.center,10)}});acf.registerFieldType(e);var o=new acf.Model({geocoder:!1,data:{status:!1},getStatus:function(){return this.get("status")},setStatus:function(t){return this.set("status",t)},isReady:function(){if("ready"==this.getStatus())return!0;if("loading"==this.getStatus())return!1;if(acf.isset(window,"google","maps","places"))return this.setStatus("ready"),!0;var t=acf.get("google_map_api");return t&&(this.setStatus("loading"),s.ajax({url:t,dataType:"script",cache:!0,context:this,success:function(){this.setStatus("ready"),this.geocoder=new google.maps.Geocoder,acf.doAction("google_map_api_loaded")}})),!1},ready:function(t,e){acf.addAction("google_map_api_loaded",t,10,e)}})}(jQuery),function(n,i){var t=acf.Field.extend({type:"image",$control:function(){return this.$(".acf-image-uploader")},$input:function(){return this.$('input[type="hidden"]')},events:{'click a[data-name="add"]':"onClickAdd",'click a[data-name="edit"]':"onClickEdit",'click a[data-name="remove"]':"onClickRemove",'change input[type="file"]':"onChange"},initialize:function(){"basic"===this.get("uploader")&&this.$el.closest("form").attr("enctype","multipart/form-data")},validateAttachment:function(t){(t=t||{}).id!==i&&(t=t.attributes),t=acf.parseArgs(t,{url:"",alt:"",title:"",caption:"",description:"",width:0,height:0});var e=acf.isget(t,"sizes",this.get("preview_size"),"url");return null!==e&&(t.url=e),t},render:function(t){t=this.validateAttachment(t),this.$("img").attr({src:t.url,alt:t.alt,title:t.title});var e=t.id||"";this.val(e),e?this.$control().addClass("has-value"):this.$control().removeClass("has-value")},append:function(t,e){var i=function(t,e){for(var i=acf.getFields({key:t.get("key"),parent:e.$el}),n=0;n
          '):this.$el=a('
            '),i.before(this.$el),this.set("index",r,!0),r++},initializeTabs:function(){var t=this.getVisible().shift(),e,i,n=(acf.getPreference("this.tabs")||[])[this.get("index")];this.tabs[n]&&this.tabs[n].isVisible()&&(t=this.tabs[n]),t?this.selectTab(t):this.closeTabs(),this.set("initialized",!0)},getVisible:function(){return this.tabs.filter(function(t){return t.isVisible()})},getActive:function(){return this.active},setActive:function(t){return this.active=t},hasActive:function(){return!1!==this.active},isActive:function(t){var e=this.getActive();return e&&e.cid===t.cid},closeActive:function(){this.hasActive()&&this.closeTab(this.getActive())},openTab:function(t){this.closeActive(),t.open(),this.setActive(t)},closeTab:function(t){t.close(),this.setActive(!1)},closeTabs:function(){this.tabs.map(this.closeTab,this)},selectTab:function(e){this.tabs.map(function(t){e.cid!==t.cid&&this.closeTab(t)},this),this.openTab(e)},addTab:function(t,e){var i=a("
          • ");i.append(t),this.$("ul").append(i);var n=new s({$el:i,field:e,group:this});return this.tabs.push(n),n},reset:function(){return this.closeActive(),this.refresh()},refresh:function(){if(this.hasActive())return!1;var t=this.getVisible().shift();return t&&this.openTab(t),t},onRefresh:function(){if("left"===this.get("placement")){var t=this.$el.parent(),e=this.$el.children("ul"),i=t.is("td")?"height":"min-height",n=e.position().top+e.outerHeight(!0)-1;t.css(i,n)}}}),s=acf.Model.extend({group:!1,field:!1,events:{"click a":"onClick"},index:function(){return this.$el.index()},isVisible:function(){return acf.isVisible(this.$el)},isActive:function(){return this.$el.hasClass("active")},open:function(){this.$el.addClass("active"),this.field.showFields()},close:function(){this.$el.removeClass("active"),this.field.hideFields()},onClick:function(t,e){t.preventDefault(),this.toggle()},toggle:function(){this.isActive()||this.group.openTab(this)}}),o=new acf.Model({priority:50,actions:{prepare:"render",append:"render",unload:"onUnload",invalid_field:"onInvalidField"},findTabs:function(){return a(".acf-tab-wrap")},getTabs:function(){return acf.getInstances(this.findTabs())},render:function(t){this.getTabs().map(function(t){t.get("initialized")||t.initializeTabs()})},onInvalidField:function(t){this.busy||t.hiddenByTab&&(t.hiddenByTab.toggle(),this.busy=!0,this.setTimeout(function(){this.busy=!1},100))},onUnload:function(){var i=[];this.getTabs().map(function(t){var e=t.hasActive()?t.getActive().index():0;i.push(e)}),i.length&&acf.setPreference("this.tabs",i)}})}(jQuery),function(t,e){var i=acf.models.SelectField.extend({type:"post_object"});acf.registerFieldType(i)}(jQuery),function(t,e){var i=acf.models.SelectField.extend({type:"page_link"});acf.registerFieldType(i)}(jQuery),function(t,e){var i=acf.models.SelectField.extend({type:"user"});acf.registerFieldType(i)}(jQuery),function(g,t){var e=acf.Field.extend({type:"taxonomy",data:{ftype:"select"},select2:!1,wait:"load",events:{'click a[data-name="add"]':"onClickAdd",'click input[type="radio"]':"onClickRadio"},$control:function(){return this.$(".acf-taxonomy-field")},$input:function(){return this.getRelatedPrototype().$input.apply(this,arguments)},getRelatedType:function(){var t=this.get("ftype");return"multi_select"==t&&(t="select"),t},getRelatedPrototype:function(){return acf.getFieldType(this.getRelatedType()).prototype},getValue:function(){return this.getRelatedPrototype().getValue.apply(this,arguments)},setValue:function(){return this.getRelatedPrototype().setValue.apply(this,arguments)},initialize:function(){this.getRelatedPrototype().initialize.apply(this,arguments)},onRemove:function(){this.select2&&this.select2.destroy()},onClickAdd:function(t,e){var n=this,i=!1,a=!1,r=!1,s=!1,o=!1,c=!1,l=!1,u=function(){i=acf.newPopup({title:e.attr("title"),loading:!0,width:"300px"});var t={action:"acf/fields/taxonomy/add_term",field_key:n.get("key")};g.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(t),type:"post",dataType:"html",success:d})},d=function(t){i.loading(!1),i.content(t),a=i.$("form"),r=i.$('input[name="term_name"]'),s=i.$('select[name="term_parent"]'),o=i.$(".acf-submit-button"),r.focus(),i.on("submit","form",f)},f=function(t,e){if(t.preventDefault(),t.stopImmediatePropagation(),""===r.val())return r.focus(),!1;acf.startButtonLoading(o);var i={action:"acf/fields/taxonomy/add_term",field_key:n.get("key"),term_name:r.val(),term_parent:s.length?s.val():0};g.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(i),type:"post", +dataType:"json",success:h})},h=function(t){acf.stopButtonLoading(o),l&&l.remove(),l=acf.isAjaxSuccess(t)?(r.val(""),p(t.data),acf.newNotice({type:"success",text:acf.getAjaxMessage(t),target:a,timeout:2e3,dismiss:!1})):acf.newNotice({type:"error",text:acf.getAjaxError(t),target:a,timeout:2e3,dismiss:!1}),r.focus()},p=function(e){var t=g('"),i;e.term_parent?s.children('option[value="'+e.term_parent+'"]').after(t):s.append(t),acf.getFields({type:"taxonomy"}).map(function(t){t.get("taxonomy")==n.get("taxonomy")&&t.appendTerm(e)}),n.selectTerm(e.term_id)};u()},appendTerm:function(t){"select"==this.getRelatedType()?this.appendTermSelect(t):this.appendTermCheckbox(t)},appendTermSelect:function(t){this.select2.addOption({id:t.term_id,text:t.term_label})},appendTermCheckbox:function(t){var e=this.$("[name]:first").attr("name"),i=this.$("ul:first");"checkbox"==this.getRelatedType()&&(e+="[]");var n=g(['
          • ',"","
          • "].join(""));if(t.term_parent){var a=i.find('li[data-id="'+t.term_parent+'"]');(i=a.children("ul")).exists()||(i=g('
              '),a.append(i))}i.append(n)},selectTerm:function(t){var e;"select"==this.getRelatedType()?this.select2.selectOption(t):this.$('input[value="'+t+'"]').prop("checked",!0).trigger("change")},onClickRadio:function(t,e){var i=e.parent("label"),n=i.hasClass("selected");this.$(".selected").removeClass("selected"),i.addClass("selected"),this.get("allow_null")&&n&&(i.removeClass("selected"),e.prop("checked",!1).trigger("change"))}});acf.registerFieldType(e)}(jQuery),function(i,t){var e=acf.models.DatePickerField.extend({type:"time_picker",$control:function(){return this.$(".acf-time-picker")},initialize:function(){var t=this.$input(),e=this.$inputText(),i={timeFormat:this.get("time_format"),altField:t,altFieldTimeOnly:!1,altTimeFormat:"HH:mm:ss",showButtonPanel:!0,controlType:"select",oneLine:!0,closeText:acf.get("dateTimePickerL10n").selectText,timeOnly:!0,onClose:function(t,e,i){var n=e.dpDiv.find(".ui-datepicker-close");!t&&n.is(":hover")&&i._updateDateTime()}};i=acf.applyFilters("time_picker_args",i,this),acf.newTimePicker(e,i),acf.doAction("time_picker_init",e,i,this)}});acf.registerFieldType(e),acf.newTimePicker=function(t,e){if(void 0===i.timepicker)return!1;e=e||{},t.timepicker(e),i("body > #ui-datepicker-div").exists()&&i("body > #ui-datepicker-div").wrap('
              ')}}(jQuery),function(t,e){var i=acf.Field.extend({type:"true_false",events:{"change .acf-switch-input":"onChange","focus .acf-switch-input":"onFocus","blur .acf-switch-input":"onBlur","keypress .acf-switch-input":"onKeypress"},$input:function(){return this.$('input[type="checkbox"]')},$switch:function(){return this.$(".acf-switch")},getValue:function(){return this.$input().prop("checked")?1:0},initialize:function(){this.render()},render:function(){var t=this.$switch();if(t.length){var e=t.children(".acf-switch-on"),i=t.children(".acf-switch-off"),n=Math.max(e.width(),i.width());n&&(e.css("min-width",n),i.css("min-width",n))}},switchOn:function(){this.$input().prop("checked",!0),this.$switch().addClass("-on")},switchOff:function(){this.$input().prop("checked",!1),this.$switch().removeClass("-on")},onChange:function(t,e){e.prop("checked")?this.switchOn():this.switchOff()},onFocus:function(t,e){this.$switch().addClass("-focus")},onBlur:function(t,e){this.$switch().removeClass("-focus")},onKeypress:function(t,e){return 37===t.keyCode?this.switchOff():39===t.keyCode?this.switchOn():void 0}});acf.registerFieldType(i)}(jQuery),function(t,e){var i=acf.Field.extend({type:"url",events:{'keyup input[type="url"]':"onkeyup"},$control:function(){return this.$(".acf-input-wrap")},$input:function(){return this.$('input[type="url"]')},initialize:function(){this.render()},isValid:function(){var t=this.val();return!!t&&(-1!==t.indexOf("://")||0===t.indexOf("//"))},render:function(){this.isValid()?this.$control().addClass("-valid"):this.$control().removeClass("-valid")},onkeyup:function(t,e){this.render()}});acf.registerFieldType(i)}(jQuery),function(t,e){var i=acf.Field.extend({type:"wysiwyg",wait:"load",events:{"mousedown .acf-editor-wrap.delay":"onMousedown",sortstartField:"disableEditor",sortstopField:"enableEditor",removeField:"disableEditor"},$control:function(){return this.$(".acf-editor-wrap")},$input:function(){return this.$("textarea")},getMode:function(){return this.$control().hasClass("tmce-active")?"visual":"text"},initialize:function(){this.$control().hasClass("delay")||this.initializeEditor()},initializeEditor:function(){var t=this.$control(),e=this.$input(),i={tinymce:!0,quicktags:!0,toolbar:this.get("toolbar"),mode:this.getMode(),field:this},n=e.attr("id"),a=acf.uniqueId("acf-editor-"),r=e.data();acf.rename({target:t,search:n,replace:a,destructive:!0}),this.set("id",a,!0),acf.tinymce.initialize(a,i),this.$input().data(r)},onMousedown:function(t){t.preventDefault();var e=this.$control();e.removeClass("delay"),e.find(".acf-editor-toolbar").remove(),this.initializeEditor()},enableEditor:function(){"visual"==this.getMode()&&acf.tinymce.enable(this.get("id"))},disableEditor:function(){acf.tinymce.destroy(this.get("id"))}});acf.registerFieldType(i)}(jQuery),function(e,t){var s=[];acf.Condition=acf.Model.extend({type:"",operator:"==",label:"",choiceType:"input",fieldTypes:[],data:{conditions:!1,field:!1,rule:{}},events:{change:"change",keyup:"change",enableField:"change",disableField:"change"},setup:function(t){e.extend(this.data,t)},getEventTarget:function(t,e){return t||this.get("field").$el},change:function(t,e){this.get("conditions").change(t)},match:function(t,e){return!1},calculate:function(){return this.match(this.get("rule"),this.get("field"))},choices:function(t){return''}}),acf.newCondition=function(t,e){var i=e.get("field"),n=i.getField(t.field);if(!i||!n)return!1;var a={rule:t,target:i,conditions:e,field:n},r=n.get("type"),s=t.operator,o,c,l;return new(acf.getConditionTypes({fieldType:r,operator:s})[0]||acf.Condition)(a)};var a=function(t){return acf.strPascalCase(t||"")+"Condition"};acf.registerConditionType=function(t){var e,i=t.prototype.type,n=a(i);acf.models[n]=t,s.push(i)},acf.getConditionType=function(t){var e=a(t);return acf.models[e]||!1},acf.registerConditionForFieldType=function(t,e){var i=acf.getConditionType(t);i&&i.prototype.fieldTypes.push(e)},acf.getConditionTypes=function(a){a=acf.parseArgs(a,{fieldType:"",operator:""});var r=[];return s.map(function(t){var e=acf.getConditionType(t),i=e.prototype.fieldTypes,n=e.prototype.operator;a.fieldType&&-1===i.indexOf(a.fieldType)||a.operator&&n!==a.operator||r.push(e)}),r}}(jQuery),function(t,e){var i="conditional_logic",n=new acf.Model({id:"conditionsManager",priority:20,actions:{new_field:"onNewField"},onNewField:function(t){t.has("conditions")&&t.getConditions().render()}}),a=function(t,e){var i=acf.getFields({key:e,sibling:t.$el,suppressFilters:!0});return i.length||(i=acf.getFields({key:e,parent:t.$el.parent(),suppressFilters:!0})),!!i.length&&i[0]};acf.Field.prototype.getField=function(t){var e=a(this,t);if(e)return e;for(var i=this.parents(),n=0;nparseFloat(e)},c=function(t,e){return parseFloat(t)'}});acf.registerConditionType(f);var e=f.extend({type:"hasNoValue",operator:"==empty",label:a("Has no value"),match:function(t,e){return!f.prototype.match.apply(this,arguments)}});acf.registerConditionType(e);var h=acf.Condition.extend({type:"equalTo",operator:"==",label:a("Value is equal to"),fieldTypes:["text","textarea","number","range","email","url","password"],match:function(t,e){return n.isNumeric(t.value)?i(t.value,e.val()):s(t.value,e.val())},choices:function(t){return''}});acf.registerConditionType(h);var p=h.extend({type:"notEqualTo",operator:"!=",label:a("Value is not equal to"),match:function(t,e){return!h.prototype.match.apply(this,arguments)}});acf.registerConditionType(p);var g=acf.Condition.extend({type:"patternMatch",operator:"==pattern",label:a("Value matches pattern"),fieldTypes:["text","textarea","email","url","password","wysiwyg"],match:function(t,e){return d(e.val(),t.value)},choices:function(t){return''}});acf.registerConditionType(g);var m=acf.Condition.extend({type:"contains",operator:"==contains",label:a("Value contains"),fieldTypes:["text","textarea","number","email","url","password","wysiwyg","oembed","select"],match:function(t,e){return u(e.val(),t.value)},choices:function(t){return''}});acf.registerConditionType(m);var v=h.extend({type:"trueFalseEqualTo",choiceType:"select",fieldTypes:["true_false"],choices:function(t){return[{id:1,text:a("Checked")}]}});acf.registerConditionType(v);var y=p.extend({type:"trueFalseNotEqualTo",choiceType:"select",fieldTypes:["true_false"],choices:function(t){return[{id:1,text:a("Checked")}]}});acf.registerConditionType(y);var b=acf.Condition.extend({type:"selectEqualTo",operator:"==",label:a("Value is equal to"),fieldTypes:["select","checkbox","radio","button_group"],match:function(t,e){var i=e.val();return i instanceof Array?l(t.value,i):s(t.value,i)},choices:function(t){var e=[],i=t.$setting("choices textarea").val().split("\n");return t.$input("allow_null").prop("checked")&&e.push({id:"",text:a("Null")}),i.map(function(t){(t=t.split(":"))[1]=t[1]||t[0],e.push({id:n.trim(t[0]),text:n.trim(t[1])})}),e}});acf.registerConditionType(b);var x=b.extend({type:"selectNotEqualTo",operator:"!=",label:a("Value is not equal to"),match:function(t,e){return!b.prototype.match.apply(this,arguments)}});acf.registerConditionType(x);var w=acf.Condition.extend({type:"greaterThan",operator:">",label:a("Value is greater than"),fieldTypes:["number","range"],match:function(t,e){var i=e.val();return i instanceof Array&&(i=i.length),o(i,t.value)},choices:function(t){return''}});acf.registerConditionType(w);var _=w.extend({type:"lessThan",operator:"<",label:a("Value is less than"),match:function(t,e){var i=e.val();return i instanceof Array&&(i=i.length),c(i,t.value)},choices:function(t){return''}});acf.registerConditionType(_);var $=w.extend({type:"selectionGreaterThan",label:a("Selection is greater than"),fieldTypes:["checkbox","select","post_object","page_link","relationship","taxonomy","user"]});acf.registerConditionType($);var k=_.extend({type:"selectionLessThan",label:a("Selection is less than"),fieldTypes:["checkbox","select","post_object","page_link","relationship","taxonomy","user"]});acf.registerConditionType(k)}(jQuery),function(s,n){acf.newMediaPopup=function(t){var e=null,t=acf.parseArgs(t,{mode:"select",title:"",button:"",type:"",field:!1,allowedTypes:"",library:"all",multiple:!1,attachment:0,autoOpen:!0,open:function(){},select:function(){},close:function(){}});return e="edit"==t.mode?new acf.models.EditMediaPopup(t):new acf.models.SelectMediaPopup(t),t.autoOpen&&setTimeout(function(){e.open()},1),acf.doAction("new_media_popup",e),e};var e=function(){var t=acf.get("post_id");return s.isNumeric(t)?t:0};acf.getMimeTypes=function(){return this.get("mimeTypes")},acf.getMimeType=function(t){var e=acf.getMimeTypes();if(e[t]!==n)return e[t];for(var i in e)if(-1!==i.indexOf(t))return e[i];return!1};var i=acf.Model.extend({id:"MediaPopup",data:{},defaults:{},frame:!1,setup:function(t){s.extend(this.data,t)},initialize:function(){var t=this.getFrameOptions();this.addFrameStates(t);var e=wp.media(t);(e.acf=this).addFrameEvents(e,t),this.frame=e},open:function(){this.frame.open()},close:function(){this.frame.close()},remove:function(){this.frame.detach(),this.frame.remove()},getFrameOptions:function(){var t={title:this.get("title"),multiple:this.get("multiple"),library:{},states:[]};return this.get("type")&&(t.library.type=this.get("type")),"uploadedTo"===this.get("library")&&(t.library.uploadedTo=e()),this.get("attachment")&&(t.library.post__in=[this.get("attachment")]),this.get("button")&&(t.button={text:this.get("button")}),t},addFrameStates:function(t){var e=wp.media.query(t.library);this.get("field")&&acf.isset(e,"mirroring","args")&&(e.mirroring.args._acfuploader=this.get("field")),t.states.push(new wp.media.controller.Library({library:e,multiple:this.get("multiple"),title:this.get("title"),priority:20,filterable:"all",editable:!0,allowLocalEdits:!0})),acf.isset(wp,"media","controller","EditImage")&&t.states.push(new wp.media.controller.EditImage)},addFrameEvents:function(i,t){i.on("open",function(){this.$el.closest(".media-modal").addClass("acf-media-modal -"+this.acf.get("mode"))},i),i.on("content:render:edit-image",function(){var t=this.state().get("image"),e=new wp.media.view.EditImage({model:t,controller:this}).render();this.content.set(e),e.loadEditor()},i),i.on("select",function(){var t=i.state().get("selection");t&&t.each(function(t,e){i.acf.get("select").apply(i.acf,[t,e])})}),i.on("close",function(){setTimeout(function(){i.acf.get("close").apply(i.acf),i.acf.remove()},1)})}});acf.models.SelectMediaPopup=i.extend({id:"SelectMediaPopup",setup:function(t){t.button||(t.button=acf._x("Select","verb")),i.prototype.setup.apply(this,arguments)},addFrameEvents:function(e,t){acf.isset(_wpPluploadSettings,"defaults","multipart_params")&&(_wpPluploadSettings.defaults.multipart_params._acfuploader=this.get("field"),e.on("open",function(){delete _wpPluploadSettings.defaults.multipart_params._acfuploader})),e.on("content:activate:browse",function(){var t=!1;try{t=e.content.get().toolbar}catch(t){return void console.log(t)}e.acf.customizeFilters.apply(e.acf,[t])}),i.prototype.addFrameEvents.apply(this,arguments)},customizeFilters:function(t){var n=t.get("filters"),e;("image"==this.get("type")&&(n.filters.all.text=acf.__("All images"),delete n.filters.audio,delete n.filters.video,delete n.filters.image,s.each(n.filters,function(t,e){e.props.type=e.props.type||"image"})),this.get("allowedTypes"))&&this.get("allowedTypes").split(" ").join("").split(".").join("").split(",").map(function(t){var e=acf.getMimeType(t);if(e){var i={text:e,props:{status:null,type:e,uploadedTo:null,orderby:"date",order:"DESC"},priority:20};n.filters[e]=i}});if("uploadedTo"===this.get("library")){var i=this.frame.options.library.uploadedTo;delete n.filters.unattached,delete n.filters.uploaded,s.each(n.filters,function(t,e){e.text+=" ("+acf.__("Uploaded to this post")+")",e.props.uploadedTo=i})}var a=this.get("field"),r;s.each(n.filters,function(t,e){e.props._acfuploader=a}),t.get("search").model.attributes._acfuploader=a,n.renderFilters&&n.renderFilters()}}),acf.models.EditMediaPopup=i.extend({id:"SelectMediaPopup",setup:function(t){t.button||(t.button=acf._x("Update","verb")),i.prototype.setup.apply(this,arguments)},addFrameEvents:function(n,t){n.on("open",function(){this.$el.closest(".media-modal").addClass("acf-expanded"),"browse"!=this.content.mode()&&this.content.mode("browse");var t,e=this.state().get("selection"),i=wp.media.attachment(n.acf.get("attachment"));e.add(i)},n),i.prototype.addFrameEvents.apply(this,arguments)}});var t=new acf.Model({id:"customizePrototypes",wait:"ready",initialize:function(){if(acf.isset(window,"wp","media","view")){var t=e();t&&acf.isset(wp,"media","view","settings","post")&&(wp.media.view.settings.post.id=t),this.customizeAttachmentsRouter(),this.customizeAttachmentFilters(),this.customizeAttachmentCompat(),this.customizeAttachmentLibrary()}},customizeAttachmentsRouter:function(){if(acf.isset(wp,"media","view","Router")){var t=wp.media.view.Router;wp.media.view.Router=t.extend({addExpand:function(){var t=s(['',''+acf.__("Expand Details")+"",''+acf.__("Collapse Details")+"",""].join(""));t.on("click",function(t){t.preventDefault();var e=s(this).closest(".media-modal");e.hasClass("acf-expanded")?e.removeClass("acf-expanded"):e.addClass("acf-expanded")}),this.$el.append(t)},initialize:function(){return t.prototype.initialize.apply(this,arguments),this.addExpand(),this}})}},customizeAttachmentFilters:function(){var t;acf.isset(wp,"media","view","AttachmentFilters","All")&&(wp.media.view.AttachmentFilters.All.prototype.renderFilters=function(){this.$el.html(_.chain(this.filters).map(function(t,e){return{el:s("").val(e).html(t.text)[0],priority:t.priority||50}},this).sortBy("priority").pluck("el").value())})},customizeAttachmentCompat:function(){if(acf.isset(wp,"media","view","AttachmentCompat")){var t=wp.media.view.AttachmentCompat,e=!1;wp.media.view.AttachmentCompat=t.extend({render:function(){return this.rendered?this:(t.prototype.render.apply(this,arguments),this.$("#acf-form-data").length&&(clearTimeout(e),e=setTimeout(s.proxy(function(){this.rendered=!0,acf.doAction("append",this.$el)},this),50)),this)},save:function(t){var e={};t&&t.preventDefault(),e=acf.serializeForAjax(this.$el),this.controller.trigger("attachment:compat:waiting",["waiting"]),this.model.saveCompat(e).always(_.bind(this.postSave,this))}})}},customizeAttachmentLibrary:function(){if(acf.isset(wp,"media","view","Attachment","Library")){var l=wp.media.view.Attachment.Library;wp.media.view.Attachment.Library=l.extend({render:function(){var t=acf.isget(this,"controller","acf"),e=acf.isget(this,"model","attributes");if(t&&e){e.acf_errors&&this.$el.addClass("acf-disabled");var i=t.get("selected");i&&-1',''+acf.__("Restricted")+"",''+c+"",''+s+"","
              "].join("")),i.reset(),void i.single(n)}return l.prototype.toggleSelection.apply(this,arguments)}})}}})}(jQuery),function(h,n){acf.screen=new acf.Model({active:!0,xhr:!1,timeout:!1,wait:"load",events:{"change #page_template":"onChange","change #parent_id":"onChange","change #post-formats-select":"onChange","change .categorychecklist":"onChange","change .tagsdiv":"onChange",'change .acf-taxonomy-field[data-save="1"]':"onChange","change #product-type":"onChange"},isPost:function(){return"post"===acf.get("screen")},isUser:function(){return"user"===acf.get("screen")},isTaxonomy:function(){return"taxonomy"===acf.get("screen")},isAttachment:function(){return"attachment"===acf.get("screen")},isNavMenu:function(){return"nav_menu"===acf.get("screen")},isWidget:function(){return"widget"===acf.get("screen")},isComment:function(){return"comment"===acf.get("screen")},getPageTemplate:function(){var t=h("#page_template");return t.length?t.val():null},getPageParent:function(t,e){var e;return(e=h("#parent_id")).length?e.val():null},getPageType:function(t,e){return this.getPageParent()?"child":"parent"},getPostType:function(){return h("#post_type").val()},getPostFormat:function(t,e){var e;if((e=h("#post-formats-select input:checked")).length){var i=e.val();return"0"==i?"standard":i}return null},getPostCoreTerms:function(){var t={},e=acf.serialize(h(".categorydiv, .tagsdiv"));for(var i in e.tax_input&&(t=e.tax_input),e.post_category&&(t.category=e.post_category),t)acf.isArray(t[i])||(t[i]=t[i].split(", "));return t},getPostTerms:function(){var n=this.getPostCoreTerms();for(var t in acf.getFields({type:"taxonomy"}).map(function(t){if(t.get("save")){var e=t.val(),i=t.get("taxonomy");e&&(n[i]=n[i]||[],e=acf.isArray(e)?e:[e],n[i]=n[i].concat(e))}}),null!==(productType=this.getProductType())&&(n.product_type=[productType]),n)n[t]=acf.uniqueArray(n[t]);return n},getProductType:function(){var t=h("#product-type");return t.length?t.val():null},check:function(){if("post"===acf.get("screen")){this.xhr&&this.xhr.abort();var e=acf.parseArgs(this.data,{action:"acf/ajax/check_screen",screen:acf.get("screen"),exists:[]});this.isPost()&&(e.post_id=acf.get("post_id")),null!==(postType=this.getPostType())&&(e.post_type=postType),null!==(pageTemplate=this.getPageTemplate())&&(e.page_template=pageTemplate),null!==(pageParent=this.getPageParent())&&(e.page_parent=pageParent),null!==(pageType=this.getPageType())&&(e.page_type=pageType),null!==(postFormat=this.getPostFormat())&&(e.post_format=postFormat),null!==(postTerms=this.getPostTerms())&&(e.post_terms=postTerms),acf.getPostboxes().map(function(t){e.exists.push(t.get("key"))}),e=acf.applyFilters("check_screen_args",e);var t=function(t){acf.isAjaxSuccess(t)&&("post"==acf.get("screen")?this.renderPostScreen(t.data):"user"==acf.get("screen")&&this.renderUserScreen(t.data)),acf.doAction("check_screen_complete",t.data,e)};this.xhr=h.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(e),type:"post",dataType:"json",context:this,success:t})}},onChange:function(t,e){this.setTimeout(this.check,1)},renderPostScreen:function(l){var u=[],d=function(t,e){var i=h._data(t[0]).events;for(var n in i)for(var a=0;a','",'

              ',""+e.title+"","

              ",'
              ',e.html,"
              ",""].join(""));if(h("#adv-settings").length){var a=h("#adv-settings .metabox-prefs"),r=h(['"].join(""));d(a.find("input").first(),r.find("input")),a.append(r)}"side"===e.position?h("#"+e.position+"-sortables").append(n):h("#"+e.position+"-sortables").prepend(n);var s=[];if(l.results.map(function(t){e.position===t.position&&h("#"+e.position+"-sortables #"+t.id).length&&s.push(t.id)}),f(e.id,s),l.sorted)for(var o in l.sorted){var s=l.sorted[o].split(",");if(f(e.id,s))break}var c=h("#submitdiv");h("#submitdiv").length&&(d(c.children(".handlediv"),n.children(".handlediv")),d(c.children(".hndle"),n.children(".hndle"))),i=acf.newPostbox(e),acf.doAction("append",n),acf.doAction("append_postbox",i)}i.showEnable(),acf.doAction("show_postbox",i),u.push(e.id)}),acf.getPostboxes().map(function(t){-1===u.indexOf(t.get("id"))&&(t.hideDisable(),acf.doAction("hide_postbox",t))}),h("#acf-style").html(l.style)},renderUserScreen:function(t){}});var t=new acf.Model({wait:"load",initialize:function(){acf.isGutenberg()&&(wp.data.subscribe(this.proxy(this.onChange)),acf.screen.getPageTemplate=this.getPageTemplate,acf.screen.getPageParent=this.getPageParent,acf.screen.getPostType=this.getPostType,acf.screen.getPostFormat=this.getPostFormat,acf.screen.getPostCoreTerms=this.getPostCoreTerms,this.addAction("append_postbox",acf.screen.refreshAvailableMetaBoxesPerLocation))},onChange:function(){var e=wp.data.select("core/editor").getPostEdits(),i=["template","parent","format"],t;(wp.data.select("core").getTaxonomies()||[]).map(function(t){i.push(t.rest_base)}),(i=i.filter(this.proxy(function(t){return e[t]!==n&&e[t]!==this.get(t)}))).length&&this.triggerChange(e)},triggerChange:function(t){t!==n&&(this.data=t),acf.screen.check()},getPageTemplate:function(){return wp.data.select("core/editor").getEditedPostAttribute("template")},getPageParent:function(t,e){return wp.data.select("core/editor").getEditedPostAttribute("parent")},getPostType:function(){return wp.data.select("core/editor").getEditedPostAttribute("type")},getPostFormat:function(t,e){return wp.data.select("core/editor").getEditedPostAttribute("format")},getPostCoreTerms:function(){var i={},t;return(wp.data.select("core").getTaxonomies()||[]).map(function(t){var e=wp.data.select("core/editor").getEditedPostAttribute(t.rest_base);e&&(i[t.slug]=e)}),i}});acf.screen.refreshAvailableMetaBoxesPerLocation=function(){var e=wp.data.select("core/edit-post"),t=wp.data.dispatch("core/edit-post"),i={};e.getActiveMetaBoxLocations().map(function(t){i[t]=e.getMetaBoxesPerLocation(t)});var n=[];for(var a in i)n=n.concat(i[a].map(function(t){return t.id}));acf.getPostboxes().map(function(t){if(-1===n.indexOf(t.get("id"))){var e=t.$el.closest("form").attr("class").replace("metabox-location-","");i[e]=i[e]||[],i[e].push({id:t.get("id"),title:t.get("title")})}}),t.setAvailableMetaBoxesPerLocation(i)}}(jQuery),function(l,t){function a(){return acf.isset(window,"jQuery","fn","select2","amd")?4:!!acf.isset(window,"Select2")&&3}acf.newSelect2=function(t,e){if(e=acf.parseArgs(e,{allowNull:!1,placeholder:"",multiple:!1,field:!1,ajax:!1,ajaxAction:"",ajaxData:function(t){return t},ajaxResults:function(t){return t}}),4==a())var i=new r(t,e);else var i=new s(t,e);return acf.doAction("new_select2",i),i};var n=acf.Model.extend({setup:function(t,e){l.extend(this.data,e),this.$el=t},initialize:function(){},selectOption:function(t){var e=this.getOption(t);e.prop("selected")||e.prop("selected",!0).trigger("change")},unselectOption:function(t){var e=this.getOption(t);e.prop("selected")&&e.prop("selected",!1).trigger("change")},getOption:function(t){return this.$('option[value="'+t+'"]')},addOption:function(t){t=acf.parseArgs(t,{id:"",text:"",selected:!1});var e=this.getOption(t.id);return e.length||((e=l("")).html(t.text),e.attr("value",t.id),e.prop("selected",t.selected),this.$el.append(e)),e},getValue:function(){var e=[],t=this.$el.find("option:selected");return t.exists()&&(t=t.sort(function(t,e){return+t.getAttribute("data-i")-+e.getAttribute("data-i")})).each(function(){var t=l(this);e.push({$el:t,id:t.attr("value"),text:t.text()})}),e},mergeOptions:function(){},getChoices:function(){var i=function(t){var e=[];return t.children().each(function(){var t=l(this);t.is("optgroup")?e.push({text:t.attr("label"),children:i(t)}):e.push({id:t.attr("value"),text:t.text()})}),e};return i(this.$el)},decodeChoices:function(t){var e=function(t){return t.map(function(t){return t.text=acf.decode(t.text),t.children&&(t.children=e(t.children)),t}),t};return e(t)},getAjaxData:function(t){var e={action:this.get("ajaxAction"),s:t.term||"",paged:t.page||1},i=this.get("field");i&&(e.field_key=i.get("key"));var n=this.get("ajaxData");return n&&(e=n.apply(this,[e,t])),e=acf.applyFilters("select2_ajax_data",e,this.data,this.$el,i||!1,this),acf.prepareForAjax(e)},getAjaxResults:function(t,e){(t=acf.parseArgs(t,{results:!1,more:!1})).results&&(t.results=this.decodeChoices(t.results));var i=this.get("ajaxResults");return i&&(t=i.apply(this,[t,e])),t=acf.applyFilters("select2_ajax_results",t,e,this)},processAjaxResults:function(t,e){var t;return(t=this.getAjaxResults(t,e)).more&&(t.pagination={more:!0}),setTimeout(l.proxy(this.mergeOptions,this),1),t},destroy:function(){this.$el.data("select2")&&this.$el.select2("destroy"),this.$el.siblings(".select2-container").remove()}}),r=n.extend({initialize:function(){var e=this.$el,t={width:"100%",allowClear:this.get("allowNull"),placeholder:this.get("placeholder"),multiple:this.get("multiple"),data:[],escapeMarkup:function(t){return t}};t.multiple&&this.getValue().map(function(t){t.$el.detach().appendTo(e)}),e.removeData("ajax"),e.removeAttr("data-ajax"),this.get("ajax")&&(t.ajax={url:acf.get("ajaxurl"),delay:250,dataType:"json",type:"post",cache:!1,data:l.proxy(this.getAjaxData,this),processResults:l.proxy(this.processAjaxResults,this)});var i=this.get("field");t=acf.applyFilters("select2_args",t,e,this.data,i||!1,this),e.select2(t);var n=e.next(".select2-container");if(t.multiple){var a=n.find("ul");a.sortable({stop:function(t){a.find(".select2-selection__choice").each(function(){var t;l(l(this).data("data").element).detach().appendTo(e)}),e.trigger("change")}}),e.on("select2:select",this.proxy(function(t){this.getOption(t.params.data.id).detach().appendTo(this.$el)}))}n.addClass("-acf"),acf.doAction("select2_init",e,t,this.data,i||!1,this)},mergeOptions:function(){var i=!1,n=!1;l('.select2-results__option[role="group"]').each(function(){var t=l(this).children("ul"),e=l(this).children("strong");if(n&&n.text()===e.text())return i.append(t.children()),void l(this).remove();i=t,n=e})}}),s=n.extend({initialize:function(){var n=this.$el,i=this.getValue(),a=this.get("multiple"),t={width:"100%",allowClear:this.get("allowNull"),placeholder:this.get("placeholder"),separator:"||",multiple:this.get("multiple"),data:this.getChoices(),escapeMarkup:function(t){return t},dropdownCss:{"z-index":"999999999"},initSelection:function(t,e){e(a?i:i.shift())}},e=n.siblings("input");e.length||(e=l(''),n.before(e)),inputValue=i.map(function(t){return t.id}).join("||"),e.val(inputValue +),t.multiple&&i.map(function(t){t.$el.detach().appendTo(n)}),t.allowClear&&(t.data=t.data.filter(function(t){return""!==t.id})),n.removeData("ajax"),n.removeAttr("data-ajax"),this.get("ajax")&&(t.ajax={url:acf.get("ajaxurl"),quietMillis:250,dataType:"json",type:"post",cache:!1,data:l.proxy(this.getAjaxData,this),results:l.proxy(this.processAjaxResults,this)});var r=this.get("field");t=acf.applyFilters("select2_args",t,n,this.data,r||!1,this),e.select2(t);var s=e.select2("container"),o=l.proxy(this.getOption,this);if(t.multiple){var c=s.find("ul");c.sortable({stop:function(){c.find(".select2-search-choice").each(function(){var t=l(this).data("select2Data"),e;o(t.id).detach().appendTo(n)}),n.trigger("change")}})}e.on("select2-selecting",function(t){var e=t.choice,i=o(e.id);i.length||(i=l('")),i.detach().appendTo(n)}),s.addClass("-acf"),acf.doAction("select2_init",n,t,this.data,r||!1,this),e.on("change",function(){var t=e.val();t.indexOf("||")&&(t=t.split("||")),n.val(t).trigger("change")}),n.hide()},mergeOptions:function(){var i=!1,n=!1;l("#select2-drop .select2-result-with-children").each(function(){var t=l(this).children("ul"),e=l(this).children(".select2-result-label");if(n&&n.text()===e.text())return n.append(t.children()),void l(this).remove();i=t,n=e})},getAjaxData:function(t,e){var i={term:t,page:e};return n.prototype.getAjaxData.apply(this,[i])}}),e=new acf.Model({priority:5,wait:"prepare",initialize:function(){var t=acf.get("locale"),e=acf.get("rtl"),i=acf.get("select2L10n"),n=a();return!!i&&(0!==t.indexOf("en")&&void(4==n?this.addTranslations4():3==n&&this.addTranslations3()))},addTranslations4:function(){var i=acf.get("select2L10n"),t=acf.get("locale");t=t.replace("_","-");var e={errorLoading:function(){return i.load_fail},inputTooLong:function(t){var e=t.input.length-t.maximum;return 1'),t.addClass("acf-sortable-tr-helper"),t.children().each(function(){l(this).width(l(this).width())}),e.height(t.height()+"px"),t.removeClass("acf-sortable-tr-helper"))}}),n=new acf.Model({actions:{after_duplicate:"onAfterDuplicate"},onAfterDuplicate:function(t,e){var i=[];t.find("select").each(function(t){i.push(l(this).val())}),e.find("select").each(function(t){l(this).val(i[t])})}}),a=new acf.Model({id:"tableHelper",priority:20,actions:{refresh:"renderTables"},renderTables:function(t){var e=this;l(".acf-table:visible").each(function(){e.renderTable(l(this))})},renderTable:function(t){var e=t.find("> thead > tr:visible > th[data-key]"),r=t.find("> tbody > tr:visible > td[data-key]");if(!e.length||!r.length)return!1;e.each(function(t){var e=l(this),i=e.data("key"),n=r.filter('[data-key="'+i+'"]'),a=n.filter(".acf-hidden");n.removeClass("acf-empty"),n.length===a.length?acf.hide(e):(acf.show(e),a.addClass("acf-empty"))}),e.css("width","auto"),e=e.not(".acf-hidden");var i=100,n=e.length,a;e.filter("[data-width]").each(function(){var t=l(this).data("width");l(this).css("width",t+"%"),i-=t});var s=e.not("[data-width]");if(s.length){var o=i/s.length;s.css("width",o+"%"),i=0}0set( $class, $instance ); - - // Return instance. - return $instance; + global $acf_instances; + return $acf_instances[ $class ] = new $class(); } /** @@ -60,7 +35,11 @@ function acf_new_instance( $class = '' ) { * @return object The instance. */ function acf_get_instance( $class = '' ) { - return acf_instances()->get( $class ); + global $acf_instances; + if( !isset($acf_instances[ $class ]) ) { + $acf_instances[ $class ] = new $class(); + } + return $acf_instances[ $class ]; } /** @@ -75,16 +54,17 @@ function acf_get_instance( $class = '' ) { * @param array $data Array of data to start the store with. * @return ACF_Data */ - function acf_register_store( $name = '', $data = false ) { +function acf_register_store( $name = '', $data = false ) { - // Create store. - $store = new ACF_Data( $data ); - - // Register store. - acf_instances()->set( "ACF_Store_$name", $store ); - - // Return store. - return $store; + // Create store. + $store = new ACF_Data( $data ); + + // Register store. + global $acf_stores; + $acf_stores[ $name ] = $store; + + // Return store. + return $store; } /** @@ -99,6 +79,28 @@ function acf_get_instance( $class = '' ) { * @return ACF_Data */ function acf_get_store( $name = '' ) { - return acf_instances()->get( "ACF_Store_$name" ); + global $acf_stores; + return isset( $acf_stores[ $name ] ) ? $acf_stores[ $name ] : false; } - \ No newline at end of file + +/** + * acf_switch_stores + * + * Triggered when switching between sites on a multisite installation. + * + * @date 13/2/19 + * @since 5.7.11 + * + * @param int $site_id New blog ID. + * @param int prev_blog_id Prev blog ID. + * @return void + */ +function acf_switch_stores( $site_id, $prev_site_id ) { + + // Loop over stores and call switch_site(). + global $acf_stores; + foreach( $acf_stores as $store ) { + $store->switch_site( $site_id, $prev_site_id ); + } +} +add_action( 'switch_blog', 'acf_switch_stores', 10, 2 ); diff --git a/includes/acf-deprecated-functions.php b/includes/acf-deprecated-functions.php new file mode 100644 index 0000000..9a602f6 --- /dev/null +++ b/includes/acf-deprecated-functions.php @@ -0,0 +1,116 @@ + $parent_id, 'key' => "group_$parent_id" )); +} + +/** + * acf_update_option + * + * A wrapper for the WP update_option but provides logic for a 'no' autoload + * + * @date 4/01/2014 + * @since 5.0.0 + * @deprecated 5.7.11 + * + * @param string $option The option name. + * @param string $value The option value. + * @param string $autoload An optional autoload value. + * @return bool + */ +function acf_update_option( $option = '', $value = '', $autoload = null ) { + + // Warning. + _deprecated_function( __FUNCTION__, '5.7.11', 'update_option()' ); + + // Update. + if( $autoload === null ) { + $autoload = (bool) acf_get_setting('autoload'); + } + return update_option( $option, $value, $autoload ); +} + +/** + * acf_get_field_reference + * + * Finds the field key for a given field name and post_id. + * + * @date 26/1/18 + * @since 5.6.5 + * @deprecated 5.6.8 + * + * @param string $field_name The name of the field. eg 'sub_heading' + * @param mixed $post_id The post_id of which the value is saved against + * @return string $reference The field key + */ +function acf_get_field_reference( $field_name, $post_id ) { + + // Warning. + _deprecated_function( __FUNCTION__, '5.6.8', 'acf_get_reference()' ); + + // Return reference. + return acf_get_reference( $field_name, $post_id ); +} + + + + diff --git a/includes/acf-field-functions.php b/includes/acf-field-functions.php new file mode 100644 index 0000000..ea543e0 --- /dev/null +++ b/includes/acf-field-functions.php @@ -0,0 +1,1570 @@ +prop( 'multisite', true ); + +/** + * acf_get_field + * + * Retrieves a field for the given identifier. + * + * @date 17/1/19 + * @since 5.7.10 + * + * @param (int|string) $id The field ID, key or name. + * @return (array|false) The field array. + */ +function acf_get_field( $id = 0 ) { + + // Allow WP_Post to be passed. + if( is_object($id) ) { + $id = $id->ID; + } + + // Check store. + $store = acf_get_store( 'fields' ); + if( $store->has( $id ) ) { + return $store->get( $id ); + } + + // Check local fields first. + if( acf_is_local_field($id) ) { + $field = acf_get_local_field( $id ); + + // Then check database. + } else { + $field = acf_get_raw_field( $id ); + } + + // Bail early if no field. + if( !$field ) { + return false; + } + + // Validate field. + $field = acf_validate_field( $field ); + + // Set input prefix. + $field['prefix'] = 'acf'; + + /** + * Filters the $field array after it has been loaded. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array The field array. + */ + $field = apply_filters( "acf/load_field", $field ); + + // Store field using aliasses to also find via key, ID and name. + $store->set( $field['key'], $field ); + $store->alias( $field['key'], $field['ID'], $field['name'] ); + + // Return. + return $field; +} + +// Register variation. +acf_add_filter_variations( 'acf/load_field', array('type', 'name', 'key'), 0 ); + +/** + * acf_get_raw_field + * + * Retrieves raw field data for the given identifier. + * + * @date 18/1/19 + * @since 5.7.10 + * + * @param (int|string) $id The field ID, key or name. + * @return (array|false) The field array. + */ +function acf_get_raw_field( $id = 0 ) { + + // Get raw field from database. + $post = acf_get_field_post( $id ); + if( !$post ) { + return false; + } + + // Bail early if incorrect post type. + if( $post->post_type !== 'acf-field' ) { + return false; + } + + // Unserialize post_content. + $field = (array) maybe_unserialize( $post->post_content ); + + // update attributes + $field['ID'] = $post->ID; + $field['key'] = $post->post_name; + $field['label'] = $post->post_title; + $field['name'] = $post->post_excerpt; + $field['menu_order'] = $post->menu_order; + $field['parent'] = $post->post_parent; + + // Return field. + return $field; +} + +/** + * acf_get_field_post + * + * Retrieves the field's WP_Post object. + * + * @date 18/1/19 + * @since 5.7.10 + * + * @param (int|string) $id The field ID, key or name. + * @return (array|false) The field array. + */ +function acf_get_field_post( $id = 0 ) { + + // Get post if numeric. + if( is_numeric($id) ) { + return get_post( $id ); + + // Search posts if is string. + } elseif( is_string($id) ) { + + // Determine id type. + $type = acf_is_field_key($id) ? 'key' : 'name'; + + // Try cache. + $cache_key = acf_cache_key( "acf_get_field_post:$type:$id" ); + $post_id = wp_cache_get( $cache_key, 'acf' ); + if( $post_id === false ) { + + // Query posts. + $posts = get_posts(array( + 'posts_per_page' => 1, + 'post_type' => 'acf-field', + 'orderby' => 'menu_order title', + 'order' => 'ASC', + 'suppress_filters' => false, + 'cache_results' => true, + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + "acf_field_$type" => $id + )); + + // Update $post_id with a non false value. + $post_id = $posts ? $posts[0]->ID : 0; + + // Update cache. + wp_cache_set( $cache_key, $post_id, 'acf' ); + } + + // Check $post_id and return the post when possible. + if( $post_id ) { + return get_post( $post_id ); + } + } + + // Return false by default. + return false; +} + +/** + * acf_is_field_key + * + * Returns true if the given identifier is a field key. + * + * @date 6/12/2013 + * @since 5.0.0 + * + * @param string $id The identifier. + * @return bool + */ +function acf_is_field_key( $id = '' ) { + + // Check if $id is a string starting with "field_". + if( is_string($id) && substr($id, 0, 6) === 'field_' ) { + return true; + } + + /** + * Filters whether the $id is a field key. + * + * @date 23/1/19 + * @since 5.7.10 + * + * @param bool $bool The result. + * @param string $id The identifier. + */ + return apply_filters( 'acf/is_field_key', false, $id ); +} + +/** + * acf_validate_field + * + * Ensures the given field valid. + * + * @date 18/1/19 + * @since 5.7.10 + * + * @param array $field The field array. + * @return array + */ +function acf_validate_field( $field = array() ) { + + // Bail early if already valid. + if( is_array($field) && !empty($field['_valid']) ) { + return $field; + } + + // Apply defaults. + $field = wp_parse_args($field, array( + 'ID' => 0, + 'key' => '', + 'label' => '', + 'name' => '', + 'prefix' => '', + 'type' => 'text', + 'value' => null, + 'menu_order' => 0, + 'instructions' => '', + 'required' => false, + 'id' => '', + 'class' => '', + 'conditional_logic' => false, + 'parent' => 0, + 'wrapper' => array() + //'attributes' => array() + )); + + // Add backwards compatibility for wrapper attributes. + // Todo: Remove need for this. + $field['wrapper'] = wp_parse_args($field['wrapper'], array( + 'width' => '', + 'class' => '', + 'id' => '' + )); + + // Store backups. + $field['_name'] = $field['name']; + $field['_valid'] = 1; + + /** + * Filters the $field array to validate settings. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field The field array. + */ + $field = apply_filters( "acf/validate_field", $field ); + + // return + return $field; +} + +// Register variation. +acf_add_filter_variations( 'acf/validate_field', array('type'), 0 ); + +/** + * acf_get_valid_field + * + * Ensures the given field valid. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param array $field The field array. + * @return array + */ +function acf_get_valid_field( $field = false ) { + return acf_validate_field( $field ); +} + +/** + * acf_translate_field + * + * Translates a field's settings. + * + * @date 8/03/2016 + * @since 5.3.2 + * + * @param array $field The field array. + * @return array + */ +function acf_translate_field( $field = array() ) { + + // Get settings. + $l10n = acf_get_setting('l10n'); + $l10n_textdomain = acf_get_setting('l10n_textdomain'); + + // Translate field settings if textdomain is set. + if( $l10n && $l10n_textdomain ) { + + $field['label'] = acf_translate( $field['label'] ); + $field['instructions'] = acf_translate( $field['instructions'] ); + + /** + * Filters the $field array to translate strings. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field The field array. + */ + $field = apply_filters( "acf/translate_field", $field ); + } + + // Return field. + return $field; +} + +// Register variation. +acf_add_filter_variations( 'acf/translate_field', array('type'), 0 ); + +// Translate fields passing through validation. +add_action('acf/validate_field', 'acf_translate_field'); + +/** + * acf_get_fields + * + * Returns and array of fields for the given $parent. + * + * @date 30/09/13 + * @since 5.0.0 + * + * @param array $parent The field group or field array. + * @return array + */ +function acf_get_fields( $parent ) { + + // Allow field group selector as $parent. + if( !is_array($parent) ) { + $parent = acf_get_field_group( $parent ); + if( !$parent ) { + return array(); + } + } + + // Vars. + $fields = array(); + + // Check local fields first. + if( acf_have_local_fields($parent['key']) ) { + $raw_fields = acf_get_local_fields( $parent['key'] ); + foreach( $raw_fields as $raw_field ) { + $fields[] = acf_get_field( $raw_field['key'] ); + } + + // Then check database. + } else { + $raw_fields = acf_get_raw_fields( $parent['ID'] ); + foreach( $raw_fields as $raw_field ) { + $fields[] = acf_get_field( $raw_field['ID'] ); + } + } + + /** + * Filters the $fields array. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $fields The array of fields. + */ + $fields = apply_filters( 'acf/load_fields', $fields, $parent ); + $fields = apply_filters( 'acf/get_fields', $fields, $parent ); + + // Return fields + return $fields; +} + +/** + * acf_get_raw_fields + * + * Returns and array of raw field data for the given parent id. + * + * @date 18/1/19 + * @since 5.7.10 + * + * @param int $id The field group or field id. + * @return array + */ +function acf_get_raw_fields( $id = 0 ) { + + // Try cache. + $cache_key = acf_cache_key( "acf_get_field_posts:$id" ); + $post_ids = wp_cache_get( $cache_key, 'acf' ); + if( $post_ids === false ) { + + // Query posts. + $posts = get_posts(array( + 'posts_per_page' => -1, + 'post_type' => 'acf-field', + 'orderby' => 'menu_order', + 'order' => 'ASC', + 'suppress_filters' => true, // DO NOT allow WPML to modify the query + 'cache_results' => true, + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'post_parent' => $id, + 'post_status' => array('publish', 'trash'), + )); + + // Update $post_ids with a non false value. + $post_ids = array(); + foreach( $posts as $post ) { + $post_ids[] = $post->ID; + } + + // Update cache. + wp_cache_set( $cache_key, $post_ids, 'acf' ); + } + + // Loop over ids and populate array of fields. + $fields = array(); + foreach( $post_ids as $post_id ) { + $fields[] = acf_get_raw_field( $post_id ); + } + + // Return fields. + return $fields; +} + +/** + * acf_get_field_count + * + * Return the number of fields for the given field group. + * + * @date 17/10/13 + * @since 5.0.0 + * + * @param array $parent The field group or field array. + * @return int + */ +function acf_get_field_count( $parent ) { + + // Check local fields first. + if( acf_have_local_fields($parent['key']) ) { + $raw_fields = acf_get_local_fields( $parent['key'] ); + + // Then check database. + } else { + $raw_fields = acf_get_raw_fields( $parent['ID'] ); + } + + /** + * Filters the counted number of fields. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param int $count The number of fields. + * @param array $parent The field group or field array. + */ + return apply_filters( 'acf/get_field_count', count($raw_fields), $parent ); +} + +/** + * acf_clone_field + * + * Allows customization to a field when it is cloned. Used by the clone field. + * + * @date 8/03/2016 + * @since 5.3.2 + * + * @param array $field The field being cloned. + * @param array $clone_field The clone field. + * @return array + */ +function acf_clone_field( $field, $clone_field ) { + + // Add reference to the clone field. + $field['_clone'] = $clone_field['key']; + + /** + * Filters the $field array when it is being cloned. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field The field array. + * @param array $clone_field The clone field array. + */ + $field = apply_filters( "acf/clone_field", $field, $clone_field ); + + // Return field. + return $field; +} + +// Register variation. +acf_add_filter_variations( 'acf/clone_field', array('type'), 0 ); + +/** + * acf_prepare_field + * + * Prepare a field for input. + * + * @date 20/1/19 + * @since 5.7.10 + * + * @param array $field The field array. + * @return array + */ +function acf_prepare_field( $field ) { + + // Bail early if already prepared. + if( !empty($field['_prepare']) ) { + return $field; + } + + // Use field key to override input name. + if( $field['key'] ) { + $field['name'] = $field['key']; + } + + // Use field prefix to modify input name. + if( $field['prefix'] ) { + $field['name'] = "{$field['prefix']}[{$field['name']}]"; + } + + // Generate id attribute from name. + $field['id'] = acf_idify( $field['name'] ); + + // Add state to field. + $field['_prepare'] = true; + + /** + * Filters the $field array. + * + * Allows developers to modify field settings or return false to remove field. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field The field array. + */ + $field = apply_filters( "acf/prepare_field", $field ); + + // return + return $field; +} + +// Register variation. +acf_add_filter_variations( 'acf/prepare_field', array('type', 'name', 'key'), 0 ); + +/** + * acf_render_fields + * + * Renders an array of fields. Also loads the field's value. + * + * @date 8/10/13 + * @since 5.0.0 + * @since 5.6.9 Changed parameter order. + * + * @param array $fields An array of fields. + * @param (int|string) $post_id The post ID to load values from. + * @param string $element The wrapping element type. + * @param string $instruction The instruction render position (label|field). + * @return void + */ +function acf_render_fields( $fields, $post_id = 0, $el = 'div', $instruction = 'label' ) { + + // Parameter order changed in ACF 5.6.9. + if( is_array($post_id) ) { + $args = func_get_args(); + $fields = $args[1]; + $post_id = $args[0]; + } + + /** + * Filters the $fields array before they are rendered. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $fields An array of fields. + * @param (int|string) $post_id The post ID to load values from. + */ + $fields = apply_filters( 'acf/pre_render_fields', $fields, $post_id ); + + // Filter our false results. + $fields = array_filter( $fields ); + + // Loop over and render fields. + if( $fields ) { + foreach( $fields as $field ) { + + // Load value if not already loaded. + if( $field['value'] === null ) { + $field['value'] = acf_get_value( $post_id, $field ); + } + + // Render wrap. + acf_render_field_wrap( $field, $el, $instruction ); + } + } + + /** + * Fires after fields have been rendered. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $fields An array of fields. + * @param (int|string) $post_id The post ID to load values from. + */ + do_action( 'acf/render_fields', $fields, $post_id ); +} + +/** + * acf_render_field_wrap + * + * Render the wrapping element for a given field. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param array $field The field array. + * @param string $element The wrapping element type. + * @param string $instruction The instruction render position (label|field). + * @return void + */ +function acf_render_field_wrap( $field, $element = 'div', $instruction = 'label' ) { + + // Ensure field is complete (adds all settings). + $field = acf_validate_field( $field ); + + // Prepare field for input (modifies settings). + $field = acf_prepare_field( $field ); + + // Allow filters to cancel render. + if( !$field ) { + return; + } + + // Determine wrapping element. + $elements = array( + 'div' => 'div', + 'tr' => 'td', + 'td' => 'div', + 'ul' => 'li', + 'ol' => 'li', + 'dl' => 'dt', + ); + + if( isset($elements[$element]) ) { + $inner_element = $elements[$element]; + } else { + $element = $inner_element = 'div'; + } + + // Generate wrapper attributes. + $wrapper = array( + 'id' => '', + 'class' => 'acf-field', + 'width' => '', + 'style' => '', + 'data-name' => $field['_name'], + 'data-type' => $field['type'], + 'data-key' => $field['key'], + ); + + // Add field type attributes. + $wrapper['class'] .= " acf-field-{$field['type']}"; + + // add field key attributes + if( $field['key'] ) { + $wrapper['class'] .= " acf-field-{$field['key']}"; + } + + // Add required attributes. + // Todo: Remove data-required + if( $field['required'] ) { + $wrapper['class'] .= ' is-required'; + $wrapper['data-required'] = 1; + } + + // Clean up class attribute. + $wrapper['class'] = str_replace( '_', '-', $wrapper['class'] ); + $wrapper['class'] = str_replace( 'field-field-', 'field-', $wrapper['class'] ); + + // Merge in field 'wrapper' setting without destroying class and style. + if( $field['wrapper'] ) { + $wrapper = acf_merge_attributes( $wrapper, $field['wrapper'] ); + } + + // Extract wrapper width and generate style. + // Todo: Move from $wrapper out into $field. + $width = acf_extract_var( $wrapper, 'width' ); + if( $width ) { + if( $element !== 'tr' && $element !== 'td' ) { + $wrapper['data-width'] = $width; + $wrapper['style'] .= " width:{$width}%;"; + } + } + + // Clean up all attributes. + $wrapper = array_map( 'trim', $wrapper ); + $wrapper = array_filter( $wrapper ); + + /** + * Filters the $wrapper array before rendering. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param array $wrapper The wrapper attributes array. + * @param array $field The field array. + */ + $wrapper = apply_filters( 'acf/field_wrapper_attributes', $wrapper, $field ); + + // Append conditional logic attributes. + if( !empty($field['conditional_logic']) ) { + $wrapper['data-conditions'] = $field['conditional_logic']; + } + if( !empty($field['conditions']) ) { + $wrapper['data-conditions'] = $field['conditions']; + } + + // Vars for render. + $attributes_html = acf_esc_attr( $wrapper ); + + // Render HTML + echo "<$element $attributes_html>" . "\n"; + if( $element !== 'td' ) { + echo "<$inner_element class=\"acf-label\">" . "\n"; + acf_render_field_label( $field ); + if( $instruction == 'label' ) { + acf_render_field_instructions( $field ); + } + echo "" . "\n"; + } + echo "<$inner_element class=\"acf-input\">" . "\n"; + acf_render_field( $field ); + if( $instruction == 'field' ) { + acf_render_field_instructions( $field ); + } + echo "" . "\n"; + echo "" . "\n"; +} + +/** + * acf_render_field + * + * Render the input element for a given field. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param array $field The field array. + * @return void + */ +function acf_render_field( $field ) { + + // Ensure field is complete (adds all settings). + $field = acf_validate_field( $field ); + + // Prepare field for input (modifies settings). + $field = acf_prepare_field( $field ); + + // Allow filters to cancel render. + if( !$field ) { + return; + } + + /** + * Fires when rendering a field. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field The field array. + */ + do_action( "acf/render_field", $field ); +} + +// Register variation. +acf_add_action_variations( 'acf/render_field', array('type', 'name', 'key'), 0 ); + +/** + * acf_render_field_label + * + * Renders the field's label. + * + * @date 19/9/17 + * @since 5.6.3 + * + * @param array $field The field array. + * @return void + */ +function acf_render_field_label( $field ) { + + // Get label. + $label = acf_get_field_label( $field ); + + // Output label. + if( $label ) { + echo '' . acf_esc_html($label) . ''; + } +} + +/** + * acf_get_field_label + * + * Returns the field's label with appropriate required label. + * + * @date 4/11/2013 + * @since 5.0.0 + * + * @param array $field The field array. + * @param string $context The output context (admin). + * @return void + */ +function acf_get_field_label( $field, $context = '' ) { + + // Get label. + $label = $field['label']; + + // Display empty text when editing field. + if( $context == 'admin' && $label === '' ) { + $label = __('(no label)', 'acf'); + } + + // Add required HTML. + if( $field['required'] ) { + $label .= ' *'; + } + + /** + * Filters the field's label HTML. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param string The label HTML. + * @param array $field The field array. + * @param string $context The output context (admin). + */ + $label = apply_filters( "acf/get_field_label", $label, $field, $context ); + + // Return label. + return $label; +} + +/** + * acf_render_field_instructions + * + * Renders the field's instructions. + * + * @date 19/9/17 + * @since 5.6.3 + * + * @param array $field The field array. + * @return void + */ +function acf_render_field_instructions( $field ) { + + // Output instructions. + if( $field['instructions'] ) { + echo '

              ' . acf_esc_html($field['instructions']) . '

              '; + } +} + +/** + * acf_render_field_setting + * + * Renders a field setting used in the admin edit screen. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param array $field The field array. + * @param array $setting The settings field array. + * @param bool $global Whether this setting is a global or field type specific one. + * @return void + */ +function acf_render_field_setting( $field, $setting, $global = false ) { + + // Validate field. + $setting = acf_validate_field( $setting ); + + // Add custom attributes to setting wrapper. + $setting['wrapper']['data-key'] = $setting['name']; + $setting['wrapper']['class'] .= ' acf-field-setting-' . $setting['name']; + if( !$global ) { + $setting['wrapper']['data-setting'] = $field['type']; + } + + // Copy across prefix. + $setting['prefix'] = $field['prefix']; + + // Find setting value from field. + if( $setting['value'] === null ) { + + // Name. + if( isset($field[ $setting['name'] ]) ) { + $setting['value'] = $field[ $setting['name'] ]; + + // Default value. + } elseif( isset($setting['default_value']) ) { + $setting['value'] = $setting['default_value']; + } + } + + // Add append attribute used by JS to join settings. + if( isset($setting['_append']) ) { + $setting['wrapper']['data-append'] = $setting['_append']; + } + + // Render setting. + acf_render_field_wrap( $setting, 'tr', 'label' ); +} + +/** + * acf_update_field + * + * Updates a field in the database. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param array $field The field array. + * @param array $specific An array of specific field attributes to update. + * @return void + */ +function acf_update_field( $field, $specific = array() ) { + + // Validate field. + $field = acf_validate_field( $field ); + + // May have been posted. Remove slashes. + $field = wp_unslash( $field ); + + // Parse types (converts string '0' to int 0). + $field = acf_parse_types( $field ); + + // Clean up conditional logic keys. + if( $field['conditional_logic'] ) { + + // Remove empty values and convert to associated array. + $field['conditional_logic'] = array_filter( $field['conditional_logic'] ); + $field['conditional_logic'] = array_values( $field['conditional_logic'] ); + $field['conditional_logic'] = array_map( 'array_filter', $field['conditional_logic'] ); + $field['conditional_logic'] = array_map( 'array_values', $field['conditional_logic'] ); + } + + // Parent may be provided as a field key. + if( $field['parent'] && !is_numeric($field['parent']) ) { + $parent = acf_get_field_post( $field['parent'] ); + $field['parent'] = $parent ? $parent->ID : 0; + } + + /** + * Filters the $field array before it is updated. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field The field array. + */ + $field = apply_filters( "acf/update_field", $field ); + + // Make a backup of field data and remove some args. + $_field = $field; + acf_extract_vars( $_field, array( 'ID', 'key', 'label', 'name', 'prefix', 'value', 'menu_order', 'id', 'class', 'parent', '_name', '_prepare', '_valid' ) ); + + // Create array of data to save. + $save = array( + 'ID' => $field['ID'], + 'post_status' => 'publish', + 'post_type' => 'acf-field', + 'post_title' => $field['label'], + 'post_name' => $field['key'], + 'post_excerpt' => $field['name'], + 'post_content' => maybe_serialize( $_field ), + 'post_parent' => $field['parent'], + 'menu_order' => $field['menu_order'], + ); + + // Reduce save data if specific key list is provided. + if( $specific ) { + $specific[] = 'ID'; + $save = acf_get_sub_array( $save, $specific ); + } + + // Unhook wp_targeted_link_rel() filter from WP 5.1 corrupting serialized data. + remove_filter( 'content_save_pre', 'wp_targeted_link_rel' ); + + // Slash data. + // WP expects all data to be slashed and will unslash it (fixes '\' character issues). + $save = wp_slash( $save ); + + // Update or Insert. + if( $field['ID'] ) { + wp_update_post( $save ); + } else { + $field['ID'] = wp_insert_post( $save ); + } + + // Flush field cache. + acf_flush_field_cache( $field ); + + /** + * Fires after a field has been updated, and the field cache has been cleaned. + * + * @date 24/1/19 + * @since 5.7.10 + * + * @param array $field The field array. + */ + do_action( "acf/updated_field", $field ); + + // Return field. + return $field; +} + +// Register variation. +acf_add_filter_variations( 'acf/update_field', array('type', 'name', 'key'), 0 ); + +/** + * _acf_apply_unique_field_slug + * + * Allows full control over 'acf-field' slugs. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param string $slug The post slug. + * @param int $post_ID Post ID. + * @param string $post_status The post status. + * @param string $post_type Post type. + * @param int $post_parent Post parent ID + * @param string $original_slug The original post slug. + */ +function _acf_apply_unique_field_slug( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) { + + // Check post type and reset to original value. + if( $post_type === 'acf-field' ) { + return $original_slug; + } + + // Return slug. + return $slug; +} + +// Hook into filter. +add_filter( 'wp_unique_post_slug', '_acf_apply_unique_field_slug', 999, 6 ); + +/** + * acf_flush_field_cache + * + * Deletes all caches for this field. + * + * @date 22/1/19 + * @since 5.7.10 + * + * @param array $field The field array. + * @return void + */ +function acf_flush_field_cache( $field ) { + + // Delete stored data. + acf_get_store( 'fields' )->remove( $field['key'] ); + + // Flush cached post_id for this field's name and key. + wp_cache_delete( acf_cache_key("acf_get_field_post:name:{$field['name']}"), 'acf' ); + wp_cache_delete( acf_cache_key("acf_get_field_post:key:{$field['key']}"), 'acf' ); + + // Flush cached array of post_ids for this field's parent. + wp_cache_delete( acf_cache_key("acf_get_field_posts:{$field['parent']}"), 'acf' ); +} + +/** + * acf_delete_field + * + * Deletes a field from the database. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param (int|string) $id The field ID, key or name. + * @return bool True if field was deleted. + */ +function acf_delete_field( $id = 0 ) { + + // Get the field. + $field = acf_get_field( $id ); + + // Bail early if field was not found. + if( !$field || !$field['ID'] ) { + return false; + } + + // Delete post. + wp_delete_post( $field['ID'], true ); + + // Flush field cache. + acf_flush_field_cache( $field ); + + /** + * Fires immediately after a field has been deleted. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field The field array. + */ + do_action( "acf/delete_field", $field ); + + // Return true. + return true; +} + +// Register variation. +acf_add_action_variations( 'acf/delete_field', array('type', 'name', 'key'), 0 ); + +/** + * acf_trash_field + * + * Trashes a field from the database. + * + * @date 2/10/13 + * @since 5.0.0 + * + * @param (int|string) $id The field ID, key or name. + * @return bool True if field was trashed. + */ +function acf_trash_field( $id = 0 ) { + + // Get the field. + $field = acf_get_field( $id ); + + // Bail early if field was not found. + if( !$field || !$field['ID'] ) { + return false; + } + + // Trash post. + wp_trash_post( $field['ID'], true ); + + /** + * Fires immediately after a field has been trashed. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field The field array. + */ + do_action( 'acf/trash_field', $field ); + + // Return true. + return true; +} + +/** + * acf_untrash_field + * + * Restores a field from the trash. + * + * @date 2/10/13 + * @since 5.0.0 + * + * @param (int|string) $id The field ID, key or name. + * @return bool True if field was trashed. + */ +function acf_untrash_field( $id = 0 ) { + + // Get the field. + $field = acf_get_field( $id ); + + // Bail early if field was not found. + if( !$field || !$field['ID'] ) { + return false; + } + + // Untrash post. + wp_untrash_post( $field['ID'], true ); + + // Flush field cache. + acf_flush_field_cache( $field ); + + /** + * Fires immediately after a field has been trashed. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field The field array. + */ + do_action( 'acf/untrash_field', $field ); + + // Return true. + return true; +} + +/** + * acf_prefix_fields + * + * Changes the prefix for an array of fields by reference. + * + * @date 5/9/17 + * @since 5.6.0 + * + * @param array $fields An array of fields. + * @param string $prefix The new prefix. + * @return void + */ +function acf_prefix_fields( &$fields, $prefix = 'acf' ) { + + // Loopover fields. + foreach( $fields as &$field ) { + + // Replace 'acf' with $prefix. + $field['prefix'] = $prefix . substr($field['prefix'], 3); + } +} + +/** + * acf_get_sub_field + * + * Searches a field for sub fields matching the given selector. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param (int|string) $id The field ID, key or name. + * @param array $field The parent field array. + * @return (array|false) + */ +function acf_get_sub_field( $id, $field ) { + + // Vars. + $sub_field = false; + + // Search sub fields. + if( isset($field['sub_fields']) ) { + $sub_field = acf_search_fields( $id, $field['sub_fields'] ); + } + + /** + * Filters the $sub_field found. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $sub_field The found sub field array. + * @param string $selector The selector used to search. + * @param array $field The parent field array. + */ + $sub_field = apply_filters( "acf/get_sub_field", $sub_field, $id, $field ); + + // return + return $sub_field; + +} + +// Register variation. +acf_add_filter_variations( 'acf/get_sub_field', array('type'), 2 ); + +/** + * acf_search_fields + * + * Searches an array of fields for one that matches the given identifier. + * + * @date 12/2/19 + * @since 5.7.11 + * + * @param (int|string) $id The field ID, key or name. + * @param array $haystack The array of fields. + * @return (int|false) + */ +function acf_search_fields( $id, $fields ) { + + // Loop over searchable keys in order of priority. + // Important to search "name" on all fields before "_name" backup. + foreach( array( 'key', 'name', '_name', '__name' ) as $key ) { + + // Loop over fields and compare. + foreach( $fields as $field ) { + if( isset($field[$key]) && $field[$key] === $id ) { + return $field; + } + } + } + + // Return not found. + return false; +} + +/** + * acf_is_field + * + * Returns true if the given params match a field. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param array $field The field array. + * @param mixed $id An optional identifier to search for. + * @return bool + */ +function acf_is_field( $field = false, $id = '' ) { + return ( + is_array($field) + && isset($field['key']) + && isset($field['name']) + ); +} + +/** + * acf_get_field_ancestors + * + * Returns an array of ancestor field ID's or keys. + * + * @date 22/06/2016 + * @since 5.3.8 + * + * @param array $field The field array. + * @return array + */ +function acf_get_field_ancestors( $field ) { + + // Vars. + $ancestors = array(); + + // Loop over parents. + while( $field = acf_get_field($field['parent']) ) { + $ancestors[] = $field['ID'] ? $field['ID'] : $field['key']; + } + + // return + return $ancestors; +} + +/** + * acf_duplicate_fields + * + * Duplicate an array of fields. + * + * @date 16/06/2014 + * @since 5.0.0 + * + * @param array $fields An array of fields. + * @param int $parent_id The new parent ID. + * @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). + $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 ); + + // Duplicate fields. + foreach( $fields as $field ) { + $duplicates[] = acf_duplicate_field( $field['ID'], $parent_id ); + } + + // Return. + return $duplicates; +} + +/** + * acf_duplicate_field + * + * Duplicates a field. + * + * @date 16/06/2014 + * @since 5.0.0 + * + * @param (int|string) $id The field ID, key or name. + * @param int $parent_id The new parent ID. + * @return bool True if field was duplicated. + */ +function acf_duplicate_field( $id = 0, $parent_id = 0 ){ + + // Get the field. + $field = acf_get_field( $id ); + + // Bail early if field was not found. + if( !$field ) { + return false; + } + + // Remove ID to avoid update. + $field['ID'] = 0; + + // Generate key. + $keys = acf_get_data( 'duplicates' ); + $field['key'] = isset($keys[ $field['key'] ]) ? $keys[ $field['key'] ] : uniqid('field_'); + + // Set parent. + if( $parent_id ) { + $field['parent'] = $parent_id; + } + + // Update conditional logic references because field keys have changed. + if( $field['conditional_logic'] ) { + + // Loop over groups + foreach( $field['conditional_logic'] as $group_i => $group ) { + + // Loop over rules + foreach( $group as $rule_i => $rule ) { + $field['conditional_logic'][ $group_i ][ $rule_i ]['field'] = isset($keys[ $rule['field'] ]) ? $keys[ $rule['field'] ] : $rule['field']; + } + } + } + + /** + * Filters the $field array after it has been duplicated. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field The field array. + */ + $field = apply_filters( "acf/duplicate_field", $field); + + // Update and return. + return acf_update_field( $field ); +} + +// Register variation. +acf_add_filter_variations( 'acf/duplicate_field', array('type'), 0 ); + +/** + * acf_prepare_fields_for_export + * + * Returns a modified array of fields ready for export. + * + * @date 11/03/2014 + * @since 5.0.0 + * + * @param array $fields An array of fields. + * @return array + */ +function acf_prepare_fields_for_export( $fields = array() ) { + + // Map function and return. + return array_map( 'acf_prepare_field_for_export', $fields ); +} + +/** + * acf_prepare_field_for_export + * + * Returns a modified field ready for export. + * + * @date 11/03/2014 + * @since 5.0.0 + * + * @param array $field The field array. + * @return array + */ +function acf_prepare_field_for_export( $field ) { + + // Remove args. + acf_extract_vars( $field, array( 'ID', 'prefix', 'value', 'menu_order', 'id', 'class', 'parent', '_name', '_prepare', '_valid' ) ); + + /** + * Filters the $field array before being returned to the export tool. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field The field array. + */ + $field = apply_filters( "acf/prepare_field_for_export", $field ); + + // Return field. + return $field; +} + +// Register variation. +acf_add_filter_variations( 'acf/prepare_field_for_export', array('type'), 0 ); + +/** + * acf_prepare_field_for_import + * + * Returns a modified array of fields ready for import. + * + * @date 11/03/2014 + * @since 5.0.0 + * + * @param array $fields An array of fields. + * @return array + */ +function acf_prepare_fields_for_import( $fields = array() ) { + + // Ensure array indexes are clean. + $fields = array_values($fields); + + // Loop through fields allowing for growth. + $i = 0; + while( $i < count($fields) ) { + + // Prepare for import. + $field = acf_prepare_field_for_import( $fields[ $i ] ); + + // Allow multiple fields to be returned (parent + children). + if( is_array($field) && !isset($field['key']) ) { + + // Replace this field ($i) with all returned fields. + array_splice( $fields, $i, 1, $field ); + } + + // Iterate. + $i++; + } + + /** + * Filters the $fields array before being returned to the import tool. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field The field array. + */ + $fields = apply_filters( 'acf/prepare_fields_for_import', $fields ); + + // Return. + return $fields; +} + +/** + * acf_prepare_field_for_import + * + * Returns a modified field ready for import. + * Allows parent fields to modify themselves and also return sub fields. + * + * @date 11/03/2014 + * @since 5.0.0 + * + * @param array $field The field array. + * @return array + */ +function acf_prepare_field_for_import( $field ) { + + /** + * Filters the $field array before being returned to the import tool. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field The field array. + */ + $field = apply_filters( "acf/prepare_field_for_import", $field ); + + // Return field. + return $field; +} + +// Register variation. +acf_add_filter_variations( 'acf/prepare_field_for_import', array('type'), 0 ); \ No newline at end of file diff --git a/includes/acf-field-group-functions.php b/includes/acf-field-group-functions.php new file mode 100644 index 0000000..8d0512c --- /dev/null +++ b/includes/acf-field-group-functions.php @@ -0,0 +1,1071 @@ +prop( 'multisite', true ); + +/** + * acf_get_field_group + * + * Retrieves a field group for the given identifier. + * + * @date 30/09/13 + * @since 5.0.0 + * + * @param (int|string) $id The field group ID, key or name. + * @return (array|false) The field group array. + */ +function acf_get_field_group( $id = 0 ) { + + // Allow WP_Post to be passed. + if( is_object($id) ) { + $id = $id->ID; + } + + // Check store. + $store = acf_get_store( 'field-groups' ); + if( $store->has( $id ) ) { + return $store->get( $id ); + } + + // Check local fields first. + if( acf_is_local_field_group($id) ) { + $field_group = acf_get_local_field_group( $id ); + + // Then check database. + } else { + $field_group = acf_get_raw_field_group( $id ); + } + + // Bail early if no field group. + if( !$field_group ) { + return false; + } + + // Validate field group. + $field_group = acf_validate_field_group( $field_group ); + + /** + * Filters the $field_group array after it has been loaded. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array The field_group array. + */ + $field_group = apply_filters( 'acf/get_field_group', $field_group ); + $field_group = apply_filters( 'acf/load_field_group', $field_group ); + + // Store field group using aliasses to also find via key, ID and name. + $store->set( $field_group['key'], $field_group ); + $store->alias( $field_group['key'], $field_group['ID'] ); + + // Return. + return $field_group; +} + +/** + * acf_get_raw_field_group + * + * Retrieves raw field group data for the given identifier. + * + * @date 18/1/19 + * @since 5.7.10 + * + * @param (int|string) $id The field ID, key or name. + * @return (array|false) The field group array. + */ +function acf_get_raw_field_group( $id = 0 ) { + + // Get raw field group from database. + $post = acf_get_field_group_post( $id ); + if( !$post ) { + return false; + } + + // Bail early if incorrect post type. + if( $post->post_type !== 'acf-field-group' ) { + return false; + } + + // Unserialize post_content. + $field_group = (array) maybe_unserialize( $post->post_content ); + + // update attributes + $field_group['ID'] = $post->ID; + $field_group['title'] = $post->post_title; + $field_group['key'] = $post->post_name; + $field_group['menu_order'] = $post->menu_order; + $field_group['active'] = in_array($post->post_status, array('publish', 'auto-draft')); + + // Return field. + return $field_group; +} + +/** + * acf_get_field_group_post + * + * Retrieves the field group's WP_Post object. + * + * @date 18/1/19 + * @since 5.7.10 + * + * @param (int|string) $id The field group's ID, key or name. + * @return (array|false) The field group's array. + */ +function acf_get_field_group_post( $id = 0 ) { + + // Get post if numeric. + if( is_numeric($id) ) { + return get_post( $id ); + + // Search posts if is string. + } elseif( is_string($id) ) { + + // Try cache. + $cache_key = acf_cache_key( "acf_get_field_group_post:key:$id" ); + $post_id = wp_cache_get( $cache_key, 'acf' ); + if( $post_id === false ) { + + // Query posts. + $posts = get_posts(array( + 'posts_per_page' => 1, + 'post_type' => 'acf-field-group', + 'post_status' => array('publish', 'acf-disabled', 'trash'), + 'orderby' => 'menu_order title', + 'order' => 'ASC', + 'suppress_filters' => false, + 'cache_results' => true, + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'acf_group_key' => $id + )); + + // Update $post_id with a non false value. + $post_id = $posts ? $posts[0]->ID : 0; + + // Update cache. + wp_cache_set( $cache_key, $post_id, 'acf' ); + } + + // Check $post_id and return the post when possible. + if( $post_id ) { + return get_post( $post_id ); + } + } + + // Return false by default. + return false; +} + +/** + * acf_is_field_group_key + * + * Returns true if the given identifier is a field group key. + * + * @date 6/12/2013 + * @since 5.0.0 + * + * @param string $id The identifier. + * @return bool + */ +function acf_is_field_group_key( $id = '' ) { + + // Check if $id is a string starting with "group_". + if( is_string($id) && substr($id, 0, 6) === 'group_' ) { + return true; + } + + /** + * Filters whether the $id is a field group key. + * + * @date 23/1/19 + * @since 5.7.10 + * + * @param bool $bool The result. + * @param string $id The identifier. + */ + return apply_filters( 'acf/is_field_group_key', false, $id ); +} + +/** + * acf_validate_field_group + * + * Ensures the given field group is valid. + * + * @date 18/1/19 + * @since 5.7.10 + * + * @param array $field The field group array. + * @return array + */ +function acf_validate_field_group( $field_group = array() ) { + + // Bail early if already valid. + if( is_array($field_group) && !empty($field_group['_valid']) ) { + return $field_group; + } + + // Apply defaults. + $field_group = wp_parse_args($field_group, array( + 'ID' => 0, + 'key' => '', + 'title' => '', + 'fields' => array(), + 'location' => array(), + 'menu_order' => 0, + 'position' => 'normal', + 'style' => 'default', + 'label_placement' => 'top', + 'instruction_placement' => 'label', + 'hide_on_screen' => array(), + 'active' => true, + 'description' => '', + )); + + // Field group is now valid. + $field_group['_valid'] = 1; + + /** + * Filters the $field_group array to validate settings. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field_group The field group array. + */ + $field_group = apply_filters( 'acf/validate_field_group', $field_group ); + + // return + return $field_group; +} + +/** + * acf_get_valid_field_group + * + * Ensures the given field group is valid. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param array $field_group The field group array. + * @return array + */ +function acf_get_valid_field_group( $field_group = false ) { + return acf_validate_field_group( $field_group ); +} + +/** + * acf_translate_field_group + * + * Translates a field group's settings. + * + * @date 8/03/2016 + * @since 5.3.2 + * + * @param array $field_group The field group array. + * @return array + */ +function acf_translate_field_group( $field_group = array() ) { + + // Get settings. + $l10n = acf_get_setting('l10n'); + $l10n_textdomain = acf_get_setting('l10n_textdomain'); + + // Translate field settings if textdomain is set. + if( $l10n && $l10n_textdomain ) { + + $field_group['title'] = acf_translate( $field_group['title'] ); + + /** + * Filters the $field group array to translate strings. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field_group The field group array. + */ + $field_group = apply_filters( "acf/translate_field_group", $field_group ); + } + + // Return field. + return $field_group; +} + +// Translate field groups passing through validation. +add_action('acf/validate_field_group', 'acf_translate_field_group'); + + +/** + * acf_get_field_groups + * + * Returns and array of field_groups for the given $filter. + * + * @date 30/09/13 + * @since 5.0.0 + * + * @param array $filter An array of args to filter results by. + * @return array + */ +function acf_get_field_groups( $filter = array() ) { + + // Vars. + $field_groups = array(); + + // Check database. + $raw_field_groups = acf_get_raw_field_groups(); + if( $raw_field_groups ) { + foreach( $raw_field_groups as $raw_field_group ) { + $field_groups[] = acf_get_field_group( $raw_field_group['ID'] ); + } + } + + + /** + * Filters the $field_groups array. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field_groups The array of field_groups. + */ + $field_groups = apply_filters( 'acf/load_field_groups', $field_groups ); + $field_groups = apply_filters( 'acf/get_field_groups', $field_groups ); + + // Filter results. + if( $filter ) { + return acf_filter_field_groups( $field_groups, $filter ); + } + + // Return field groups. + return $field_groups; +} + +/** + * acf_get_raw_field_groups + * + * Returns and array of raw field_group data. + * + * @date 18/1/19 + * @since 5.7.10 + * + * @param void + * @return array + */ +function acf_get_raw_field_groups() { + + // Try cache. + $cache_key = acf_cache_key( "acf_get_field_group_posts" ); + $post_ids = wp_cache_get( $cache_key, 'acf' ); + if( $post_ids === false ) { + + // Query posts. + $posts = get_posts(array( + 'posts_per_page' => -1, + 'post_type' => 'acf-field-group', + 'orderby' => 'menu_order title', + 'order' => 'ASC', + 'suppress_filters' => false, // Allow WPML to modify the query + 'cache_results' => true, + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'post_status' => array('publish', 'acf-disabled'), + )); + + // Update $post_ids with a non false value. + $post_ids = array(); + foreach( $posts as $post ) { + $post_ids[] = $post->ID; + } + + // Update cache. + wp_cache_set( $cache_key, $post_ids, 'acf' ); + } + + // Loop over ids and populate array of field groups. + $field_groups = array(); + foreach( $post_ids as $post_id ) { + $field_groups[] = acf_get_raw_field_group( $post_id ); + } + + // Return field groups. + return $field_groups; +} + +/** + * acf_filter_field_groups + * + * Returns a filtered aray of field groups based on the given $args. + * + * @date 29/11/2013 + * @since 5.0.0 + * + * @param array $field_groups An array of field groups. + * @param array $args An array of location args. + * @return array + */ +function acf_filter_field_groups( $field_groups, $args = array() ) { + + // Loop over field groups and check visibility. + $filtered = array(); + if( $field_groups ) { + foreach( $field_groups as $field_group ) { + if( acf_get_field_group_visibility( $field_group, $args ) ) { + $filtered[] = $field_group; + } + } + } + + // Return filtered. + return $filtered; +} + +/** + * acf_get_field_group_visibility + * + * Returns true if the given field group's location rules match the given $args. + * + * @date 7/10/13 + * @since 5.0.0 + * + * @param array $field_groups An array of field groups. + * @param array $args An array of location args. + * @return bool + */ +function acf_get_field_group_visibility( $field_group, $args = array() ) { + + // Check if active. + if( !$field_group['active'] ) { + return false; + } + + // Check if location rules exist + if( $field_group['location'] ) { + + // Get the current screen. + $screen = acf_get_location_screen( $args ); + + // Loop through location groups. + foreach( $field_group['location'] as $group ) { + + // ignore group if no rules. + if( empty($group) ) { + continue; + } + + // Loop over rules and determine if all rules match. + $match_group = true; + foreach( $group as $rule ) { + if( !acf_match_location_rule( $rule, $screen ) ) { + $match_group = false; + break; + } + } + + // If this group matches, show the field group. + if( $match_group ) { + return true; + } + } + } + + // Return default. + return false; +} + +/** + * acf_update_field_group + * + * Updates a field group in the database. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param array $field_group The field group array. + * @return array + */ +function acf_update_field_group( $field_group ) { + + // Validate field group. + $field_group = acf_get_valid_field_group( $field_group ); + + // May have been posted. Remove slashes. + $field_group = wp_unslash( $field_group ); + + // Parse types (converts string '0' to int 0). + $field_group = acf_parse_types( $field_group ); + + // Clean up location keys. + if( $field_group['location'] ) { + + // Remove empty values and convert to associated array. + $field_group['location'] = array_filter( $field_group['location'] ); + $field_group['location'] = array_values( $field_group['location'] ); + $field_group['location'] = array_map( 'array_filter', $field_group['location'] ); + $field_group['location'] = array_map( 'array_values', $field_group['location'] ); + } + + // Make a backup of field group data and remove some args. + $_field_group = $field_group; + acf_extract_vars( $_field_group, array( 'ID', 'key', 'title', 'menu_order', 'fields', 'active', '_valid' ) ); + + // Create array of data to save. + $save = array( + 'ID' => $field_group['ID'], + 'post_status' => $field_group['active'] ? 'publish' : 'acf-disabled', + 'post_type' => 'acf-field-group', + 'post_title' => $field_group['title'], + 'post_name' => $field_group['key'], + 'post_excerpt' => sanitize_title( $field_group['title'] ), + 'post_content' => maybe_serialize( $_field_group ), + 'menu_order' => $field_group['menu_order'], + ); + + // Unhook wp_targeted_link_rel() filter from WP 5.1 corrupting serialized data. + remove_filter( 'content_save_pre', 'wp_targeted_link_rel' ); + + // Slash data. + // WP expects all data to be slashed and will unslash it (fixes '\' character issues). + $save = wp_slash( $save ); + + // Update or Insert. + if( $field_group['ID'] ) { + wp_update_post( $save ); + } else { + $field_group['ID'] = wp_insert_post( $save ); + } + + // Flush field group cache. + acf_flush_field_group_cache( $field_group ); + + /** + * Fires immediately after a field group has been updated. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field_group The field group array. + */ + do_action( 'acf/update_field_group', $field_group ); + + // Return field group. + return $field_group; +} + +/** + * _acf_apply_unique_field_group_slug + * + * Allows full control over 'acf-field-group' slugs. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param string $slug The post slug. + * @param int $post_ID Post ID. + * @param string $post_status The post status. + * @param string $post_type Post type. + * @param int $post_parent Post parent ID + * @param string $original_slug The original post slug. + */ +function _acf_apply_unique_field_group_slug( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) { + + // Check post type and reset to original value. + if( $post_type === 'acf-field-group' ) { + return $original_slug; + } + + // Return slug. + return $slug; +} + +// Hook into filter. +add_filter( 'wp_unique_post_slug', '_acf_apply_unique_field_group_slug', 999, 6 ); + +/** + * acf_flush_field_group_cache + * + * Deletes all caches for this field group. + * + * @date 22/1/19 + * @since 5.7.10 + * + * @param array $field_group The field group array. + * @return void + */ +function acf_flush_field_group_cache( $field_group ) { + + // Delete stored data. + acf_get_store( 'field-groups' )->remove( $field_group['key'] ); + + // Flush cached post_id for this field group's key. + wp_cache_delete( acf_cache_key( "acf_get_field_group_post:key:{$field_group['key']}" ), 'acf' ); + + // Flush cached array of post_ids for collection of field groups. + wp_cache_delete( acf_cache_key( "acf_get_field_group_posts" ), 'acf' ); +} + +/** + * acf_delete_field_group + * + * Deletes a field group from the database. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param (int|string) $id The field group ID, key or name. + * @return bool True if field group was deleted. + */ +function acf_delete_field_group( $id = 0 ) { + + // Disable filters to ensure ACF loads data from DB. + acf_disable_filters(); + + // Get the field_group. + $field_group = acf_get_field_group( $id ); + + // Bail early if field group was not found. + if( !$field_group || !$field_group['ID'] ) { + return false; + } + + // Delete fields. + $fields = acf_get_fields( $field_group ); + if( $fields ) { + foreach( $fields as $field ) { + acf_delete_field( $field['ID'] ); + } + } + + // Delete post. + wp_delete_post( $field_group['ID'], true ); + + // Flush field group cache. + acf_flush_field_group_cache( $field_group ); + + /** + * Fires immediately after a field group has been deleted. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field_group The field group array. + */ + do_action( 'acf/delete_field_group', $field_group ); + + // Return true. + return true; +} + +/** + * acf_trash_field_group + * + * Trashes a field group from the database. + * + * @date 2/10/13 + * @since 5.0.0 + * + * @param (int|string) $id The field group ID, key or name. + * @return bool True if field group was trashed. + */ +function acf_trash_field_group( $id = 0 ) { + + // Disable filters to ensure ACF loads data from DB. + acf_disable_filters(); + + // Get the field_group. + $field_group = acf_get_field_group( $id ); + + // Bail early if field_group was not found. + if( !$field_group || !$field_group['ID'] ) { + return false; + } + + // Trash fields. + $fields = acf_get_fields( $field_group ); + if( $fields ) { + foreach( $fields as $field ) { + acf_trash_field( $field['ID'] ); + } + } + + // Trash post. + wp_trash_post( $field_group['ID'], true ); + + // Flush field group cache. + acf_flush_field_group_cache( $field_group ); + + /** + * Fires immediately after a field_group has been trashed. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field_group The field_group array. + */ + do_action( 'acf/trash_field_group', $field_group ); + + // Return true. + return true; +} + +/** + * acf_untrash_field_group + * + * Restores a field_group from the trash. + * + * @date 2/10/13 + * @since 5.0.0 + * + * @param (int|string) $id The field_group ID, key or name. + * @return bool True if field_group was trashed. + */ +function acf_untrash_field_group( $id = 0 ) { + + // Disable filters to ensure ACF loads data from DB. + acf_disable_filters(); + + // Get the field_group. + $field_group = acf_get_field_group( $id ); + + // Bail early if field_group was not found. + if( !$field_group || !$field_group['ID'] ) { + return false; + } + + // Untrash fields. + $fields = acf_get_fields( $field_group ); + if( $fields ) { + foreach( $fields as $field ) { + acf_untrash_field( $field['ID'] ); + } + } + + // Untrash post. + wp_untrash_post( $field_group['ID'], true ); + + // Flush field group cache. + acf_flush_field_group_cache( $field_group ); + + /** + * Fires immediately after a field_group has been trashed. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field_group The field_group array. + */ + do_action( 'acf/untrash_field_group', $field_group ); + + // Return true. + return true; +} + +/** + * acf_is_field_group + * + * Returns true if the given params match a field group. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param array $field_group The field group array. + * @param mixed $id An optional identifier to search for. + * @return bool + */ +function acf_is_field_group( $field_group = false ) { + return ( + is_array($field_group) + && isset($field_group['key']) + && isset($field_group['title']) + ); +} + +/** + * acf_duplicate_field_group + * + * Duplicates a field group. + * + * @date 16/06/2014 + * @since 5.0.0 + * + * @param (int|string) $id The field_group ID, key or name. + * @param int $new_post_id Optional post ID to override. + * @return array The new field group. + */ +function acf_duplicate_field_group( $id = 0, $new_post_id = 0 ){ + + // Disable filters to ensure ACF loads data from DB. + acf_disable_filters(); + + // Get the field_group. + $field_group = acf_get_field_group( $id ); + + // Bail early if field_group was not found. + if( !$field_group || !$field_group['ID'] ) { + return false; + } + + // Get fields. + $fields = acf_get_fields( $field_group ); + + // Update attributes. + $field_group['ID'] = $new_post_id; + $field_group['key'] = uniqid('group_'); + + // Add (copy) to title when apropriate. + if( !$new_post_id ) { + $field_group['title'] .= ' (' . __("copy", 'acf') . ')'; + } + + // When importing a new field group, insert a temporary post and set the field group's ID. + // This allows fields to be updated before the field group (field group ID is needed for field parent setting). + if( !$field_group['ID'] ) { + $field_group['ID'] = wp_insert_post( array( 'post_title' => $field_group['key'] ) ); + } + + // Duplicate fields. + $duplicates = acf_duplicate_fields( $fields, $field_group['ID'] ); + + // Save field group. + $field_group = acf_update_field_group( $field_group ); + + /** + * Fires immediately after a field_group has been duplicated. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field_group The field_group array. + */ + do_action( 'acf/duplicate_field_group', $field_group ); + + // return + return $field_group; +} + +/** + * acf_get_field_group_style + * + * Returns the CSS styles generated from field group settings. + * + * @date 20/10/13 + * @since 5.0.0 + * + * @param array $field_group The field group array. + * @return string. + */ +function acf_get_field_group_style( $field_group ) { + + // Vars. + $style = ''; + $elements = array( + 'permalink' => '#edit-slug-box', + 'the_content' => '#postdivrich', + 'excerpt' => '#postexcerpt', + 'custom_fields' => '#postcustom', + 'discussion' => '#commentstatusdiv', + 'comments' => '#commentsdiv', + 'slug' => '#slugdiv', + 'author' => '#authordiv', + 'format' => '#formatdiv', + 'page_attributes' => '#pageparentdiv', + 'featured_image' => '#postimagediv', + 'revisions' => '#revisionsdiv', + 'categories' => '#categorydiv', + 'tags' => '#tagsdiv-post_tag', + 'send-trackbacks' => '#trackbacksdiv' + ); + + // Loop over field group settings and generate list of selectors to hide. + if( is_array($field_group['hide_on_screen']) ) { + $hide = array(); + foreach( $field_group['hide_on_screen'] as $k ) { + if( isset($elements[ $k ]) ) { + $id = $elements[ $k ]; + $hide[] = $id; + $hide[] = '#screen-meta label[for=' . substr($id, 1) . '-hide]'; + } + } + $style = implode(', ', $hide) . ' {display: none;}'; + } + + /** + * Filters the generated CSS styles. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param string $style The CSS styles. + * @param array $field_group The field group array. + */ + return apply_filters('acf/get_field_group_style', $style, $field_group); +} + +/** + * acf_get_field_group_edit_link + * + * Checks if the current user can edit the field group and returns the edit url. + * + * @date 23/9/18 + * @since 5.7.7 + * + * @param int $post_id The field group ID. + * @return string + */ +function acf_get_field_group_edit_link( $post_id ) { + if( $post_id && acf_current_user_can_admin() ) { + return admin_url('post.php?post=' . $post_id . '&action=edit'); + } + return ''; +} + +/** + * acf_prepare_field_group_for_export + * + * Returns a modified field group ready for export. + * + * @date 11/03/2014 + * @since 5.0.0 + * + * @param array $field_group The field group array. + * @return array + */ +function acf_prepare_field_group_for_export( $field_group = array() ) { + + // Remove args. + acf_extract_vars( $field_group, array( 'ID', 'local', '_valid' ) ); + + // Prepare fields. + $field_group['fields'] = acf_prepare_fields_for_export( $field_group['fields'] ); + + /** + * Filters the $field_group array before being returned to the export tool. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field_group The $field group array. + */ + return apply_filters( 'acf/prepare_field_group_for_export', $field_group ); +} + +/** + * acf_import_field_group + * + * Imports a field group into the databse. + * + * @date 11/03/2014 + * @since 5.0.0 + * + * @param array $field_group The field group array. + * @return array The new field group. + */ +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. + $field_group = acf_get_valid_field_group( $field_group ); + + // 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( $field_group['ID'] ) { + + // Load database fields. + $db_fields = acf_get_fields( $field_group ); + $db_fields = acf_prepare_fields_for_import( $db_fields ); + + // Generate map of "index" => "key" data. + $keys = wp_list_pluck( $fields, 'key' ); + + // Loop over db fields and delete those who don't exist in $new_fields. + foreach( $db_fields as $field ) { + + // Add field data to $ids map. + $ids[ $field['key'] ] = $field['ID']; + + // Delete field if not in $keys. + if( !in_array($field['key'], $keys) ) { + acf_delete_field( $field['ID'] ); + } + } + } + + // When importing a new field group, insert a temporary post and set the field group's ID. + // This allows fields to be updated before the field group (field group ID is needed for field parent setting). + if( !$field_group['ID'] ) { + $field_group['ID'] = wp_insert_post( array( 'post_title' => $field_group['key'] ) ); + } + + // 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. + 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'] ]) ) { + $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( empty($field['menu_order']) ) { + $field['menu_order'] = ($count[ $field['parent'] ] - 1); + } + + // Save field. + $field = acf_update_field( $field ); + + // Add field data to $ids map. + $ids[ $field['key'] ] = $field['ID']; + } + } + + // Save field group. + $field_group = acf_update_field_group( $field_group ); + + // Enable filters again. + acf_enable_filters( $filters ); + + /** + * Fires immediately after a field_group has been imported. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $field_group The field_group array. + */ + do_action( 'acf/import_field_group', $field_group ); + + // return new field group. + return $field_group; +} diff --git a/includes/acf-form-functions.php b/includes/acf-form-functions.php index ca05607..e430b74 100644 --- a/includes/acf-form-functions.php +++ b/includes/acf-form-functions.php @@ -153,20 +153,9 @@ function acf_save_post( $post_id = 0, $values = null ) { */ function _acf_do_save_post( $post_id = 0 ) { - // Check $_POST data. + // Check and update $_POST data. if( $_POST['acf'] ) { - - // Loop over posted values. - foreach( $_POST['acf'] as $key => $value ) { - - // Get field. - $field = acf_get_field( $key ); - - // Update value. - if( $field ) { - acf_update_value( $value, $post_id, $field ); - } - } + acf_update_values( $_POST['acf'], $post_id ); } } diff --git a/includes/acf-helper-functions.php b/includes/acf-helper-functions.php index 034c890..e09c424 100644 --- a/includes/acf-helper-functions.php +++ b/includes/acf-helper-functions.php @@ -22,3 +22,204 @@ function acf_uniqid( $prefix = 'acf' ) { // Return id. return $prefix . '-' . $acf_uniqid++; } + +/** + * acf_merge_attributes + * + * Merges together two arrays but with extra functionality to append class names. + * + * @date 22/1/19 + * @since 5.7.10 + * + * @param array $array1 An array of attributes. + * @param array $array2 An array of attributes. + * @return array + */ +function acf_merge_attributes( $array1, $array2 ) { + + // Merge together attributes. + $array3 = array_merge( $array1, $array2 ); + + // Append together special attributes. + foreach( array('class', 'style') as $key ) { + if( isset($array1[$key]) && isset($array2[$key]) ) { + $array3[$key] = trim($array1[$key]) . ' ' . trim($array2[$key]); + } + } + + // Return + return $array3; +} + +/** + * acf_cache_key + * + * Returns a filtered cache key. + * + * @date 25/1/19 + * @since 5.7.11 + * + * @param string $key The cache key. + * @return string + */ +function acf_cache_key( $key = '' ) { + + /** + * Filters the cache key. + * + * @date 25/1/19 + * @since 5.7.11 + * + * @param string $key The cache key. + * @param string $original_key The original cache key. + */ + return apply_filters( "acf/get_cache_key", $key, $key ); +} + +/** + * acf_request_args + * + * Returns an array of $_REQUEST values using the provided defaults. + * + * @date 28/2/19 + * @since 5.7.13 + * + * @param array $args An array of args. + * @return array + */ +function acf_request_args( $args = array() ) { + foreach( $args as $k => $v ) { + $args[ $k ] = isset($_REQUEST[ $k ]) ? $_REQUEST[ $k ] : $args[ $k ]; + } + return $args; +} + +// Register store. +acf_register_store( 'filters' ); + +/** + * acf_enable_filter + * + * Enables a filter with the given name. + * + * @date 14/7/16 + * @since 5.4.0 + * + * @param string name The modifer name. + * @return void + */ +function acf_enable_filter( $name = '' ) { + acf_get_store( 'filters' )->set( $name, true ); +} + +/** + * acf_disable_filter + * + * Disables a filter with the given name. + * + * @date 14/7/16 + * @since 5.4.0 + * + * @param string name The modifer name. + * @return void + */ +function acf_disable_filter( $name = '' ) { + acf_get_store( 'filters' )->set( $name, false ); +} + +/** + * acf_is_filter_enabled + * + * Returns the state of a filter for the given name. + * + * @date 14/7/16 + * @since 5.4.0 + * + * @param string name The modifer name. + * @return array + */ +function acf_is_filter_enabled( $name = '' ) { + return acf_get_store( 'filters' )->get( $name ); +} + +/** + * acf_get_filters + * + * Returns an array of filters in their current state. + * + * @date 14/7/16 + * @since 5.4.0 + * + * @param void + * @return array + */ +function acf_get_filters() { + return acf_get_store( 'filters' )->get(); +} + +/** + * acf_set_filters + * + * Sets an array of filter states. + * + * @date 14/7/16 + * @since 5.4.0 + * + * @param array $filters An Array of modifers + * @return array + */ +function acf_set_filters( $filters = array() ) { + acf_get_store( 'filters' )->set( $filters ); +} + +/** + * acf_disable_filters + * + * Disables all filters and returns the previous state. + * + * @date 14/7/16 + * @since 5.4.0 + * + * @param void + * @return array + */ +function acf_disable_filters() { + + // Get state. + $prev_state = acf_get_filters(); + + // Set all modifers as false. + acf_set_filters( array_map('__return_false', $prev_state) ); + + // Return prev state. + return $prev_state; +} + +/** + * acf_enable_filters + * + * Enables all or an array of specific filters and returns the previous state. + * + * @date 14/7/16 + * @since 5.4.0 + * + * @param array $filters An Array of modifers + * @return array + */ +function acf_enable_filters( $filters = array() ) { + + // Get state. + $prev_state = acf_get_filters(); + + // Allow specific filters to be enabled. + if( $filters ) { + acf_set_filters( $filters ); + + // Set all modifers as true. + } else { + acf_set_filters( array_map('__return_true', $prev_state) ); + } + + // Return prev state. + return $prev_state; +} diff --git a/includes/acf-hook-functions.php b/includes/acf-hook-functions.php new file mode 100644 index 0000000..80fc42d --- /dev/null +++ b/includes/acf-hook-functions.php @@ -0,0 +1,220 @@ +set( $filter, array( + 'type' => 'filter', + 'variations' => $variations, + 'index' => $index, + )); + + // Add generic handler. + // Use a priotiry of 10, and accepted args of 10 (ignored by WP). + add_filter( $filter, '_acf_apply_hook_variations', 10, 10 ); +} + +/** + * acf_add_action_variations + * + * Registers variations for the given action. + * + * @date 26/1/19 + * @since 5.7.11 + * + * @param string $action The action name. + * @param array $variations An array variation keys. + * @param int $index The param index to find variation values. + * @return void + */ +function acf_add_action_variations( $action = '', $variations = array(), $index = 0 ) { + + // Store replacement data. + acf_get_store('hook-variations')->set( $action, array( + 'type' => 'action', + 'variations' => $variations, + 'index' => $index, + )); + + // Add generic handler. + // Use a priotiry of 10, and accepted args of 10 (ignored by WP). + add_action( $action, '_acf_apply_hook_variations', 10, 10 ); +} + +/** + * _acf_apply_hook_variations + * + * Applys hook variations during apply_filters() or do_action(). + * + * @date 25/1/19 + * @since 5.7.11 + * + * @param mixed + * @return mixed + */ +function _acf_apply_hook_variations() { + + // Get current filter. + $filter = current_filter(); + + // Get args provided. + $args = func_get_args(); + + // Get variation information. + $variations = acf_get_store('hook-variations')->get( $filter ); + extract( $variations ); + + // Find field in args using index. + $field = $args[ $index ]; + + // Loop over variations and apply filters. + foreach( $variations as $variation ) { + + // Get value from field. + // First look for "backup" value ("_name", "_key"). + if( isset($field[ "_$variation" ]) ) { + $value = $field[ "_$variation" ]; + } elseif( isset($field[ $variation ]) ) { + $value = $field[ $variation ]; + } else { + continue; + } + + // Apply filters. + if( $type === 'filter' ) { + $args[0] = apply_filters_ref_array( "$filter/$variation=$value", $args ); + + // Or do action. + } else { + do_action_ref_array( "$filter/$variation=$value", $args ); + } + } + + // Return first arg. + return $args[0]; +} + +// Register store. +acf_register_store( 'deprecated-hooks' ); + +/** + * acf_add_deprecated_filter + * + * Registers a deprecated filter to run during the replacement. + * + * @date 25/1/19 + * @since 5.7.11 + * + * @param string $deprecated The deprecated hook. + * @param string $version The version this hook was deprecated. + * @param string $replacement The replacement hook. + * @return void + */ +function acf_add_deprecated_filter( $deprecated, $version, $replacement ) { + + // Store replacement data. + acf_get_store('deprecated-hooks')->append(array( + 'type' => 'filter', + 'deprecated' => $deprecated, + 'replacement' => $replacement, + 'version' => $version + )); + + // Add generic handler. + // Use a priotiry of 10, and accepted args of 10 (ignored by WP). + add_filter( $replacement, '_acf_apply_deprecated_hook', 10, 10 ); +} + +/** + * acf_add_deprecated_action + * + * Registers a deprecated action to run during the replacement. + * + * @date 25/1/19 + * @since 5.7.11 + * + * @param string $deprecated The deprecated hook. + * @param string $version The version this hook was deprecated. + * @param string $replacement The replacement hook. + * @return void + */ +function acf_add_deprecated_action( $deprecated, $version, $replacement ) { + + // Store replacement data. + acf_get_store('deprecated-hooks')->append(array( + 'type' => 'action', + 'deprecated' => $deprecated, + 'replacement' => $replacement, + 'version' => $version + )); + + // Add generic handler. + // Use a priotiry of 10, and accepted args of 10 (ignored by WP). + add_filter( $replacement, '_acf_apply_deprecated_hook', 10, 10 ); +} + +/** + * _acf_apply_deprecated_hook + * + * Applys a deprecated filter during apply_filters() or do_action(). + * + * @date 25/1/19 + * @since 5.7.11 + * + * @param mixed + * @return mixed + */ +function _acf_apply_deprecated_hook() { + + // Get current hook. + $hook = current_filter(); + + // Get args provided. + $args = func_get_args(); + + // Get deprecated items for this hook. + $items = acf_get_store('deprecated-hooks')->query(array( 'replacement' => $hook )); + + // Loop over results. + foreach( $items as $item ) { + + // Extract data. + extract( $item ); + + // Check if anyone is hooked into this deprecated hook. + if( has_filter($deprecated) ) { + + // Log warning. + _deprecated_hook( $deprecated, $version, $hook ); + + // Apply filters. + if( $type === 'filter' ) { + $args[0] = apply_filters_ref_array( $deprecated, $args ); + + // Or do action. + } else { + do_action_ref_array( $deprecated, $args ); + } + } + } + + // Return first arg. + return $args[0]; +} + diff --git a/includes/acf-meta-functions.php b/includes/acf-meta-functions.php new file mode 100644 index 0000000..cfe7b00 --- /dev/null +++ b/includes/acf-meta-functions.php @@ -0,0 +1,439 @@ + 'post', + 'id' => 0 + ); + + // Check if is numeric. + if( is_numeric($post_id) ) { + $data['id'] = (int) $post_id; + + // Check if is string. + } elseif( is_string($post_id) ) { + + // Determine "{$type}_{$id}" from string. + $bits = explode( '_', $post_id ); + $id = array_pop( $bits ); + $type = implode( '_', $bits ); + + // Check if is meta type. + if( function_exists("get_{$type}_meta") && is_numeric($id) ) { + $data['type'] = $type; + $data['id'] = (int) $id; + + // Check if is taxonomy name. + } elseif( taxonomy_exists($type) && is_numeric($id) ) { + $data['type'] = 'term'; + $data['id'] = (int) $id; + + // Otherwise, default to option. + } else { + $data['type'] = 'option'; + $data['id'] = $post_id; + } + } + + /** + * Filters the $data array after it has been decoded. + * + * @date 12/02/2014 + * @since 5.0.0 + * + * @param array $data The type and id array. + */ + return apply_filters( "acf/decode_post_id", $data, $post_id ); +} + +/** + * acf_get_meta + * + * Returns an array of "ACF only" meta for the given post_id. + * + * @date 9/10/18 + * @since 5.8.0 + * + * @param mixed $post_id The post_id for this data. + * @return array + */ +function acf_get_meta( $post_id = 0 ) { + + // Allow filter to short-circuit load_value logic. + $pre = apply_filters( "acf/pre_load_meta", null, $post_id ); + if( $pre !== null ) { + return $pre; + } + + // Decode $post_id for $type and $id. + extract( acf_decode_post_id($post_id) ); + + // Use get_$type_meta() function when possible. + if( function_exists("get_{$type}_meta") ) { + $allmeta = call_user_func("get_{$type}_meta", $id, ''); + + // Default to wp_options. + } else { + $allmeta = acf_get_option_meta( $id ); + } + + // Loop over meta and check that a reference exists for each value. + $meta = array(); + foreach( $allmeta as $key => $value ) { + + // If a reference exists for this value, add it to the meta array. + if( isset($allmeta["_$key"]) ) { + $meta[ $key ] = $allmeta[ $key ][0]; + $meta[ "_$key" ] = $allmeta[ "_$key" ][0]; + } + } + + // Unserialized results (get_metadata does not unserialize if $key is empty). + $meta = array_map('maybe_unserialize', $meta); + + /** + * Filters the $meta array after it has been loaded. + * + * @date 25/1/19 + * @since 5.7.11 + * + * @param array $meta The arary of loaded meta. + * @param string $post_id The $post_id for this meta. + */ + return apply_filters( "acf/load_meta", $meta, $post_id ); +} + + +/** + * acf_get_option_meta + * + * Returns an array of meta for the given wp_option name prefix in the same format as get_post_meta(). + * + * @date 9/10/18 + * @since 5.8.0 + * + * @param string $prefix The wp_option name prefix. + * @return array + */ +function acf_get_option_meta( $prefix = '' ) { + + // Globals. + global $wpdb; + + // Vars. + $meta = array(); + $search = "{$prefix}_%"; + $_search = "_{$prefix}_%"; + + // Escape underscores for LIKE. + $search = str_replace('_', '\_', $search); + $_search = str_replace('_', '\_', $_search); + + // Query database for results. + $rows = $wpdb->get_results($wpdb->prepare( + "SELECT * + FROM $wpdb->options + WHERE option_name LIKE %s + OR option_name LIKE %s", + $search, + $_search + ), ARRAY_A); + + // Loop over results and append meta (removing the $prefix from the option name). + $len = strlen("{$prefix}_"); + foreach( $rows as $row ) { + $meta[ substr($row['option_name'], $len) ][] = $row['option_value']; + } + + // Return results. + return $meta; +} + +/** + * acf_get_metadata + * + * Retrieves specific metadata from the database. + * + * @date 16/10/2015 + * @since 5.2.3 + * + * @param (int|string) $post_id The post id. + * @param string $name The meta name. + * @param bool $hidden If the meta is hidden (starts with an underscore). + * @return mixed + */ +function acf_get_metadata( $post_id = 0, $name = '', $hidden = false ) { + + // Allow filter to short-circuit logic. + $pre = apply_filters( "acf/pre_load_metadata", null, $post_id, $name, $hidden ); + if( $pre !== null ) { + return $pre; + } + + // Decode $post_id for $type and $id. + extract( acf_decode_post_id($post_id) ); + + // Hidden meta uses an underscore prefix. + $prefix = $hidden ? '_' : ''; + + // Bail early if no $id (possible during new acf_form). + if( !$id ) { + return null; + } + + // Check option. + if( $type === 'option' ) { + return get_option( "{$prefix}{$id}_{$name}", null ); + + // Check meta. + } else { + $meta = get_metadata( $type, $id, "{$prefix}{$name}", false ); + return isset($meta[0]) ? $meta[0] : null; + } +} + +/** + * acf_update_metadata + * + * Updates metadata in the database. + * + * @date 16/10/2015 + * @since 5.2.3 + * + * @param (int|string) $post_id The post id. + * @param string $name The meta name. + * @param mixed $value The meta value. + * @param bool $hidden If the meta is hidden (starts with an underscore). + * @return (int|bool) Meta ID if the key didn't exist, true on successful update, false on failure. + */ +function acf_update_metadata( $post_id = 0, $name = '', $value = '', $hidden = false ) { + + // Allow filter to short-circuit logic. + $pre = apply_filters( "acf/pre_update_metadata", null, $post_id, $name, $value, $hidden ); + if( $pre !== null ) { + return $pre; + } + + // Decode $post_id for $type and $id. + extract( acf_decode_post_id($post_id) ); + + // Hidden meta uses an underscore prefix. + $prefix = $hidden ? '_' : ''; + + // Bail early if no $id (possible during new acf_form). + if( !$id ) { + return false; + } + + // Update option. + if( $type === 'option' ) { + + // Unslash value to match update_metadata() functionality. + $value = wp_unslash( $value ); + $autoload = (bool) acf_get_setting('autoload'); + return update_option( "{$prefix}{$id}_{$name}", $value, $autoload ); + + // Update meta. + } else { + return update_metadata( $type, $id, "{$prefix}{$name}", $value ); + } +} + +/** + * acf_delete_metadata + * + * Deletes metadata from the database. + * + * @date 16/10/2015 + * @since 5.2.3 + * + * @param (int|string) $post_id The post id. + * @param string $name The meta name. + * @param bool $hidden If the meta is hidden (starts with an underscore). + * @return bool + */ +function acf_delete_metadata( $post_id = 0, $name = '', $hidden = false ) { + + // Allow filter to short-circuit logic. + $pre = apply_filters( "acf/pre_delete_metadata", null, $post_id, $name, $hidden ); + if( $pre !== null ) { + return $pre; + } + + // Decode $post_id for $type and $id. + extract( acf_decode_post_id($post_id) ); + + // Hidden meta uses an underscore prefix. + $prefix = $hidden ? '_' : ''; + + // Bail early if no $id (possible during new acf_form). + if( !$id ) { + return false; + } + + // Update option. + if( $type === 'option' ) { + $autoload = (bool) acf_get_setting('autoload'); + return delete_option( "{$prefix}{$id}_{$name}" ); + + // Update meta. + } else { + return delete_metadata( $type, $id, "{$prefix}{$name}" ); + } +} + +/** + * acf_copy_postmeta + * + * Copies meta from one post to another. Useful for saving and restoring revisions. + * + * @date 25/06/2016 + * @since 5.3.8 + * + * @param (int|string) $from_post_id The post id to copy from. + * @param (int|string) $to_post_id The post id to paste to. + * @return void + */ +function acf_copy_metadata( $from_post_id = 0, $to_post_id = 0 ) { + + // Get all postmeta. + $meta = acf_get_meta( $from_post_id ); + + // Check meta. + if( $meta ) { + + // Slash data. WP expects all data to be slashed and will unslash it (fixes '\' character issues). + $meta = wp_slash( $meta ); + + // Loop over meta. + foreach( $meta as $name => $value ) { + acf_update_metadata( $to_post_id, $name, $value ); + } + } +} + +/** + * acf_copy_postmeta + * + * Copies meta from one post to another. Useful for saving and restoring revisions. + * + * @date 25/06/2016 + * @since 5.3.8 + * @deprecated 5.7.11 + * + * @param int $from_post_id The post id to copy from. + * @param int $to_post_id The post id to paste to. + * @return void + */ +function acf_copy_postmeta( $from_post_id = 0, $to_post_id = 0 ) { + return acf_copy_metadata( $from_post_id, $to_post_id ); +} + +/** + * acf_get_meta_field + * + * Returns a field using the provided $id and $post_id parameters. + * Looks for a reference to help loading the correct field via name. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param string $key The meta name (field name). + * @param (int|string) $post_id The post_id where this field's value is saved. + * @return (array|false) The field array. + */ +function acf_get_meta_field( $key = 0, $post_id = 0 ) { + + // Try reference. + $field_key = acf_get_reference( $key, $post_id ); + + if( $field_key ) { + $field = acf_get_field( $field_key ); + if( $field ) { + $field['name'] = $key; + return $field; + } + } + + // Return false. + return false; +} + +/** + * acf_get_metaref + * + * Retrieves reference metadata from the database. + * + * @date 16/10/2015 + * @since 5.2.3 + * + * @param (int|string) $post_id The post id. + * @param string type The reference type (fields|groups). + * @param string $name An optional specific name + * @return mixed + */ +function acf_get_metaref( $post_id = 0, $type = 'fields', $name = '' ) { + + // Load existing meta. + $meta = acf_get_metadata( $post_id, "_acf_$type" ); + + // Handle no meta. + if( !$meta ) { + return $name ? '' : array(); + } + + // Return specific reference. + if( $name ) { + return isset($meta[ $name ]) ? $meta[ $name ] : ''; + + // Or return all references. + } else { + return $meta; + } +} + +/** + * acf_update_metaref + * + * Updates reference metadata in the database. + * + * @date 16/10/2015 + * @since 5.2.3 + * + * @param (int|string) $post_id The post id. + * @param string type The reference type (fields|groups). + * @param array $references An array of references. + * @return (int|bool) Meta ID if the key didn't exist, true on successful update, false on failure. + */ +function acf_update_metaref( $post_id = 0, $type = 'fields', $references = array() ) { + + // Get current references. + $current = acf_get_metaref( $post_id, $type ); + + // Merge in new references. + $references = array_merge( $current, $references ); + + // Simplify groups + if( $type === 'groups' ) { + $references = array_values($references); + } + + // Remove duplicate references. + $references = array_unique($references); + + // Update metadata. + return acf_update_metadata( $post_id, "_acf_$type", $references ); +} diff --git a/includes/acf-post-functions.php b/includes/acf-post-functions.php new file mode 100644 index 0000000..06abc62 --- /dev/null +++ b/includes/acf-post-functions.php @@ -0,0 +1,34 @@ + templates data. + * + * @date 29/8/17 + * @since 5.6.2 + * + * @param void + * @return array + */ +function acf_get_post_templates() { + + // Defaults. + $post_templates = array( + 'page' => array() + ); + + // Loop over post types and append their templates. + if( method_exists('WP_Theme', 'get_page_templates') ) { + $post_types = acf_get_post_types(); + foreach( $post_types as $post_type ) { + $templates = wp_get_theme()->get_page_templates( null, $post_type ); + if( $templates ) { + $post_templates[ $post_type ] = $templates; + } + } + } + + // Return. + return $post_templates; +} \ No newline at end of file diff --git a/includes/acf-value-functions.php b/includes/acf-value-functions.php new file mode 100644 index 0000000..78576be --- /dev/null +++ b/includes/acf-value-functions.php @@ -0,0 +1,329 @@ +prop( 'multisite', true ); + +/** + * acf_get_reference + * + * Retrieves the field key for a given field name and post_id. + * + * @date 26/1/18 + * @since 5.6.5 + * + * @param string $field_name The name of the field. eg 'sub_heading'. + * @param mixed $post_id The post_id of which the value is saved against. + * @return string The field key. + */ +function acf_get_reference( $field_name, $post_id ) { + + // Allow filter to short-circuit load_value logic. + $reference = apply_filters( "acf/pre_load_reference", null, $field_name, $post_id ); + if( $reference !== null ) { + return $reference; + } + + // Get hidden meta for this field name. + $reference = acf_get_metadata( $post_id, $field_name, true ); + + /** + * Filters the reference value. + * + * @date 25/1/19 + * @since 5.7.11 + * + * @param string $reference The reference value. + * @param string $field_name The field name. + * @param (int|string) $post_id The post ID where meta is stored. + */ + return apply_filters( "acf/load_reference", $reference, $field_name, $post_id ); +} + +// Register deprecated. +acf_add_deprecated_filter( 'acf/get_field_reference', '5.6.5', 'acf/load_reference' ); + +/** + * acf_get_value + * + * Retrieves the value for a given field and post_id. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param (int|string) $post_id The post id. + * @param array $field The field array. + * @return mixed. + */ +function acf_get_value( $post_id = 0, $field ) { + + // Allow filter to short-circuit load_value logic. + $value = apply_filters( "acf/pre_load_value", null, $post_id, $field ); + if( $value !== null ) { + return $value; + } + + // Get field name. + $field_name = $field['name']; + + // Check store. + $store = acf_get_store( 'values' ); + if( $store->has( "$post_id:$field_name" ) ) { + return $store->get( "$post_id:$field_name" ); + } + + // Load value from database. + $value = acf_get_metadata( $post_id, $field_name ); + + // Use field's default_value if no meta was found. + if( $value === null && isset($field['default_value']) ) { + $value = $field['default_value']; + } + + /** + * Filters the $value after it has been loaded. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param mixed $value The value to preview. + * @param string $post_id The post ID for this value. + * @param array $field The field array. + */ + $value = apply_filters( "acf/load_value", $value, $post_id, $field ); + + // Update store. + $store->set( "$post_id:$field_name", $value ); + + // Return value. + return $value; +} + +// Register variation. +acf_add_filter_variations( 'acf/load_value', array('type', 'name', 'key'), 2 ); + +/** + * acf_format_value + * + * Returns a formatted version of the provided value. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param mixed $value The field value. + * @param (int|string) $post_id The post id. + * @param array $field The field array. + * @return mixed. + */ +function acf_format_value( $value, $post_id, $field ) { + + // Allow filter to short-circuit load_value logic. + $check = apply_filters( "acf/pre_format_value", null, $post_id, $field ); + if( $check !== null ) { + return $check; + } + + // Get field name. + $field_name = $field['name']; + + // Check store. + $store = acf_get_store( 'values' ); + if( $store->has( "$post_id:$field_name:formatted" ) ) { + return $store->get( "$post_id:$field_name:formatted" ); + } + + /** + * Filters the $value for use in a template function. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param mixed $value The value to preview. + * @param string $post_id The post ID for this value. + * @param array $field The field array. + */ + $value = apply_filters( "acf/format_value", $value, $post_id, $field ); + + // Update store. + $store->set( "$post_id:$field_name:formatted", $value ); + + // Return value. + return $value; +} + +// Register variation. +acf_add_filter_variations( 'acf/format_value', array('type', 'name', 'key'), 2 ); + +/** + * acf_update_value + * + * Updates the value for a given field and post_id. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param mixed $value The new value. + * @param (int|string) $post_id The post id. + * @param array $field The field array. + * @return bool. + */ +function acf_update_value( $value = null, $post_id = 0, $field ) { + + // Allow filter to short-circuit update_value logic. + $check = apply_filters( "acf/pre_update_value", null, $value, $post_id, $field ); + if( $check !== null ) { + return $check; + } + + /** + * Filters the $value before it is updated. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param mixed $value The value to update. + * @param string $post_id The post ID for this value. + * @param array $field The field array. + * @param mixed $original The original value before modification. + */ + $value = apply_filters( "acf/update_value", $value, $post_id, $field, $value ); + + // Allow null to delete value. + if( $value === null ) { + return acf_delete_value( $post_id, $field ); + } + + // Update meta. + $return = acf_update_metadata( $post_id, $field['name'], $value ); + + // Update reference. + acf_update_metadata( $post_id, $field['name'], $field['key'], true ); + + // Delete stored data. + acf_flush_value_cache( $post_id, $field['name'] ); + + // Return update status. + return $return; +} + +// Register variation. +acf_add_filter_variations( 'acf/update_value', array('type', 'name', 'key'), 2 ); + +/** + * acf_update_values + * + * Updates an array of values. + * + * @date 26/2/19 + * @since 5.7.13 + * + * @param array values The array of values. + * @param (int|string) $post_id The post id. + * @return void + */ +function acf_update_values( $values = array(), $post_id = 0 ) { + + // Loop over values. + foreach( $values as $key => $value ) { + + // Get field. + $field = acf_get_field( $key ); + + // Update value. + if( $field ) { + acf_update_value( $value, $post_id, $field ); + } + } +} + +/** + * acf_flush_value_cache + * + * Deletes all cached data for this value. + * + * @date 22/1/19 + * @since 5.7.10 + * + * @param (int|string) $post_id The post id. + * @param string $field_name The field name. + * @return void + */ +function acf_flush_value_cache( $post_id = 0, $field_name = '' ) { + + // Delete stored data. + acf_get_store( 'values' ) + ->remove( "$post_id:$field_name" ) + ->remove( "$post_id:$field_name:formatted" ); +} + +/** + * acf_delete_value + * + * Deletes the value for a given field and post_id. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param (int|string) $post_id The post id. + * @param array $field The field array. + * @return bool. + */ +function acf_delete_value( $post_id, $field ) { + + /** + * Fires before a value is deleted. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param string $post_id The post ID for this value. + * @param mixed $name The meta name. + * @param array $field The field array. + */ + do_action( "acf/delete_value", $post_id, $field['name'], $field ); + + // Delete meta. + $return = acf_delete_metadata( $post_id, $field['name'] ); + + // Delete reference. + acf_delete_metadata( $post_id, $field['name'], true ); + + // Delete stored data. + acf_flush_value_cache( $post_id, $field['name'] ); + + // Return delete status. + return $return; +} + +// Register variation. +acf_add_filter_variations( 'acf/delete_value', array('type', 'name', 'key'), 2 ); + +/** + * acf_preview_value + * + * Return a human friendly 'preview' for a given field value. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param mixed $value The new value. + * @param (int|string) $post_id The post id. + * @param array $field The field array. + * @return bool. + */ +function acf_preview_value( $value, $post_id, $field ) { + + /** + * Filters the $value before used in HTML. + * + * @date 24/10/16 + * @since 5.5.0 + * + * @param mixed $value The value to preview. + * @param string $post_id The post ID for this value. + * @param array $field The field array. + */ + return apply_filters( "acf/preview_value", $value, $post_id, $field ); +} + +// Register variation. +acf_add_filter_variations( 'acf/preview_value', array('type', 'name', 'key'), 2 ); diff --git a/includes/admin/admin-field-group.php b/includes/admin/admin-field-group.php index 9a6cc91..99e5048 100644 --- a/includes/admin/admin-field-group.php +++ b/includes/admin/admin-field-group.php @@ -213,7 +213,7 @@ class acf_admin_field_group { // set global var - $field_group = acf_get_field_group( $post ); + $field_group = acf_get_field_group( $post->ID ); // metaboxes @@ -557,7 +557,7 @@ class acf_admin_field_group { // get fields $view = array( - 'fields' => acf_get_fields_by_id( $field_group['ID'] ), + 'fields' => acf_get_fields( $field_group ), 'parent' => 0 ); diff --git a/includes/admin/admin-field-groups.php b/includes/admin/admin-field-groups.php index a6321b1..f9ac7d7 100644 --- a/includes/admin/admin-field-groups.php +++ b/includes/admin/admin-field-groups.php @@ -270,22 +270,22 @@ class acf_admin_field_groups { $modified = acf_maybe_get($group, 'modified', 0); $private = acf_maybe_get($group, 'private', false); + // Ignore if is private. + if( $private ) { + continue; - // ignore DB / PHP / private field groups - if( $local !== 'json' || $private ) { - - // do nothing - + // Ignore not local "json". + } elseif( $local !== 'json' ) { + continue; + + // Append to sync if not yet in database. } elseif( !$group['ID'] ) { - $this->sync[ $group['key'] ] = $group; - + + // Append to sync if "json" modified time is newer than database. } elseif( $modified && $modified > get_post_modified_time('U', true, $group['ID'], true) ) { - $this->sync[ $group['key'] ] = $group; - } - } @@ -334,21 +334,22 @@ class acf_admin_field_groups { // loop foreach( $sync_keys as $key ) { - // append fields - if( acf_have_local_fields($key) ) { - - $this->sync[ $key ]['fields'] = acf_get_local_fields( $key ); - + // Bail early if not found. + if( !isset($this->sync[ $key ]) ) { + continue; } + // Get field group. + $field_group = $this->sync[ $key ]; - // import - $field_group = acf_import_field_group( $this->sync[ $key ] ); + // Append fields. + $field_group['fields'] = acf_get_fields( $field_group ); + + // Import field group. + $field_group = acf_import_field_group( $field_group ); - - // append + // Append imported ID. $new_ids[] = $field_group['ID']; - } @@ -614,7 +615,6 @@ class acf_admin_field_groups { // vars $url_home = 'https://www.advancedcustomfields.com'; - $url_support = 'https://support.advancedcustomfields.com'; $icon = ''; ?> @@ -637,7 +637,7 @@ class acf_admin_field_groups {
              • -
              • +
              • diff --git a/includes/admin/tools/class-acf-admin-tool-import.php b/includes/admin/tools/class-acf-admin-tool-import.php index 360bd7b..1faaccd 100644 --- a/includes/admin/tools/class-acf-admin-tool-import.php +++ b/includes/admin/tools/class-acf-admin-tool-import.php @@ -43,20 +43,6 @@ class ACF_Admin_Tool_Import extends ACF_Admin_Tool { function html() { - // vars - $choices = array(); - $field_groups = acf_get_field_groups(); - - - // loop - if( $field_groups ) { - foreach( $field_groups as $field_group ) { - $choices[ $field_group['key'] ] = esc_html( $field_group['title'] ); - } - } - - - // html ?>

                @@ -94,166 +80,73 @@ class ACF_Admin_Tool_Import extends ACF_Admin_Tool { function submit() { - // validate + // Check file size. if( empty($_FILES['acf_import_file']['size']) ) { return acf_add_admin_notice( __("No file selected", 'acf'), 'warning' ); } - - // vars + // Get file data. $file = $_FILES['acf_import_file']; - - // validate error + // Check errors. if( $file['error'] ) { return acf_add_admin_notice( __("Error uploading file. Please try again", 'acf'), 'warning' ); } - - // validate type + // Check file type. if( pathinfo($file['name'], PATHINFO_EXTENSION) !== 'json' ) { return acf_add_admin_notice( __("Incorrect file type", 'acf'), 'warning' ); } - - // read file + // Read JSON. $json = file_get_contents( $file['tmp_name'] ); - - - // decode json $json = json_decode($json, true); - - // validate json - if( empty($json) ) { + // Check if empty. + if( !$json || !is_array($json) ) { return acf_add_admin_notice( __("Import file empty", 'acf'), 'warning' ); } - - // if importing an auto-json, wrap field group in array + // Ensure $json is an array of groups. if( isset($json['key']) ) { - - $json = array( $json ); - + $json = array( $json ); } - - // vars + // Remeber imported field group ids. $ids = array(); - $keys = array(); - $imported = array(); - - // populate keys + // Loop over json foreach( $json as $field_group ) { - // append key - $keys[] = $field_group['key']; - - } - - - // look for existing ids - foreach( $keys as $key ) { - - // attempt find ID - $field_group = _acf_get_field_group_by_key( $key ); - - - // bail early if no field group - if( !$field_group ) continue; - - - // append - $ids[ $key ] = $field_group['ID']; - - } - - - // enable local - acf_enable_local(); - - - // reset local (JSON class has already included .json field groups which may conflict) - acf_reset_local(); - - - // add local field groups - foreach( $json as $field_group ) { - - // add field group - acf_add_local_field_group( $field_group ); - - } - - - // loop over keys - foreach( $keys as $key ) { - - // vars - $field_group = acf_get_local_field_group( $key ); - - - // attempt get id - $id = acf_maybe_get( $ids, $key ); - - if( $id ) { - - $field_group['ID'] = $id; - + // Search database for existing field group. + $post = acf_get_field_group_post( $field_group['key'] ); + if( $post ) { + $field_group['ID'] = $post->ID; } + // Import field group. + $field_group = acf_import_field_group( $field_group ); - // append fields - if( acf_have_local_fields($key) ) { - - $field_group['fields'] = acf_get_local_fields( $key ); - - } - - - // import - $field_group = acf_import_field_group( $field_group ); - - - // append message - $imported[] = array( - 'ID' => $field_group['ID'], - 'title' => $field_group['title'], - 'updated' => $id ? 1 : 0 - ); - + // append message + $ids[] = $field_group['ID']; } - - // messages - if( !empty($imported) ) { - - // vars - $links = array(); - $count = count($imported); - $message = sprintf(_n( 'Imported 1 field group', 'Imported %s field groups', $count, 'acf' ), $count) . '.'; - - - // populate links - foreach( $imported as $import ) { - - $links[] = '' . $import['title'] . ''; - - } - - - // append links - $message .= ' ' . implode(', ', $links); - - - // add notice - acf_add_admin_notice( $message, 'success' ); - } + // Count number of imported field groups. + $total = count($ids); + // Generate text. + $text = sprintf( _n( 'Imported 1 field group', 'Imported %s field groups', $total, 'acf' ), $total ); + + // Add links to text. + $links = array(); + foreach( $ids as $id ) { + $links[] = '' . get_the_title( $id ) . ''; + } + $text .= ' ' . implode( ', ', $links ); + + // Add notice + acf_add_admin_notice( $text, 'success' ); } - - } // initialize diff --git a/includes/api/api-field-group.php b/includes/api/api-field-group.php deleted file mode 100644 index 9663c1a..0000000 --- a/includes/api/api-field-group.php +++ /dev/null @@ -1,1238 +0,0 @@ - 0, - 'key' => '', - 'title' => '', - 'fields' => array(), - 'location' => array(), - 'menu_order' => 0, - 'position' => 'normal', - 'style' => 'default', - 'label_placement' => 'top', - 'instruction_placement' => 'label', - 'hide_on_screen' => array(), - 'active' => 1, // Added in 5.2.9 - 'description' => '', // Added in 5.2.9 - '_valid' => 0, // Added in 5.6.2 - )); - - - // field is now valid - $field_group['_valid'] = 1; - - - // filter - $field_group = apply_filters('acf/validate_field_group', $field_group); - - - // translate - $field_group = acf_translate_field_group( $field_group ); - - - // return - return $field_group; - -} - - -/* -* acf_translate_field_group -* -* This function will translate field group's settings -* -* @type function -* @date 8/03/2016 -* @since 5.3.2 -* -* @param $field_group (array) -* @return $field_group -*/ - -function acf_translate_field_group( $field_group ) { - - // vars - $l10n = acf_get_setting('l10n'); - $l10n_textdomain = acf_get_setting('l10n_textdomain'); - - - // if - if( $l10n && $l10n_textdomain ) { - - // translate - $field_group['title'] = acf_translate( $field_group['title'] ); - - - // filters - $field_group = apply_filters( "acf/translate_field_group", $field_group ); - - } - - - // return - return $field_group; - -} - - -/* -* acf_get_field_groups -* -* This function will return an array of field groupss for the given args. Similar to the WP get_posts function -* -* @type function -* @date 30/09/13 -* @since 5.0.0 -* -* @param $args (array) -* @return $field_groups (array) -*/ - -function acf_get_field_groups( $args = false ) { - - // vars - $field_groups = array(); - $post_ids = array(); - $cache_key = "get_field_groups"; - - - // check cache for ids - if( acf_isset_cache($cache_key) ) { - - $post_ids = acf_get_cache($cache_key); - - // query DB for child ids - } else { - - // query - $posts = get_posts(array( - 'post_type' => 'acf-field-group', - 'posts_per_page' => -1, - 'orderby' => 'menu_order title', - 'order' => 'asc', - 'suppress_filters' => false, // allow WPML to modify the query - 'post_status' => array('publish', 'acf-disabled'), - 'update_post_meta_cache' => false - )); - - - // loop - if( $posts ) { - - foreach( $posts as $post ) { - - $post_ids[] = $post->ID; - - } - - } - - - // update cache - acf_set_cache($cache_key, $post_ids); - - } - - - // load field groups - foreach( $post_ids as $post_id ) { - - $field_groups[] = acf_get_field_group( $post_id ); - - } - - - // filter - // - allows local field groups to be appended - $field_groups = apply_filters('acf/get_field_groups', $field_groups); - - - // filter via args - if( $args ) { - - $field_groups = acf_filter_field_groups( $field_groups, $args ); - - } - - - // return - return $field_groups; - -} - - -/* -* acf_filter_field_groups -* -* This function is used by acf_get_field_groups to filter out fields groups based on location rules -* -* @type function -* @date 29/11/2013 -* @since 5.0.0 -* -* @param $field_groups (array) -* @param $args (array) -* @return $field_groups (array) -*/ - -function acf_filter_field_groups( $field_groups, $args = false ) { - - // bail early if empty sargs - if( empty($args) || empty($field_groups) ) { - - return $field_groups; - - } - - - // vars - $keys = array_keys( $field_groups ); - - - // loop through keys - foreach( $keys as $key ) { - - // get visibility - $visibility = acf_get_field_group_visibility( $field_groups[ $key ], $args ); - - - // unset - if( !$visibility ) { - - unset($field_groups[ $key ]); - - } - - } - - - // re assign index - $field_groups = array_values( $field_groups ); - - - // return - return $field_groups; - -} - - -/* -* acf_get_field_group_visibility -* -* This function will look at the given field group's location rules and compare them against -* the args given to see if this field group is to be shown or not. -* -* @type function -* @date 7/10/13 -* @since 5.0.0 -* -* @param $field group (array) -* @param $args (array) -* @return (boolean) -*/ - -function acf_get_field_group_visibility( $field_group, $args = array() ) { - - // bail early if not active - if( !$field_group['active'] ) return false; - - - // bail early if no location rules - if( empty($field_group['location']) ) return false; - - - // get screen - $screen = acf_get_location_screen( $args, $field_group ); - - - // loop through location rules - foreach( $field_group['location'] as $group_id => $group ) { - - // continue if no rules - if( empty($group) ) continue; - - - // vars - $match_group = true; - - - // loop - foreach( $group as $rule_id => $rule ) { - - // bail ealry if no match - if( !acf_match_location_rule( $rule, $screen ) ) { - - $match_group = false; - break; - - } - - } - - - // this group matches screen. Ignore remaining groups and retunr true - if( $match_group ) return true; - - } - - - // return - return false; -} - - -/* -* acf_get_field_group -* -* This function will take either a post object, post ID or even null (for global $post), and -* will then return a valid field group array -* -* @type function -* @date 30/09/13 -* @since 5.0.0 -* -* @param $selector (mixed) -* @return $field_group (array) -*/ - -function acf_get_field_group( $selector = null ) { - - // vars - $field_group = false; - $type = 'ID'; - - - // ID - if( is_numeric($selector) ) { - - // do nothing - - // object - } elseif( is_object($selector) ) { - - $selector = $selector->ID; - - // string - } elseif( is_string($selector) ) { - - $type = 'key'; - - // other - } else { - - return false; - - } - - - // return early if cache is found - $cache_key = "get_field_group/{$type}={$selector}"; - - if( acf_isset_cache($cache_key) ) { - - return acf_get_cache($cache_key); - - } - - - // ID - if( $type == 'ID' ) { - - $field_group = _acf_get_field_group_by_id( $selector ); - - // key - } else { - - $field_group = _acf_get_field_group_by_key( $selector ); - - } - - - // bail early if no field - if( !$field_group ) return false; - - - // validate - $field_group = acf_get_valid_field_group( $field_group ); - - - // filter for 3rd party customization - $field_group = apply_filters('acf/get_field_group', $field_group); - - - // update cache - // - Use key instead of ID for best compatibility (not all field groups exist in the DB) - $cache_key = acf_set_cache("get_field_group/key={$field_group['key']}", $field_group); - - - // update cache reference - // - allow cache to return if using an ID selector - acf_set_cache_reference("get_field_group/ID={$field_group['ID']}", $cache_key); - - - // return - return $field_group; - -} - - -/* -* _acf_get_field_group_by_id -* -* This function will get a field group by its ID -* -* @type function -* @date 27/02/2014 -* @since 5.0.0 -* -* @param $post_id (int) -* @return $field_group (array) -*/ - -function _acf_get_field_group_by_id( $post_id = 0 ) { - - // get post - $post = get_post( $post_id ); - - - // bail early if no post, or is not a field group - if( empty($post) || $post->post_type != 'acf-field-group' ) return false; - - - // modify post_status (new field-group starts as auto-draft) - if( $post->post_status == 'auto-draft' ) { - - $post->post_status = 'publish'; - - } - - - // unserialize data - $field_group = maybe_unserialize( $post->post_content ); - - - // new field group does not contain any post_content - if( empty($field_group) ) $field_group = array(); - - - // update attributes - $field_group['ID'] = $post->ID; - $field_group['title'] = $post->post_title; - $field_group['key'] = $post->post_name; - $field_group['menu_order'] = $post->menu_order; - $field_group['active'] = ($post->post_status === 'publish') ? 1 : 0; - - - // override with JSON - if( acf_is_local_field_group( $field_group['key'] ) ) { - - // load JSON field - $local = acf_get_local_field_group( $field_group['key'] ); - - - // restore ID - $local['ID'] = $post->ID; - - - // return - return $local; - - } - - - // return - return $field_group; - -} - - -/* -* _acf_get_field_group_by_key -* -* This function will get a field group by its key -* -* @type function -* @date 27/02/2014 -* @since 5.0.0 -* -* @param $key (string) -* @return $field_group (array) -*/ - -function _acf_get_field_group_by_key( $key = '' ) { - - // try JSON before DB to save query time - if( acf_is_local_field_group( $key ) ) { - - return acf_get_local_field_group( $key ); - - } - - - // vars - $post_id = acf_get_field_group_id( $key ); - - - // bail early if no post_id - if( !$post_id ) return false; - - - // return - return _acf_get_field_group_by_id( $post_id ); - -} - - -/* -* acf_get_field_group_id -* -* This function will lookup a field group's ID from the DB -* Useful for local fields to find DB sibling -* -* @type function -* @date 25/06/2015 -* @since 5.5.8 -* -* @param $key (string) -* @return $post_id (int) -*/ - -function acf_get_field_group_id( $key = '' ) { - - // vars - $args = array( - 'posts_per_page' => 1, - 'post_type' => 'acf-field-group', - 'orderby' => 'menu_order title', - 'order' => 'ASC', - 'suppress_filters' => false, - 'post_status' => array('publish', 'acf-disabled', 'trash'), - 'acf_group_key' => $key - ); - - - // load posts - $posts = get_posts( $args ); - - - // validate - if( empty($posts) ) return 0; - - - // return - return $posts[0]->ID; - -} - - -/* -* acf_update_field_group -* -* This function will update a field group into the database. -* The returned field group will always contain an ID -* -* @type function -* @date 28/09/13 -* @since 5.0.0 -* -* @param $field_group (array) -* @return $field_group (array) -*/ - -function acf_update_field_group( $field_group = array() ) { - - // validate - $field_group = acf_get_valid_field_group( $field_group ); - - - // may have been posted. Remove slashes - $field_group = wp_unslash( $field_group ); - - - // parse types (converts string '0' to int 0) - $field_group = acf_parse_types( $field_group ); - - - // locations may contain 'uniquid' array keys - $field_group['location'] = array_values( $field_group['location'] ); - - foreach( $field_group['location'] as $k => $v ) { - - $field_group['location'][ $k ] = array_values( $v ); - - } - - - // store origional field group for return - $data = $field_group; - - - // extract some args - $extract = acf_extract_vars($data, array( - 'ID', - 'key', - 'title', - 'menu_order', - 'fields', - 'active', - '_valid' - )); - - - // vars - $data = maybe_serialize( $data ); - $post_status = $extract['active'] ? 'publish' : 'acf-disabled'; - - - // save - $save = array( - 'ID' => $extract['ID'], - 'post_status' => $post_status, - 'post_type' => 'acf-field-group', - 'post_title' => $extract['title'], - 'post_name' => $extract['key'], - 'post_excerpt' => sanitize_title($extract['title']), - 'post_content' => $data, - 'menu_order' => $extract['menu_order'], - ); - - - // allow field groups to contain the same name - add_filter( 'wp_unique_post_slug', 'acf_update_field_group_wp_unique_post_slug', 100, 6 ); - - - // slash data - // - WP expects all data to be slashed and will unslash it (fixes '\' character issues) - $save = wp_slash( $save ); - - - // update the field group and update the ID - if( $field_group['ID'] ) { - - wp_update_post( $save ); - - } else { - - $field_group['ID'] = wp_insert_post( $save ); - - } - - - // action for 3rd party customization - do_action('acf/update_field_group', $field_group); - - - // clear cache - acf_delete_cache("get_field_group/key={$field_group['key']}"); - - - // return - return $field_group; - -} - -function acf_update_field_group_wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) { - - if( $post_type == 'acf-field-group' ) { - - $slug = $original_slug; - - } - - return $slug; -} - - -/* -* acf_duplicate_field_group -* -* This function will duplicate a field group into the database -* -* @type function -* @date 28/09/13 -* @since 5.0.0 -* -* @param $selector (mixed) -* @param $new_post_id (int) allow specific ID to override (good for WPML translations) -* @return $field_group (array) -*/ - -function acf_duplicate_field_group( $selector = 0, $new_post_id = 0 ) { - - // disable filters to ensure ACF loads raw data from DB - acf_disable_filters(); - - - // load the origional field gorup - $field_group = acf_get_field_group( $selector ); - - - // bail early if field group did not load correctly - if( empty($field_group) ) { - - return false; - - } - - - // keep backup of field group - $orig_field_group = $field_group; - - - // update ID - $field_group['ID'] = $new_post_id; - $field_group['key'] = uniqid('group_'); - - - // add (copy) - if( !$new_post_id ) { - - $field_group['title'] .= ' (' . __("copy", 'acf') . ')'; - - } - - - // save - $field_group = acf_update_field_group( $field_group ); - - - // get fields - $fields = acf_get_fields( $orig_field_group ); - - - // duplicate fields - acf_duplicate_fields( $fields, $field_group['ID'] ); - - - // action for 3rd party customization - do_action('acf/duplicate_field_group', $field_group); - - - // return - return $field_group; - -} - - -/* -* acf_get_field_count -* -* This function will return the number of fields for the given field group -* -* @type function -* @date 17/10/13 -* @since 5.0.0 -* -* @param $field_group_id (int) -* @return (int) -*/ - -function acf_get_field_count( $field_group ) { - - // vars - $count = 0; - - - // local - if( !$field_group['ID'] ) { - - $count = acf_count_local_fields( $field_group['key'] ); - - // DB - } else { - - // load fields - $posts = get_posts(array( - 'posts_per_page' => -1, - 'post_type' => 'acf-field', - 'orderby' => 'menu_order', - 'order' => 'ASC', - 'suppress_filters' => true, // DO NOT allow WPML to modify the query - 'post_parent' => $field_group['ID'], - 'fields' => 'ids', - 'post_status' => 'publish, trash' // 'any' won't get trashed fields - )); - - $count = count($posts); - - } - - - // filter for 3rd party customization - $count = apply_filters('acf/get_field_count', $count, $field_group); - - - // return - return $count; - -} - - -/* -* acf_delete_field_group -* -* This function will delete the field group and its fields from the DB -* -* @type function -* @date 5/12/2013 -* @since 5.0.0 -* -* @param $selector (mixed) -* @return (boolean) -*/ - -function acf_delete_field_group( $selector = 0 ) { - - // disable filters to ensure ACF loads raw data from DB - acf_disable_filters(); - - - // load the origional field gorup - $field_group = acf_get_field_group( $selector ); - - - // bail early if field group did not load correctly - if( empty($field_group) ) return false; - - - // get fields - $fields = acf_get_fields($field_group); - - - if( !empty($fields) ) { - - foreach( $fields as $field ) { - - acf_delete_field( $field['ID'] ); - - } - - } - - - // delete - wp_delete_post( $field_group['ID'] ); - - - // action for 3rd party customization - do_action('acf/delete_field_group', $field_group); - - - // return - return true; -} - - -/* -* acf_trash_field_group -* -* This function will trash the field group and its fields -* -* @type function -* @date 5/12/2013 -* @since 5.0.0 -* -* @param $selector (mixed) -* @return (boolean) -*/ - -function acf_trash_field_group( $selector = 0 ) { - - // disable filters to ensure ACF loads raw data from DB - acf_disable_filters(); - - - // load the origional field gorup - $field_group = acf_get_field_group( $selector ); - - - // bail early if field group did not load correctly - if( empty($field_group) ) return false; - - - // get fields - $fields = acf_get_fields($field_group); - - - if( !empty($fields) ) { - - foreach( $fields as $field ) { - - acf_trash_field( $field['ID'] ); - - } - - } - - - // delete - wp_trash_post( $field_group['ID'] ); - - - // action for 3rd party customization - do_action('acf/trash_field_group', $field_group); - - - // return - return true; -} - - -/* -* acf_untrash_field_group -* -* This function will restore from trash the field group and its fields -* -* @type function -* @date 5/12/2013 -* @since 5.0.0 -* -* @param $selector (mixed) -* @return (boolean) -*/ - -function acf_untrash_field_group( $selector = 0 ) { - - // disable filters to ensure ACF loads raw data from DB - acf_disable_filters(); - - - // load the origional field gorup - $field_group = acf_get_field_group( $selector ); - - - // bail early if field group did not load correctly - if( empty($field_group) ) return false; - - - // get fields - $fields = acf_get_fields($field_group); - - - if( !empty($fields) ) { - - foreach( $fields as $field ) { - - acf_untrash_field( $field['ID'] ); - - } - - } - - - // delete - wp_untrash_post( $field_group['ID'] ); - - - // action for 3rd party customization - do_action('acf/untrash_field_group', $field_group); - - - // return - return true; -} - - - -/* -* acf_get_field_group_style -* -* This function will render the CSS for a given field group -* -* @type function -* @date 20/10/13 -* @since 5.0.0 -* -* @param $field_group (array) -* @return n/a -*/ - -function acf_get_field_group_style( $field_group ) { - - // vars - $style = ''; - $elements = array( - 'permalink' => '#edit-slug-box', - 'the_content' => '#postdivrich', - 'excerpt' => '#postexcerpt', - 'custom_fields' => '#postcustom', - 'discussion' => '#commentstatusdiv', - 'comments' => '#commentsdiv', - 'slug' => '#slugdiv', - 'author' => '#authordiv', - 'format' => '#formatdiv', - 'page_attributes' => '#pageparentdiv', - 'featured_image' => '#postimagediv', - 'revisions' => '#revisionsdiv', - 'categories' => '#categorydiv', - 'tags' => '#tagsdiv-post_tag', - 'send-trackbacks' => '#trackbacksdiv' - ); - - // loop over field group settings and generate list of selectors to hide - if( is_array($field_group['hide_on_screen']) ) { - $hide = array(); - foreach( $field_group['hide_on_screen'] as $k ) { - if( isset($elements[ $k ]) ) { - $id = $elements[ $k ]; - $hide[] = $id; - $hide[] = '#screen-meta label[for=' . substr($id, 1) . '-hide]'; - } - } - $style = implode(', ', $hide) . ' {display: none;}'; - } - - // return - return apply_filters('acf/get_field_group_style', $style, $field_group); -} - - -/* -* acf_import_field_group -* -* This function will import a field group from JSON into the DB -* -* @type function -* @date 10/12/2014 -* @since 5.1.5 -* -* @param $field_group (array) -* @return $id (int) -*/ - -function acf_import_field_group( $field_group ) { - - // disable filters to ensure ACF loads raw data from DB - acf_disable_filters(); - - - // vars - $ref = array(); - $order = array(); - - - // extract fields - $fields = acf_extract_var($field_group, 'fields'); - - - // format fields - $fields = acf_prepare_fields_for_import( $fields ); - - - // remove old fields - if( $field_group['ID'] ) { - - // load fields - $db_fields = acf_get_fields_by_id( $field_group['ID'] ); - $db_fields = acf_prepare_fields_for_import( $db_fields ); - - - // get field keys - $keys = array(); - foreach( $fields as $field ) { - - $keys[] = $field['key']; - - } - - - // loop over db fields - foreach( $db_fields as $field ) { - - // add to ref - $ref[ $field['key'] ] = $field['ID']; - - - if( !in_array($field['key'], $keys) ) { - - acf_delete_field( $field['ID'] ); - - } - - } - - } - - - // enable local filter for JSON to be created - acf_enable_filter('local'); - - - // save field group - $field_group = acf_update_field_group( $field_group ); - - - // add to ref - $ref[ $field_group['key'] ] = $field_group['ID']; - - - // add to order - $order[ $field_group['ID'] ] = 0; - - - // add fields - foreach( $fields as $field ) { - - // add ID - if( !$field['ID'] && isset($ref[ $field['key'] ]) ) { - - $field['ID'] = $ref[ $field['key'] ]; - - } - - - // add parent - if( empty($field['parent']) ) { - - $field['parent'] = $field_group['ID']; - - } elseif( isset($ref[ $field['parent'] ]) ) { - - $field['parent'] = $ref[ $field['parent'] ]; - - } - - - // add field menu_order - if( !isset($order[ $field['parent'] ]) ) { - - $order[ $field['parent'] ] = 0; - - } - - $field['menu_order'] = $order[ $field['parent'] ]; - $order[ $field['parent'] ]++; - - - // save field - $field = acf_update_field( $field ); - - - // add to ref - $ref[ $field['key'] ] = $field['ID']; - - } - - - // return new field group - return $field_group; - -} - - -/* -* acf_prepare_field_group_for_export -* -* description -* -* @type function -* @date 4/12/2015 -* @since 5.3.2 -* -* @param $post_id (int) -* @return $post_id (int) -*/ - -function acf_prepare_field_group_for_export( $field_group ) { - - // extract some args - $extract = acf_extract_vars($field_group, array( - 'ID', - 'local', // local may have added 'php' or 'json' - '_valid', - )); - - - // prepare fields - $field_group['fields'] = acf_prepare_fields_for_export( $field_group['fields'] ); - - - // filter for 3rd party customization - $field_group = apply_filters('acf/prepare_field_group_for_export', $field_group); - - - // return - return $field_group; -} - -/** -* acf_get_field_group_edit_link -* -* Checks if the current user can edit the field group and returns the edit url. -* -* @date 23/9/18 -* @since 5.7.7 -* -* @param int $post_id The field group ID. -* @return string -*/ -function acf_get_field_group_edit_link( $post_id ) { - if( $post_id && acf_current_user_can_admin() ) { - return admin_url('post.php?post=' . $post_id . '&action=edit'); - } - return ''; -} - - -?> \ No newline at end of file diff --git a/includes/api/api-field.php b/includes/api/api-field.php deleted file mode 100644 index 9b41bfc..0000000 --- a/includes/api/api-field.php +++ /dev/null @@ -1,2177 +0,0 @@ - 0, - 'key' => '', - 'label' => '', - 'name' => '', - 'prefix' => '', - 'type' => 'text', - 'value' => null, - 'menu_order' => 0, - 'instructions' => '', - 'required' => 0, - 'id' => '', - 'class' => '', - 'conditional_logic' => 0, - 'parent' => 0, - 'wrapper' => array(), - '_name' => '', - '_prepare' => 0, - '_valid' => 0, - )); - - $field['wrapper'] = wp_parse_args($field['wrapper'], array( - 'width' => '', - 'class' => '', - 'id' => '' - )); - - - // _name - $field['_name'] = $field['name']; - - - // field is now valid - $field['_valid'] = 1; - - - /** - * Filters the $field array to validate settings. - * - * @date 12/02/2014 - * @since 5.0.0 - * - * @param array $field The field array. - */ - $field = apply_filters( "acf/validate_field/type={$field['type']}", $field ); - $field = apply_filters( "acf/validate_field", $field ); - - - // translate - $field = acf_translate_field( $field ); - - - // return - return $field; - -} - - -/* -* acf_translate_field -* -* This function will translate field's settings -* -* @type function -* @date 8/03/2016 -* @since 5.3.2 -* -* @param $field (array) -* @return $field -*/ - -function acf_translate_field( $field ) { - - // vars - $l10n = acf_get_setting('l10n'); - $l10n_textdomain = acf_get_setting('l10n_textdomain'); - - - // if - if( $l10n && $l10n_textdomain ) { - - // translate - $field['label'] = acf_translate( $field['label'] ); - $field['instructions'] = acf_translate( $field['instructions'] ); - - - /** - * Filters the $field array to translate strings. - * - * @date 12/02/2014 - * @since 5.0.0 - * - * @param array $field The field array. - */ - $field = apply_filters( "acf/translate_field/type={$field['type']}", $field ); - $field = apply_filters( "acf/translate_field", $field ); - - } - - - // return - return $field; - -} - - -/* -* acf_clone_field -* -* This function will allow customization to a field when it is cloned -* Cloning a field is the act of mimicing another. Some settings may need to be altered -* -* @type function -* @date 8/03/2016 -* @since 5.3.2 -* -* @param $field (array) -* @return $field -*/ - -function acf_clone_field( $field, $clone_field ) { - - // add reference - $field['_clone'] = $clone_field['key']; - - - /** - * Filters the $field array when it is being cloned. - * - * @date 12/02/2014 - * @since 5.0.0 - * - * @param array $field The field array. - * @param array $clone_field The clone field array. - */ - $field = apply_filters( "acf/clone_field/type={$field['type']}", $field, $clone_field ); - $field = apply_filters( "acf/clone_field", $field, $clone_field ); - - - // return - return $field; - -} - - -/* -* acf_prepare_field -* -* This function will prepare the field for input -* -* @type function -* @date 12/02/2014 -* @since 5.0.0 -* -* @param $field (array) -* @return $field (array) -*/ - -function acf_prepare_field( $field ) { - - // bail early if already prepared - if( $field['_prepare'] ) return $field; - - - // key overrides name - if( $field['key'] ) $field['name'] = $field['key']; - - - // prefix - if( $field['prefix'] ) $field['name'] = $field['prefix'] . '[' . $field['name'] . ']'; - - - // field is now prepared - $field['_prepare'] = 1; - - - /** - * Filters the $field array. - * - * Allows developers to modify field settings or return false to remove field. - * - * @date 12/02/2014 - * @since 5.0.0 - * - * @param array $field The field array. - */ - $field = apply_filters( "acf/prepare_field/type={$field['type']}", $field ); - $field = apply_filters( "acf/prepare_field/name={$field['_name']}", $field ); - $field = apply_filters( "acf/prepare_field/key={$field['key']}", $field ); - $field = apply_filters( "acf/prepare_field", $field ); - - - // bail ealry if no field - if( !$field ) return false; - - - // id attr is generated from name - $field['id'] = acf_idify( $field['name'] ); - - - // return - return $field; - -} - - -/* -* acf_is_sub_field -* -* This function will return true if the field is a sub field -* -* @type function -* @date 17/05/2014 -* @since 5.0.0 -* -* @param $field (array) -* @return (boolean) -*/ - -function acf_is_sub_field( $field ) { - - // local field uses a field instead of ID - if( acf_is_field_key($field['parent']) ) return true; - - - // attempt to load parent field - if( acf_get_field($field['parent']) ) return true; - - - // return - return false; - -} - - -/* -* acf_get_field_label -* -* This function will return the field label with appropriate required label -* -* @type function -* @date 4/11/2013 -* @since 5.0.0 -* -* @param $field (array) -* @return $label (string) -*/ - -function acf_get_field_label( $field, $context = '' ) { - - // vars - $label = $field['label']; - - - // show (no label) when editing field - if( $context == 'admin' && $label === '' ) { - $label = __('(no label)', 'acf'); - } - - - // required - if( $field['required'] ) { - $label .= ' *'; - } - - - // filter for 3rd party customization - $label = apply_filters("acf/get_field_label", $label, $field); - - - // return - return $label; - -} - -function acf_the_field_label( $field ) { - - echo acf_get_field_label( $field ); - -} - - -/* -* acf_render_fields -* -* This function will render an array of fields for a given form. -* Becasue the $field's values have not been loaded yet, this function will also load values -* -* @type function -* @date 8/10/13 -* @since 5.0.0 -* -* @param $post_id (int) the post to load values from -* @param $fields (array) the fields to render -* @param $el (string) the wrapping element type -* @param $instruction (int) the instructions position -* @return n/a -*/ - -function acf_render_fields( $fields, $post_id = 0, $el = 'div', $instruction = 'label' ) { - - // parameter order changed in ACF 5.6.9 - if( is_array($post_id) ) { - $args = func_get_args(); - $fields = $args[1]; - $post_id = $args[0]; - } - - // filter - $fields = apply_filters('acf/pre_render_fields', $fields, $post_id); - - // bail early if no fields - if( empty($fields) ) return; - - // loop - foreach( $fields as $field ) { - - // bail ealry if no field - if( !$field ) continue; - - // load value - if( $field['value'] === null ) { - $field['value'] = acf_get_value( $post_id, $field ); - } - - // render - acf_render_field_wrap( $field, $el, $instruction ); - } - - // action - do_action( 'acf/render_fields', $fields, $post_id ); -} - - -/* -* acf_render_field -* -* This function will render a field input -* -* @type function -* @date 28/09/13 -* @since 5.0.0 -* -* @param $field (array) -* @return n/a -*/ - -function acf_render_field( $field = false ) { - - // get valid field - $field = acf_get_valid_field( $field ); - - - // prepare field for input - $field = acf_prepare_field( $field ); - - - // bail ealry if no field - if( !$field ) return; - - - /** - * Fires when rendering a field. - * - * @date 12/02/2014 - * @since 5.0.0 - * - * @param array $field The field array. - */ - do_action( "acf/render_field/type={$field['type']}", $field ); - do_action( "acf/render_field/name={$field['_name']}", $field ); - do_action( "acf/render_field/key={$field['key']}", $field ); - do_action( "acf/render_field", $field ); -} - - -/* -* acf_render_field_wrap -* -* This function will render the complete HTML wrap with label & field -* -* @type function -* @date 28/09/13 -* @since 5.0.0 -* -* @param $field (array) must be a valid ACF field array -* @param $el (string) modifys the rendered wrapping elements. Default to 'div', but can be 'tr', 'ul', 'ol', 'dt' or custom -* @param $instruction (string) specifys the placement of the instructions. Default to 'label', but can be 'field' -* @param $atts (array) an array of custom attributes to render on the $el -* @return N/A -*/ - -function acf_render_field_wrap( $field, $el = 'div', $instruction = 'label' ) { - - // get valid field - $field = acf_get_valid_field( $field ); - - - // prepare field for input - $field = acf_prepare_field( $field ); - - - // bail ealry if no field - if( !$field ) return; - - - // elements - $elements = array( - 'div' => 'div', - 'tr' => 'td', - 'ul' => 'li', - 'ol' => 'li', - 'dl' => 'dt', - 'td' => 'div' // special case for sub field! - ); - - - // vars - $el = isset($elements[ $el ]) ? $el : 'div'; - $el2 = $elements[ $el ]; - $show_label = ($el !== 'td') ? true : false; - - - // wrapper - $wrapper = array( - 'id' => '', - 'class' => 'acf-field', - 'width' => '', - 'style' => '', - 'data-name' => $field['_name'], - 'data-type' => $field['type'], - 'data-key' => '', - ); - - - // add required - if( $field['required'] ) { - $wrapper['data-required'] = 1; - } - - - // add type - $wrapper['class'] .= " acf-field-{$field['type']}"; - - - // add key - if( $field['key'] ) { - - $wrapper['class'] .= " acf-field-{$field['key']}"; - $wrapper['data-key'] = $field['key']; - - } - - - // replace - $wrapper['class'] = str_replace('_', '-', $wrapper['class']); - $wrapper['class'] = str_replace('field-field-', 'field-', $wrapper['class']); - - - // wrap classes have changed (5.2.7) - if( acf_get_compatibility('field_wrapper_class') ) { - - $wrapper['class'] .= " field_type-{$field['type']}"; - - if( $field['key'] ) { - - $wrapper['class'] .= " field_key-{$field['key']}"; - - } - - } - - - // merge in atts - $wrapper = acf_merge_atts( $wrapper, $field['wrapper'] ); - - - // add width - $width = (int) acf_extract_var( $wrapper, 'width' ); - - if( $el == 'tr' || $el == 'td' ) { - - // do nothing - - } elseif( $width > 0 && $width < 100 ) { - - $wrapper['data-width'] = $width; - $wrapper['style'] .= " width:{$width}%;"; - - } - - - // remove empty attributes - $wrapper = array_filter($wrapper); - - - // conditional logic - if( !empty($field['conditional_logic']) ) { - $field['conditions'] = $field['conditional_logic']; - } - - // conditions - if( !empty($field['conditions']) ) { - $wrapper['data-conditions'] = $field['conditions']; - } - - - // html - ?> -< > - - < class="acf-label">> - - < class="acf-input"> - - - > -> -' . acf_esc_html($label) . ''; - } - -} - - -/* depreciated since 5.6.5 */ -function acf_render_field_wrap_label( $field ) { - acf_render_field_label( $field ); -} - - -/** -* acf_render_field_instructions -* -* This function will maybe output the field's instructions -* -* @date 19/9/17 -* @since 5.6.3 -* -* @param array $field -* @return n/a -*/ - -function acf_render_field_instructions( $field ) { - - // vars - $instructions = $field['instructions']; - - - // check - if( $instructions ) { - echo '

                ' . acf_esc_html($instructions) . '

                '; - } - -} - - -/* depreciated since 5.6.5 */ -function acf_render_field_wrap_description( $field ) { - acf_render_field_instructions( $field ); -} - - -/* -* acf_render_field_setting -* -* This function will render a tr element containing a label and field cell, but also setting the tr data attribute for AJAX -* -* @type function -* @date 28/09/13 -* @since 5.0.0 -* -* @param $field (array) the origional field being edited -* @param $setting (array) the settings field to create -* @return n/a -*/ - -function acf_render_field_setting( $field, $setting, $global = false ) { - - // validate - $setting = acf_get_valid_field( $setting ); - - // custom key and class - $setting['wrapper']['data-key'] = $setting['name']; - $setting['wrapper']['class'] .= ' acf-field-setting-' . $setting['name']; - - // context - if( !$global ) { - $setting['wrapper']['data-setting'] = $field['type']; - } - - // copy across prefix - $setting['prefix'] = $field['prefix']; - - // attempt find value - if( $setting['value'] === null ) { - - // name - if( isset($field[ $setting['name'] ]) ) { - $setting['value'] = $field[ $setting['name'] ]; - - // default - } elseif( isset($setting['default_value']) ) { - $setting['value'] = $setting['default_value']; - } - } - - // append (used by JS to join settings) - if( isset($setting['_append']) ) { - $setting['wrapper']['data-append'] = $setting['_append']; - } - - // render - acf_render_field_wrap( $setting, 'tr', 'label' ); -} - - -/* -* acf_get_fields -* -* This function will return an array of fields for the given $parent -* -* @type function -* @date 30/09/13 -* @since 5.0.0 -* -* @param $parent (array) a field or field group -* @return (array) -*/ - -function acf_get_fields( $parent = false ) { - - // allow $parent to be a field group ID - if( !is_array($parent) ) { - - $parent = acf_get_field_group( $parent ); - - } - - - // bail early if no parent - if( !$parent ) return false; - - - // vars - $fields = array(); - - - // try JSON before DB to save query time - if( acf_have_local_fields( $parent['key'] ) ) { - - $fields = acf_get_local_fields( $parent['key'] ); - - } else { - - $fields = acf_get_fields_by_id( $parent['ID'] ); - - } - - - // filter - $fields = apply_filters('acf/load_fields', $fields, $parent); - $fields = apply_filters('acf/get_fields', $fields, $parent); - - - // return - return $fields; - -} - - -/* -* acf_get_fields_by_id -* -* This function will get all fields for the given parent -* -* @type function -* @date 27/02/2014 -* @since 5.0.0 -* -* @param $post_id (int) -* @return $fields (array) -*/ - -function acf_get_fields_by_id( $parent_id = 0 ) { - - // bail early if no ID - if( !$parent_id ) return false; - - - // vars - $fields = array(); - $post_ids = array(); - $cache_key = "get_fields/ID={$parent_id}"; - - - // check cache for child ids - if( acf_isset_cache($cache_key) ) { - - $post_ids = acf_get_cache($cache_key); - - // query DB for child ids - } else { - - // query - $posts = get_posts(array( - 'posts_per_page' => -1, - 'post_type' => 'acf-field', - 'orderby' => 'menu_order', - 'order' => 'ASC', - 'suppress_filters' => true, // DO NOT allow WPML to modify the query - 'post_parent' => $parent_id, - 'post_status' => 'publish, trash', // 'any' won't get trashed fields - 'update_post_meta_cache' => false, - 'update_post_term_cache' => false - )); - - - // loop - if( $posts ) { - - foreach( $posts as $post ) { - - $post_ids[] = $post->ID; - - } - - } - - - // update cache - acf_set_cache($cache_key, $post_ids); - - } - - - // bail early if no children - if( empty($post_ids) ) return false; - - - // load fields - foreach( $post_ids as $post_id ) { - - $fields[] = acf_get_field( $post_id ); - - } - - - // return - return $fields; - -} - - -/* -* acf_get_field -* -* This function will return a field for the given selector. -* -* @type function -* @date 30/09/13 -* @since 5.0.0 -* -* @param $selector (mixed) identifyer of field. Can be an ID, key, name or post object -* @param $db_only (boolean) return $field in it's raw form without filters or cache -* @return $field (array) -*/ - -function acf_get_field( $selector = null, $db_only = false ) { - - // vars - $field = false; - $type = 'ID'; - - - // ID - if( is_numeric($selector) ) { - - // do nothing - - // object - } elseif( is_object($selector) ) { - - $selector = $selector->ID; - - // string - } elseif( is_string($selector) ) { - - $type = acf_is_field_key($selector) ? 'key' : 'name'; - - // other - } else { - - return false; - - } - - - // return early if cache is found - $cache_key = "get_field/{$type}={$selector}"; - - if( !$db_only && acf_isset_cache($cache_key) ) { - - return acf_get_cache($cache_key); - - } - - - // ID - if( $type == 'ID' ) { - - $field = _acf_get_field_by_id( $selector, $db_only ); - - // key - } elseif( $type == 'key' ) { - - $field = _acf_get_field_by_key( $selector, $db_only ); - - // name (rare case) - } else { - - $field = _acf_get_field_by_name( $selector, $db_only ); - - } - - - // bail early if no field - if( !$field ) return false; - - - // validate - $field = acf_get_valid_field( $field ); - - - // set prefix (acf fields save with prefix 'acf') - $field['prefix'] = 'acf'; - - - // bail early if db only value (no need to update cache) - if( $db_only ) return $field; - - - /** - * Filters the $field array after it has been loaded. - * - * @date 12/02/2014 - * @since 5.0.0 - * - * @param array $field The field array. - */ - $field = apply_filters( "acf/load_field/type={$field['type']}", $field ); - $field = apply_filters( "acf/load_field/name={$field['_name']}", $field ); - $field = apply_filters( "acf/load_field/key={$field['key']}", $field ); - $field = apply_filters( "acf/load_field", $field ); - - - // update cache - // - Use key instead of ID for best compatibility (not all fields exist in the DB) - $cache_key = acf_set_cache("get_field/key={$field['key']}", $field); - - - // update cache reference - // - allow cache to return if using an ID selector - acf_set_cache_reference("get_field/ID={$field['ID']}", $cache_key); - - - // return - return $field; - -} - - -/* -* _acf_get_field_by_id -* -* This function will get a field via its ID -* -* @type function -* @date 27/02/2014 -* @since 5.0.0 -* -* @param $post_id (int) -* @return $field (array) -*/ - -function _acf_get_field_by_id( $post_id = 0, $db_only = false ) { - - // get post - $post = get_post( $post_id ); - - - // bail early if no post, or is not a field - if( empty($post) || $post->post_type != 'acf-field' ) return false; - - - // unserialize - $field = maybe_unserialize( $post->post_content ); - - - // update attributes - $field['ID'] = $post->ID; - $field['key'] = $post->post_name; - $field['label'] = $post->post_title; - $field['name'] = $post->post_excerpt; - $field['menu_order'] = $post->menu_order; - $field['parent'] = $post->post_parent; - - - // override with JSON - if( !$db_only && acf_is_local_field($field['key']) ) { - - // load JSON field - $local = acf_get_local_field( $field['key'] ); - - - // override IDs - $local['ID'] = $field['ID']; - $local['parent'] = $field['parent']; - - - // return - return $local; - - } - - - // return - return $field; - -} - - -/* -* _acf_get_field_by_key -* -* This function will get a field via its key -* -* @type function -* @date 27/02/2014 -* @since 5.0.0 -* -* @param $key (string) -* @return $field (array) -*/ - -function _acf_get_field_by_key( $key = '', $db_only = false ) { - - // try JSON before DB to save query time - if( !$db_only && acf_is_local_field( $key ) ) { - - return acf_get_local_field( $key ); - - } - - - // vars - $post_id = acf_get_field_id( $key ); - - - // bail early if no post_id - if( !$post_id ) return false; - - - // return - return _acf_get_field_by_id( $post_id, $db_only ); - -} - - -/* -* _acf_get_field_by_name -* -* This function will get a field via its name -* -* @type function -* @date 27/02/2014 -* @since 5.0.0 -* -* @param $key (string) -* @return $field (array) -*/ - -function _acf_get_field_by_name( $name = '', $db_only = false ) { - - // try JSON before DB to save query time - if( !$db_only && acf_is_local_field( $name ) ) { - - return acf_get_local_field( $name ); - - } - - - // vars - $args = array( - 'posts_per_page' => 1, - 'post_type' => 'acf-field', - 'orderby' => 'menu_order title', - 'order' => 'ASC', - 'suppress_filters' => false, - 'acf_field_name' => $name, - 'update_post_meta_cache' => false, - 'update_post_term_cache' => false - ); - - - // load posts - $posts = get_posts( $args ); - - - // bail early if no posts - if( empty($posts) ) return false; - - - // return - return _acf_get_field_by_id( $posts[0]->ID, $db_only ); - -} - - -/* -* acf_maybe_get_field -* -* This function will return a field for the given selector. -* It will also review the field_reference to ensure the correct field is returned which makes it useful for the template API -* -* @type function -* @date 4/08/2015 -* @since 5.2.3 -* -* @param $selector (mixed) identifyer of field. Can be an ID, key, name or post object -* @param $post_id (mixed) the post_id of which the value is saved against -* @param $strict (boolean) if true, return a field only when a field key is found. -* @return $field (array) -*/ - -function acf_maybe_get_field( $selector, $post_id = false, $strict = true ) { - - // init - acf_init(); - - - // bail early if is field key - if( acf_is_field_key($selector) ) { - - return acf_get_field( $selector ); - - } - - - // save selector as field_name (could be sub field name 'images_0_image') - $field_name = $selector; - - - // get valid post_id - $post_id = acf_get_valid_post_id( $post_id ); - - - // get reference - $field_key = acf_get_reference( $selector, $post_id ); - - - // update selector - if( $field_key ) { - - $selector = $field_key; - - // bail early if no reference - } elseif( $strict ) { - - return false; - - } - - - // get field - $field = acf_get_field( $selector ); - - - // update name - if( $field ) $field['name'] = $field_name; - - - // return - return $field; - -} - - -/* -* acf_get_field_id -* -* This function will lookup a field's ID from the DB -* Useful for local fields to find DB sibling -* -* @type function -* @date 25/06/2015 -* @since 5.2.3 -* -* @param $key (string) -* @return $post_id (int) -*/ - -function acf_get_field_id( $key = '' ) { - - // vars - $args = array( - 'posts_per_page' => 1, - 'post_type' => 'acf-field', - 'orderby' => 'menu_order title', - 'order' => 'ASC', - 'suppress_filters' => false, - 'acf_field_key' => $key, - 'update_post_meta_cache' => false, - 'update_post_term_cache' => false - ); - - - // load posts - $posts = get_posts( $args ); - - - // validate - if( empty($posts) ) return 0; - - - // return - return $posts[0]->ID; - -} - - -/* -* acf_update_field -* -* This function will update a field into the DB. -* The returned field will always contain an ID -* -* @type function -* @date 1/10/13 -* @since 5.0.0 -* -* @param $field (array) -* @return $field (array) -*/ - -function acf_update_field( $field = false, $specific = false ) { - - // $field must be an array - if( !is_array($field) ) return false; - - - // validate - $field = acf_get_valid_field( $field ); - - - // may have been posted. Remove slashes - $field = wp_unslash( $field ); - - - // parse types (converts string '0' to int 0) - $field = acf_parse_types( $field ); - - - // clean up conditional logic keys - if( !empty($field['conditional_logic']) ) { - - // extract groups - $groups = acf_extract_var( $field, 'conditional_logic' ); - - - // clean array - $groups = array_filter($groups); - $groups = array_values($groups); - - - // clean rules - foreach( array_keys($groups) as $i ) { - - $groups[ $i ] = array_filter($groups[ $i ]); - $groups[ $i ] = array_values($groups[ $i ]); - - } - - - // reset conditional logic - $field['conditional_logic'] = $groups; - - } - - - // parent may be a field key - // - lookup parent ID - if( acf_is_field_key($field['parent']) ) { - - $field['parent'] = acf_get_field_id( $field['parent'] ); - - } - - - /** - * Filters the $field array before it is updated. - * - * @date 12/02/2014 - * @since 5.0.0 - * - * @param array $field The field array. - */ - $field = apply_filters( "acf/update_field/type={$field['type']}", $field ); - $field = apply_filters( "acf/update_field/name={$field['_name']}", $field ); - $field = apply_filters( "acf/update_field/key={$field['key']}", $field ); - $field = apply_filters( "acf/update_field", $field ); - - - // store origional field for return - $data = $field; - - - // extract some args - $extract = acf_extract_vars($data, array( - 'ID', - 'key', - 'label', - 'name', - 'prefix', - 'value', - 'menu_order', - 'id', - 'class', - 'parent', - '_name', - '_prepare', - '_valid', - )); - - - // serialize for DB - $data = maybe_serialize( $data ); - - - // save - $save = array( - 'ID' => $extract['ID'], - 'post_status' => 'publish', - 'post_type' => 'acf-field', - 'post_title' => $extract['label'], - 'post_name' => $extract['key'], - 'post_excerpt' => $extract['name'], - 'post_content' => $data, - 'post_parent' => $extract['parent'], - 'menu_order' => $extract['menu_order'], - ); - - - // specific - if( acf_is_array($specific) ) { - - // append ID - $specific[] = 'ID'; - - - // get sub array - $save = acf_get_sub_array( $save, $specific ); - - } - - - // allow fields to contain the same name - add_filter( 'wp_unique_post_slug', 'acf_update_field_wp_unique_post_slug', 999, 6 ); - - - // slash data - // - WP expects all data to be slashed and will unslash it (fixes '\' character issues) - $save = wp_slash( $save ); - - - // update the field and update the ID - if( $field['ID'] ) { - - wp_update_post( $save ); - - } else { - - $field['ID'] = wp_insert_post( $save ); - - } - - - // clear cache - acf_delete_cache("get_field/key={$field['key']}"); - - - // return - return $field; - -} - -function acf_update_field_wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) { - - if( $post_type == 'acf-field' ) { - - $slug = $original_slug; - - } - - // return - return $slug; - -} - - -/* -* acf_duplicate_fields -* -* This function will duplicate an array of fields and update conditional logic references -* -* @type function -* @date 16/06/2014 -* @since 5.0.0 -* -* @param $fields (array) -* @param $new_parent (int) -* @return n/a -*/ - -function acf_duplicate_fields( $fields, $new_parent = 0 ) { - - // bail early if no fields - if( empty($fields) ) return; - - - // create new field keys (for conditional logic fixes) - foreach( $fields as $field ) { - - // ensure a delay for unique ID - usleep(1); - - acf_update_setting( 'duplicate_key_' . $field['key'] , uniqid('field_') ); - - } - - - // duplicate fields - foreach( $fields as $field ) { - - // duplicate - acf_duplicate_field( $field['ID'], $new_parent ); - - } - -} - - -/* -* acf_duplicate_field -* -* This function will duplicate a field and attach it to the given field group ID -* -* @type function -* @date 17/10/13 -* @since 5.0.0 -* -* @param $selector (int) -* @param $new_parent (int) -* @return $field (array) the new field -*/ - -function acf_duplicate_field( $selector = 0, $new_parent = 0 ){ - - // disable filters to ensure ACF loads raw data from DB - acf_disable_filters(); - - - // load the origional field - $field = acf_get_field( $selector ); - - - // bail early if field did not load correctly - if( empty($field) ) { - - return false; - - } - - - // update ID - $field['ID'] = false; - - - // try duplicate keys - $field['key'] = acf_get_setting( 'duplicate_key_' . $field['key'] ); - - - // default key - if( empty($field['key']) ) { - - $field['key'] = uniqid('field_'); - - } - - - // update parent - if( $new_parent ) { - - $field['parent'] = $new_parent; - - } - - - // update conditional logic references (because field keys have changed) - if( !empty($field['conditional_logic']) ) { - - // extract groups - $groups = acf_extract_var( $field, 'conditional_logic' ); - - - // loop over groups - foreach( array_keys($groups) as $g ) { - - // extract group - $group = acf_extract_var( $groups, $g ); - - - // bail early if empty - if( empty($group) ) { - - continue; - - } - - - // loop over rules - foreach( array_keys($group) as $r ) { - - // extract rule - $rule = acf_extract_var( $group, $r ); - - - // vars - $new_key = acf_get_setting( 'duplicate_key_' . $rule['field'] ); - - - // update rule with new key - if( $new_key ) { - - $rule['field'] = $new_key; - - } - - - // append to group - $group[ $r ] = $rule; - - } - - - // append to groups - $groups[ $g ] = $group; - - } - - - // update conditional logic - $field['conditional_logic'] = $groups; - - - } - - - /** - * Filters the $field array after it has been duplicated. - * - * @date 12/02/2014 - * @since 5.0.0 - * - * @param array $field The field array. - */ - $field = apply_filters( "acf/duplicate_field/type={$field['type']}", $field ); - $field = apply_filters( "acf/duplicate_field", $field); - - - // save - return acf_update_field( $field ); - -} - - -/* -* acf_delete_field -* -* This function will delete a field from the databse -* -* @type function -* @date 2/10/13 -* @since 5.0.0 -* -* @param $id (int) -* @return (boolean) -*/ - -function acf_delete_field( $selector = 0 ) { - - // disable filters to ensure ACF loads raw data from DB - acf_disable_filters(); - - - // load the origional field gorup - $field = acf_get_field( $selector ); - - - // bail early if field did not load correctly - if( empty($field) ) return false; - - - // delete field - wp_delete_post( $field['ID'], true ); - - - /** - * Fires immediately after a field has been deleted. - * - * @date 12/02/2014 - * @since 5.0.0 - * - * @param array $field The field array. - */ - do_action( "acf/delete_field/type={$field['type']}", $field ); - do_action( "acf/delete_field/name={$field['_name']}", $field ); - do_action( "acf/delete_field/key={$field['key']}", $field ); - do_action( "acf/delete_field", $field ); - - - // clear cache - acf_delete_cache("get_field/key={$field['key']}"); - - - // return - return true; - -} - - -/* -* acf_trash_field -* -* This function will trash a field from the databse -* -* @type function -* @date 2/10/13 -* @since 5.0.0 -* -* @param $id (int) -* @return (boolean) -*/ - -function acf_trash_field( $selector = 0 ) { - - // disable filters to ensure ACF loads raw data from DB - acf_disable_filters(); - - - // load the origional field gorup - $field = acf_get_field( $selector ); - - - // bail early if field did not load correctly - if( empty($field) ) return false; - - - // delete field - wp_trash_post( $field['ID'] ); - - - // action for 3rd party customisation - do_action( 'acf/trash_field', $field ); - - - // return - return true; - -} - - -/* -* acf_untrash_field -* -* This function will restore a field from the trash -* -* @type function -* @date 2/10/13 -* @since 5.0.0 -* -* @param $id (int) -* @return (boolean) -*/ - -function acf_untrash_field( $selector = 0 ) { - - // disable filters to ensure ACF loads raw data from DB - acf_disable_filters(); - - - // load the origional field gorup - $field = acf_get_field( $selector ); - - - // bail early if field did not load correctly - if( empty($field) ) return false; - - - // delete field - wp_untrash_post( $field['ID'] ); - - - // action for 3rd party customisation - do_action( 'acf/untrash_field', $field ); - - - // return - return true; -} - - -/* -* acf_prepare_fields_for_export -* -* description -* -* @type function -* @date 11/03/2014 -* @since 5.0.0 -* -* @param $post_id (int) -* @return $post_id (int) -*/ - -function acf_prepare_fields_for_export( $fields = false ) { - - // validate - if( empty($fields) ) return $fields; - - - // format - foreach( array_keys($fields) as $i ) { - - // prepare - $fields[ $i ] = acf_prepare_field_for_export( $fields[ $i ] ); - - } - - - // return - return $fields; - -} - - -/* -* acf_prepare_field_for_export -* -* description -* -* @type function -* @date 11/03/2014 -* @since 5.0.0 -* -* @param $post_id (int) -* @return $post_id (int) -*/ - -function acf_prepare_field_for_export( $field ) { - - // extract some args - $extract = acf_extract_vars($field, array( - 'ID', - 'prefix', - 'value', - 'menu_order', - 'id', - 'class', - 'parent', - '_name', - '_prepare', - '_valid', - )); - - - /** - * Filters the $field array before being returned to the export tool. - * - * @date 12/02/2014 - * @since 5.0.0 - * - * @param array $field The field array. - */ - $field = apply_filters( "acf/prepare_field_for_export/type={$field['type']}", $field ); - $field = apply_filters( "acf/prepare_field_for_export", $field ); - - - // return - return $field; -} - - -/* -* acf_prepare_fields_for_import -* -* description -* -* @type function -* @date 11/03/2014 -* @since 5.0.0 -* -* @param $post_id (int) -* @return $post_id (int) -*/ - -function acf_prepare_fields_for_import( $fields = false ) { - - // validate - if( empty($fields) ) return array(); - - - // re-index array - $fields = array_values($fields); - - - // vars - $i = 0; - - - // format - while( $i < count($fields) ) { - - // prepare field - $field = acf_prepare_field_for_import( $fields[ $i ] ); - - - // allow multiple fields to be returned ($field + $sub_fields) - if( !isset($field['key']) && isset($field[0]) ) { - - // merge in $field (1 or more fields) - array_splice($fields, $i, 1, $field); - - } - - - // $i - $i++; - - } - - - // filter for 3rd party customization - $fields = apply_filters('acf/prepare_fields_for_import', $fields); - - - // return - return $fields; - -} - - -/* -* acf_prepare_field_for_import -* -* description -* -* @type function -* @date 11/03/2014 -* @since 5.0.0 -* -* @param $post_id (int) -* @return $post_id (int) -*/ - -function acf_prepare_field_for_import( $field ) { - - // extract some args - $extract = acf_extract_vars($field, array( - 'value', - 'id', - 'class', - '_name', - '_prepare', - '_valid', - )); - - - /** - * Filters the $field array before being returned to the import tool. - * - * @date 12/02/2014 - * @since 5.0.0 - * - * @param array $field The field array. - */ - $field = apply_filters( "acf/prepare_field_for_import/type={$field['type']}", $field ); - $field = apply_filters( "acf/prepare_field_for_import", $field ); - - - // return - return $field; -} - - -/* -* acf_get_sub_field -* -* This function will return a field for the given selector, and $field (parent). -* -* @type function -* @date 30/09/13 -* @since 5.0.0 -* -* @param $selector (string) -* @param $field (mixed) -* @return $field (array) -*/ - -function acf_get_sub_field( $selector, $field ) { - - // vars - $sub_field = false; - - - // check sub_fields - if( isset($field['sub_fields']) ) { - - // loop - foreach( $field['sub_fields'] as $_sub_field ) { - - // check name and key - if( acf_is_field($_sub_field, $selector) ) { - - $sub_field = $_sub_field; - break; - - } - - } - - } - - - /** - * Filters the $sub_field found. - * - * @date 12/02/2014 - * @since 5.0.0 - * - * @param array $sub_field The found sub field array. - * @param string $selector The selector used to search. - * @param array $field The parent field array. - */ - $sub_field = apply_filters( "acf/get_sub_field/type={$field['type']}", $sub_field, $selector, $field ); - $sub_field = apply_filters( "acf/get_sub_field", $sub_field, $selector, $field ); - - - // return - return $sub_field; - -} - - -/* -* acf_is_field -* -* This function will compare a $selector against a $field array -* -* @type function -* @date 1/7/17 -* @since 5.6.0 -* -* @param $post_id (int) -* @return $post_id (int) -*/ - -function acf_is_field( $field, $selector = '' ) { - - // vars - $keys = array( - 'ID', - 'name', - 'key', - '_name', - '__name', - ); - - - // loop - foreach( $keys as $k ) { - - if( isset($field[ $k ]) && $field[ $k ] === $selector ) return true; - - } - - - // return - return false; - -} - - -/* -* acf_get_field_ancestors -* -* This function will return an array of all ancestor fields -* -* @type function -* @date 22/06/2016 -* @since 5.3.8 -* -* @param $field (array) -* @return (array) -*/ - -function acf_get_field_ancestors( $field ) { - - // get field - $ancestors = array(); - - - // loop - while( $field && acf_is_field_key($field['parent']) ) { - - $ancestors[] = $field['parent']; - $field = acf_get_field($field['parent']); - - } - - - // return - return $ancestors; - -} - - -/* -* acf_maybe_get_sub_field -* -* This function will attempt to find a sub field -* -* @type function -* @date 3/10/2016 -* @since 5.4.0 -* -* @param $post_id (int) -* @return $post_id (int) -*/ - -function acf_maybe_get_sub_field( $selectors, $post_id = false, $strict = true ) { - - // bail ealry if not enough selectors - if( !is_array($selectors) || count($selectors) < 3 ) return false; - - - // vars - $offset = acf_get_setting('row_index_offset'); - $selector = acf_extract_var( $selectors, 0 ); - $selectors = array_values( $selectors ); // reset keys - - - // attempt get field - $field = acf_maybe_get_field( $selector, $post_id, $strict ); - - - // bail early if no field - if( !$field ) return false; - - - // loop - for( $j = 0; $j < count($selectors); $j+=2 ) { - - // vars - $sub_i = $selectors[ $j ]; - $sub_s = $selectors[ $j+1 ]; - $field_name = $field['name']; - - - // find sub field - $field = acf_get_sub_field( $sub_s, $field ); - - - // bail early if no sub field - if( !$field ) return false; - - - // add to name - $field['name'] = $field_name . '_' . ($sub_i-$offset) . '_' . $field['name']; - - } - - - // return - return $field; - - -} - - -/* -* acf_prefix_fields -* -* This funtion will safely change the prefix for an array of fields -* Needed to allow clone field to continue working on nave menu item and widget forms -* -* @type function -* @date 5/9/17 -* @since 5.6.0 -* -* @param $post_id (int) -* @return $post_id (int) -*/ - -function acf_prefix_fields( &$fields, $prefix = 'acf' ) { - - // loop - foreach( $fields as &$field ) { - - // replace 'acf' with $prefix - $field['prefix'] = substr_replace($field['prefix'], $prefix, 0, 3); - - } - - - // return - return $fields; - -} - -/** -* acf_apply_field_filters -* -* description -* -* @date 11/9/18 -* @since 5.7.6 -* -* @param type $var Description. Default. -* @return type Description. -*/ -/* -function acf_apply_field_filters( $value ) { - - // get function args - $args = func_get_args(); - - // find field in $args - $field = false; - foreach( $args as $arg ) { - if( is_array($arg) && isset($arg['key'], $arg['type'], $arg['_name']) ) { - $field = $arg; - break; - } - } - - // vars - $filter = current_filter(); - - // unshift tag to args - array_unshift($args, $filter); - - // apply field filters - if( $field ) { - - // $filter/type=$type - $args[0] = "{$filter}/type={$field['type']}"; - $value = call_user_func_array('apply_filters', $args); - - // $filter/name=$name - $args[0] = "{$filter}/name={$field['_name']}"; - $value = call_user_func_array('apply_filters', $args); - - // $filter/key=$key - $args[0] = "{$filter}/key={$field['key']}"; - $value = call_user_func_array('apply_filters', $args); - } - - // return - return $value; -} -*/ - -?> \ No newline at end of file diff --git a/includes/api/api-helpers.php b/includes/api/api-helpers.php index 0019fba..9ffa31e 100644 --- a/includes/api/api-helpers.php +++ b/includes/api/api-helpers.php @@ -546,10 +546,7 @@ function acf_parse_args( $args, $defaults = array() ) { */ function acf_parse_types( $array ) { - - // return return array_map( 'acf_parse_type', $array ); - } @@ -567,26 +564,21 @@ function acf_parse_types( $array ) { */ function acf_parse_type( $v ) { + + // Check if is string. + if( is_string($v) ) { - // bail early if not string - if( !is_string($v) ) return $v; - - - // trim - $v = trim($v); - - - // convert int (string) to int - if( is_numeric($v) && strval((int)$v) === $v ) { - - $v = intval( $v ); + // Trim ("Word " = "Word"). + $v = trim( $v ); + // Convert int strings to int ("123" = 123). + if( is_numeric($v) && strpos($v, '.') === false ) { + $v = intval( $v ); + } } - - // return + // return. return $v; - } @@ -3607,14 +3599,6 @@ function acf_str_join( $s1 = '', $s2 = '' ) { return $s1 . $s2; } -// Tests. -//acf_test( acf_str_join('http://multisite.local/sub1/', '/sample-page/'), 'http://multisite.local/sub1/sample-page/' ); -//acf_test( acf_str_join('http://multisite.local/sub1/', 'sample-page/'), 'http://multisite.local/sub1/sample-page/' ); -//acf_test( acf_str_join('http://multisite.local/sub1/', '/sub1'), 'http://multisite.local/sub1/sub1' ); -//acf_test( acf_str_join('http://multisite.local/sub1/', '/sub1/sample-page/'), 'http://multisite.local/sub1/sample-page/' ); -//acf_test( acf_str_join('http://multisite.local/', '/sub1/sample-page/'), 'http://multisite.local/sub1/sample-page/' ); - - /* * acf_current_user_can_admin * @@ -4474,6 +4458,20 @@ function acf_format_date( $value, $format ) { } +/** + * acf_clear_log + * + * Deletes the debug.log file. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param type $var Description. Default. + * @return type Description. + */ +function acf_clear_log() { + unlink( WP_CONTENT_DIR . '/debug.log' ); +} /* * acf_log @@ -4530,23 +4528,6 @@ function acf_dev_log() { } } -/** -* acf_test -* -* Tests a function against an expected result and logs the pass/fail. -* -* @date 19/11/18 -* @since 5.8.0 -* -* @param type $var Description. Default. -* @return type Description. -*/ -function acf_test( $result, $expected_result ) { - $success = ($result === $expected_result); - acf_log('ACF Test', $success ? '(Pass)' : '(Fail)', $result, $expected_result); -} - - /* * acf_doing * @@ -4645,183 +4626,6 @@ function acf_is_plugin_active() { } - -/** -* acf_get_filters -* -* Returns the registered filters -* -* @date 2/2/18 -* @since 5.6.5 -* -* @param type $var Description. Default. -* @return type Description. -*/ - -function acf_get_filters() { - - // get - $filters = acf_raw_setting('filters'); - - // array - $filters = is_array($filters) ? $filters : array(); - - // return - return $filters; -} - - -/** -* acf_update_filters -* -* Updates the registered filters -* -* @date 2/2/18 -* @since 5.6.5 -* -* @param type $var Description. Default. -* @return type Description. -*/ - -function acf_update_filters( $filters ) { - return acf_update_setting('filters', $filters); -} - - -/* -* acf_enable_filter -* -* This function will enable a filter -* -* @type function -* @date 15/07/2016 -* @since 5.4.0 -* -* @param $post_id (int) -* @return $post_id (int) -*/ - -function acf_enable_filter( $filter = '' ) { - - // get - $filters = acf_get_filters(); - - // append - $filters[ $filter ] = true; - - // update - acf_update_filters( $filters ); -} - - -/* -* acf_disable_filter -* -* This function will disable a filter -* -* @type function -* @date 15/07/2016 -* @since 5.4.0 -* -* @param $post_id (int) -* @return $post_id (int) -*/ - -function acf_disable_filter( $filter = '' ) { - - // get - $filters = acf_get_filters(); - - // append - $filters[ $filter ] = false; - - // update - acf_update_filters( $filters ); -} - - -/* -* acf_enable_filters -* -* ACF uses filters to modify field group and field data -* This function will enable them allowing ACF to interact with all data -* -* @type function -* @date 14/07/2016 -* @since 5.4.0 -* -* @param $post_id (int) -* @return $post_id (int) -*/ - -function acf_enable_filters() { - - // get - $filters = acf_get_filters(); - - // loop - foreach( array_keys($filters) as $k ) { - $filters[ $k ] = true; - } - - // update - acf_update_filters( $filters ); -} - - -/* -* acf_disable_filters -* -* ACF uses filters to modify field group and field data -* This function will disable them allowing ACF to interact only with raw DB data -* -* @type function -* @date 14/07/2016 -* @since 5.4.0 -* -* @param $post_id (int) -* @return $post_id (int) -*/ - -function acf_disable_filters() { - - // get - $filters = acf_get_filters(); - - // loop - foreach( array_keys($filters) as $k ) { - $filters[ $k ] = false; - } - - // update - acf_update_filters( $filters ); -} - - -/* -* acf_is_filter_enabled -* -* ACF uses filters to modify field group and field data -* This function will return true if they are enabled -* -* @type function -* @date 14/07/2016 -* @since 5.4.0 -* -* @param $post_id (int) -* @return $post_id (int) -*/ - -function acf_is_filter_enabled( $filter = '' ) { - - // get - $filters = acf_get_filters(); - - // return - return !empty($filters[ $filter ]); -} - - /* * acf_send_ajax_results * @@ -5180,42 +4984,6 @@ function acf_decrypt( $data = '' ) { } - -/* -* acf_get_post_templates -* -* This function will return an array of all post templates (including parent theme templates) -* -* @type function -* @date 29/8/17 -* @since 5.6.2 -* -* @param n/a -* @return (array) -*/ - -function acf_get_post_templates() { - - // vars - $post_types = acf_get_post_types(); - $post_templates = array(); - - - // loop - foreach( $post_types as $post_type ) { - $post_templates[ $post_type ] = wp_get_theme()->get_page_templates(null, $post_type); - } - - - // remove empty templates - $post_templates = array_filter( $post_templates ); - - - // return - return $post_templates; - -} - /** * acf_parse_markdown * diff --git a/includes/api/api-template.php b/includes/api/api-template.php index bbfba1f..bfd0fd2 100644 --- a/includes/api/api-template.php +++ b/includes/api/api-template.php @@ -147,6 +147,106 @@ function get_field_object( $selector, $post_id = false, $format_value = true, $l } +/* +* acf_get_object_field +* +* This function will return a field for the given selector. +* It will also review the field_reference to ensure the correct field is returned which makes it useful for the template API +* +* @type function +* @date 4/08/2015 +* @since 5.2.3 +* +* @param $selector (mixed) identifyer of field. Can be an ID, key, name or post object +* @param $post_id (mixed) the post_id of which the value is saved against +* @param $strict (boolean) if true, return a field only when a field key is found. +* @return $field (array) +*/ +function acf_maybe_get_field( $selector, $post_id = false, $strict = true ) { + + // init + acf_init(); + + // Check if field key was given. + if( acf_is_field_key($selector) ) { + return acf_get_field( $selector ); + } + + // Lookup field via reference. + $post_id = acf_get_valid_post_id( $post_id ); + $field = acf_get_meta_field( $selector, $post_id ); + if( $field ) { + return $field; + } + + // Lookup field loosely via name. + if( !$strict ) { + return acf_get_field( $selector ); + } + + // Return no result. + return false; +} + +/* +* acf_maybe_get_sub_field +* +* This function will attempt to find a sub field +* +* @type function +* @date 3/10/2016 +* @since 5.4.0 +* +* @param $post_id (int) +* @return $post_id (int) +*/ + +function acf_maybe_get_sub_field( $selectors, $post_id = false, $strict = true ) { + + // bail ealry if not enough selectors + if( !is_array($selectors) || count($selectors) < 3 ) return false; + + + // vars + $offset = acf_get_setting('row_index_offset'); + $selector = acf_extract_var( $selectors, 0 ); + $selectors = array_values( $selectors ); // reset keys + + + // attempt get field + $field = acf_maybe_get_field( $selector, $post_id, $strict ); + + + // bail early if no field + if( !$field ) return false; + + + // loop + for( $j = 0; $j < count($selectors); $j+=2 ) { + + // vars + $sub_i = $selectors[ $j ]; + $sub_s = $selectors[ $j+1 ]; + $field_name = $field['name']; + + + // find sub field + $field = acf_get_sub_field( $sub_s, $field ); + + + // bail early if no sub field + if( !$field ) return false; + + + // add to name + $field['name'] = $field_name . '_' . ($sub_i-$offset) . '_' . $field['name']; + + } + + + // return + return $field; +} /* * get_fields() @@ -206,6 +306,9 @@ function get_fields( $post_id = false, $format_value = true ) { function get_field_objects( $post_id = false, $format_value = true, $load_value = true ) { + // init + acf_init(); + // validate post_id $post_id = acf_get_valid_post_id( $post_id ); diff --git a/includes/api/api-value.php b/includes/api/api-value.php deleted file mode 100644 index bd59965..0000000 --- a/includes/api/api-value.php +++ /dev/null @@ -1,715 +0,0 @@ - https://core.trac.wordpress.org/browser/tags/3.4.2/wp-includes/meta.php#L82: line 101 (does use stripslashes_deep) - // update_option -> https://core.trac.wordpress.org/browser/tags/3.5.1/wp-includes/option.php#L0: line 215 (does not use stripslashes_deep) - $value = stripslashes_deep($value); - - - // add or update - if( get_option($option) !== false ) { - - $return = update_option( $option, $value ); - - } else { - - $return = add_option( $option, $value, $deprecated, $autoload ); - - } - - - // return - return $return; - -} - - -/** -* acf_get_reference -* -* Finds the field key for a given field name and post_id. -* -* @date 26/1/18 -* @since 5.6.5 -* -* @param string $field_name The name of the field. eg 'sub_heading' -* @param mixed $post_id The post_id of which the value is saved against -* @return string $reference The field key -*/ - -function acf_get_reference( $field_name, $post_id ) { - - // allow filter to short-circuit load_value logic - $reference = apply_filters( "acf/pre_load_reference", null, $field_name, $post_id ); - if( $reference !== null ) { - return $reference; - } - - // get hidden meta for this field name - $reference = acf_get_metadata( $post_id, $field_name, true ); - - // filter - $reference = apply_filters('acf/load_reference', $reference, $field_name, $post_id); - $reference = apply_filters('acf/get_field_reference', $reference, $field_name, $post_id); - - // return - return $reference; - -} - -// deprecated in 5.6.8 -function acf_get_field_reference( $field_name, $post_id ) { - return acf_get_reference( $field_name, $post_id ); -} - - -/* -* acf_get_value -* -* This function will load in a field's value -* -* @type function -* @date 28/09/13 -* @since 5.0.0 -* -* @param $post_id (int) -* @param $field (array) -* @return (mixed) -*/ - -function acf_get_value( $post_id = 0, $field ) { - - // allow filter to short-circuit load_value logic - $value = apply_filters( "acf/pre_load_value", null, $post_id, $field ); - if( $value !== null ) { - return $value; - } - - - // vars - $cache_key = "get_value/post_id={$post_id}/name={$field['name']}"; - - - // return early if cache is found - if( acf_isset_cache($cache_key) ) { - return acf_get_cache($cache_key); - } - - - // load value - $value = acf_get_metadata( $post_id, $field['name'] ); - - - // if value was duplicated, it may now be a serialized string! - $value = maybe_unserialize( $value ); - - - // no value? try default_value - if( $value === null && isset($field['default_value']) ) { - $value = $field['default_value']; - } - - - /** - * Filters the $value after it has been loaded. - * - * @date 28/09/13 - * @since 5.0.0 - * - * @param mixed $value The value to preview. - * @param string $post_id The post ID for this value. - * @param array $field The field array. - */ - $value = apply_filters( "acf/load_value/type={$field['type']}", $value, $post_id, $field ); - $value = apply_filters( "acf/load_value/name={$field['_name']}", $value, $post_id, $field ); - $value = apply_filters( "acf/load_value/key={$field['key']}", $value, $post_id, $field ); - $value = apply_filters( "acf/load_value", $value, $post_id, $field ); - - - // update cache - acf_set_cache($cache_key, $value); - - - // return - return $value; - -} - - -/* -* acf_format_value -* -* This function will format the value for front end use -* -* @type function -* @date 3/07/2014 -* @since 5.0.0 -* -* @param $value (mixed) -* @param $post_id (mixed) -* @param $field (array) -* @return $value -*/ - -function acf_format_value( $value, $post_id, $field ) { - - // vars - $cache_key = "format_value/post_id={$post_id}/name={$field['name']}"; - - - // return early if cache is found - if( acf_isset_cache($cache_key) ) { - - return acf_get_cache($cache_key); - - } - - - /** - * Filters the $value for use in a template function. - * - * @date 28/09/13 - * @since 5.0.0 - * - * @param mixed $value The value to preview. - * @param string $post_id The post ID for this value. - * @param array $field The field array. - */ - $value = apply_filters( "acf/format_value/type={$field['type']}", $value, $post_id, $field ); - $value = apply_filters( "acf/format_value/name={$field['_name']}", $value, $post_id, $field ); - $value = apply_filters( "acf/format_value/key={$field['key']}", $value, $post_id, $field ); - $value = apply_filters( "acf/format_value", $value, $post_id, $field ); - - - // update cache - acf_set_cache($cache_key, $value); - - - // return - return $value; - -} - - -/* -* acf_update_value -* -* updates a value into the db -* -* @type action -* @date 23/01/13 -* -* @param $value (mixed) -* @param $post_id (mixed) -* @param $field (array) -* @return (boolean) -*/ - -function acf_update_value( $value = null, $post_id = 0, $field ) { - - // strip slashes - if( acf_get_setting('stripslashes') ) { - $value = stripslashes_deep($value); - } - - - /** - * Allows developers to run a custom update function. - * - * @date 28/09/13 - * @since 5.0.0 - * - * @param null $check Return a non null value to prevent default. - * @param mixed $value The value to update. - * @param string $post_id The post ID for this value. - * @param array $field The field array. - */ - $check = apply_filters( "acf/pre_update_value", null, $value, $post_id, $field ); - if( $check !== null ) { - return $check; - } - - - /** - * Filters the $value before it is saved. - * - * @date 28/09/13 - * @since 5.0.0 - * @since 5.7.6 Added $_value parameter. - * - * @param mixed $value The value to update. - * @param string $post_id The post ID for this value. - * @param array $field The field array. - * @param mixed $_value The original value before modification. - */ - $_value = $value; - $value = apply_filters( "acf/update_value/type={$field['type']}", $value, $post_id, $field, $_value ); - $value = apply_filters( "acf/update_value/name={$field['_name']}", $value, $post_id, $field, $_value ); - $value = apply_filters( "acf/update_value/key={$field['key']}", $value, $post_id, $field, $_value ); - $value = apply_filters( "acf/update_value", $value, $post_id, $field, $_value ); - - - // allow null to delete - if( $value === null ) { - - return acf_delete_value( $post_id, $field ); - - } - - - // update value - $return = acf_update_metadata( $post_id, $field['name'], $value ); - - - // update reference - acf_update_metadata( $post_id, $field['name'], $field['key'], true ); - - - // clear cache - acf_delete_cache("get_value/post_id={$post_id}/name={$field['name']}"); - acf_delete_cache("format_value/post_id={$post_id}/name={$field['name']}"); - - - // return - return $return; - -} - - -/* -* acf_delete_value -* -* This function will delete a value from the database -* -* @type function -* @date 28/09/13 -* @since 5.0.0 -* -* @param $post_id (mixed) -* @param $field (array) -* @return (boolean) -*/ - -function acf_delete_value( $post_id = 0, $field ) { - - /** - * Fires before a value is deleted. - * - * @date 28/09/13 - * @since 5.0.0 - * - * @param string $post_id The post ID for this value. - * @param mixed $name The meta name. - * @param array $field The field array. - */ - do_action( "acf/delete_value/type={$field['type']}", $post_id, $field['name'], $field ); - do_action( "acf/delete_value/name={$field['_name']}", $post_id, $field['name'], $field ); - do_action( "acf/delete_value/key={$field['key']}", $post_id, $field['name'], $field ); - do_action( "acf/delete_value", $post_id, $field['name'], $field ); - - - // delete value - $return = acf_delete_metadata( $post_id, $field['name'] ); - - - // delete reference - acf_delete_metadata( $post_id, $field['name'], true ); - - - // clear cache - acf_delete_cache("get_value/post_id={$post_id}/name={$field['name']}"); - acf_delete_cache("format_value/post_id={$post_id}/name={$field['name']}"); - - - // return - return $return; - -} - - -/* -* acf_copy_postmeta -* -* This function will copy postmeta from one post to another. -* Very useful for saving and restoring revisions -* -* @type function -* @date 25/06/2016 -* @since 5.3.8 -* -* @param $from_post_id (int) -* @param $to_post_id (int) -* @return n/a -*/ - -function acf_copy_postmeta( $from_post_id, $to_post_id ) { - - // get all postmeta - $meta = get_post_meta( $from_post_id ); - - - // bail early if no meta - if( !$meta ) return; - - - // loop - foreach( $meta as $name => $value ) { - - // attempt to find key value - $key = acf_maybe_get( $meta, '_'.$name ); - - - // bail ealry if no key - if( !$key ) continue; - - - // update vars - $value = $value[0]; - $key = $key[0]; - - - // bail early if $key is a not a field_key - if( !acf_is_field_key($key) ) continue; - - - // get_post_meta will return array before running maybe_unserialize - $value = maybe_unserialize( $value ); - - - // add in slashes - // - update_post_meta will unslash the value, so we must first slash it to avoid losing backslashes - // - https://codex.wordpress.org/Function_Reference/update_post_meta#Character_Escaping - if( is_string($value) ) { - - $value = wp_slash($value); - - } - - - // update value - acf_update_metadata( $to_post_id, $name, $value ); - acf_update_metadata( $to_post_id, $name, $key, true ); - - } - -} - - -/* -* acf_preview_value -* -* This function will return a human freindly 'preview' for a given field value -* -* @type function -* @date 24/10/16 -* @since 5.5.0 -* -* @param $value (mixed) -* @param $post_id (mixed) -* @param $field (array) -* @return (string) -*/ - -function acf_preview_value( $value, $post_id, $field ) { - - /** - * Filters the $value before used in HTML. - * - * @date 24/10/16 - * @since 5.5.0 - * - * @param mixed $value The value to preview. - * @param string $post_id The post ID for this value. - * @param array $field The field array. - */ - $value = apply_filters( "acf/preview_value/type={$field['type']}", $value, $post_id, $field ); - $value = apply_filters( "acf/preview_value/name={$field['_name']}", $value, $post_id, $field ); - $value = apply_filters( "acf/preview_value/key={$field['key']}", $value, $post_id, $field ); - $value = apply_filters( "acf/preview_value", $value, $post_id, $field ); - - // return - return $value; -} - -/** -* acf_get_option_meta -* -* Returns an array of meta for the given wp_option name prefix. -* -* @date 9/10/18 -* @since 5.8.0 -* -* @param string $prefix The wp_option name prefix. -* @return array -*/ -function acf_get_option_meta( $prefix = '' ) { - - // global - global $wpdb; - - // vars - $meta = array(); - $search = "{$prefix}_%"; - $_search = "_{$prefix}_%"; - - // escape underscores - $search = str_replace('_', '\_', $search); - $_search = str_replace('_', '\_', $_search); - - // query - $rows = $wpdb->get_results($wpdb->prepare( - "SELECT * - FROM $wpdb->options - WHERE option_name LIKE %s - OR option_name LIKE %s", - $search, - $_search - ), ARRAY_A); - - // loop - $len = strlen("{$prefix}_"); - foreach( $rows as $row ) { - $meta[ substr($row['option_name'], $len) ][] = $row['option_value']; - } - - // return unserialized - return array_map('maybe_unserialize', $meta); -} - -/** -* acf_get_meta -* -* Returns an array of "ACF only" meta for the given post_id. -* -* @date 9/10/18 -* @since 5.8.0 -* -* @param mixed $post_id The post_id for this data. -* @return array -*/ -function acf_get_meta( $post_id = 0 ) { - - // allow filter to short-circuit load_value logic - $pre = apply_filters( "acf/pre_load_meta", null, $post_id ); - if( $pre !== null ) { - return $pre; - } - - // get post_id info - extract( acf_get_post_id_info($post_id) ); - - // use get_$type_meta() function when possible - if( function_exists("get_{$type}_meta") ) { - $allmeta = call_user_func("get_{$type}_meta", $id, '', true); - - // default to wp_options - } else { - $allmeta = acf_get_option_meta( $id ); - } - - // loop - $meta = array(); - foreach( $allmeta as $key => $value ) { - - // if is value - if( isset($allmeta["_$key"]) ) { - $meta[ $key ] = $allmeta[ $key ][0]; - $meta[ "_$key" ] = $allmeta[ "_$key" ][0]; - } - } - - // return - return $meta; -} - -?> \ No newline at end of file diff --git a/includes/cache.php b/includes/cache.php deleted file mode 100644 index f74a203..0000000 --- a/includes/cache.php +++ /dev/null @@ -1,445 +0,0 @@ -active; - - } - - - /* - * enable - * - * This function will enable ACF caching - * - * @type function - * @date 26/6/17 - * @since 5.6.0 - * - * @param n/a - * @return n/a - */ - - function enable() { - - $this->active = true; - - } - - - /* - * disable - * - * This function will disable ACF caching - * - * @type function - * @date 26/6/17 - * @since 5.6.0 - * - * @param n/a - * @return n/a - */ - - function disable() { - - $this->active = false; - - } - - - /* - * get_key - * - * This function will check for references and modify the key - * - * @type function - * @date 30/06/2016 - * @since 5.4.0 - * - * @param $key (string) - * @return $key - */ - - function get_key( $key = '' ) { - - // check for reference - if( isset($this->reference[ $key ]) ) { - - $key = $this->reference[ $key ]; - - } - - - // return - return $key; - - } - - - - /* - * isset_cache - * - * This function will return true if a cached data exists for the given key - * - * @type function - * @date 30/06/2016 - * @since 5.4.0 - * - * @param $key (string) - * @return (boolean) - */ - - function isset_cache( $key = '' ) { - - // bail early if not active - if( !$this->is_active() ) return false; - - - // vars - $key = $this->get_key($key); - $found = false; - - - // get cache - $cache = wp_cache_get($key, 'acf', false, $found); - - - // return - return $found; - - } - - - /* - * get_cache - * - * This function will return cached data for a given key - * - * @type function - * @date 30/06/2016 - * @since 5.4.0 - * - * @param $key (string) - * @return (mixed) - */ - - function get_cache( $key = '' ) { - - // bail early if not active - if( !$this->is_active() ) return false; - - - // vars - $key = $this->get_key($key); - $found = false; - - - // get cache - $cache = wp_cache_get($key, 'acf', false, $found); - - - // return - return $cache; - - } - - - /* - * set_cache - * - * This function will set cached data for a given key - * - * @type function - * @date 30/06/2016 - * @since 5.4.0 - * - * @param $key (string) - * @param $data (mixed) - * @return n/a - */ - - function set_cache( $key = '', $data = '' ) { - - // bail early if not active - if( !$this->is_active() ) return false; - - - // set - wp_cache_set($key, $data, 'acf'); - - - // return - return $key; - - } - - - /* - * set_cache_reference - * - * This function will set a reference to cached data for a given key - * - * @type function - * @date 30/06/2016 - * @since 5.4.0 - * - * @param $key (string) - * @param $reference (string) - * @return n/a - */ - - function set_cache_reference( $key = '', $reference = '' ) { - - // bail early if not active - if( !$this->is_active() ) return false; - - - // add - $this->reference[ $key ] = $reference; - - - // resturn - return $key; - - } - - - /* - * delete_cache - * - * This function will delete cached data for a given key - * - * @type function - * @date 30/06/2016 - * @since 5.4.0 - * - * @param $key (string) - * @return n/a - */ - - function delete_cache( $key = '' ) { - - // bail early if not active - if( !$this->is_active() ) return false; - - - // delete - return wp_cache_delete( $key, 'acf' ); - - } - -} - - -// initialize -acf()->cache = new acf_cache(); - -endif; // class_exists check - - -/* -* acf_is_cache_active -* -* alias of acf()->cache->is_active() -* -* @type function -* @date 26/6/17 -* @since 5.6.0 -* -* @param n/a -* @return n/a -*/ - -function acf_is_cache_active() { - - return acf()->cache->is_active(); - -} - - -/* -* acf_disable_cache -* -* alias of acf()->cache->disable() -* -* @type function -* @date 26/6/17 -* @since 5.6.0 -* -* @param n/a -* @return n/a -*/ - -function acf_disable_cache() { - - return acf()->cache->disable(); - -} - - -/* -* acf_enable_cache -* -* alias of acf()->cache->enable() -* -* @type function -* @date 26/6/17 -* @since 5.6.0 -* -* @param n/a -* @return n/a -*/ - -function acf_enable_cache() { - - return acf()->cache->enable(); - -} - - -/* -* acf_isset_cache -* -* alias of acf()->cache->isset_cache() -* -* @type function -* @date 30/06/2016 -* @since 5.4.0 -* -* @param n/a -* @return n/a -*/ - -function acf_isset_cache( $key = '' ) { - - return acf()->cache->isset_cache( $key ); - -} - - -/* -* acf_get_cache -* -* alias of acf()->cache->get_cache() -* -* @type function -* @date 30/06/2016 -* @since 5.4.0 -* -* @param n/a -* @return n/a -*/ - -function acf_get_cache( $key = '' ) { - - return acf()->cache->get_cache( $key ); - -} - - -/* -* acf_set_cache -* -* alias of acf()->cache->set_cache() -* -* @type function -* @date 30/06/2016 -* @since 5.4.0 -* -* @param n/a -* @return n/a -*/ - -function acf_set_cache( $key = '', $data ) { - - return acf()->cache->set_cache( $key, $data ); - -} - - -/* -* acf_set_cache_reference -* -* alias of acf()->cache->set_cache_reference() -* -* @type function -* @date 30/06/2016 -* @since 5.4.0 -* -* @param n/a -* @return n/a -*/ - -function acf_set_cache_reference( $key = '', $reference = '' ) { - - return acf()->cache->set_cache_reference( $key, $reference ); - -} - - -/* -* acf_delete_cache -* -* alias of acf()->cache->delete_cache() -* -* @type function -* @date 30/06/2016 -* @since 5.4.0 -* -* @param n/a -* @return n/a -*/ - -function acf_delete_cache( $key = '' ) { - - return acf()->cache->delete_cache( $key ); - -} - -?> \ No newline at end of file diff --git a/includes/class-acf-data.php b/includes/class-acf-data.php index 3cf987c..455410b 100644 --- a/includes/class-acf-data.php +++ b/includes/class-acf-data.php @@ -12,6 +12,12 @@ class ACF_Data { /** @var array Storage for data. */ var $data = array(); + /** @var array Storage for data aliases. */ + var $aliases = array(); + + /** @var bool Enables unique data per site. */ + var $multisite = false; + /** * __construct * @@ -29,8 +35,8 @@ class ACF_Data { $this->cid = acf_uniqid(); // Set data. - if( $data && is_array($data) ) { - $this->data = array_merge($this->data, $data); + if( $data ) { + $this->set( $data ); } // Initialize. @@ -49,7 +55,43 @@ class ACF_Data { * @return void */ function initialize() { + // Do nothing. + } + + /** + * prop + * + * Sets a property for the given name and returns $this for chaining. + * + * @date 9/1/19 + * @since 5.7.10 + * + * @param (string|array) $name The data name or an array of data. + * @param mixed $value The data value. + * @return ACF_Data + */ + function prop( $name = '', $value = null ) { + // Update property. + $this->{$name} = $value; + + // Return this for chaining. + return $this; + } + + /** + * _key + * + * Returns a key for the given name allowing aliasses to work. + * + * @date 18/1/19 + * @since 5.7.10 + * + * @param type $var Description. Default. + * @return type Description. + */ + function _key( $name = '' ) { + return isset($this->aliases[ $name ]) ? $this->aliases[ $name ] : $name; } /** @@ -64,7 +106,23 @@ class ACF_Data { * @return boolean */ function has( $name = '' ) { - return isset($this->data[ $name ]); + $key = $this->_key($name); + return isset($this->data[ $key ]); + } + + /** + * is + * + * Similar to has() but does not check aliases. + * + * @date 7/2/19 + * @since 5.7.11 + * + * @param type $var Description. Default. + * @return type Description. + */ + function is( $key = '' ) { + return isset($this->data[ $key ]); } /** @@ -78,8 +136,17 @@ class ACF_Data { * @param string $name The data name. * @return mixed */ - function get( $name = '' ) { - return isset($this->data[ $name ]) ? $this->data[ $name ] : null; + function get( $name = false ) { + + // Get all. + if( $name === false ) { + return $this->data; + + // Get specific. + } else { + $key = $this->_key($name); + return isset($this->data[ $key ]) ? $this->data[ $key ] : null; + } } /** @@ -109,7 +176,7 @@ class ACF_Data { * @param mixed $value The data value. * @return ACF_Data */ - function set( $name = '', $value ) { + function set( $name = '', $value = null ) { // Set multiple. if( is_array($name) ) { @@ -124,6 +191,26 @@ class ACF_Data { return $this; } + /** + * append + * + * Appends data for the given name and returns $this for chaining. + * + * @date 9/1/19 + * @since 5.7.10 + * + * @param mixed $value The data value. + * @return ACF_Data + */ + function append( $value = null ) { + + // Append. + $this->data[] = $value; + + // Return this for chaining. + return $this; + } + /** * remove * @@ -143,6 +230,125 @@ class ACF_Data { // Return this for chaining. return $this; } + + /** + * reset + * + * Resets the data. + * + * @date 22/1/19 + * @since 5.7.10 + * + * @param void + * @return void + */ + function reset() { + $this->data = array(); + $this->aliases = array(); + } + + /** + * count + * + * Returns the data count. + * + * @date 23/1/19 + * @since 5.7.10 + * + * @param void + * @return int + */ + function count() { + return count( $this->data ); + } + + /** + * query + * + * Returns a filtered array of data based on the set of key => value arguments. + * + * @date 23/1/19 + * @since 5.7.10 + * + * @param void + * @return int + */ + function query( $args, $operator = 'AND' ) { + return wp_list_filter( $this->data, $args, $operator ); + } + + /** + * alias + * + * Sets an alias for the given name allowing data to be found via multiple identifiers. + * + * @date 18/1/19 + * @since 5.7.10 + * + * @param type $var Description. Default. + * @return type Description. + */ + function alias( $name = '' /*, $alias, $alias2, etc */ ) { + + // Get all aliases. + $args = func_get_args(); + array_shift( $args ); + + // Loop over aliases and add to data. + foreach( $args as $alias ) { + $this->aliases[ $alias ] = $name; + } + + // Return this for chaining. + return $this; + } + + /** + * switch_site + * + * Triggered when switching between sites on a multisite installation. + * + * @date 13/2/19 + * @since 5.7.11 + * + * @param int $site_id New blog ID. + * @param int prev_blog_id Prev blog ID. + * @return void + */ + function switch_site( $site_id, $prev_site_id ) { + + // Bail early if not multisite compatible. + if( !$this->multisite ) { + return; + } + + // Bail early if no change in blog ID. + if( $site_id === $prev_site_id ) { + return; + } + + // Create storage. + if( !isset($this->site_data) ) { + $this->site_data = array(); + $this->site_aliases = array(); + } + + // Save state. + $this->site_data[ $prev_site_id ] = $this->data; + $this->site_aliases[ $prev_site_id ] = $this->aliases; + + // Reset state. + $this->data = array(); + $this->aliases = array(); + + // Load state. + if( isset($this->site_data[ $site_id ]) ) { + $this->data = $this->site_data[ $site_id ]; + $this->aliases = $this->site_aliases[ $site_id ]; + unset( $this->site_data[ $site_id ] ); + unset( $this->site_aliases[ $site_id ] ); + } + } } endif; // class_exists check diff --git a/includes/compatibility.php b/includes/compatibility.php index f5988eb..8778177 100644 --- a/includes/compatibility.php +++ b/includes/compatibility.php @@ -34,11 +34,39 @@ class ACF_Compatibility { add_filter('acf/validate_field/type=user', array($this, 'validate_user_field'), 20, 1); add_filter('acf/validate_field_group', array($this, 'validate_field_group'), 20, 1); + // Modify field wrapper attributes + add_filter('acf/field_wrapper_attributes', array($this, 'field_wrapper_attributes'), 20, 2); + // location add_filter('acf/location/validate_rule/type=post_taxonomy', array($this, 'validate_post_taxonomy_location_rule'), 20, 1); add_filter('acf/location/validate_rule/type=post_category', array($this, 'validate_post_taxonomy_location_rule'), 20, 1); } + /** + * field_wrapper_attributes + * + * Adds compatibility with deprecated field wrap attributes. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param array $wrapper The wrapper attributes array. + * @param array $field The field array. + */ + function field_wrapper_attributes( $wrapper, $field ) { + + // Check compatibility setting. + if( acf_get_compatibility('field_wrapper_class') ) { + $wrapper['class'] .= " field_type-{$field['type']}"; + if( $field['key'] ) { + $wrapper['class'] .= " field_key-{$field['key']}"; + } + } + + // Return wrapper. + return $wrapper; + } + /** * validate_field * @@ -326,7 +354,7 @@ class ACF_Compatibility { // detect ACF4 data and generate key if( !$field_group['key'] ) { $version = 4; - $field_group['key'] = uniqid('group_'); + $field_group['key'] = isset($field_group['id']) ? "group_{$field_group['id']}" : uniqid('group_'); } // prior to version 5.0.0, settings were saved in an 'options' array diff --git a/includes/fields/class-acf-field-text.php b/includes/fields/class-acf-field-text.php index e9a9feb..528385e 100644 --- a/includes/fields/class-acf-field-text.php +++ b/includes/fields/class-acf-field-text.php @@ -160,6 +160,30 @@ class acf_field_text extends acf_field { } + /** + * validate_value + * + * Validates a field's value. + * + * @date 29/1/19 + * @since 5.7.11 + * + * @param (bool|string) Whether the value is vaid or not. + * @param mixed $value The field value. + * @param array $field The field array. + * @param string $input The HTML input name. + * @return (bool|string) + */ + function validate_value( $valid, $value, $field, $input ){ + + // Check maxlength + if( $field['maxlength'] && mb_strlen(wp_unslash($value)) > $field['maxlength'] ) { + return sprintf( __('Value must not exceed %d characters', 'acf'), $field['maxlength'] ); + } + + // Return. + return $valid; + } } diff --git a/includes/fields/class-acf-field-textarea.php b/includes/fields/class-acf-field-textarea.php index 8c41ee8..6999fdf 100644 --- a/includes/fields/class-acf-field-textarea.php +++ b/includes/fields/class-acf-field-textarea.php @@ -192,6 +192,30 @@ class acf_field_textarea extends acf_field { return $value; } + /** + * validate_value + * + * Validates a field's value. + * + * @date 29/1/19 + * @since 5.7.11 + * + * @param (bool|string) Whether the value is vaid or not. + * @param mixed $value The field value. + * @param array $field The field array. + * @param string $input The HTML input name. + * @return (bool|string) + */ + function validate_value( $valid, $value, $field, $input ){ + + // Check maxlength + if( $field['maxlength'] && mb_strlen(wp_unslash($value)) > $field['maxlength'] ) { + return sprintf( __('Value must not exceed %d characters', 'acf'), $field['maxlength'] ); + } + + // Return. + return $valid; + } } diff --git a/includes/forms/form-gutenberg.php b/includes/forms/form-gutenberg.php index 707f9f1..fa98964 100644 --- a/includes/forms/form-gutenberg.php +++ b/includes/forms/form-gutenberg.php @@ -85,9 +85,20 @@ class ACF_Form_Gutenberg {