├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── README.md ├── acf-extended.php ├── assets ├── css │ ├── acfe-admin.css │ ├── acfe-admin.min.css │ ├── acfe-field-group.css │ ├── acfe-field-group.min.css │ ├── acfe-input.css │ ├── acfe-input.min.css │ ├── acfe-ui.css │ ├── acfe-ui.min.css │ ├── acfe.css │ └── acfe.min.css ├── inc │ └── tinymce │ │ ├── acfe-form.js │ │ └── acfe-form.min.js └── js │ ├── acfe-admin.js │ ├── acfe-admin.min.js │ ├── acfe-field-group.js │ ├── acfe-field-group.min.js │ ├── acfe-input.js │ ├── acfe-input.min.js │ ├── acfe-ui.js │ ├── acfe-ui.min.js │ ├── acfe.js │ └── acfe.min.js ├── includes ├── acfe-deprecated-functions.php ├── acfe-field-functions.php ├── acfe-field-group-functions.php ├── acfe-file-functions.php ├── acfe-form-functions.php ├── acfe-helper-functions.php ├── acfe-meta-functions.php ├── acfe-post-functions.php ├── acfe-screen-functions.php ├── acfe-template-functions.php ├── acfe-term-functions.php ├── acfe-user-functions.php ├── acfe-wp-functions.php ├── admin │ ├── menu.php │ ├── plugins.php │ ├── settings.php │ ├── tools │ │ ├── field-groups-export.php │ │ ├── field-groups-local.php │ │ ├── module-export.php │ │ └── module-import.php │ └── views │ │ ├── html-options-edit.php │ │ └── html-options-list.php ├── assets.php ├── compatibility-6.0.php ├── compatibility.php ├── field-extend.php ├── field-groups │ ├── field-group-advanced.php │ ├── field-group-category.php │ ├── field-group-display-title.php │ ├── field-group-hide-on-screen.php │ ├── field-group-instruction-placement.php │ ├── field-group-meta.php │ ├── field-group-permissions.php │ ├── field-group.php │ ├── field-groups-local.php │ ├── field-groups.php │ └── field-types.php ├── field.php ├── fields-settings │ ├── bidirectional.php │ ├── data.php │ ├── instructions.php │ ├── permissions.php │ ├── settings.php │ └── validation.php ├── fields │ ├── field-advanced-link.php │ ├── field-button.php │ ├── field-checkbox.php │ ├── field-clone.php │ ├── field-code-editor.php │ ├── field-column.php │ ├── field-dynamic-render.php │ ├── field-file.php │ ├── field-flexible-content-actions.php │ ├── field-flexible-content-async.php │ ├── field-flexible-content-controls.php │ ├── field-flexible-content-edit.php │ ├── field-flexible-content-hide.php │ ├── field-flexible-content-preview.php │ ├── field-flexible-content-select.php │ ├── field-flexible-content-settings.php │ ├── field-flexible-content-state.php │ ├── field-flexible-content-thumbnail.php │ ├── field-flexible-content.php │ ├── field-forms.php │ ├── field-group.php │ ├── field-hidden.php │ ├── field-image.php │ ├── field-post-object.php │ ├── field-post-statuses.php │ ├── field-post-types.php │ ├── field-recaptcha.php │ ├── field-repeater.php │ ├── field-select.php │ ├── field-slug.php │ ├── field-taxonomies.php │ ├── field-taxonomy-terms.php │ ├── field-taxonomy.php │ ├── field-textarea.php │ ├── field-user-roles.php │ └── field-wysiwyg.php ├── hooks.php ├── init.php ├── local-meta.php ├── locations │ ├── post-type-all.php │ ├── post-type-archive.php │ ├── post-type-list.php │ └── taxonomy-list.php ├── module-acf.php ├── module-db.php ├── module-l10n.php ├── module-legacy.php ├── module-manager.php ├── module-post.php ├── module-posts.php ├── module-upgrades.php ├── module.php ├── modules │ ├── author.php │ ├── autosync-json.php │ ├── autosync-php.php │ ├── block-type │ │ ├── module-block-type-fields.php │ │ ├── module-block-type-upgrades.php │ │ └── module-block-type.php │ ├── dev │ │ ├── module-dev-delete-meta.php │ │ └── module-dev.php │ ├── form │ │ ├── module-form-action-custom.php │ │ ├── module-form-action-email.php │ │ ├── module-form-action-post.php │ │ ├── module-form-action-redirect.php │ │ ├── module-form-action-term.php │ │ ├── module-form-action-user.php │ │ ├── module-form-action.php │ │ ├── module-form-compatibility.php │ │ ├── module-form-deprecated.php │ │ ├── module-form-fields.php │ │ ├── module-form-format.php │ │ ├── module-form-front-hooks.php │ │ ├── module-form-front-render.php │ │ ├── module-form-front.php │ │ ├── module-form-shortcode.php │ │ ├── module-form-upgrades.php │ │ └── module-form.php │ ├── option │ │ ├── module-option-table.php │ │ └── module-option.php │ ├── options-page │ │ ├── module-options-page-features.php │ │ ├── module-options-page-fields.php │ │ ├── module-options-page-upgrades.php │ │ └── module-options-page.php │ ├── performance │ │ ├── module-performance-connector.php │ │ ├── module-performance-functions.php │ │ ├── module-performance-ui.php │ │ ├── module-performance-ultra-fields.php │ │ ├── module-performance-ultra-revisions.php │ │ ├── module-performance-ultra.php │ │ ├── module-performance-upgrades.php │ │ └── module-performance.php │ ├── post-type │ │ ├── module-post-type-features.php │ │ ├── module-post-type-fields.php │ │ ├── module-post-type-upgrades.php │ │ └── module-post-type.php │ ├── taxonomy │ │ ├── module-taxonomy-features.php │ │ ├── module-taxonomy-fields.php │ │ ├── module-taxonomy-upgrades.php │ │ └── module-taxonomy.php │ └── ui │ │ ├── module-ui-attachment.php │ │ ├── module-ui-settings.php │ │ ├── module-ui-term.php │ │ ├── module-ui-user.php │ │ └── module-ui.php ├── multilang.php ├── screens │ ├── screen-attachment.php │ ├── screen-options-page.php │ ├── screen-post.php │ ├── screen-settings.php │ ├── screen-taxonomy.php │ └── screen-user.php ├── settings.php ├── template-tags.php ├── third-party.php └── upgrades.php ├── lang ├── acfe-fr_FR.mo ├── acfe-fr_FR.po └── acfe.pot └── readme.txt /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior. 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Screenshots** 20 | If applicable, add screenshots to help explain your problem. 21 | 22 | **WordPress & ACF** 23 | WordPress version: 24 | ACF Pro version: 25 | ACF add-ons: 26 | 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: feature request 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /assets/inc/tinymce/acfe-form.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | if (typeof acf === 'undefined' || typeof acfe === 'undefined' || typeof window.wp.mce === 'undefined') { 4 | return; 5 | } 6 | 7 | tinymce.PluginManager.add('acfe_form', function(editor, url) { 8 | 9 | window.wp.mce.views.register('acfe_form', { 10 | 11 | initialize: function() { 12 | 13 | // send ajax 14 | $.ajax({ 15 | url: acf.get('ajaxurl'), 16 | data: acf.prepareForAjax({ 17 | action: 'acfe/form/shortcode', 18 | args: this.shortcode.attrs.named, 19 | }), 20 | type: 'post', 21 | dataType: 'html', 22 | context: this, 23 | beforeSend: function() { 24 | this.render('
'); 25 | }, 26 | success: function(response) { 27 | this.render(response, true); 28 | }, 29 | }); 30 | 31 | }, 32 | 33 | edit: function(text, update) { 34 | 35 | editor.windowManager.open({ 36 | width: 800, 37 | height: 62, 38 | title: 'Shortcode', 39 | body: [{ 40 | label: '', 41 | name: 'content', 42 | type: 'textbox', 43 | value: text, 44 | }, ], 45 | onsubmit: function(e) { 46 | update(e.data.content); 47 | }, 48 | }); 49 | 50 | }, 51 | 52 | }); 53 | 54 | }); 55 | 56 | })(jQuery); -------------------------------------------------------------------------------- /assets/inc/tinymce/acfe-form.min.js: -------------------------------------------------------------------------------- 1 | !function(t){"undefined"!=typeof acf&&"undefined"!=typeof acfe&&void 0!==window.wp.mce&&tinymce.PluginManager.add("acfe_form",function(n,e){window.wp.mce.views.register("acfe_form",{initialize:function(){t.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax({action:"acfe/form/shortcode",args:this.shortcode.attrs.named}),type:"post",dataType:"html",context:this,beforeSend:function(){this.render('
')},success:function(e){this.render(e,!0)}})},edit:function(e,t){n.windowManager.open({width:800,height:62,title:"Shortcode",body:[{label:"",name:"content",type:"textbox",value:e}],onsubmit:function(e){t(e.data.content)}})}})})}(jQuery); -------------------------------------------------------------------------------- /assets/js/acfe-field-group.min.js: -------------------------------------------------------------------------------- 1 | !function(c){var i;"undefined"!=typeof acf&&"undefined"!=typeof acfe&&(new acf.Model({actions:{append_field_object:"appendCodeEditor"},appendCodeEditor:function(e){var t;"acfe_code_editor"===e.get("type")&&(1<(t=e.$setting("default_value").find("> .acf-input > .acf-input-wrap > .CodeMirror")).length&&t.last().remove(),1<(e=e.$setting("placeholder").find("> .acf-input > .acf-input-wrap > .CodeMirror")).length&&e.last().remove())}}),new acf.Model({actions:{"change_field_label/type=acfe_column":"renderTitle","change_field_type/type=acfe_column":"renderTitle","render_field_settings/type=acfe_column":"renderField"},ucFirst:function(e){return e.charAt(0).toUpperCase()+e.slice(1)},renderTitle:function(e){var t=acf.getInstance(e),a=t.$setting("columns"),e=acf.getInstance(a).getValue(),a=t.$setting("endpoint"),a=acf.getInstance(a).getValue();t.set("label","(Column "+this.ucFirst(e=a?"Endpoint":e)+")")},renderField:function(e){var t=acf.getFieldObject(e),e=function(){t.set("label",!0)};t.on("change",".acfe-field-columns",e),t.on("change",".acfe-field-columns-endpoint",e)}}),new acf.Model({filters:{"select2_ajax_data/action=acfe/fields/taxonomy_terms/allow_query":"taxonomyTermsAjax"},taxonomyTermsAjax:function(e,t,a,n,i){var f=a.closest(".acf-field-settings").find(".acf-field-setting-taxonomy > .acf-input > select > option:selected"),l=[];f.each(function(){l.push(c(this).val())}),e.taxonomies=l;a=a.closest(".acf-field-settings").find('.acf-field-setting-allow_terms > .acf-input input[type="number"]');return e.level=a.val(),e}}),new acf.Model({wait:"prepare",initialize:function(){c(".button.edit-field").each(function(){var e=c(this),t=e.closest("tbody, .acf-field-settings");c(t).find(".acfe-data-button:first").insertAfter(e),c(t).find(".acfe-modal:first").appendTo(c("body")),c(t).find(".acf-field-setting-acfe_field_data:first").remove()})}}),new acf.Model({actions:{new_field:"onNewField"},onNewField:function(e){var t,a,n;(e.has("before")||e.has("after"))&&"tab"!==e.get("type")&&(t=e.has("before")?"before":"after",(n=e.$el.closest(".acf-field-object")).length&&(a=acf.getFieldObject(n).get("key")),!(n=!(n=e.$el.closest(".acf-fields")).length?e.$el.closest(".acf-table"):n).length||(n=(a?n.find('[data-name="'+e.get(t)+'"]').not('.acf-input-sub .acf-field-object[data-key!="'+a+'"] [data-name="'+e.get(t)+'"]'):n.find('[data-name="'+e.get(t)+'"]')).first()).length&&n[t](e.$el))}}),i=acf.models.TabField,acf.models.TabField=i.extend({initialize:function(){var e,t,a,n;(this.has("before")||this.has("after"))&&(e=this.has("before")?"before":"after",n=this.$el.closest(".acf-fields"),(t=this.$el.closest(".acf-field-object")).length&&(a=acf.getFieldObject(t).get("key")),!(n=!n.length?this.$el.closest(".acf-table"):n).length||(n=(a?n.find('[data-name="'+this.get(e)+'"]').not('.acf-input-sub .acf-field-object[data-key!="'+a+'"] [data-name="'+this.get(e)+'"]'):n.find('[data-name="'+this.get(e)+'"]')).first()).length&&n[e](this.$el)),i.prototype.initialize.apply(this,arguments)}}),new acf.Model({wait:"ready",actions:{append:"onAppend","acfe/field_group/rule_refresh":"refreshFields"},initialize:function(){this.$el=c("#acf-field-group-locations, .field-group-locations")},onAppend:function(e){(e.is(".rule-group")||e.parent().parent().parent().is(".rule-group"))&&this.refreshFields()},refreshFields:function(){acf.getFields({parent:this.$("td.value")}).map(function(e){acfe.inArray(e.get("type"),["date_picker","date_time_picker","time_picker"])&&(e.$inputText().removeClass("hasDatepicker").removeAttr("id"),e.initialize())})}}),new acf.Model({actions:{"new_field/name=acfe_meta":"renderClass","new_field/name=acfe_settings":"renderClass","new_field/name=acfe_validate":"renderClass"},renderClass:function(e){e.$(".acf-button").removeClass("button-primary")}}),new acf.Model({events:{"keyup #post_name":"onInput"},onInput:function(e,t){var a=t.val();a.startsWith("group_")||t.val(a="group_"+a),c('[name="acf_field_group[key]"]').val(a),c(".misc-pub-acfe-field-group-key code").html(a)}}))}(jQuery),jQuery,"undefined"!=typeof acf&&"undefined"!=typeof acfe&&new acf.Model({actions:{duplicate:"onAppend"},onAppend:function(e,t){!acfe.versionCompare(acf.get("acf_version"),">=","6.0")||(t=acf.findClosestField(t)).is('[data-type="repeater"]')&&acf.getField(t).render()}}); -------------------------------------------------------------------------------- /includes/acfe-deprecated-functions.php: -------------------------------------------------------------------------------- 1 | deprecated since version %2$s! Use %3$s instead.'), $function, $version, $replacement); 113 | }else{ 114 | $message = 'ACF Extended: ' . $label . ' ' . sprintf(__('%1$s is deprecated since version %2$s with no alternative available.'), $function, $version); 115 | } 116 | 117 | // trigger error 118 | trigger_error($message, E_USER_DEPRECATED); 119 | 120 | } 121 | 122 | } -------------------------------------------------------------------------------- /includes/acfe-post-functions.php: -------------------------------------------------------------------------------- 1 | name ] = $object; 84 | 85 | } 86 | 87 | // return 88 | return $return; 89 | 90 | } 91 | 92 | /** 93 | * acfe_get_pretty_post_statuses 94 | * 95 | * Similar to acf_get_pretty_post_types() but for Post Statuses 96 | * 97 | * @param array $posts_statuses 98 | * 99 | * @return array 100 | */ 101 | function acfe_get_pretty_post_statuses($posts_statuses = array()){ 102 | 103 | // vars 104 | $ref = array(); 105 | $return = array(); 106 | 107 | // get post statuses 108 | if(empty($posts_statuses)){ 109 | $posts_statuses = get_post_stati(); 110 | } 111 | 112 | // loop 113 | foreach($posts_statuses as $post_status){ 114 | 115 | // vars 116 | $object = get_post_status_object($post_status); 117 | $label = $object->label; 118 | 119 | // append to return 120 | $return[ $object->name ] = $label; 121 | 122 | // increase counter 123 | if(!isset($ref[ $label ])){ 124 | $ref[ $label ] = 0; 125 | } 126 | 127 | $ref[ $label ]++; 128 | 129 | } 130 | 131 | // get slugs 132 | foreach(array_keys($return) as $slug){ 133 | 134 | // vars 135 | $label = $return[ $slug ]; 136 | 137 | // append slug 138 | if($ref[ $label ] > 1){ 139 | $return[ $slug ] .= " ({$slug})"; 140 | } 141 | 142 | } 143 | 144 | // return 145 | return $return; 146 | 147 | } -------------------------------------------------------------------------------- /includes/acfe-screen-functions.php: -------------------------------------------------------------------------------- 1 | post_type === 'post' && $screen->taxonomy === 'acf-field-group-category'; 96 | 97 | } 98 | 99 | if(in_array($screen->post_type, $post_types) || $is_category){ 100 | return true; 101 | } 102 | 103 | } 104 | 105 | } 106 | 107 | return false; 108 | 109 | } 110 | 111 | /** 112 | * acfe_match_location_rules 113 | * 114 | * Match screen data against an array of location 115 | * 116 | * @param $location 117 | * @param $screen 118 | * 119 | * @return bool 120 | */ 121 | function acfe_match_location_rules($location, $screen){ 122 | 123 | // Loop through location groups. 124 | foreach($location as $group){ 125 | 126 | // ignore group if no rules. 127 | if(empty($group)){ 128 | continue; 129 | } 130 | 131 | // Loop over rules and determine if all rules match. 132 | $match_group = true; 133 | 134 | foreach($group as $rule){ 135 | 136 | if(!acf_match_location_rule($rule, $screen, array())){ 137 | $match_group = false; 138 | break; 139 | } 140 | 141 | } 142 | 143 | // Show the field group 144 | if($match_group){ 145 | return true; 146 | } 147 | 148 | } 149 | 150 | return false; 151 | 152 | } 153 | 154 | /** 155 | * acfe_is_dynamic_preview 156 | * 157 | * Check if currently in ACFE FlexibleContent Preview or ACF Block Type Preview 158 | * 159 | * @return bool 160 | */ 161 | function acfe_is_dynamic_preview(){ 162 | 163 | // vars 164 | global $is_preview; 165 | $return = false; 166 | 167 | // flexible content 168 | if(isset($is_preview) && $is_preview){ 169 | 170 | $return = true; 171 | 172 | // block type 173 | }elseif(wp_doing_ajax() && acf_maybe_get_POST('query')){ 174 | 175 | $query = acf_maybe_get_POST('query'); 176 | 177 | if(acf_maybe_get($query, 'preview')){ 178 | $return = true; 179 | } 180 | 181 | } 182 | 183 | return apply_filters('acfe/is_preview', $return); 184 | 185 | } 186 | 187 | /** 188 | * acfe_is_block_editor 189 | * 190 | * An enhanced version of acf_is_block_editor that also check if currently in a block type 191 | * 192 | * @return bool 193 | */ 194 | function acfe_is_block_editor(){ 195 | 196 | // check block editor screen or ajax fetch (block edit mode) 197 | return acf_is_block_editor() || acf_maybe_get_POST('action') === 'acf/ajax/fetch-block'; 198 | 199 | } 200 | 201 | 202 | /** 203 | * acfe_is_gutenberg 204 | * 205 | * Check if current screen is block editor 206 | * 207 | * @return bool 208 | * @deprecated 209 | */ 210 | function acfe_is_gutenberg(){ 211 | return acfe_is_block_editor(); 212 | } -------------------------------------------------------------------------------- /includes/acfe-term-functions.php: -------------------------------------------------------------------------------- 1 | name ] = $taxonomy_object; 32 | 33 | } 34 | 35 | } 36 | 37 | return $return; 38 | 39 | } 40 | 41 | /** 42 | * acfe_get_taxonomy_terms_ids 43 | * 44 | * Similar to acf_get_taxonomy_terms() 45 | * Returns "array('256' => 'Category name')" instead of "array('category:category_name' => 'Category name')" 46 | * 47 | * @param array $taxonomies 48 | * 49 | * @return array 50 | */ 51 | function acfe_get_taxonomy_terms_ids($taxonomies = array()){ 52 | 53 | // force array 54 | $taxonomies = acf_get_array($taxonomies); 55 | 56 | // get pretty taxonomy names 57 | $taxonomies = acf_get_taxonomy_labels($taxonomies); 58 | 59 | // vars 60 | $r = array(); 61 | 62 | // populate $r 63 | foreach(array_keys($taxonomies) as $taxonomy){ 64 | 65 | // vars 66 | $label = $taxonomies[ $taxonomy ]; 67 | $is_hierarchical = is_taxonomy_hierarchical($taxonomy); 68 | 69 | $terms = acf_get_terms(array( 70 | 'taxonomy' => $taxonomy, 71 | 'hide_empty' => false 72 | )); 73 | 74 | // bail early if no terms 75 | if(empty($terms)){ 76 | continue; 77 | } 78 | 79 | // sort into hierachial order! 80 | if($is_hierarchical){ 81 | $terms = _get_term_children(0, $terms, $taxonomy); 82 | } 83 | 84 | // add placeholder 85 | $r[ $label ] = array(); 86 | 87 | // add choices 88 | foreach($terms as $term){ 89 | $r[ $label ][ $term->term_id ] = acf_get_term_title($term); 90 | } 91 | 92 | } 93 | 94 | // return 95 | return $r; 96 | 97 | } 98 | 99 | /** 100 | * acfe_get_term_level 101 | * 102 | * Retrive the Term Level number 103 | * 104 | * @param $term 105 | * @param $taxonomy 106 | * 107 | * @return int 108 | */ 109 | function acfe_get_term_level($term, $taxonomy){ 110 | 111 | $ancestors = get_ancestors($term, $taxonomy); 112 | 113 | return count($ancestors) + 1; 114 | 115 | } -------------------------------------------------------------------------------- /includes/acfe-user-functions.php: -------------------------------------------------------------------------------- 1 | roles as $role => $settings){ 27 | $list[ $role ] = $settings['name']; 28 | } 29 | 30 | $user_roles = $list; 31 | 32 | if(!empty($filtered_user_roles)){ 33 | 34 | $user_roles = array(); 35 | 36 | foreach($list as $role => $role_label){ 37 | if(in_array($role, $filtered_user_roles)){ 38 | $user_roles[$role] = $role_label; 39 | } 40 | } 41 | 42 | } 43 | 44 | return $user_roles; 45 | 46 | } 47 | 48 | /** 49 | * acfe_get_current_user_roles 50 | * 51 | * Retrieve currently logged user roles 52 | * 53 | * @return false|string[] 54 | */ 55 | function acfe_get_current_user_roles(){ 56 | 57 | global $current_user; 58 | 59 | if(!is_object($current_user) || !isset($current_user->roles)){ 60 | return false; 61 | } 62 | 63 | $roles = $current_user->roles; 64 | 65 | if(is_multisite() && current_user_can('setup_network')){ 66 | $roles[] = 'super_admin'; 67 | } 68 | 69 | return $roles; 70 | 71 | } -------------------------------------------------------------------------------- /includes/admin/menu.php: -------------------------------------------------------------------------------- 1 | =', '5.9')){ 30 | 31 | // allowed screens 32 | $allowed = array( 33 | 'edit-acf-field-group-category', 34 | 'edit-acfe-dbt', 35 | 'acfe-dbt', 36 | 'edit-acfe-dop', 37 | 'acfe-dop', 38 | 'edit-acfe-template', 39 | 'acfe-template', 40 | 'edit-acfe-form', 41 | 'acfe-form' 42 | ); 43 | 44 | // chgeck allowed 45 | if(acf_is_screen($allowed)){ 46 | add_action('in_admin_header', array($this, 'in_admin_header')); 47 | } 48 | 49 | } 50 | 51 | } 52 | 53 | 54 | /** 55 | * in_admin_header 56 | */ 57 | function in_admin_header(){ 58 | acf_get_view('html-admin-navigation'); 59 | } 60 | 61 | 62 | /** 63 | * admin_menu 64 | * 65 | * Swap menu items to the correct order 66 | */ 67 | function admin_menu(){ 68 | 69 | // global 70 | global $submenu; 71 | 72 | // bail early 73 | if(!acf_maybe_get($submenu, 'edit.php?post_type=acf-field-group')){ 74 | return; 75 | } 76 | 77 | // vars 78 | $new_menu = array(); 79 | $all_menu = $submenu['edit.php?post_type=acf-field-group']; 80 | 81 | // order 82 | $order = array( 83 | 'edit.php?post_type=acf-field-group', 84 | 'post-new.php?post_type=acf-field-group', 85 | 'edit-tags.php?taxonomy=acf-field-group-category', 86 | 'edit.php?post_type=acfe-dbt', 87 | 'edit.php?post_type=acfe-form', 88 | 'edit.php?post_type=acfe-dop', 89 | 'edit.php?post_type=acf-post-type', 90 | 'acfe-settings', 91 | 'edit.php?post_type=acf-taxonomy', 92 | 'acf-tools', 93 | 'acf-settings-updates', 94 | ); 95 | 96 | // loop 97 | foreach($submenu['edit.php?post_type=acf-field-group'] as $k => $item){ 98 | 99 | //name 100 | $name = $item[2]; 101 | 102 | // search 103 | $position = array_search($name, $order); 104 | 105 | // found position 106 | if($position !== false){ 107 | $this->assign_submenu($new_menu, $position, $item, $all_menu, $k); 108 | } 109 | 110 | } 111 | 112 | // sort new menu 113 | ksort($new_menu); 114 | 115 | // assign new menu 116 | $submenu['edit.php?post_type=acf-field-group'] = $new_menu; 117 | 118 | // add menu items that are left 119 | if(!empty($all_menu)){ 120 | $submenu['edit.php?post_type=acf-field-group'] = array_merge($new_menu, $all_menu); 121 | } 122 | 123 | } 124 | 125 | 126 | /** 127 | * assign_submenu 128 | * 129 | * @param $new_menu 130 | * @param $new_menu_key 131 | * @param $item 132 | * @param $all_menu 133 | * @param $all_menu_key 134 | */ 135 | function assign_submenu(&$new_menu, $new_menu_key, $item, &$all_menu, $all_menu_key){ 136 | 137 | $new_menu[ $new_menu_key ] = $item; 138 | unset($all_menu[ $all_menu_key ]); 139 | 140 | } 141 | 142 | } 143 | 144 | new acfe_admin_menu(); 145 | 146 | endif; -------------------------------------------------------------------------------- /includes/admin/plugins.php: -------------------------------------------------------------------------------- 1 | name = 'acfe-export'; 14 | 15 | } 16 | 17 | function load(){ 18 | 19 | $action = $this->get_action(); 20 | 21 | if($action === 'json'){ 22 | 23 | acf()->admin_tools->get_tool('export')->submit_download(); 24 | 25 | } 26 | 27 | // active 28 | if($this->is_active()){ 29 | 30 | // get selected keys 31 | $selected = acf()->admin_tools->get_tool('export')->get_selected_keys(); 32 | 33 | // add notice 34 | if($selected){ 35 | 36 | $count = count($selected); 37 | $text = sprintf( _n('Exported 1 field group.', 'Exported %s field groups.', $count, 'acf' ), $count); 38 | 39 | acf_add_admin_notice( $text, 'success' ); 40 | 41 | } 42 | } 43 | 44 | } 45 | 46 | function get_action(){ 47 | 48 | // vars 49 | $action = acfe_maybe_get_REQUEST('action'); 50 | 51 | // check allowed 52 | if(!in_array($action, array('json', 'php'))) 53 | $action = false; 54 | 55 | // return 56 | return $action; 57 | 58 | } 59 | 60 | } 61 | 62 | acf_register_admin_tool('acfe_field_groups_export'); 63 | 64 | endif; -------------------------------------------------------------------------------- /includes/admin/tools/module-import.php: -------------------------------------------------------------------------------- 1 | module = $module; 23 | 24 | // vars 25 | $this->name = $this->module->get_import_tool(); 26 | $this->title = $this->module->get_message('import_title'); 27 | 28 | parent::__construct(); 29 | 30 | } 31 | 32 | 33 | /** 34 | * html 35 | * 36 | * @return void 37 | */ 38 | function html(){ 39 | 40 | ?> 41 | 42 | 43 |
44 |

module->get_message('import_description'); ?>

45 |
46 |
47 | 48 | 49 | 50 |

module->get_message('import_description'); ?>

51 | 52 | 53 | 54 |
55 | __('Select File', 'acf'), 59 | 'type' => 'file', 60 | 'name' => 'acf_import_file', 61 | 'value' => false, 62 | 'uploader' => 'basic', 63 | )); 64 | 65 | ?> 66 |
67 | 68 |

69 | 70 |

71 | 72 | 73 |
74 | 75 | 76 | validate_file(); 90 | 91 | if(!$json){ 92 | return; 93 | } 94 | 95 | $ids = array(); 96 | 97 | // Loop over json 98 | foreach($json as $key => $item){ 99 | 100 | // prior 0.9 101 | // old import had name as key 102 | if(!is_numeric($key) && !isset($item['name'])){ 103 | $item['name'] = $key; 104 | } 105 | 106 | // validate 107 | // todo: remove 108 | //$item = $this->module->validate_item($item); 109 | //$item = $this->module->prepare_item_for_import($item); 110 | 111 | // search database for existing item 112 | $post = $this->module->get_item_post($item['name']); 113 | if($post){ 114 | $item['ID'] = $post->ID; 115 | } 116 | 117 | // import item 118 | $item = $this->module->import_item($item); 119 | 120 | // append message 121 | $ids[] = $item['ID']; 122 | 123 | } 124 | 125 | if(empty($ids)){ 126 | return; 127 | } 128 | 129 | // Count total 130 | $total = count($ids); 131 | 132 | $text = $this->module->get_message('import_success_single'); 133 | 134 | if($total > 1){ 135 | $text = sprintf($this->module->get_message('import_success_multiple'), $total); 136 | } 137 | 138 | // Add links to text 139 | $links = array(); 140 | foreach($ids as $id){ 141 | $links[] = '' . get_the_title($id) . ''; 142 | } 143 | 144 | $text .= ': ' . implode(', ', $links); 145 | 146 | // Add notice 147 | acf_add_admin_notice($text, 'success'); 148 | 149 | } 150 | 151 | 152 | /** 153 | * validate_file 154 | * 155 | * @return array|false 156 | */ 157 | function validate_file(){ 158 | 159 | // Check file size. 160 | if(empty($_FILES['acf_import_file']['size'])){ 161 | 162 | acf_add_admin_notice(__('No file selected', 'acf'), 'warning'); 163 | return false; 164 | 165 | } 166 | 167 | // Get file data. 168 | $file = $_FILES['acf_import_file']; 169 | 170 | // Check errors. 171 | if($file['error']){ 172 | 173 | acf_add_admin_notice(__('Error uploading file. Please try again', 'acf'), 'warning'); 174 | return false; 175 | 176 | } 177 | 178 | // Check file type. 179 | if(pathinfo($file['name'], PATHINFO_EXTENSION) !== 'json'){ 180 | 181 | acf_add_admin_notice(__('Incorrect file type', 'acf'), 'warning'); 182 | return false; 183 | 184 | } 185 | 186 | // Read JSON. 187 | $json = file_get_contents($file['tmp_name']); 188 | $json = json_decode($json, true); 189 | 190 | // Check if empty. 191 | if(!$json || !is_array($json)){ 192 | 193 | acf_add_admin_notice(__('Import file empty', 'acf'), 'warning'); 194 | return false; 195 | 196 | } 197 | 198 | return $json; 199 | 200 | } 201 | 202 | } 203 | 204 | endif; -------------------------------------------------------------------------------- /includes/admin/views/html-options-edit.php: -------------------------------------------------------------------------------- 1 |
2 | 3 | 8 |

9 | 10 |
11 | 12 |
13 | 14 | 'acfe-options-edit', 19 | 'post_id' => 'acfe_options_edit', 20 | )); 21 | 22 | wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false); 23 | wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false); 24 | 25 | ?> 26 | 27 |
28 | 29 |
30 | 31 | 40 | 41 |
42 | 43 | 44 | 45 |
46 | 47 |
48 | 49 | 50 | 51 |
52 | 53 |
54 | 55 |
56 | 57 |
58 | 59 |
60 | 61 |
-------------------------------------------------------------------------------- /includes/admin/views/html-options-list.php: -------------------------------------------------------------------------------- 1 |
2 | 3 |

4 | 5 | 6 |
7 | 8 |
9 | 10 |
11 |
12 |
13 |
14 | 15 | prepare_items(); 22 | 23 | $acfe_options_list->search_box('Search', 'search'); 24 | 25 | $acfe_options_list->display(); 26 | 27 | ?> 28 | 29 |
30 |
31 |
32 |
33 | 34 |
35 | 36 |
37 | 38 |
-------------------------------------------------------------------------------- /includes/field-groups/field-group-advanced.php: -------------------------------------------------------------------------------- 1 | __('Advanced settings', 'acfe'), 52 | 'name' => 'acfe_form', 53 | 'prefix' => 'acf_field_group', 54 | 'type' => 'true_false', 55 | 'ui' => 1, 56 | 'instructions' => __('Enable advanced fields settings & validation', 'acfe'), 57 | 'value' => (isset($field_group['acfe_form'])) ? $field_group['acfe_form'] : '', 58 | 'required' => false, 59 | 'wrapper' => array( 60 | 'data-after' => 'active' 61 | ) 62 | ), 'div', 'label', true); 63 | 64 | } 65 | 66 | } 67 | 68 | // initialize 69 | new acfe_field_group_advanced(); 70 | 71 | endif; -------------------------------------------------------------------------------- /includes/field-groups/field-group-display-title.php: -------------------------------------------------------------------------------- 1 | $value){ 50 | 51 | if($key === 'the_content'){ 52 | 53 | $choices['block_editor'] = __('Block Editor'); 54 | 55 | } 56 | 57 | 58 | $choices[$key] = $value; 59 | 60 | } 61 | 62 | $field['choices'] = $choices; 63 | 64 | return $field; 65 | 66 | } 67 | 68 | 69 | /** 70 | * acf_add_meta_boxes 71 | * 72 | * Apply all Field Groups styles 73 | * Fix ACF only which only use the first Field Group style 74 | * 75 | * @param $post_type 76 | * @param $post 77 | * @param $field_groups 78 | */ 79 | function acf_add_meta_boxes($post_type, $post, $field_groups){ 80 | 81 | $instance = acf_get_instance('ACF_Form_Post'); 82 | 83 | $styles = ''; 84 | 85 | foreach($field_groups as $field_group){ 86 | 87 | $styles .= acf_get_field_group_style($field_group); 88 | 89 | } 90 | 91 | $instance->style = $styles; 92 | 93 | } 94 | 95 | 96 | /** 97 | * ajax_check_screen 98 | * 99 | * Merges hide on screen settings instead of using the first field group style only 100 | */ 101 | function ajax_check_screen(){ 102 | 103 | // get ajax check screen instance & simulate request 104 | $instance = acf_get_instance('ACF_Ajax_Check_Screen'); 105 | $instance->request = wp_unslash($_REQUEST); 106 | 107 | // get response from ACF core 108 | $response = $instance->get_response($instance->request); 109 | 110 | // vars 111 | $args = wp_parse_args($instance->request, array( 112 | 'screen' => '', 113 | 'post_id' => 0, 114 | 'ajax' => true, 115 | 'exists' => array() 116 | )); 117 | 118 | // get field groups 119 | $field_groups = acf_get_field_groups($args); 120 | 121 | // loop through field groups 122 | if($field_groups){ 123 | 124 | $response['style'] = ''; 125 | 126 | foreach($field_groups as $i => $field_group){ 127 | 128 | // merge styles instead of using only the first field group rules 129 | $response['style'] .= acf_get_field_group_style($field_group); 130 | 131 | } 132 | 133 | } 134 | 135 | // verify error and send request based on ACF_Ajax->request() method 136 | $error = $instance->verify_request($instance->request); 137 | if(is_wp_error($error)){ 138 | $instance->send($error); 139 | } 140 | 141 | // send response 142 | $instance->send($response); 143 | 144 | } 145 | 146 | 147 | /** 148 | * hide_block_editor 149 | */ 150 | function hide_block_editor(){ 151 | 152 | // globals 153 | global $typenow; 154 | 155 | // Restrict 156 | $restricted = array('acf-field-group', 'attachment'); 157 | 158 | if(in_array($typenow, $restricted)){ 159 | return; 160 | } 161 | 162 | $post_type = $typenow; 163 | $post_id = 0; 164 | 165 | if(isset( $_GET['post'])){ 166 | $post_id = (int) $_GET['post']; 167 | 168 | }elseif(isset($_POST['post_ID'])){ 169 | $post_id = (int) $_POST['post_ID']; 170 | } 171 | 172 | $field_groups = acf_get_field_groups(array( 173 | 'post_id' => $post_id, 174 | 'post_type' => $post_type 175 | )); 176 | 177 | $hide_block_editor = false; 178 | 179 | foreach($field_groups as $field_group){ 180 | 181 | $hide_on_screen = acf_get_array($field_group['hide_on_screen']); 182 | 183 | if(!in_array('block_editor', $hide_on_screen)) 184 | continue; 185 | 186 | $hide_block_editor = true; 187 | break; 188 | 189 | } 190 | 191 | if($hide_block_editor){ 192 | add_filter('use_block_editor_for_post_type', '__return_false'); 193 | } 194 | 195 | } 196 | 197 | } 198 | 199 | // initialize 200 | new acfe_field_group_hide_on_screen(); 201 | 202 | endif; -------------------------------------------------------------------------------- /includes/field-groups/field-group-instruction-placement.php: -------------------------------------------------------------------------------- 1 | __('Above fields', 'acfe'), 40 | 'tooltip' => __('Tooltip', 'acfe') 41 | )); 42 | 43 | return $field; 44 | 45 | } 46 | 47 | } 48 | 49 | // initialize 50 | new acfe_field_group_instruction_placement(); 51 | 52 | endif; -------------------------------------------------------------------------------- /includes/field-groups/field-group-permissions.php: -------------------------------------------------------------------------------- 1 | &$fields){ 32 | asort($fields); 33 | } 34 | 35 | // before acf 6.1 category was 'jQuery' 36 | $category = acfe_is_acf_61() ? 'Advanced' : 'jQuery'; 37 | 38 | if(isset($groups['E-Commerce'])){ 39 | $groups = acfe_array_insert_after($groups, $category, 'E-Commerce', $groups['E-Commerce']); 40 | } 41 | 42 | if(isset($groups['ACF'])){ 43 | $groups = acfe_array_insert_after($groups, $category, 'ACF', $groups['ACF']); 44 | } 45 | 46 | if(isset($groups['WordPress'])){ 47 | $groups = acfe_array_insert_after($groups, $category, 'WordPress', $groups['WordPress']); 48 | } 49 | 50 | return $groups; 51 | 52 | } 53 | 54 | 55 | /** 56 | * localized_field_categories 57 | * 58 | * Added in ACF 6.1 59 | * 60 | * @param $categories_i18n 61 | * 62 | * @return array 63 | */ 64 | function localized_field_categories($categories_i18n){ 65 | 66 | $categories_i18n = acfe_array_insert_after($categories_i18n, 'advanced', 'E-Commerce', 'E-Commerce'); 67 | $categories_i18n = acfe_array_insert_after($categories_i18n, 'advanced', 'ACF', 'ACF'); 68 | $categories_i18n = acfe_array_insert_after($categories_i18n, 'advanced', 'WordPress', 'WordPress'); 69 | 70 | unset($categories_i18n['pro']); 71 | 72 | return $categories_i18n; 73 | 74 | } 75 | 76 | } 77 | 78 | acf_new_instance('ACFE_Field_Group_Field_Types'); 79 | 80 | endif; -------------------------------------------------------------------------------- /includes/field.php: -------------------------------------------------------------------------------- 1 | add_field_filter('acfe/field_wrapper_attributes', array($this, 'field_wrapper_attributes'), 10, 2); 21 | $this->add_field_filter('acfe/load_fields', array($this, 'load_fields'), 10, 2); 22 | 23 | } 24 | 25 | } 26 | 27 | endif; -------------------------------------------------------------------------------- /includes/fields-settings/data.php: -------------------------------------------------------------------------------- 1 | false, 39 | 'instructions' => '', 40 | 'type' => 'acfe_dynamic_render', 41 | 'required' => false, 42 | 'name' => 'acfe_field_data', 43 | 'key' => 'acfe_field_data', 44 | 'value' => $id, 45 | ), true); 46 | 47 | } 48 | 49 | 50 | /** 51 | * render_field 52 | * 53 | * @param $field 54 | * 55 | * @return void 56 | */ 57 | function render_field($field){ 58 | 59 | // get field id 60 | $id = $field['value']; 61 | 62 | // validate 63 | if(!$id){ 64 | return; 65 | } 66 | 67 | // Field 68 | $field = acf_get_field($id); 69 | $field = @map_deep($field, 'esc_html'); 70 | 71 | $field_debug = $field ? '
' . print_r($field, true) . '
' : '
' . __('Field data unavailable', 'acfe') . '
'; 72 | 73 | // Post 74 | $post = get_post($id, ARRAY_A); 75 | $post = @map_deep($post, 'esc_html'); 76 | 77 | $post_debug = $post ? '
' . print_r($post, true) . '
' : '
' . __('Post object unavailable', 'acfe') . '
'; 78 | 79 | // title 80 | $title = __('Field Data', 'acf'); 81 | 82 | // field label 83 | if($field){ 84 | 85 | $label = acf_maybe_get($field, 'label'); 86 | $name = acf_maybe_get($field, 'name'); 87 | 88 | $title = $label ? $label : $name; 89 | 90 | } 91 | 92 | ?> 93 | 94 |
95 |
96 | 97 |
98 |
99 | __('Permissions'), 24 | 'name' => 'acfe_permissions', 25 | 'key' => 'acfe_permissions', 26 | 'instructions' => __('Restrict user roles that are allowed to view and edit this field'), 27 | 'type' => 'checkbox', 28 | 'required' => false, 29 | 'default_value' => false, 30 | 'choices' => acfe_get_roles(), 31 | 'layout' => 'horizontal', 32 | 'wrapper' => array( 33 | 'data-after' => 'instructions' 34 | ) 35 | ), true); 36 | 37 | } 38 | 39 | } 40 | 41 | function prepare_field($field){ 42 | 43 | if(!acf_maybe_get($field, 'acfe_permissions')) 44 | return $field; 45 | 46 | $user_roles = acfe_get_current_user_roles(); 47 | $render = false; 48 | 49 | foreach($user_roles as $user_role){ 50 | 51 | foreach($field['acfe_permissions'] as $field_role){ 52 | 53 | if($user_role !== $field_role) 54 | continue; 55 | 56 | $render = true; 57 | break 2; 58 | 59 | } 60 | 61 | } 62 | 63 | if(!$render) 64 | return false; 65 | 66 | return $field; 67 | 68 | } 69 | 70 | } 71 | 72 | new acfe_permissions(); 73 | 74 | endif; -------------------------------------------------------------------------------- /includes/fields/field-checkbox.php: -------------------------------------------------------------------------------- 1 |
" . __('You may use "## Title" to create a group of options.', 'acfe'); 39 | 40 | if(acf_maybe_get($field, 'hint')){ 41 | $field['hint'] .= $text; 42 | }else{ 43 | $field['instructions'] .= $text; 44 | } 45 | 46 | 47 | } 48 | 49 | return $field; 50 | 51 | } 52 | 53 | 54 | /** 55 | * prepare_choices 56 | * 57 | * @param $field 58 | * 59 | * @return mixed 60 | */ 61 | function prepare_choices($field){ 62 | 63 | // bail early if no choices 64 | if(empty($field['choices'])){ 65 | return $field; 66 | } 67 | 68 | // map '## group' 69 | if(is_array($field['choices'])){ 70 | 71 | $found = false; 72 | $found_array = array(); 73 | 74 | foreach($field['choices'] as $k => $choice){ 75 | 76 | if(is_string($choice)){ 77 | 78 | $choice = trim($choice); 79 | 80 | if(strpos($choice, '##') === 0){ 81 | 82 | $choice = substr($choice, 2); 83 | $choice = trim($choice); 84 | 85 | $found = $choice; 86 | $found_array[$choice] = array(); 87 | 88 | }elseif(!empty($found)){ 89 | 90 | $found_array[$found][$k] = $choice; 91 | 92 | } 93 | 94 | } 95 | 96 | } 97 | 98 | if(!empty($found_array)){ 99 | $field['choices'] = $found_array; 100 | } 101 | 102 | } 103 | 104 | // Labels 105 | $labels = $this->walk_choices($field['choices']); 106 | 107 | if(!empty($labels)){ 108 | $field['wrapper']['data-acfe-labels'] = json_encode($labels); 109 | } 110 | 111 | return $field; 112 | 113 | } 114 | 115 | 116 | /** 117 | * walk_choices 118 | * 119 | * @param $choices 120 | * @param $depth 121 | * @param $labels 122 | * 123 | * @return array|mixed 124 | */ 125 | function walk_choices($choices = array(), $depth = 1, $labels = array()){ 126 | 127 | // bail early if no choices 128 | if(empty($choices)){ 129 | return $labels; 130 | } 131 | 132 | foreach($choices as $value => $label){ 133 | 134 | // bail early if not array 135 | if(!is_array($label)) continue; 136 | 137 | reset($label); 138 | $key = key($label); 139 | 140 | if(!is_numeric($value)){ 141 | $labels = array_merge($labels, array($value => $key)); 142 | } 143 | 144 | $labels = $this->walk_choices($label, $depth+1, $labels); 145 | 146 | } 147 | 148 | return $labels; 149 | 150 | } 151 | 152 | 153 | /** 154 | * prepare_radio 155 | * 156 | * @param $field 157 | * 158 | * @return mixed 159 | */ 160 | function prepare_radio($field){ 161 | 162 | if($field['type'] !== 'radio' && $field['field_type'] !== 'radio'){ 163 | return $field; 164 | } 165 | 166 | if(empty($field['choices'])){ 167 | return $field; 168 | } 169 | 170 | $choices = array(); 171 | 172 | foreach($field['choices'] as $value => $label){ 173 | 174 | if(is_array($label)){ 175 | $choices = $choices + $label; 176 | }else{ 177 | $choices = $choices + array($value => $label); 178 | } 179 | 180 | } 181 | 182 | $field['choices'] = $choices; 183 | 184 | return $field; 185 | 186 | } 187 | 188 | } 189 | 190 | acf_new_instance('acfe_field_checkbox'); 191 | 192 | endif; 193 | 194 | 195 | /** 196 | * acfe_prepare_checkbox_labels 197 | * 198 | * @param $field 199 | * 200 | * @return mixed 201 | */ 202 | function acfe_prepare_checkbox_labels($field){ 203 | 204 | $instance = acf_get_instance('acfe_field_checkbox'); 205 | 206 | $field = $instance->prepare_choices($field); 207 | $field = $instance->prepare_radio($field); 208 | 209 | return $field; 210 | 211 | } -------------------------------------------------------------------------------- /includes/fields/field-column.php: -------------------------------------------------------------------------------- 1 | name = 'acfe_column'; 17 | $this->label = __('Column', 'acfe'); 18 | $this->category = 'layout'; 19 | $this->defaults = array( 20 | 'columns' => '6/12', 21 | 'endpoint' => false, 22 | ); 23 | 24 | } 25 | 26 | 27 | /** 28 | * render_field_settings 29 | * 30 | * @param $field 31 | */ 32 | function render_field_settings($field){ 33 | 34 | // columns 35 | acf_render_field_setting($field, array( 36 | 'label' => __('Columns', 'acfe'), 37 | 'instructions' => '', 38 | 'type' => 'select', 39 | 'name' => 'columns', 40 | 'choices' => array( 41 | '1/12' => '1/12', 42 | '2/12' => '2/12', 43 | '3/12' => '3/12', 44 | '4/12' => '4/12', 45 | '5/12' => '5/12', 46 | '6/12' => '6/12', 47 | '7/12' => '7/12', 48 | '8/12' => '8/12', 49 | '9/12' => '9/12', 50 | '10/12' => '10/12', 51 | '11/12' => '11/12', 52 | '12/12' => '12/12', 53 | ), 54 | 'class' => 'acfe-field-columns', 55 | 'conditional_logic' => array( 56 | array( 57 | array( 58 | 'field' => 'endpoint', 59 | 'operator' => '!=', 60 | 'value' => '1', 61 | ) 62 | ) 63 | ) 64 | )); 65 | 66 | // endpoint 67 | acf_render_field_setting($field, array( 68 | 'label' => __('Endpoint','acf'), 69 | 'instructions' => __('Define an endpoint for the previous columns to stop.', 'acf'), 70 | 'name' => 'endpoint', 71 | 'type' => 'true_false', 72 | 'ui' => 1, 73 | 'class' => 'acfe-field-columns-endpoint', 74 | )); 75 | 76 | } 77 | 78 | 79 | /** 80 | * load_field 81 | * 82 | * @param $field 83 | * 84 | * @return mixed 85 | */ 86 | function load_field($field){ 87 | 88 | $columns = ''; 89 | 90 | if($field['columns']){ 91 | $columns = ucfirst($field['columns']); 92 | } 93 | 94 | if($field['endpoint']){ 95 | $columns = 'Endpoint'; 96 | } 97 | 98 | $field['label'] = '(Column ' . $columns . ')'; 99 | $field['name'] = ''; 100 | $field['instructions'] = ''; 101 | $field['required'] = 0; 102 | $field['value'] = false; 103 | 104 | return $field; 105 | 106 | } 107 | 108 | 109 | /** 110 | * prepare_field 111 | * 112 | * @param $field 113 | * 114 | * @return false 115 | */ 116 | function prepare_field($field){ 117 | 118 | global $pagenow; 119 | 120 | // do not render on User/Term views without Enhanced UI module (because of Table render) 121 | if((acf_is_screen(array('profile', 'user-edit')) || (acf_is_screen('user') && !is_multisite()) || $pagenow === 'term.php') && !acf_get_setting('acfe/modules/ui')){ 122 | return false; 123 | } 124 | 125 | // do not render on New Term page (forced to left) 126 | if($pagenow === 'edit-tags.php'){ 127 | return false; 128 | } 129 | 130 | // hide label 131 | $field['label'] = false; 132 | 133 | // return 134 | return $field; 135 | 136 | } 137 | 138 | 139 | /** 140 | * field_wrapper_attributes 141 | * 142 | * @param $wrapper 143 | * @param $field 144 | * 145 | * @return mixed 146 | */ 147 | function field_wrapper_attributes($wrapper, $field){ 148 | 149 | if($field['endpoint']){ 150 | $wrapper['data-endpoint'] = $field['endpoint']; 151 | 152 | }elseif($field['columns']){ 153 | $wrapper['data-columns'] = $field['columns']; 154 | } 155 | 156 | return $wrapper; 157 | 158 | } 159 | 160 | 161 | /** 162 | * render_field 163 | * 164 | * @param $field 165 | */ 166 | function render_field($field){ 167 | 168 | // vars 169 | $atts = array( 170 | 'class' => 'acf-fields', 171 | ); 172 | 173 | ?> 174 |
>
175 | name = 'acfe_dynamic_render'; 17 | $this->label = __('Dynamic Render', 'acfe'); 18 | $this->category = 'layout'; 19 | $this->defaults = array( 20 | 'render' => '' 21 | ); 22 | 23 | } 24 | 25 | 26 | /** 27 | * render_field 28 | * 29 | * @param $field 30 | */ 31 | function render_field($field){ 32 | 33 | // check callback 34 | // check isset() for backward compatibility with the old acfe_dynamic_message field type 35 | if(isset($field['render']) && is_callable($field['render'])){ 36 | call_user_func_array($field['render'], array($field)); 37 | } 38 | 39 | } 40 | 41 | } 42 | 43 | // initialize 44 | acf_register_field_type('acfe_field_dynamic_render'); 45 | 46 | endif; -------------------------------------------------------------------------------- /includes/fields/field-file.php: -------------------------------------------------------------------------------- 1 | name = 'file'; 17 | $this->defaults = array( 18 | 'uploader' => '', 19 | ); 20 | 21 | $this->add_filter('gettext', array($this, 'gettext'), 99, 3); 22 | $this->add_filter('acf/prepare_field/name=min_size', array($this, 'prepare_size')); 23 | $this->add_filter('acf/prepare_field/name=max_size', array($this, 'prepare_size')); 24 | $this->add_filter('acf/prepare_field/name=library', array($this, 'prepare_library')); 25 | 26 | $this->add_field_action('acf/render_field_settings', array($this, '_render_field_settings'), 0); 27 | 28 | } 29 | 30 | 31 | /** 32 | * gettext 33 | * 34 | * @param $translated_text 35 | * @param $text 36 | * @param $domain 37 | * 38 | * @return string 39 | */ 40 | function gettext($translated_text, $text, $domain){ 41 | 42 | if($domain === 'acf' && $text === 'No file selected'){ 43 | return ''; 44 | } 45 | 46 | return $translated_text; 47 | 48 | } 49 | 50 | 51 | /** 52 | * prepare_size 53 | * 54 | * @param $field 55 | * 56 | * @return mixed 57 | */ 58 | function prepare_size($field){ 59 | 60 | if(acf_maybe_get($field['wrapper'], 'data-setting') === 'file'){ 61 | 62 | switch($field['_name']){ 63 | 64 | case 'min_size': { 65 | 66 | $field['label'] = __('File size', 'acf'); 67 | $field['prepend'] = __('Min size', 'acfe'); 68 | break; 69 | 70 | } 71 | 72 | case 'max_size': { 73 | 74 | $field['prepend'] = __('Max size', 'acfe'); 75 | $field['wrapper']['data-append'] = 'min_size'; 76 | break; 77 | 78 | } 79 | 80 | } 81 | 82 | } 83 | 84 | return $field; 85 | 86 | } 87 | 88 | 89 | /** 90 | * prepare_library 91 | * 92 | * @param $field 93 | * 94 | * @return mixed 95 | */ 96 | function prepare_library($field){ 97 | 98 | // check if field group ui setting 99 | if(acf_maybe_get($field['wrapper'], 'data-setting') === 'file'){ 100 | 101 | // add conditional logic 102 | $field['conditional_logic'] = array( 103 | array( 104 | array( 105 | 'field' => 'uploader', 106 | 'operator' => '==', 107 | 'value' => 'wp', 108 | ) 109 | ) 110 | ); 111 | 112 | } 113 | 114 | return $field; 115 | 116 | } 117 | 118 | 119 | /** 120 | * _render_field_settings 121 | * 122 | * acf/render_field_settings:0 123 | * 124 | * @param $field 125 | */ 126 | function _render_field_settings($field){ 127 | 128 | // uploader 129 | acf_render_field_setting($field, array( 130 | 'label' => __('Uploader Type', 'acfe'), 131 | 'name' => 'uploader', 132 | 'key' => 'uploader', 133 | 'instructions' => __('Choose the uploader type', 'acfe'), 134 | 'type' => 'radio', 135 | 'choices' => array( 136 | '' => __('Default', 'acf'), 137 | 'wp' => 'WordPress', 138 | 'basic' => __('Browser', 'acfe'), 139 | ), 140 | 'default_value' => '', 141 | 'layout' => 'horizontal', 142 | 'return_format' => 'value', 143 | )); 144 | 145 | } 146 | 147 | 148 | /** 149 | * prepare_field 150 | * 151 | * @param $field 152 | * 153 | * @return mixed 154 | */ 155 | function prepare_field($field){ 156 | 157 | // let acfe form force specific uploader 158 | if(acf_is_filter_enabled('acfe/form/uploader')){ 159 | $field['uploader'] = ''; 160 | } 161 | 162 | // default uploader in settings 163 | // use global acf uploader 164 | if(empty($field['uploader'])){ 165 | $field['uploader'] = acf_get_setting('uploader'); 166 | } 167 | 168 | // current user can't upload files 169 | // force basic 170 | if(!current_user_can('upload_files')){ 171 | $field['uploader'] = 'basic'; 172 | } 173 | 174 | // update global uploader 175 | acf_update_setting('uploader', $field['uploader']); 176 | 177 | // return 178 | return $field; 179 | 180 | } 181 | 182 | } 183 | 184 | acf_new_instance('acfe_field_file'); 185 | 186 | endif; -------------------------------------------------------------------------------- /includes/fields/field-flexible-content-hide.php: -------------------------------------------------------------------------------- 1 | 'Hide "Collapse"', 52 | 'add' => 'Hide "Add"', 53 | 'delete' => 'Hide "Delete"', 54 | 'duplicate' => 'Hide "Duplicate"', 55 | ); 56 | 57 | if(acf_version_compare(acf_get_setting('version'), '<', '5.9')){ 58 | acfe_unset($hide_choices, 'duplicate'); 59 | } 60 | 61 | // Hide Buttons 62 | acf_render_field_setting($field, array( 63 | 'label' => __('Hide Buttons', 'acfe'), 64 | 'name' => 'acfe_flexible_remove_button', 65 | 'key' => 'acfe_flexible_remove_button', 66 | 'instructions' => '' . __('See documentation', 'acfe') . '', 67 | 'type' => 'checkbox', 68 | 'default_value' => '', 69 | 'layout' => 'horizontal', 70 | 'choices' => $hide_choices, 71 | 'conditional_logic' => array( 72 | array( 73 | array( 74 | 'field' => 'acfe_flexible_advanced', 75 | 'operator' => '==', 76 | 'value' => '1', 77 | ), 78 | ) 79 | ) 80 | )); 81 | 82 | } 83 | 84 | 85 | /** 86 | * validate_hide 87 | * 88 | * @param $field 89 | * 90 | * @return mixed 91 | */ 92 | function validate_hide($field){ 93 | 94 | /** 95 | * old settings: 96 | * 97 | * acfe_flexible_remove_add_button 98 | * acfe_flexible_remove_duplicate_button 99 | * acfe_flexible_remove_delete_button 100 | */ 101 | 102 | $hide = acf_get_array($field['acfe_flexible_remove_button']); 103 | 104 | // acfe_flexible_remove_add_button 105 | if(acf_maybe_get($field, 'acfe_flexible_remove_add_button')){ 106 | 107 | if(!in_array('add', $hide)) $hide[] = 'add'; 108 | acfe_unset($field, 'acfe_flexible_remove_add_button'); 109 | 110 | } 111 | 112 | // acfe_flexible_remove_duplicate_button 113 | if(acf_maybe_get($field, 'acfe_flexible_remove_duplicate_button')){ 114 | 115 | if(!in_array('duplicate', $hide)) $hide[] = 'duplicate'; 116 | acfe_unset($field, 'acfe_flexible_remove_duplicate_button'); 117 | 118 | } 119 | 120 | // acfe_flexible_remove_delete_button 121 | if(acf_maybe_get($field, 'acfe_flexible_remove_delete_button')){ 122 | 123 | if(!in_array('delete', $hide)) $hide[] = 'delete'; 124 | acfe_unset($field, 'acfe_flexible_remove_delete_button'); 125 | 126 | } 127 | 128 | $field['acfe_flexible_remove_button'] = $hide; 129 | 130 | return $field; 131 | 132 | } 133 | 134 | 135 | /** 136 | * remove_actions 137 | * 138 | * @param $return 139 | * @param $field 140 | * 141 | * @return bool|mixed 142 | */ 143 | function remove_actions($return, $field){ 144 | 145 | if(!in_array('add', $field['acfe_flexible_remove_button'])){ 146 | return $return; 147 | } 148 | 149 | return true; 150 | 151 | } 152 | 153 | 154 | /** 155 | * layout_icons 156 | * 157 | * @param $icons 158 | * @param $layout 159 | * @param $field 160 | * 161 | * @return mixed 162 | */ 163 | function layout_icons($icons, $layout, $field){ 164 | 165 | if(in_array('add', $field['acfe_flexible_remove_button'])){ 166 | acfe_unset($icons, 'add'); 167 | } 168 | 169 | if(in_array('duplicate', $field['acfe_flexible_remove_button'])){ 170 | acfe_unset($icons, 'duplicate'); 171 | } 172 | 173 | if(in_array('delete', $field['acfe_flexible_remove_button'])){ 174 | acfe_unset($icons, 'delete'); 175 | } 176 | 177 | if(in_array('collapse', $field['acfe_flexible_remove_button'])){ 178 | acfe_unset($icons, 'collapse'); 179 | } 180 | 181 | return $icons; 182 | 183 | } 184 | 185 | } 186 | 187 | acf_new_instance('acfe_field_flexible_content_hide'); 188 | 189 | endif; -------------------------------------------------------------------------------- /includes/fields/field-group.php: -------------------------------------------------------------------------------- 1 | name = 'group'; 17 | $this->defaults = array( 18 | 'acfe_seamless_style' => 0, 19 | 'acfe_group_modal' => 0, 20 | 'acfe_group_modal_close' => 0, 21 | 'acfe_group_modal_button' => '', 22 | 'acfe_group_modal_size' => 'large', 23 | ); 24 | 25 | } 26 | 27 | 28 | /** 29 | * render_field_settings 30 | * 31 | * @param $field 32 | */ 33 | function render_field_settings($field){ 34 | 35 | acf_render_field_setting($field, array( 36 | 'label' => __('Seamless Style', 'acfe'), 37 | 'name' => 'acfe_seamless_style', 38 | 'instructions' => __('Enable better CSS integration: remove borders and padding'), 39 | 'type' => 'true_false', 40 | 'message' => '', 41 | 'default_value' => false, 42 | 'ui' => true, 43 | 'conditional_logic' => array( 44 | array( 45 | array( 46 | 'field' => 'acfe_group_modal', 47 | 'operator' => '!=', 48 | 'value' => '1', 49 | ) 50 | ) 51 | ) 52 | )); 53 | 54 | acf_render_field_setting($field, array( 55 | 'label' => __('Edition modal'), 56 | 'name' => 'acfe_group_modal', 57 | 'instructions' => __('Edit fields in a modal'), 58 | 'type' => 'true_false', 59 | 'message' => '', 60 | 'default_value' => false, 61 | 'ui' => true, 62 | 'conditional_logic' => array( 63 | array( 64 | array( 65 | 'field' => 'acfe_seamless_style', 66 | 'operator' => '!=', 67 | 'value' => '1', 68 | ) 69 | ) 70 | ) 71 | )); 72 | 73 | acf_render_field_setting($field, array( 74 | 'label' => __('Edition modal: Close button'), 75 | 'name' => 'acfe_group_modal_close', 76 | 'instructions' => __('Display close button'), 77 | 'type' => 'true_false', 78 | 'message' => '', 79 | 'default_value' => false, 80 | 'ui' => true, 81 | 'conditional_logic' => array( 82 | array( 83 | array( 84 | 'field' => 'acfe_group_modal', 85 | 'operator' => '==', 86 | 'value' => '1', 87 | ), 88 | ) 89 | ) 90 | )); 91 | 92 | acf_render_field_setting($field, array( 93 | 'label' => __('Edition modal: Text button'), 94 | 'name' => 'acfe_group_modal_button', 95 | 'instructions' => __('Text displayed in the edition modal button'), 96 | 'type' => 'text', 97 | 'placeholder' => __('Edit', 'acf'), 98 | 'conditional_logic' => array( 99 | array( 100 | array( 101 | 'field' => 'acfe_group_modal', 102 | 'operator' => '==', 103 | 'value' => '1', 104 | ), 105 | ) 106 | ) 107 | )); 108 | 109 | acf_render_field_setting($field, array( 110 | 'label' => __('Edition modal: Size'), 111 | 'name' => 'acfe_group_modal_size', 112 | 'instructions' => __('Choose the modal size'), 113 | 'type' => 'select', 114 | 'choices' => array( 115 | 'small' => 'Small', 116 | 'medium' => 'Medium', 117 | 'large' => 'Large', 118 | 'full' => 'Full', 119 | ), 120 | 'default_value' => 'large', 121 | 'conditional_logic' => array( 122 | array( 123 | array( 124 | 'field' => 'acfe_group_modal', 125 | 'operator' => '==', 126 | 'value' => '1', 127 | ), 128 | ) 129 | ) 130 | )); 131 | 132 | } 133 | 134 | 135 | /** 136 | * prepare_field 137 | * 138 | * @param $field 139 | * 140 | * @return array 141 | */ 142 | function prepare_field($field){ 143 | 144 | // seamless style 145 | if($field['acfe_seamless_style']){ 146 | $field['wrapper']['class'] .= ' acfe-seamless-style'; 147 | } 148 | 149 | // class 150 | $field['wrapper']['class'] .= ' acfe-field-group-layout-' . $field['layout']; 151 | 152 | // modal edit 153 | if($field['acfe_group_modal']){ 154 | 155 | $field['wrapper']['data-acfe-group-modal'] = $field['acfe_group_modal']; 156 | $field['wrapper']['data-acfe-group-modal-button'] = $field['acfe_group_modal_button'] ? $field['acfe_group_modal_button'] : __('Edit', 'acf'); 157 | $field['wrapper']['data-acfe-group-modal-close'] = $field['acfe_group_modal_close']; 158 | $field['wrapper']['data-acfe-group-modal-size'] = $field['acfe_group_modal_size']; 159 | 160 | } 161 | 162 | // return 163 | return $field; 164 | 165 | } 166 | 167 | 168 | /** 169 | * translate_field 170 | * 171 | * @param $field 172 | * 173 | * @return mixed 174 | */ 175 | function translate_field($field){ 176 | 177 | $field['acfe_group_modal_button'] = acf_translate($field['acfe_group_modal_button']); 178 | 179 | return $field; 180 | 181 | } 182 | 183 | } 184 | 185 | acf_new_instance('acfe_field_group_field'); 186 | 187 | endif; -------------------------------------------------------------------------------- /includes/fields/field-hidden.php: -------------------------------------------------------------------------------- 1 | name = 'acfe_hidden'; 17 | $this->label = __('Hidden', 'acfe'); 18 | $this->category = 'basic'; 19 | $this->defaults = array( 20 | 'default_value' => '' 21 | ); 22 | 23 | } 24 | 25 | 26 | /** 27 | * prepare_field 28 | * 29 | * @param $field 30 | * 31 | * @return array 32 | */ 33 | function prepare_field($field){ 34 | 35 | $field['wrapper']['class'] = 'acf-hidden'; 36 | 37 | return $field; 38 | 39 | } 40 | 41 | 42 | /** 43 | * render_field 44 | * 45 | * @param $field 46 | */ 47 | function render_field($field){ 48 | 49 | acf_hidden_input(array( 50 | 'name' => $field['name'], 51 | 'value' => $field['value'], 52 | )); 53 | 54 | } 55 | 56 | 57 | /** 58 | * render_field_settings 59 | * 60 | * @param $field 61 | */ 62 | function render_field_settings($field){ 63 | 64 | // default_value 65 | acf_render_field_setting($field, array( 66 | 'label' => __('Value', 'acf'), 67 | 'instructions' => __('Default value in the hidden input', 'acf'), 68 | 'type' => 'text', 69 | 'name' => 'default_value', 70 | )); 71 | 72 | } 73 | 74 | } 75 | 76 | // initialize 77 | acf_register_field_type('acfe_field_hidden'); 78 | 79 | endif; -------------------------------------------------------------------------------- /includes/fields/field-post-object.php: -------------------------------------------------------------------------------- 1 | name = 'post_object'; 17 | $this->defaults = array( 18 | 'save_custom' => 0, 19 | 'save_post_type' => '', 20 | 'save_post_status' => '', 21 | ); 22 | 23 | // hooks 24 | $this->add_field_filter('acf/update_value', array($this, '_update_value'), 5, 3); 25 | 26 | } 27 | 28 | 29 | /** 30 | * render_field_settings 31 | * 32 | * @param $field 33 | */ 34 | function render_field_settings($field){ 35 | 36 | // save custom value 37 | acf_render_field_setting($field, array( 38 | 'label' => __('Allow & Save Custom value', 'acf'), 39 | 'instructions' => '', 40 | 'name' => 'save_custom', 41 | 'type' => 'true_false', 42 | 'ui' => 1, 43 | 'message' => __("Save 'custom' values as new post", 'acf'), 44 | )); 45 | 46 | // save post_type 47 | acf_render_field_setting($field, array( 48 | 'label' => __('New Post Arguments', 'acf'), 49 | 'instructions' => __('See available hooks in the documentation.', 'acfe'), 50 | 'name' => 'save_post_type', 51 | 'type' => 'acfe_post_types', 52 | 'field_type' => 'select', 53 | 'conditional_logic' => array( 54 | 'field' => 'save_custom', 55 | 'operator' => '==', 56 | 'value' => 1 57 | ) 58 | )); 59 | 60 | // save post_status 61 | acf_render_field_setting($field, array( 62 | 'label' => '', 63 | 'instructions' => '', 64 | 'name' => 'save_post_status', 65 | 'type' => 'acfe_post_statuses', 66 | 'field_type' => 'select', 67 | 'conditional_logic' => array( 68 | 'field' => 'save_custom', 69 | 'operator' => '==', 70 | 'value' => 1 71 | ), 72 | '_append' => 'save_post_type' 73 | )); 74 | 75 | } 76 | 77 | 78 | /** 79 | * field_wrapper_attributes 80 | * 81 | * @param $wrapper 82 | * @param $field 83 | * 84 | * @return mixed 85 | */ 86 | function field_wrapper_attributes($wrapper, $field){ 87 | 88 | if($field['save_custom']){ 89 | $wrapper['data-acfe-allow-custom'] = 1; 90 | } 91 | 92 | return $wrapper; 93 | 94 | } 95 | 96 | 97 | /** 98 | * _update_value 99 | * 100 | * acf/update_value:5 101 | * 102 | * @param $value 103 | * @param $post_id 104 | * @param $field 105 | * 106 | * @return array|false|mixed|string[] 107 | */ 108 | function _update_value($value, $post_id, $field){ 109 | 110 | // bail early if empty 111 | if(empty($value)){ 112 | return $value; 113 | } 114 | 115 | // bail early if no save custom setting 116 | if(!$field['save_custom']){ 117 | return $value; 118 | } 119 | 120 | // bail early when local meta 121 | if(acfe_is_local_post_id($post_id)){ 122 | return $value; 123 | } 124 | 125 | // new post args 126 | $post_type = acf_maybe_get($field, 'save_post_type', 'post'); 127 | $post_status = acf_maybe_get($field, 'save_post_status', 'publish'); 128 | 129 | // vars 130 | $is_array = is_array($value); 131 | $value = acf_get_array($value); 132 | 133 | // loop 134 | foreach($value as $k => $v){ 135 | 136 | // has to be words 137 | // (post id are selected posts) 138 | if(is_numeric($v)){ 139 | continue; 140 | } 141 | 142 | // vars 143 | $title = $v; 144 | 145 | // args 146 | $args = array( 147 | 'post_title' => $title, 148 | 'post_type' => $post_type, 149 | 'post_status' => $post_status, 150 | ); 151 | 152 | // filters 153 | $args = apply_filters("acfe/fields/post_object/custom_save_args", $args, $title, $post_id, $field); 154 | $args = apply_filters("acfe/fields/post_object/custom_save_args/name={$field['name']}", $args, $title, $post_id, $field); 155 | $args = apply_filters("acfe/fields/post_object/custom_save_args/key={$field['key']}", $args, $title, $post_id, $field); 156 | 157 | // do not create post 158 | if($args === false){ 159 | 160 | unset($value[ $k ]); 161 | continue; 162 | 163 | } 164 | 165 | // insert post 166 | $_post_id = wp_insert_post($args); 167 | 168 | // error during creation 169 | if(empty($_post_id) || is_wp_error($_post_id)){ 170 | 171 | unset($value[ $k ]); 172 | continue; 173 | 174 | } 175 | 176 | // actions after create 177 | do_action("acfe/fields/post_object/custom_save", $_post_id, $title, $post_id, $field); 178 | do_action("acfe/fields/post_object/custom_save/name={$field['name']}", $_post_id, $title, $post_id, $field); 179 | do_action("acfe/fields/post_object/custom_save/key={$field['key']}", $_post_id, $title, $post_id, $field); 180 | 181 | // assign new post id as selected 182 | $value[ $k ] = $_post_id; 183 | 184 | } 185 | 186 | // check array 187 | if(!$is_array){ 188 | $value = acfe_unarray($value); 189 | } 190 | 191 | // return 192 | return $value; 193 | 194 | } 195 | 196 | } 197 | 198 | acf_new_instance('acfe_field_post_object'); 199 | 200 | endif; -------------------------------------------------------------------------------- /includes/fields/field-repeater.php: -------------------------------------------------------------------------------- 1 | name = 'repeater'; 17 | $this->defaults = array( 18 | 'acfe_repeater_stylised_button' => 0, 19 | ); 20 | 21 | $this->add_field_action('acf/render_field_settings', array($this, '_render_field_settings'), 0); 22 | 23 | } 24 | 25 | 26 | /** 27 | * _render_field_settings 28 | * 29 | * acf/render_field_settings:0 30 | * 31 | * @param $field 32 | */ 33 | function _render_field_settings($field){ 34 | 35 | // stylised button 36 | acf_render_field_setting($field, array( 37 | 'label' => __('Stylised Button', 'acfe'), 38 | 'name' => 'acfe_repeater_stylised_button', 39 | 'key' => 'acfe_repeater_stylised_button', 40 | 'instructions' => __('Better row button integration'), 41 | 'type' => 'true_false', 42 | 'message' => '', 43 | 'default_value' => false, 44 | 'ui' => true, 45 | )); 46 | 47 | } 48 | 49 | 50 | /** 51 | * field_wrapper_attributes 52 | * 53 | * @param $wrapper 54 | * @param $field 55 | * 56 | * @return mixed 57 | */ 58 | function field_wrapper_attributes($wrapper, $field){ 59 | 60 | // stylised button 61 | if($field['acfe_repeater_stylised_button']){ 62 | $wrapper['data-acfe-repeater-stylised-button'] = 1; 63 | } 64 | 65 | // lock sortable 66 | $lock = false; 67 | $lock = apply_filters("acfe/repeater/lock", $lock, $field); 68 | $lock = apply_filters("acfe/repeater/lock/name={$field['_name']}", $lock, $field); 69 | $lock = apply_filters("acfe/repeater/lock/key={$field['key']}", $lock, $field); 70 | 71 | if($lock){ 72 | $wrapper['data-acfe-repeater-lock'] = 1; 73 | } 74 | 75 | // remove actions 76 | $remove = false; 77 | $remove = apply_filters("acfe/repeater/remove_actions", $remove, $field); 78 | $remove = apply_filters("acfe/repeater/remove_actions/name={$field['_name']}", $remove, $field); 79 | $remove = apply_filters("acfe/repeater/remove_actions/key={$field['key']}", $remove, $field); 80 | 81 | if($remove){ 82 | $wrapper['data-acfe-repeater-remove-actions'] = 1; 83 | } 84 | 85 | // return 86 | return $wrapper; 87 | 88 | } 89 | 90 | } 91 | 92 | acf_new_instance('acfe_field_repeater'); 93 | 94 | endif; -------------------------------------------------------------------------------- /includes/fields/field-slug.php: -------------------------------------------------------------------------------- 1 | name = 'acfe_slug'; 17 | $this->label = __('Slug', 'acfe'); 18 | $this->category = 'basic'; 19 | $this->defaults = array( 20 | 'default_value' => '', 21 | 'placeholder' => '', 22 | 'prepend' => '', 23 | 'append' => '', 24 | 'maxlength' => '', 25 | ); 26 | 27 | } 28 | 29 | 30 | /** 31 | * render_field_settings 32 | * 33 | * @param $field 34 | */ 35 | function render_field_settings($field){ 36 | 37 | // default_value 38 | acf_render_field_setting($field, array( 39 | 'label' => __('Default Value','acf'), 40 | 'instructions' => __('Appears when creating a new post','acf'), 41 | 'type' => 'text', 42 | 'name' => 'default_value', 43 | )); 44 | 45 | // placeholder 46 | acf_render_field_setting($field, array( 47 | 'label' => __('Placeholder Text','acf'), 48 | 'instructions' => __('Appears within the input','acf'), 49 | 'type' => 'text', 50 | 'name' => 'placeholder', 51 | )); 52 | 53 | // prepend 54 | acf_render_field_setting($field, array( 55 | 'label' => __('Prepend','acf'), 56 | 'instructions' => __('Appears before the input','acf'), 57 | 'type' => 'text', 58 | 'name' => 'prepend', 59 | )); 60 | 61 | // append 62 | acf_render_field_setting($field, array( 63 | 'label' => __('Append','acf'), 64 | 'instructions' => __('Appears after the input','acf'), 65 | 'type' => 'text', 66 | 'name' => 'append', 67 | )); 68 | 69 | // maxlength 70 | acf_render_field_setting($field, array( 71 | 'label' => __('Character Limit','acf'), 72 | 'instructions' => __('Leave blank for no limit','acf'), 73 | 'type' => 'number', 74 | 'name' => 'maxlength', 75 | )); 76 | 77 | } 78 | 79 | 80 | /** 81 | * render_field 82 | * 83 | * @param $field 84 | */ 85 | function render_field($field){ 86 | 87 | // field type 88 | $field['type'] = 'text'; 89 | 90 | // render as text field 91 | acf_get_field_type('text')->render_field($field); 92 | 93 | } 94 | 95 | 96 | /** 97 | * validate_value 98 | * 99 | * @param $valid 100 | * @param $value 101 | * @param $field 102 | * @param $input 103 | * 104 | * @return string 105 | */ 106 | function validate_value($valid, $value, $field, $input){ 107 | 108 | // sanitize 109 | $value = sanitize_title($value); 110 | 111 | // check max length 112 | if($field['maxlength'] && mb_strlen(wp_unslash($value)) > $field['maxlength']){ 113 | return sprintf(__('Value must not exceed %d characters', 'acf'), $field['maxlength']); 114 | } 115 | 116 | // return 117 | return $valid; 118 | 119 | } 120 | 121 | 122 | /** 123 | * update_value 124 | * 125 | * @param $value 126 | * @param $post_id 127 | * @param $field 128 | * 129 | * @return string 130 | */ 131 | function update_value($value, $post_id, $field){ 132 | return sanitize_title($value); 133 | } 134 | 135 | 136 | /** 137 | * translate_field 138 | * 139 | * @param $field 140 | * 141 | * @return mixed 142 | */ 143 | function translate_field($field){ 144 | 145 | $field['placeholder'] = acf_translate($field['placeholder']); 146 | $field['prepend'] = acf_translate($field['prepend']); 147 | $field['append'] = acf_translate($field['append']); 148 | 149 | return $field; 150 | 151 | } 152 | 153 | } 154 | 155 | // initialize 156 | acf_register_field_type('acfe_field_slug'); 157 | 158 | endif; -------------------------------------------------------------------------------- /includes/fields/field-taxonomy.php: -------------------------------------------------------------------------------- 1 | name = 'taxonomy'; 17 | $this->replace = array( 18 | 'load_value', 19 | 'update_value', 20 | ); 21 | 22 | } 23 | 24 | 25 | /** 26 | * load_value 27 | * 28 | * @param $value 29 | * @param $post_id 30 | * @param $field 31 | * 32 | * @return mixed 33 | */ 34 | function load_value($value, $post_id, $field){ 35 | 36 | // disable load terms for local meta & acfe_form 37 | if(acfe_is_local_post_id($post_id) || acfe_starts_with($post_id, 'acfe_form')){ 38 | $field['load_terms'] = false; 39 | } 40 | 41 | // return 42 | return $this->instance->load_value($value, $post_id, $field); 43 | 44 | } 45 | 46 | 47 | /** 48 | * update_value 49 | * 50 | * @param $value 51 | * @param $post_id 52 | * @param $field 53 | * 54 | * @return array|mixed 55 | */ 56 | function update_value($value, $post_id, $field){ 57 | 58 | // disable save terms for local meta & acfe_form 59 | if(acfe_is_local_post_id($post_id) || acfe_starts_with($post_id, 'acfe_form')){ 60 | $field['save_terms'] = false; 61 | } 62 | 63 | // return 64 | return $this->instance->update_value($value, $post_id, $field); 65 | 66 | } 67 | 68 | } 69 | 70 | acf_new_instance('acfe_field_taxonomy'); 71 | 72 | endif; -------------------------------------------------------------------------------- /includes/fields/field-textarea.php: -------------------------------------------------------------------------------- 1 | name = 'textarea'; 17 | $this->defaults = array( 18 | 'acfe_textarea_code' => 0, 19 | ); 20 | 21 | } 22 | 23 | 24 | /** 25 | * field_group_admin_head 26 | */ 27 | function field_group_admin_head(){ 28 | 29 | add_filter('acf/prepare_field/name=new_lines', function($field){ 30 | 31 | // check setting 32 | if(acf_maybe_get($field['wrapper'], 'data-setting') === 'textarea'){ 33 | 34 | $field['conditional_logic'] = array( 35 | array( 36 | array( 37 | 'field' => 'acfe_textarea_code', 38 | 'operator' => '!=', 39 | 'value' => '1' 40 | ) 41 | ) 42 | ); 43 | 44 | } 45 | 46 | return $field; 47 | 48 | }); 49 | 50 | } 51 | 52 | 53 | /** 54 | * render_field_settings 55 | * 56 | * @param $field 57 | */ 58 | function render_field_settings($field){ 59 | 60 | // code mode 61 | acf_render_field_setting($field, array( 62 | 'label' => __('Code mode'), 63 | 'name' => 'acfe_textarea_code', 64 | 'key' => 'acfe_textarea_code', 65 | 'instructions' => __('Switch font family to monospace and allow tab indent. For a more advanced code editor, please use the Code Editor field type', 'acfe'), 66 | 'type' => 'true_false', 67 | 'ui' => 1, 68 | )); 69 | 70 | } 71 | 72 | 73 | /** 74 | * field_wrapper_attributes 75 | * 76 | * @param $wrapper 77 | * @param $field 78 | * 79 | * @return mixed 80 | */ 81 | function field_wrapper_attributes($wrapper, $field){ 82 | 83 | // code mode 84 | if($field['acfe_textarea_code']){ 85 | $wrapper['data-acfe-textarea-code'] = 1; 86 | } 87 | 88 | return $wrapper; 89 | 90 | } 91 | 92 | } 93 | 94 | acf_new_instance('acfe_field_textarea'); 95 | 96 | endif; -------------------------------------------------------------------------------- /includes/fields/field-wysiwyg.php: -------------------------------------------------------------------------------- 1 | name = 'wysiwyg'; 17 | 18 | } 19 | 20 | 21 | /** 22 | * field_wrapper_attributes 23 | * 24 | * @param $wrapper 25 | * @param $field 26 | * 27 | * @return mixed 28 | */ 29 | function field_wrapper_attributes($wrapper, $field){ 30 | 31 | // auto init 32 | if(acf_maybe_get($field, 'acfe_wysiwyg_auto_init')){ 33 | $wrapper['data-acfe-wysiwyg-auto-init'] = $field['acfe_wysiwyg_auto_init']; 34 | } 35 | 36 | return $wrapper; 37 | 38 | } 39 | 40 | } 41 | 42 | acf_new_instance('acfe_field_wysiwyg'); 43 | 44 | endif; -------------------------------------------------------------------------------- /includes/init.php: -------------------------------------------------------------------------------- 1 | ='); 16 | } 17 | 18 | /** 19 | * acfe_is_acf_admin_6 20 | * 21 | * @return bool 22 | */ 23 | function acfe_is_acf_6(){ 24 | return acf_version_compare(acf_get_setting('version'), '>=', '6.0'); 25 | } 26 | 27 | /** 28 | * acfe_is_acf_admin_61 29 | * 30 | * @return bool 31 | */ 32 | function acfe_is_acf_61(){ 33 | return acf_version_compare(acf_get_setting('version'), '>=', '6.1'); 34 | } 35 | 36 | /** 37 | * acfe_include 38 | * 39 | * Includes a file within the plugin 40 | * 41 | * @param $filename 42 | * @param $once 43 | * 44 | * @return false|mixed 45 | */ 46 | function acfe_include($filename = '', $once = true){ 47 | 48 | $file_path = acfe_get_path($filename); 49 | 50 | if(file_exists($file_path)){ 51 | if($once){ 52 | return include_once($file_path); 53 | }else{ 54 | return include($file_path); 55 | } 56 | } 57 | 58 | return false; 59 | 60 | } 61 | 62 | /** 63 | * acfe_get_path 64 | * 65 | * Returns the plugin path 66 | * 67 | * @param string $filename 68 | * 69 | * @return string 70 | */ 71 | function acfe_get_path($filename = ''){ 72 | return ACFE_PATH . ltrim($filename, '/'); 73 | } 74 | 75 | /** 76 | * acfe_get_url 77 | * 78 | * Returns the plugin url 79 | * 80 | * @param string $filename 81 | * 82 | * @return string 83 | */ 84 | function acfe_get_url($filename = ''){ 85 | 86 | if(!defined('ACFE_URL')){ 87 | define('ACFE_URL', acf_get_setting('acfe/url')); 88 | } 89 | 90 | return ACFE_URL . ltrim($filename, '/'); 91 | } 92 | 93 | /** 94 | * acfe_get_view 95 | * 96 | * Load in a file from the 'admin/views' folder and allow variables to be passed through 97 | * Based on acf_get_view() 98 | * 99 | * @param string $path 100 | * @param array $args 101 | */ 102 | function acfe_get_view($path = '', $args = array()){ 103 | 104 | // allow view file name shortcut 105 | if(substr($path, -4) !== '.php'){ 106 | $path = acfe_get_path("includes/admin/views/{$path}.php"); 107 | } 108 | 109 | // include 110 | if(file_exists($path)){ 111 | 112 | extract($args); 113 | include($path); 114 | 115 | } 116 | 117 | } 118 | 119 | /** 120 | * acfe_load_textdomain 121 | * 122 | * Load textdomain files based on acf_load_textdomain() 123 | * 124 | * @param string $domain 125 | * 126 | * @return bool 127 | */ 128 | function acfe_load_textdomain($domain = 'acfe'){ 129 | 130 | $locale = apply_filters('plugin_locale', acf_get_locale(), $domain); 131 | $mofile = $domain . '-' . $locale . '.mo'; 132 | 133 | // Try to load from the languages directory first. 134 | if(load_textdomain($domain, WP_LANG_DIR . '/plugins/' . $mofile)){ 135 | return true; 136 | } 137 | 138 | // Load from plugin lang folder. 139 | return load_textdomain($domain, acfe_get_path('lang/' . $mofile)); 140 | 141 | } 142 | 143 | /** 144 | * acfe_after_plugin_row 145 | * 146 | * after_plugin_row 147 | * 148 | * @param $plugin_file 149 | * @param $plugin_data 150 | * @param $status 151 | */ 152 | add_action('after_plugin_row_' . ACFE_BASENAME, 'acfe_after_plugin_row', 5, 3); 153 | function acfe_after_plugin_row($plugin_file, $plugin_data, $status){ 154 | 155 | // bail early 156 | if(acfe_has_acf()){ 157 | return; 158 | } 159 | 160 | // vars 161 | $colspan = version_compare($GLOBALS['wp_version'], '5.5', '<') ? 3 : 4; 162 | 163 | // class 164 | $class = 'acfe-plugin-tr'; 165 | if(isset($plugin_data['update']) && !empty($plugin_data['update'])){ 166 | $class .= ' acfe-plugin-tr-update'; 167 | } 168 | 169 | ?> 170 | 176 | 177 | 178 |
179 |

Advanced Custom Fields PRO (minimum: 5.8).', 'acfe'); ?>

180 |
181 | 182 | 183 | __('All', 'acf')), $choices); 32 | 33 | return $choices; 34 | 35 | } 36 | 37 | 38 | /** 39 | * rule_match 40 | * 41 | * @param $match 42 | * @param $rule 43 | * @param $options 44 | * 45 | * @return bool|mixed 46 | */ 47 | function rule_match($match, $rule, $options){ 48 | 49 | // rule value might be empty 50 | // in case a Field Group use a custom location type from third party plugin 51 | // if the third party plugin is disabled, acf will fallback to "Post Type == ''" 52 | // and pass thru this rule because it's the first one 53 | if(empty($rule['value'])){ 54 | return $match; 55 | } 56 | 57 | if($rule['value'] !== 'all'){ 58 | return $match; 59 | } 60 | 61 | if(!acf_maybe_get($options, 'post_type')){ 62 | return $match; 63 | } 64 | 65 | $post_types = acf_get_post_types(); 66 | 67 | $match = in_array($options['post_type'], $post_types); 68 | 69 | if($rule['operator'] === '!='){ 70 | $match = !$match; 71 | } 72 | 73 | return $match; 74 | 75 | } 76 | 77 | } 78 | 79 | new acfe_location_post_type_all(); 80 | 81 | endif; -------------------------------------------------------------------------------- /includes/module-db.php: -------------------------------------------------------------------------------- 1 | has_settings($module)){ 35 | return; 36 | } 37 | 38 | // cleanup keys 39 | $export = $module->prepare_item_for_export($item); 40 | 41 | // on update 42 | if($item['ID']){ 43 | 44 | // get raw item from db 45 | $raw_item = $module->get_item($item['ID']); 46 | 47 | // delete old settings if name changed 48 | if($raw_item['name'] && $raw_item['name'] !== $item['name'] && !acf_is_filter_enabled('acfe/module/update_unique_name')){ 49 | $this->delete_settings($module, $raw_item['name']); 50 | } 51 | 52 | } 53 | 54 | // settings 55 | $settings = $this->get_settings($module); 56 | $settings[ $item['name'] ] = $export; 57 | 58 | // update setting 59 | ksort($settings); 60 | $this->update_settings($module, $settings); 61 | 62 | } 63 | 64 | 65 | /** 66 | * deleted_item 67 | * 68 | * acfe/module/deleted_item 69 | * 70 | * @param $item 71 | * @param $module 72 | */ 73 | function deleted_item($item, $module){ 74 | 75 | if(!$this->has_settings($module)){ 76 | return; 77 | } 78 | 79 | // WP appends '__trashed' to end of 'name' (post_name). 80 | $name = str_replace('__trashed', '', $item['name']); 81 | 82 | // delete settings 83 | $this->delete_settings($module, $name); 84 | 85 | } 86 | 87 | 88 | /** 89 | * include_items 90 | * 91 | * acfe/module/include_items 92 | * 93 | * @param $module 94 | */ 95 | function include_items($module){ 96 | 97 | if(!$this->has_settings($module)){ 98 | return; 99 | } 100 | 101 | // get db settings 102 | $settings = acf_get_array($this->get_settings($module)); 103 | 104 | // loop 105 | foreach($settings as $key => $item){ 106 | 107 | // set local 108 | $item['local'] = 'db'; 109 | $item['local_file'] = "{$module->settings}.{$key}"; 110 | 111 | // add local item 112 | $module->add_local_item($item); 113 | 114 | } 115 | 116 | } 117 | 118 | 119 | /** 120 | * has_settings 121 | * 122 | * @param $module 123 | * 124 | * @return bool 125 | */ 126 | function has_settings($module){ 127 | return !empty($module->settings); 128 | } 129 | 130 | 131 | /** 132 | * get_settings 133 | * 134 | * @param $module 135 | * @param $selector 136 | * @param $default 137 | * 138 | * @return mixed 139 | */ 140 | function get_settings($module, $selector = null, $default = null){ 141 | 142 | if($selector === null){ 143 | $selector = $module->settings; 144 | }else{ 145 | $selector = "{$module->settings}.{$selector}"; 146 | } 147 | 148 | return acfe_get_settings($selector, $default); 149 | 150 | } 151 | 152 | 153 | /** 154 | * update_settings 155 | * 156 | * @param $module 157 | * @param $selector 158 | * @param $value 159 | */ 160 | function update_settings($module, $selector = null, $value = null){ 161 | 162 | if($value === null){ 163 | $value = $selector; 164 | $selector = $module->settings; 165 | }else{ 166 | $selector = "{$module->settings}.{$selector}"; 167 | } 168 | 169 | acfe_update_settings($selector, $value); 170 | 171 | } 172 | 173 | 174 | /** 175 | * delete_settings 176 | * 177 | * @param $module 178 | * @param $selector 179 | * 180 | * @return mixed 181 | */ 182 | function delete_settings($module, $selector = null){ 183 | 184 | if($selector === null){ 185 | $selector = $module->settings; 186 | }else{ 187 | $selector = "{$module->settings}.{$selector}"; 188 | } 189 | 190 | return acfe_delete_settings($selector); 191 | 192 | } 193 | 194 | } 195 | 196 | acf_new_instance('acfe_module_db'); 197 | 198 | endif; -------------------------------------------------------------------------------- /includes/module-l10n.php: -------------------------------------------------------------------------------- 1 | l10n as $key){ 31 | 32 | $name = ucfirst($key); 33 | acfe_register_translate(acfe_array_get($item, $key), $name, "ACF Extended: {$module->get_label('name')}"); 34 | 35 | } 36 | 37 | } 38 | 39 | 40 | /** 41 | * register_item_args 42 | * 43 | * @param $item 44 | * @param $module 45 | * 46 | * @return mixed 47 | */ 48 | function register_item_args($item, $module){ 49 | 50 | foreach($module->l10n as $key){ 51 | 52 | $name = ucfirst($key); 53 | acfe_array_set($item, $key, acfe_translate(acfe_array_get($item, $key), ucfirst($name), "ACF Extended: {$module->get_label('name')}")); 54 | 55 | } 56 | 57 | return $item; 58 | 59 | } 60 | 61 | } 62 | 63 | acf_new_instance('acfe_module_l10n'); 64 | 65 | endif; -------------------------------------------------------------------------------- /includes/module-manager.php: -------------------------------------------------------------------------------- 1 | $hook 35 | )); 36 | 37 | // bail early 38 | if(!$modules){ 39 | return; 40 | } 41 | 42 | // loop modules 43 | foreach($modules as $module){ 44 | 45 | // check active 46 | if(!$module->is_active()){ 47 | continue; 48 | } 49 | 50 | // get loaded items 51 | $items = $module->get_local_items(); 52 | $items = $module->apply_module_filters('acfe/module/register_items', $items); 53 | 54 | // loop items 55 | foreach($items as $item){ 56 | 57 | // cleanup keys (ID, local, _valid...) 58 | $item = $module->prepare_item_for_export($item); 59 | 60 | // filters 61 | $item = $module->apply_module_filters('acfe/module/register_item_args', $item); 62 | 63 | // bail early 64 | if($item === false){ 65 | continue; 66 | } 67 | 68 | // bail early 69 | if(!$item['active']){ 70 | continue; 71 | } 72 | 73 | // actions 74 | $module->do_module_action('acfe/module/register_item', $item); 75 | 76 | } 77 | 78 | } 79 | 80 | } 81 | 82 | 83 | /** 84 | * register_post_types 85 | */ 86 | function register_post_types(){ 87 | 88 | // get all modules 89 | $modules = acfe_get_modules(); 90 | 91 | // loop modules 92 | foreach($modules as $module){ 93 | 94 | // check active 95 | if(!$module->is_active()){ 96 | continue; 97 | } 98 | 99 | // capability 100 | $capability = acf_get_setting('show_admin') ? acf_get_setting('capability') : false; 101 | 102 | // arguments 103 | $args = wp_parse_args($module->args, array( 104 | 'label' => '', 105 | 'labels' => array(), 106 | 'supports' => array('title'), 107 | 'hierarchical' => false, 108 | 'public' => false, 109 | 'show_ui' => true, 110 | 'show_in_menu' => false, 111 | 'menu_icon' => 'dashicons-layout', 112 | 'show_in_admin_bar' => false, 113 | 'show_in_nav_menus' => false, 114 | 'can_export' => false, 115 | 'has_archive' => false, 116 | 'rewrite' => false, 117 | 'exclude_from_search' => true, 118 | 'publicly_queryable' => false, 119 | 'capabilities' => array( 120 | 'publish_posts' => $capability, 121 | 'edit_posts' => $capability, 122 | 'edit_others_posts' => $capability, 123 | 'delete_posts' => $capability, 124 | 'delete_others_posts' => $capability, 125 | 'read_private_posts' => $capability, 126 | 'edit_post' => $capability, 127 | 'delete_post' => $capability, 128 | 'read_post' => $capability, 129 | ), 130 | 'acfe_admin_orderby' => 'title', 131 | 'acfe_admin_order' => 'ASC', 132 | 'acfe_admin_ppp' => 999, 133 | )); 134 | 135 | // register post type 136 | register_post_type($module->post_type, $args); 137 | 138 | } 139 | 140 | } 141 | 142 | } 143 | 144 | acf_new_instance('acfe_module_manager'); 145 | 146 | endif; -------------------------------------------------------------------------------- /includes/module-upgrades.php: -------------------------------------------------------------------------------- 1 | =', '0.8.8')){ 32 | return; 33 | } 34 | 35 | acfe_delete_settings('modules.author'); 36 | acfe_delete_settings('modules.dev'); 37 | acfe_delete_settings('modules.meta'); 38 | acfe_delete_settings('modules.option'); 39 | acfe_delete_settings('modules.ui'); 40 | acfe_delete_settings('upgrades'); 41 | 42 | } 43 | 44 | } 45 | 46 | acf_new_instance('acfe_module_upgrades'); 47 | 48 | endif; -------------------------------------------------------------------------------- /includes/modules/author.php: -------------------------------------------------------------------------------- 1 | '', 26 | 'key' => 'field_acfe_author', 27 | 'name' => 'acfe_author', 28 | 'type' => 'user', 29 | 'instructions' => '', 30 | 'required' => 0, 31 | 'conditional_logic' => 0, 32 | 'allow_null' => 0, 33 | 'multiple' => 0, 34 | 'roles' => $this->get_roles(), 35 | 'return_format' => 'array', 36 | )); 37 | 38 | add_action('acfe/add_post_meta_boxes', array($this, 'add_post_meta_boxes'), 10, 2); 39 | add_filter('wp_insert_post_data', array($this, 'wp_insert_post_data'), 10, 2); 40 | add_filter('acf/get_field_group_style', array($this, 'get_field_group_style'), 10, 2); 41 | 42 | } 43 | 44 | 45 | /** 46 | * add_post_meta_boxes 47 | * 48 | * @param $post_type 49 | * @param $post 50 | */ 51 | function add_post_meta_boxes($post_type, $post){ 52 | 53 | // disable on block editor 54 | if(acfe_is_block_editor()){ 55 | return; 56 | } 57 | 58 | // validate author supports 59 | if(!post_type_supports($post_type, 'author')){ 60 | return; 61 | } 62 | 63 | // post type object 64 | $post_type_object = get_post_type_object($post_type); 65 | 66 | // check permission 67 | if(!current_user_can($post_type_object->cap->edit_others_posts)){ 68 | return; 69 | } 70 | 71 | // remove legacy authordiv 72 | remove_meta_box('authordiv', $post_type, 'normal'); 73 | 74 | // add metabox 75 | add_meta_box('acfe-author', __('Author'), array($this, 'render_meta_box'), $post_type, 'side', 'core', array()); 76 | 77 | // generate postbox 78 | // $postboxes = array(); 79 | // $postboxes[] = array( 80 | // 'id' => 'acfe-author', 81 | // ); 82 | 83 | // get postboxes 84 | // $data = acf_get_instance('ACF_Assets')->data; 85 | // $acf_postboxes = acf_maybe_get($data, 'postboxes', array()); 86 | // $acf_postboxes = array_merge($acf_postboxes, $postboxes); 87 | 88 | // localize postboxes 89 | // acf_localize_data(array( 90 | // 'postboxes' => $acf_postboxes 91 | // )); 92 | 93 | } 94 | 95 | 96 | /** 97 | * render_meta_box 98 | * 99 | * @param $post 100 | * @param $metabox 101 | */ 102 | function render_meta_box($post, $metabox){ 103 | 104 | // retrieve field 105 | $field = acf_get_field('acfe_author'); 106 | 107 | // add value 108 | $field['prefix'] = ''; 109 | $field['value'] = get_post_field('post_author', $post->ID); 110 | 111 | // render field 112 | acf_render_field_wrap($field); 113 | 114 | } 115 | 116 | 117 | /** 118 | * wp_insert_post_data 119 | * 120 | * @param $data 121 | * @param $post_array 122 | * 123 | * @return mixed 124 | */ 125 | function wp_insert_post_data($data, $post_array){ 126 | 127 | // check field exists 128 | if(!acf_maybe_get($post_array, 'field_acfe_author')){ 129 | return $data; 130 | } 131 | 132 | // authors 133 | $post_author = (int) acf_maybe_get($post_array, 'field_acfe_author'); 134 | $_post_author = (int) acf_maybe_get($post_array, 'post_author'); 135 | 136 | // check if author has been changed 137 | if($_post_author === $post_author){ 138 | return $data; 139 | } 140 | 141 | // validate author 142 | if(!get_user_by('ID', $post_author)){ 143 | return $data; 144 | } 145 | 146 | // set new author 147 | $data['post_author'] = $post_author; 148 | 149 | return $data; 150 | 151 | } 152 | 153 | 154 | /** 155 | * get_field_group_style 156 | * 157 | * @param $style 158 | * @param $field_group 159 | * 160 | * @return array|string|string[] 161 | */ 162 | function get_field_group_style($style, $field_group){ 163 | 164 | $style = str_replace('authordiv', 'acfe-author', $style); 165 | $style = str_replace('display: none;', 'display: none !important;', $style); 166 | 167 | return $style; 168 | 169 | } 170 | 171 | 172 | /** 173 | * get_roles 174 | * 175 | * @return array 176 | */ 177 | function get_roles(){ 178 | 179 | $roles = array(); 180 | 181 | foreach(wp_roles()->roles as $name => $role){ 182 | 183 | // check capability 184 | if(empty($role['capabilities']['level_1'])){ 185 | continue; 186 | } 187 | 188 | $roles[] = $name; 189 | 190 | } 191 | 192 | return $roles; 193 | 194 | } 195 | 196 | } 197 | 198 | // initialize 199 | new acfe_author(); 200 | 201 | endif; -------------------------------------------------------------------------------- /includes/modules/block-type/module-block-type-upgrades.php: -------------------------------------------------------------------------------- 1 | =', '0.8.9')){ 34 | return; 35 | } 36 | 37 | // hook on init to load all WP components 38 | // post types, post statuses 'acf-disabled' etc... 39 | add_action('init', function(){ 40 | 41 | // get block types 42 | $posts = get_posts(array( 43 | 'post_type' => 'acfe-dbt', 44 | 'posts_per_page' => -1, 45 | 'fields' => 'ids', 46 | 'post_status' => 'any', 47 | )); 48 | 49 | $todo = array(); 50 | 51 | foreach($posts as $post_id){ 52 | 53 | if(acfe_is_module_v2_item($post_id)){ 54 | $todo[] = $post_id; 55 | } 56 | 57 | } 58 | 59 | if(!$todo){ 60 | return; 61 | } 62 | 63 | // get module 64 | $module = acfe_get_module('block_type'); 65 | 66 | // loop 67 | foreach($todo as $post_id){ 68 | 69 | $name = get_post_field('post_name', $post_id); 70 | $settings = acfe_get_settings("modules.block_types.{$name}", array()); 71 | 72 | // db settings found 73 | if($settings){ 74 | 75 | // generate item 76 | $item = wp_parse_args($settings, array( 77 | 'ID' => $post_id, 78 | 'name' => $name, 79 | )); 80 | 81 | // import item (update db) 82 | $module->import_item($item); 83 | 84 | } 85 | 86 | } 87 | 88 | // log 89 | acf_log('[ACF Extended] 0.8.9 Upgrade: Block Types'); 90 | 91 | }); 92 | 93 | } 94 | 95 | 96 | /** 97 | * upgrade_0_8_8 98 | * 99 | * acfe/do_upgrade:20 100 | * 101 | * @param $db_version 102 | */ 103 | function upgrade_0_8_8($db_version){ 104 | 105 | // check already done 106 | if(acf_version_compare($db_version, '>=', '0.8.8')){ 107 | return; 108 | } 109 | 110 | $old = acfe_get_settings('modules.dynamic_block_type.data', array()); 111 | $new = acfe_get_settings('modules.block_types', array()); 112 | 113 | acfe_delete_settings('modules.dynamic_block_type'); 114 | 115 | // Check 116 | if(empty($old)){ 117 | return; 118 | } 119 | 120 | // Log 121 | acf_log('[ACF Extended] 0.8.8 Upgrade: Block Types'); 122 | 123 | // Update 124 | acfe_update_settings('modules.block_types', array_merge($old, $new)); 125 | 126 | } 127 | 128 | 129 | /** 130 | * upgrade_0_8_5 131 | * 132 | * acfe/do_upgrade:10 133 | * 134 | * @param $db_version 135 | */ 136 | function upgrade_0_8_5($db_version){ 137 | 138 | // check already done 139 | if(acf_version_compare($db_version, '>=', '0.8.5')){ 140 | return; 141 | } 142 | 143 | $old = get_option('acfe_dynamic_block_types', array()); 144 | $new = acfe_get_settings('modules.block_types', array()); 145 | 146 | delete_option('acfe_dynamic_block_types'); 147 | 148 | if(empty($old)){ 149 | return; 150 | } 151 | 152 | acf_log('[ACF Extended] 0.8.5 Upgrade: Block Types'); 153 | 154 | // Update 155 | acfe_update_settings('modules.block_types', array_merge($old, $new)); 156 | 157 | } 158 | 159 | } 160 | 161 | acf_new_instance('acfe_module_block_type_upgrades'); 162 | 163 | endif; -------------------------------------------------------------------------------- /includes/modules/dev/module-dev-delete-meta.php: -------------------------------------------------------------------------------- 1 | '#', 53 | 'class' => 'acfe-dev-delete-meta', 54 | 'data-meta-id' => $meta['id'], 55 | 'data-meta-key' => $meta['key'], 56 | 'data-meta-type' => $meta['type'], 57 | 'data-nonce' => wp_create_nonce("acfe-dev-delete-meta-{$meta['id']}"), 58 | ); 59 | 60 | $row_actions['delete'] = '' . __('Delete') . ''; 61 | 62 | // return 63 | return $row_actions; 64 | 65 | } 66 | 67 | 68 | /** 69 | * meta_after_table 70 | * 71 | * acfe/dev/meta/after_table 72 | * 73 | * @param $args 74 | */ 75 | function meta_after_table($args){ 76 | 77 | // bail early 78 | if(!current_user_can(acf_get_setting('capability')) || !$args['bulk']){ 79 | return; 80 | } 81 | 82 | ?> 83 |
84 | 85 |
86 | 87 | 88 | 89 | 90 | 91 | 95 | 96 | 97 | 98 |
99 | 100 |
101 | 102 |
103 | get_row($wpdb->prepare("SELECT option_name FROM $wpdb->options WHERE option_id = %d LIMIT 1", $id)); 139 | 140 | if($row){ 141 | 142 | if(delete_option($row->option_name)){ 143 | wp_die(1); 144 | } 145 | 146 | } 147 | 148 | wp_die(0); 149 | 150 | } 151 | 152 | // delete by meta type 153 | if(delete_metadata_by_mid($type, $id)){ 154 | wp_die(1); 155 | } 156 | 157 | wp_die(0); 158 | 159 | } 160 | 161 | 162 | /** 163 | * ajax_delete_bulk_meta 164 | * 165 | * wp_ajax_acfe/bulk_delete_meta 166 | */ 167 | function ajax_delete_bulk_meta(){ 168 | 169 | // vars 170 | $ids = acf_maybe_get_POST('ids'); 171 | $type = acf_maybe_get_POST('type'); 172 | 173 | // check vars 174 | if(!$ids || !$type){ 175 | wp_die(0); 176 | } 177 | 178 | // check referer 179 | check_ajax_referer('acfe-dev-bulk'); 180 | 181 | // check permission 182 | if(!current_user_can(acf_get_setting('capability'))){ 183 | wp_die(-1); 184 | } 185 | 186 | // delete option 187 | if($type === 'option'){ 188 | 189 | global $wpdb; 190 | 191 | foreach($ids as $id){ 192 | 193 | // retrieve option from option_id 194 | $row = $wpdb->get_row($wpdb->prepare("SELECT option_name FROM $wpdb->options WHERE option_id = %d LIMIT 1", $id)); 195 | 196 | if($row){ 197 | delete_option($row->option_name); 198 | } 199 | 200 | } 201 | 202 | wp_die(1); 203 | 204 | } 205 | 206 | // delete by meta type 207 | foreach($ids as $id){ 208 | delete_metadata_by_mid($type, $id); 209 | } 210 | 211 | wp_die(1); 212 | 213 | } 214 | 215 | } 216 | 217 | acf_new_instance('acfe_dev_delete_meta'); 218 | 219 | endif; -------------------------------------------------------------------------------- /includes/modules/form/module-form-action-custom.php: -------------------------------------------------------------------------------- 1 | name = 'custom'; 17 | $this->title = __('Custom action', 'acfe'); 18 | 19 | $this->item = array( 20 | 'action' => 'custom', 21 | 'name' => '', 22 | ); 23 | 24 | $this->validate = array('name'); 25 | 26 | } 27 | 28 | 29 | /** 30 | * prepare_action 31 | * 32 | * acfe/form/prepare_custom:9 33 | * 34 | * @param $action 35 | * @param $form 36 | * 37 | * @return mixed 38 | */ 39 | function prepare_action($action, $form){ 40 | 41 | // prepare action 42 | $action = apply_filters("acfe/form/prepare_{$action['name']}", $action, $form); 43 | if($action){$action = apply_filters("acfe/form/prepare_{$action['name']}/form={$form['name']}", $action, $form);} 44 | 45 | // return 46 | return $action; 47 | 48 | } 49 | 50 | 51 | /** 52 | * validate_action 53 | * 54 | * acfe/form/validate_custom:9 55 | * 56 | * @param $form 57 | * @param $action 58 | */ 59 | function validate_action($form, $action){ 60 | 61 | // validate action 62 | do_action("acfe/form/validate_{$action['name']}", $form, $action); 63 | do_action("acfe/form/validate_{$action['name']}/form={$form['name']}", $form, $action); 64 | 65 | } 66 | 67 | 68 | /** 69 | * make_action 70 | * 71 | * acfe/form/make_custom:9 72 | * 73 | * @param $form 74 | * @param $action 75 | */ 76 | function make_action($form, $action){ 77 | 78 | // hooks 79 | do_action("acfe/form/submit_{$action['name']}", $form, $action); 80 | do_action("acfe/form/submit_{$action['name']}/form={$form['name']}", $form, $action); 81 | 82 | } 83 | 84 | /** 85 | * validate_name 86 | * 87 | * @param $value 88 | * 89 | * @return false|string|void 90 | */ 91 | function validate_name($value){ 92 | 93 | $actions = acfe_get_form_action_types(); 94 | $names = array('form'); // reserved 95 | 96 | // get actions names 97 | foreach($actions as $action){ 98 | $names[] = $action->name; 99 | } 100 | 101 | // do not allow existing action name 102 | if(in_array($value, $names)){ 103 | return __('This action name is reserved', 'acfe'); 104 | } 105 | 106 | return false; 107 | 108 | } 109 | 110 | 111 | /** 112 | * register_layout 113 | * 114 | * @param $layout 115 | * 116 | * @return array 117 | */ 118 | function register_layout($layout){ 119 | 120 | return array( 121 | 122 | /** 123 | * documentation 124 | */ 125 | array( 126 | 'key' => 'field_doc', 127 | 'label' => '', 128 | 'name' => '', 129 | 'type' => 'acfe_dynamic_render', 130 | 'instructions' => '', 131 | 'required' => 0, 132 | 'conditional_logic' => 0, 133 | 'wrapper' => array( 134 | 'width' => '', 135 | 'class' => '', 136 | 'id' => '', 137 | ), 138 | 'render' => function(){ 139 | echo '' . __('Documentation', 'acfe') . ''; 140 | } 141 | ), 142 | 143 | /** 144 | * action 145 | */ 146 | array( 147 | 'key' => 'field_tab_action', 148 | 'label' => __('Action', 'acfe'), 149 | 'name' => '', 150 | 'type' => 'tab', 151 | 'instructions' => '', 152 | 'required' => 0, 153 | 'conditional_logic' => 0, 154 | 'wrapper' => array( 155 | 'width' => '', 156 | 'class' => '', 157 | 'id' => '', 158 | 'data-no-preference' => true, 159 | ), 160 | 'placement' => 'top', 161 | 'endpoint' => 0, 162 | ), 163 | array( 164 | 'key' => 'field_name', 165 | 'label' => __('Action name', 'acfe'), 166 | 'name' => 'name', 167 | 'type' => 'acfe_slug', 168 | 'instructions' => __('Target this action using hooks.', 'acfe'), 169 | 'required' => 1, 170 | 'conditional_logic' => 0, 171 | 'wrapper' => array( 172 | 'width' => '', 173 | 'class' => '', 174 | 'id' => '', 175 | 'data-instruction-placement' => 'field' 176 | ), 177 | 'default_value' => '', 178 | 'placeholder' => __('Custom', 'acfe'), 179 | 'prepend' => '', 180 | 'append' => '', 181 | 'maxlength' => '', 182 | ), 183 | 184 | ); 185 | 186 | } 187 | 188 | } 189 | 190 | acfe_register_form_action_type('acfe_module_form_action_custom'); 191 | 192 | endif; -------------------------------------------------------------------------------- /includes/modules/form/module-form-action-redirect.php: -------------------------------------------------------------------------------- 1 | name = 'redirect'; 17 | $this->title = __('Redirect action', 'acfe'); 18 | 19 | $this->item = array( 20 | 'action' => 'redirect', 21 | 'name' => '', 22 | 'url' => '', 23 | ); 24 | 25 | } 26 | 27 | 28 | /** 29 | * prepare_action 30 | * 31 | * acfe/form/prepare_user:9 32 | * 33 | * @param $action 34 | * @param $form 35 | * 36 | * @return mixed 37 | */ 38 | function prepare_action($action, $form){ 39 | 40 | return $action; 41 | 42 | } 43 | 44 | 45 | /** 46 | * make_action 47 | * 48 | * acfe/form/make_redirect:9 49 | * 50 | * @param $form 51 | * @param $action 52 | */ 53 | function make_action($form, $action){ 54 | 55 | // apply tags 56 | acfe_apply_tags($action['url'], array('context' => 'display')); 57 | 58 | // url 59 | $url = $action['url']; 60 | 61 | // filters 62 | $url = apply_filters("acfe/form/submit_redirect_url", $url, $form, $action); 63 | $url = apply_filters("acfe/form/submit_redirect_url/form={$form['name']}", $url, $form, $action); 64 | $url = apply_filters("acfe/form/submit_redirect_url/action={$action['name']}", $url, $form, $action); 65 | 66 | // redirect 67 | acfe_redirect($url); 68 | 69 | } 70 | 71 | 72 | /** 73 | * register_layout 74 | * 75 | * @param $layout 76 | * 77 | * @return array 78 | */ 79 | function register_layout($layout){ 80 | 81 | return array( 82 | 83 | /** 84 | * documentation 85 | */ 86 | array( 87 | 'key' => 'field_doc', 88 | 'label' => '', 89 | 'name' => '', 90 | 'type' => 'acfe_dynamic_render', 91 | 'instructions' => '', 92 | 'required' => 0, 93 | 'conditional_logic' => 0, 94 | 'wrapper' => array( 95 | 'width' => '', 96 | 'class' => '', 97 | 'id' => '', 98 | ), 99 | 'render' => function(){ 100 | echo '' . __('Documentation', 'acfe') . ''; 101 | } 102 | ), 103 | 104 | /** 105 | * action 106 | */ 107 | array( 108 | 'key' => 'field_tab_action', 109 | 'label' => __('Action', 'acfe'), 110 | 'name' => '', 111 | 'type' => 'tab', 112 | 'instructions' => '', 113 | 'required' => 0, 114 | 'conditional_logic' => 0, 115 | 'wrapper' => array( 116 | 'width' => '', 117 | 'class' => '', 118 | 'id' => '', 119 | 'data-no-preference' => true, 120 | ), 121 | 'placement' => 'top', 122 | 'endpoint' => 0, 123 | ), 124 | array( 125 | 'key' => 'field_name', 126 | 'label' => __('Action name', 'acfe'), 127 | 'name' => 'name', 128 | 'type' => 'acfe_slug', 129 | 'instructions' => __('(Optional) Target this action using hooks.', 'acfe'), 130 | 'required' => 0, 131 | 'conditional_logic' => 0, 132 | 'wrapper' => array( 133 | 'width' => '', 134 | 'class' => '', 135 | 'id' => '', 136 | 'data-instruction-placement' => 'field' 137 | ), 138 | 'default_value' => '', 139 | 'placeholder' => __('Redirect', 'acfe'), 140 | 'prepend' => '', 141 | 'append' => '', 142 | 'maxlength' => '', 143 | ), 144 | array( 145 | 'key' => 'field_url', 146 | 'label' => __('Action URL', 'acfe'), 147 | 'name' => 'url', 148 | 'type' => 'text', 149 | 'instructions' => __('The redirection URL.', 'acfe'), 150 | 'required' => 0, 151 | 'conditional_logic' => 0, 152 | 'wrapper' => array( 153 | 'width' => '', 154 | 'class' => '', 155 | 'id' => '', 156 | 'data-instruction-placement' => 'field' 157 | ), 158 | 'default_value' => '', 159 | 'placeholder' => '', 160 | 'prepend' => '', 161 | 'append' => '', 162 | 'maxlength' => '', 163 | ), 164 | 165 | ); 166 | 167 | } 168 | 169 | } 170 | 171 | acfe_register_form_action_type('acfe_module_form_action_redirect'); 172 | 173 | endif; -------------------------------------------------------------------------------- /includes/modules/form/module-form-front-hooks.php: -------------------------------------------------------------------------------- 1 | 'form_attributes', // deprecated 52 | 'fields_attributes' => 'fields_attributes', // deprecated 53 | 'settings' => 'settings', 54 | 'attributes_form' => 'attributes.form', 55 | 'attributes_fields' => 'attributes.fields', 56 | 'attributes_submit' => 'attributes.submit', 57 | 'validation' => 'validation', 58 | 'success' => 'success', 59 | ); 60 | 61 | // allow array atts 62 | foreach(array_keys($atts) as $key){ 63 | 64 | // sub array compatibility 65 | foreach($allowed_arrays as $flat => $path){ 66 | 67 | // check found allowed 68 | if(!acfe_starts_with($key, "{$flat}_")){ 69 | continue; 70 | } 71 | 72 | // grab value 73 | $value = $atts[ $key ]; 74 | unset($atts[ $key ]); 75 | 76 | // explode 77 | $explode = explode("{$flat}_", $key); 78 | $parent = array_shift($explode); 79 | $path_key = array_shift($explode); 80 | 81 | if(!$path_key){ 82 | continue; 83 | } 84 | 85 | // set attribute 86 | acfe_array_set($atts, "{$path}.{$path_key}", $value); 87 | 88 | } 89 | 90 | } 91 | 92 | // disallowed shortcode settings (deprecated) 93 | unset($atts['html_submit_button'], $atts['html_submit_spinner'], $atts['html_updated_message']); 94 | 95 | // disallowed shortcode settings 96 | acfe_array_unset($atts, array('attributes.submit.button', 'attributes.submit.spinner', 'success.wrapper')); 97 | 98 | // render 99 | ob_start(); 100 | 101 | acfe_form($atts); 102 | 103 | return ob_get_clean(); 104 | 105 | } 106 | 107 | 108 | /** 109 | * mce_plugins 110 | * 111 | * mce_external_plugins 112 | * 113 | * TinyMCE plugins 114 | * 115 | * @param $plugins 116 | * 117 | * @return mixed 118 | */ 119 | function mce_plugins($plugins){ 120 | 121 | $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; 122 | 123 | $plugins['acfe_form'] = acfe_get_url('assets/inc/tinymce/acfe-form' . $suffix . '.js'); 124 | 125 | return $plugins; 126 | 127 | } 128 | 129 | 130 | /** 131 | * ajax_shortcode 132 | * 133 | * wp_ajax_acfe/form/shortcode 134 | */ 135 | function ajax_shortcode(){ 136 | 137 | // validate 138 | if(!acf_verify_ajax()){ 139 | die(); 140 | } 141 | 142 | // vars 143 | $args = acf_maybe_get_POST('args', array()); 144 | $title = ''; 145 | 146 | // loop thru args 147 | foreach(array('name', 'id') as $key){ 148 | if(acf_maybe_get($args, $key)){ 149 | $title = acf_maybe_get($args, $key); 150 | break; 151 | } 152 | } 153 | 154 | $title = is_numeric($title) ? "#{$title}" : "\"{$title}\""; 155 | 156 | ob_start(); 157 | ?> 158 |
159 | 160 |
161 | get_raw_item($options_page['menu_slug']); 45 | if(!$item){ 46 | return; 47 | } 48 | 49 | ?> 50 | 53 | 54 | 59 | is_main_query() || $pagenow !== 'edit.php' || $query->get('post_type') !== 'acfe-dop'){ 77 | return; 78 | } 79 | 80 | //$query->set('meta_key', 'position'); 81 | //$query->set('orderby', 'meta_value_num title'); 82 | //$query->set('order', 'ASC'); 83 | 84 | } 85 | 86 | } 87 | 88 | new acfe_module_options_page_features(); 89 | 90 | endif; -------------------------------------------------------------------------------- /includes/modules/performance/module-performance-ultra-fields.php: -------------------------------------------------------------------------------- 1 | __('Save as individual meta'), 45 | 'key' => 'acfe_save_meta', 46 | 'name' => 'acfe_save_meta', 47 | 'instructions' => __('Save the field as an individual meta.'), 48 | 'type' => 'true_false', 49 | 'required' => false, 50 | 'conditional_logic' => false, 51 | 'wrapper' => array( 52 | 'width' => '', 53 | 'class' => '', 54 | 'id' => '', 55 | ), 56 | 'message' => '', 57 | 'default_value' => false, 58 | 'ui' => true, 59 | 'ui_on_text' => '', 60 | 'ui_off_text' => '', 61 | )); 62 | 63 | } 64 | 65 | 66 | /** 67 | * validate_field 68 | * 69 | * @param $field 70 | * 71 | * @return mixed 72 | */ 73 | function validate_field($field){ 74 | 75 | // cleanup setting if set and empty 76 | if(isset($field['acfe_save_meta']) && empty($field['acfe_save_meta'])){ 77 | unset($field['acfe_save_meta']); 78 | } 79 | 80 | return $field; 81 | 82 | } 83 | 84 | 85 | } 86 | 87 | acf_new_instance('acfe_performance_ultra_fields'); 88 | 89 | endif; -------------------------------------------------------------------------------- /includes/modules/performance/module-performance-upgrades.php: -------------------------------------------------------------------------------- 1 | =', '0.8.9.4')){ 32 | return; 33 | } 34 | 35 | $single_meta = acfe_get_settings('settings.acfe/modules/single_meta'); 36 | 37 | if(!$single_meta){ 38 | return; 39 | } 40 | 41 | // delete old setting 42 | acfe_delete_settings('settings.acfe/modules/single_meta'); 43 | 44 | // log 45 | acf_log('[ACF Extended] 0.8.9.4 Upgrade: Performance Mode'); 46 | 47 | // update 48 | acfe_update_settings('settings.acfe/modules/performance', 'ultra'); 49 | 50 | } 51 | 52 | } 53 | 54 | acf_new_instance('acfe_module_performance_upgrades'); 55 | 56 | endif; -------------------------------------------------------------------------------- /includes/modules/post-type/module-post-type-upgrades.php: -------------------------------------------------------------------------------- 1 | =', '0.8.9')){ 33 | return; 34 | } 35 | 36 | // hook on init to load all WP components 37 | // post types, post statuses 'acf-disabled' etc... 38 | add_action('init', function(){ 39 | 40 | // get posts 41 | $posts = get_posts(array( 42 | 'post_type' => 'acfe-dpt', 43 | 'posts_per_page' => -1, 44 | 'fields' => 'ids', 45 | 'post_status' => 'any', 46 | )); 47 | 48 | $todo = array(); 49 | 50 | foreach($posts as $post_id){ 51 | 52 | if(acfe_is_module_v2_item($post_id)){ 53 | $todo[] = $post_id; 54 | } 55 | 56 | } 57 | 58 | if(!$todo){ 59 | return; 60 | } 61 | 62 | // get module 63 | $module = acfe_get_module('post_type'); 64 | 65 | // loop 66 | foreach($todo as $post_id){ 67 | 68 | $name = get_post_field('post_name', $post_id); 69 | $settings = acfe_get_settings("modules.post_types.{$name}", array()); 70 | 71 | // db settings found 72 | if($settings){ 73 | 74 | // generate item 75 | $item = wp_parse_args($settings, array( 76 | 'ID' => $post_id, 77 | 'name' => $name, 78 | )); 79 | 80 | // import item (update db) 81 | $module->import_item($item); 82 | 83 | } 84 | 85 | } 86 | 87 | // log 88 | acf_log('[ACF Extended] 0.8.9 Upgrade: Post Types'); 89 | 90 | }); 91 | 92 | } 93 | 94 | /** 95 | * upgrade_0_8_8 96 | * 97 | * acfe/do_upgrade:20 98 | * 99 | * @param $db_version 100 | */ 101 | function upgrade_0_8_8($db_version){ 102 | 103 | // check already done 104 | if(acf_version_compare($db_version, '>=', '0.8.8')){ 105 | return; 106 | } 107 | 108 | $old = acfe_get_settings('modules.dynamic_post_type.data', array()); 109 | $new = acfe_get_settings('modules.post_types', array()); 110 | 111 | acfe_delete_settings('modules.dynamic_post_type'); 112 | 113 | // Check 114 | if(empty($old)){ 115 | return; 116 | } 117 | 118 | // Log 119 | acf_log('[ACF Extended] 0.8.8 Upgrade: Post Types'); 120 | 121 | // Update 122 | acfe_update_settings('modules.post_types', array_merge($old, $new)); 123 | 124 | } 125 | 126 | 127 | /** 128 | * upgrade_0_8_5 129 | * 130 | * acfe/do_upgrade:10 131 | * 132 | * @param $db_version 133 | */ 134 | function upgrade_0_8_5($db_version){ 135 | 136 | // check already done 137 | if(acf_version_compare($db_version, '>=', '0.8.5')){ 138 | return; 139 | } 140 | 141 | $old = get_option('acfe_dynamic_post_types', array()); 142 | $new = acfe_get_settings('modules.post_types', array()); 143 | 144 | delete_option('acfe_dynamic_post_types'); 145 | 146 | if(empty($old)){ 147 | return; 148 | } 149 | 150 | acf_log('[ACF Extended] 0.8.5 Upgrade: Post Types'); 151 | 152 | // Update 153 | acfe_update_settings('modules.post_types', array_merge($old, $new)); 154 | 155 | } 156 | 157 | } 158 | 159 | acf_new_instance('acfe_module_post_type_upgrades'); 160 | 161 | endif; -------------------------------------------------------------------------------- /includes/modules/taxonomy/module-taxonomy-upgrades.php: -------------------------------------------------------------------------------- 1 | =', '0.8.9')){ 34 | return; 35 | } 36 | 37 | // hook on init to load all WP components 38 | // post types, post statuses 'acf-disabled' etc... 39 | add_action('init', function(){ 40 | 41 | // get posts 42 | $posts = get_posts(array( 43 | 'post_type' => 'acfe-dt', 44 | 'posts_per_page' => -1, 45 | 'fields' => 'ids', 46 | 'post_status' => 'any', 47 | )); 48 | 49 | $todo = array(); 50 | 51 | foreach($posts as $post_id){ 52 | 53 | if(acfe_is_module_v2_item($post_id)){ 54 | $todo[] = $post_id; 55 | } 56 | 57 | } 58 | 59 | if(!$todo){ 60 | return; 61 | } 62 | 63 | // get module 64 | $module = acfe_get_module('taxonomy'); 65 | 66 | // loop 67 | foreach($todo as $post_id){ 68 | 69 | $name = get_post_field('post_name', $post_id); 70 | $settings = acfe_get_settings("modules.taxonomies.{$name}", array()); 71 | 72 | // db settings found 73 | if($settings){ 74 | 75 | // generate item 76 | $item = wp_parse_args($settings, array( 77 | 'ID' => $post_id, 78 | 'name' => $name, 79 | )); 80 | 81 | // import item (update db) 82 | $module->import_item($item); 83 | 84 | } 85 | 86 | } 87 | 88 | // log 89 | acf_log('[ACF Extended] 0.8.9 Upgrade: Taxonomies'); 90 | 91 | }); 92 | 93 | } 94 | 95 | 96 | /** 97 | * upgrade_0_8_8 98 | * 99 | * acfe/do_upgrade:20 100 | * 101 | * @param $db_version 102 | */ 103 | function upgrade_0_8_8($db_version){ 104 | 105 | // check already done 106 | if(acf_version_compare($db_version, '>=', '0.8.8')){ 107 | return; 108 | } 109 | 110 | $old = acfe_get_settings('modules.dynamic_taxonomy.data', array()); 111 | $new = acfe_get_settings('modules.taxonomies', array()); 112 | 113 | acfe_delete_settings('modules.dynamic_taxonomy'); 114 | 115 | // Check 116 | if(empty($old)){ 117 | return; 118 | } 119 | 120 | // Log 121 | acf_log('[ACF Extended] 0.8.8 Upgrade: Taxonomies'); 122 | 123 | // Update 124 | acfe_update_settings('modules.taxonomies', array_merge($old, $new)); 125 | 126 | } 127 | 128 | 129 | /** 130 | * upgrade_0_8_5 131 | * 132 | * acfe/do_upgrade:10 133 | * 134 | * @param $db_version 135 | */ 136 | function upgrade_0_8_5($db_version){ 137 | 138 | // check already done 139 | if(acf_version_compare($db_version, '>=', '0.8.5')){ 140 | return; 141 | } 142 | 143 | $old = get_option('acfe_dynamic_taxonomies', array()); 144 | $new = acfe_get_settings('modules.taxonomies', array()); 145 | 146 | delete_option('acfe_dynamic_taxonomies'); 147 | 148 | if(empty($old)){ 149 | return; 150 | } 151 | 152 | acf_log('[ACF Extended] 0.8.5 Upgrade: Taxonomies'); 153 | 154 | // Update 155 | acfe_update_settings('modules.taxonomies', array_merge($old, $new)); 156 | 157 | } 158 | 159 | } 160 | 161 | acf_new_instance('acfe_module_taxonomy_upgrades'); 162 | 163 | endif; -------------------------------------------------------------------------------- /includes/modules/ui/module-ui-attachment.php: -------------------------------------------------------------------------------- 1 | enqueue_scripts(); 46 | 47 | // footer 48 | add_action('acf/admin_footer', array($this, 'admin_footer')); 49 | 50 | } 51 | 52 | 53 | /** 54 | * add_attachment_meta_boxes 55 | * 56 | * @param $post 57 | */ 58 | function add_attachment_meta_boxes($post){ 59 | 60 | // post id 61 | $post_id = $post->ID; 62 | 63 | // screen 64 | $screen = get_current_screen(); 65 | 66 | // field groups 67 | $field_groups = acf_get_field_groups(array( 68 | 'attachment_id' => $post_id, 69 | 'attachment' => $post_id, // leave for backwards compatibility 70 | )); 71 | 72 | if($field_groups){ 73 | $this->add_metaboxes($field_groups, $post_id, $screen); 74 | } 75 | 76 | } 77 | 78 | 79 | /** 80 | * edit_form_after_title 81 | */ 82 | function edit_form_after_title(){ 83 | 84 | // globals 85 | global $post; 86 | 87 | // render post data 88 | acf_form_data(array( 89 | 'screen' => 'attachment', 90 | 'post_id' => $post->ID, 91 | )); 92 | 93 | // render 'acf_after_title' metaboxes 94 | do_meta_boxes(get_current_screen(), 'acf_after_title', $post); 95 | 96 | } 97 | 98 | 99 | /** 100 | * admin_footer 101 | */ 102 | function admin_footer(){ 103 | 104 | ?> 105 | 112 | enqueue_scripts(); 35 | 36 | // Settings 37 | add_action('acf/admin_footer', array($this, 'settings_footer')); 38 | 39 | } 40 | 41 | 42 | /** 43 | * add_settings_meta_boxes 44 | */ 45 | function add_settings_meta_boxes(){ 46 | 47 | $screen = get_current_screen()->id; 48 | 49 | // post id 50 | $post_id = acf_get_valid_post_id($screen); 51 | 52 | // field groups 53 | $field_groups = acf_get_field_groups(array( 54 | 'wp_settings' => $screen 55 | )); 56 | 57 | if($field_groups){ 58 | 59 | // form data 60 | acf_form_data(array( 61 | 'screen' => 'wp_settings', 62 | 'post_id' => $post_id, 63 | )); 64 | 65 | $this->add_metaboxes($field_groups, $post_id, $screen); 66 | 67 | } 68 | 69 | // Sidebar submit 70 | add_meta_box('submitdiv', __('Edit'), array($this, 'render_metabox_submit'), $screen, 'side', 'high', 'settings'); 71 | 72 | } 73 | 74 | 75 | /** 76 | * settings_footer 77 | */ 78 | function settings_footer(){ 79 | 80 | global $pagenow; 81 | 82 | ?> 83 | 99 | enqueue_scripts(); 43 | 44 | // var 45 | $this->taxonomy = $taxonomy; 46 | 47 | // hooks 48 | add_action('admin_enqueue_scripts', array($this, 'term_enqueue_scripts'), 15); // must be priority 15 49 | add_action('admin_footer', array($this, 'term_footer')); 50 | 51 | } 52 | 53 | 54 | /** 55 | * load_terms 56 | * 57 | * @param $taxonomy 58 | */ 59 | function load_terms($taxonomy){ 60 | 61 | // enqueue 62 | $this->enqueue_scripts(); 63 | 64 | // hooks 65 | add_action('admin_footer', array($this, 'terms_footer')); 66 | 67 | } 68 | 69 | 70 | /** 71 | * add_term_meta_boxes 72 | * 73 | * @param $taxonomy 74 | * @param $term 75 | */ 76 | function add_term_meta_boxes($taxonomy, $term){ 77 | 78 | // post id 79 | $post_id = 'term_' . $term->term_id; 80 | 81 | // screen 82 | $screen = get_current_screen(); 83 | 84 | // field groups 85 | $field_groups = acf_get_field_groups(array( 86 | 'taxonomy' => $taxonomy 87 | )); 88 | 89 | if($field_groups){ 90 | 91 | // form data 92 | acf_form_data(array( 93 | 'screen' => 'taxonomy', 94 | 'post_id' => $post_id, 95 | )); 96 | 97 | $this->add_metaboxes($field_groups, $post_id, $screen); 98 | 99 | } 100 | 101 | // Sidebar submit 102 | add_meta_box('submitdiv', __('Edit'), array($this, 'render_metabox_submit'), $screen, 'side', 'high', 'term'); 103 | 104 | } 105 | 106 | 107 | /** 108 | * term_enqueue_scripts 109 | */ 110 | function term_enqueue_scripts(){ 111 | 112 | // remove acf render 113 | // advanced-custom-fields-pro/includes/forms/form-taxonomy.php 114 | acfe_remove_action("{$this->taxonomy}_edit_form", array('acf_form_taxonomy', 'edit_term')); 115 | 116 | } 117 | 118 | 119 | /** 120 | * term_footer 121 | */ 122 | function term_footer(){ 123 | 124 | global $tag, $tax; 125 | 126 | ?> 127 | 134 | 135 | 146 | cap->edit_terms); 158 | 159 | ?> 160 | 165 | 166 | 186 | enqueue_scripts(); 39 | 40 | // class 41 | // advanced-custom-fields-pro/includes/forms/form-user.php 42 | $acf_form_user = acf_get_instance('ACF_Form_User'); 43 | 44 | // remove acf render 45 | remove_action('show_user_profile', array($acf_form_user, 'render_edit')); 46 | remove_action('edit_user_profile', array($acf_form_user, 'render_edit')); 47 | 48 | // footer 49 | add_action('acf/admin_footer', array($this, 'user_footer')); 50 | 51 | } 52 | 53 | 54 | /** 55 | * load_user_new 56 | */ 57 | function load_user_new(){ 58 | 59 | // enqueue 60 | $this->enqueue_scripts(); 61 | 62 | // class 63 | // advanced-custom-fields-pro/includes/forms/form-user.php 64 | $acf_form_user = acf_get_instance('ACF_Form_User'); 65 | 66 | // remove acf render 67 | remove_action('user_new_form', array($acf_form_user, 'render_new')); 68 | 69 | // footer 70 | add_action('acf/admin_footer', array($this, 'user_new_footer')); 71 | 72 | } 73 | 74 | 75 | /** 76 | * add_user_meta_boxes 77 | * 78 | * @param $user 79 | */ 80 | function add_user_meta_boxes($user){ 81 | 82 | // add compatibility with front-end user profile edit forms such as bbPress 83 | if(!is_admin()){ 84 | acf_enqueue_scripts(); 85 | } 86 | 87 | // render 88 | $this->user_add_metaboxes(array( 89 | 'user_id' => $user->ID, 90 | 'view' => 'edit' 91 | )); 92 | 93 | } 94 | 95 | 96 | /** 97 | * add_user_new_meta_boxes 98 | */ 99 | function add_user_new_meta_boxes(){ 100 | 101 | // render 102 | $this->user_add_metaboxes(array( 103 | 'user_id' => 0, 104 | 'view' => 'add' 105 | )); 106 | 107 | } 108 | 109 | 110 | /** 111 | * user_add_metaboxes 112 | * 113 | * @param $args 114 | */ 115 | function user_add_metaboxes($args = array()){ 116 | 117 | // Native ACF Form user 118 | $acf_form_user = acf_get_instance('ACF_Form_User'); 119 | 120 | // Allow $_POST data to persist across form submission attempts. 121 | if(isset($_POST['acf'])){ 122 | add_filter('acf/pre_load_value', array($acf_form_user, 'filter_pre_load_value'), 10, 3); 123 | } 124 | 125 | // args 126 | $args = wp_parse_args($args, array( 127 | 'user_id' => 0, 128 | 'view' => 'edit' 129 | )); 130 | 131 | // screen 132 | $screen = 'user'; // new 133 | 134 | if($args['view'] == 'edit'){ 135 | $screen = IS_PROFILE_PAGE ? 'profile' : 'user-edit'; 136 | } 137 | 138 | // post id 139 | $post_id = 'user_' . $args['user_id']; 140 | 141 | // field groups 142 | $field_groups = acf_get_field_groups(array( 143 | 'user_id' => $args['user_id'] ? $args['user_id'] : 'new', 144 | 'user_form' => $args['view'] 145 | )); 146 | 147 | if($field_groups){ 148 | 149 | // form data 150 | acf_form_data(array( 151 | 'screen' => 'user', 152 | 'post_id' => $post_id, 153 | 'validation' => ($args['view'] == 'register') ? 0 : 1 154 | )); 155 | 156 | $this->add_metaboxes($field_groups, $post_id, $screen); 157 | 158 | // actions 159 | add_action('acf/input/admin_footer', array($acf_form_user, 'admin_footer'), 10, 1); 160 | 161 | } 162 | 163 | $args = $args['view'] === 'add' ? 'user_new' : 'user'; 164 | 165 | // Sidebar submit 166 | add_meta_box('submitdiv', __('Edit'), array($this, 'render_metabox_submit'), $screen, 'side', 'high', $args); 167 | 168 | } 169 | 170 | 171 | /** 172 | * user_footer 173 | */ 174 | function user_footer(){ 175 | 176 | global $user_id; 177 | 178 | ?> 179 |
180 | Permalink: 181 |
182 | 191 | 201 | 211 | initialize(); 21 | } 22 | 23 | 24 | /** 25 | * initialize 26 | */ 27 | function initialize(){ 28 | // ... 29 | } 30 | 31 | 32 | /** 33 | * enqueue_scripts 34 | */ 35 | function enqueue_scripts(){ 36 | 37 | // acf 38 | acf_enqueue_scripts(); 39 | 40 | // acfe 41 | wp_enqueue_style('acf-extended-ui'); 42 | wp_enqueue_script('acf-extended-ui'); 43 | 44 | } 45 | 46 | 47 | /** 48 | * add_metaboxes 49 | * 50 | * @param $field_groups 51 | * @param $post_id 52 | * @param $screen 53 | */ 54 | function add_metaboxes($field_groups, $post_id, $screen){ 55 | 56 | $postboxes = array(); 57 | 58 | foreach($field_groups as $field_group){ 59 | 60 | // vars 61 | $id = "acf-{$field_group['key']}"; // acf-group_123 62 | $title = $field_group['title']; // Group 1 63 | $context = $field_group['position']; // normal, side, acf_after_title 64 | $priority = 'high'; // high, core, default, low 65 | 66 | // reduce priority for sidebar metaboxes for best position. 67 | if($context == 'side'){ 68 | $priority = 'core'; 69 | } 70 | 71 | $priority = apply_filters('acf/input/meta_box_priority', $priority, $field_group); 72 | 73 | // localize data 74 | $postboxes[] = array( 75 | 'id' => $id, 76 | 'key' => $field_group['key'], 77 | 'style' => $field_group['style'], 78 | 'label' => $field_group['label_placement'], 79 | 'edit' => acf_get_field_group_edit_link($field_group['ID']) 80 | ); 81 | 82 | // add meta box 83 | add_meta_box($id, $title, array($this, 'render_metabox'), $screen, $context, $priority, array('post_id' => $post_id, 'field_group' => $field_group)); 84 | 85 | } 86 | 87 | // localize postboxes 88 | acf_localize_data(array( 89 | 'postboxes' => $postboxes 90 | )); 91 | 92 | } 93 | 94 | 95 | /** 96 | * render_metabox 97 | * 98 | * @param $post 99 | * @param $metabox 100 | */ 101 | function render_metabox($post, $metabox){ 102 | 103 | // vars 104 | $post_id = $metabox['args']['post_id']; 105 | $field_group = $metabox['args']['field_group']; 106 | 107 | // render fields 108 | $fields = acf_get_fields($field_group); 109 | acf_render_fields($fields, $post_id, 'div', $field_group['instruction_placement']); 110 | 111 | } 112 | 113 | 114 | /** 115 | * render_metabox_submit 116 | * 117 | * @param $object 118 | * @param $metabox 119 | */ 120 | function render_metabox_submit($object, $metabox){ 121 | 122 | // screen 123 | $screen = $metabox['args']; 124 | 125 | do_action("acfe/{$screen}/submitbox_before_major_actions", $object); 126 | 127 | ?> 128 |
129 |
130 | 131 | 132 | 133 |
134 |
135 | page = acf_get_options_page($plugin_page); 46 | 47 | if(!$this->page){ 48 | return; 49 | } 50 | 51 | // actions 52 | do_action("acfe/load_option", $this->page); 53 | do_action("acfe/load_option/page={$this->page['menu_slug']}", $this->page); 54 | 55 | // hooks 56 | add_action('admin_head', array($this, 'admin_head')); 57 | 58 | } 59 | 60 | 61 | /** 62 | * admin_head 63 | */ 64 | function admin_head(){ 65 | 66 | do_action('acfe/add_option_meta_boxes', $this->page); 67 | 68 | } 69 | 70 | } 71 | 72 | new acfe_screen_options_page(); 73 | 74 | endif; -------------------------------------------------------------------------------- /includes/screens/screen-post.php: -------------------------------------------------------------------------------- 1 | post_type = $post_type; 100 | 101 | // actions 102 | do_action("acfe/load_posts", $post_type); 103 | do_action("acfe/load_posts/post_type={$post_type}", $post_type); 104 | 105 | // hooks 106 | add_action('admin_footer', array($this, 'posts_footer')); 107 | 108 | } 109 | 110 | 111 | /** 112 | * posts_footer 113 | * 114 | * admin_footer 115 | */ 116 | function posts_footer(){ 117 | 118 | do_action('acfe/add_posts_meta_boxes', $this->post_type); 119 | 120 | $this->posts_do_meta_boxes(); 121 | 122 | } 123 | 124 | 125 | /** 126 | * posts_do_meta_boxes 127 | */ 128 | function posts_do_meta_boxes(){ 129 | 130 | // check filter 131 | if(!acf_is_filter_enabled('acfe/post_type_list')){ 132 | return; 133 | } 134 | 135 | // enqueue 136 | acf_enqueue_scripts(); 137 | 138 | ?> 139 | 148 | 149 | 158 | 159 | 172 | 195 | page = $page; 49 | 50 | // actions 51 | do_action("acfe/load_settings", $page); 52 | do_action("acfe/load_settings/page={$page}", $page); 53 | 54 | // hooks 55 | add_action('admin_footer', array($this, 'admin_footer')); 56 | 57 | } 58 | 59 | 60 | /** 61 | * admin_footer 62 | */ 63 | function admin_footer(){ 64 | 65 | do_action('acfe/add_settings_meta_boxes', $this->page); 66 | 67 | // enhanced ui 68 | if(acf_get_setting('acfe/modules/ui')){ 69 | 70 | $screen = get_current_screen(); 71 | 72 | do_meta_boxes($screen, 'acf_after_title', $this->page); 73 | do_meta_boxes($screen, 'normal', $this->page); 74 | do_meta_boxes($screen, 'side', $this->page); 75 | 76 | } 77 | 78 | } 79 | 80 | } 81 | 82 | new acfe_screen_settings(); 83 | 84 | endif; -------------------------------------------------------------------------------- /includes/upgrades.php: -------------------------------------------------------------------------------- 1 | =', ACFE_VERSION)){ 21 | return; 22 | } 23 | 24 | // do upgrade 25 | if($db_version){ 26 | 27 | add_action('acf/init', function() use($db_version){ 28 | do_action('acfe/do_upgrade', $db_version); 29 | }, 999); 30 | 31 | // do reset 32 | }else{ 33 | 34 | // hook on init to load all WP components 35 | // post types, post statuses 'acf-disabled' etc... 36 | add_action('init', function(){ 37 | do_action('acfe/do_reset'); 38 | }); 39 | 40 | } 41 | 42 | // get db settings 43 | $settings = acf_get_array(acfe_get_settings()); 44 | 45 | // model 46 | $model = acfe_parse_args_r($settings, array( 47 | 'version' => '', 48 | 'modules' => array( 49 | 'block_types' => array(), 50 | 'options_pages' => array(), 51 | 'post_types' => array(), 52 | 'taxonomies' => array(), 53 | ) 54 | )); 55 | 56 | // assign version 57 | $model['version'] = ACFE_VERSION; 58 | 59 | // update db 60 | acfe_update_settings($model); 61 | 62 | } 63 | 64 | } 65 | 66 | acf_new_instance('acfe_upgrades'); 67 | 68 | endif; -------------------------------------------------------------------------------- /lang/acfe-fr_FR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acf-extended/ACF-Extended/3a02c5951d3234a03398e4ab8b958a4fc0aec81f/lang/acfe-fr_FR.mo --------------------------------------------------------------------------------