Advanced Custom Fields: Extended - Version 0.5.8

Version Description

  • Field: Added Bidirectional setting for the following fields: relationship, post object, user & taxonomy terms
  • Module: Added 'Ajax Author' field to replace the native WP Author Meta Box
  • Module: Dynamic Post Type & Taxonomy - Better exclusion from ACF post types selection (location & fields)
  • General: Fixed ACF Select2 CSS to fit ACF input styles (border-radius, border-color & line-height)
  • General: Renamed ACF-Extended assets for better readability in the browser console resources tab
  • Compatibility: Removed the Taxonomy Order submenu created under ACF for the taxonomy 'Field Group Category' by the plugin 'Category Order and Taxonomy Terms Order'
Download this release

Release Info

Developer hwk-fr
Plugin Icon 128x128 Advanced Custom Fields: Extended
Version 0.5.8
Comparing to
See all releases

Code changes from version 0.5.5.1 to 0.5.8

acf-extended.php CHANGED
@@ -2,12 +2,12 @@
2
  /**
3
  * Plugin Name: Advanced Custom Fields: Extended
4
  * Description: Enhancement Suite which improves Advanced Custom Fields administration
5
- * Version: 0.5.5.1
6
  * Author: hwk-fr
7
  * Author URI: https://hwk.fr
8
  * Text Domain: acfe
9
  */
10
-
11
  if(!defined('ABSPATH'))
12
  exit;
13
 
@@ -63,6 +63,7 @@ function acfe_init(){
63
  /**
64
  * Fields settings
65
  */
 
66
  require_once(ACFE_PATH . 'includes/fields-settings/data.php');
67
  require_once(ACFE_PATH . 'includes/fields-settings/permissions.php');
68
  require_once(ACFE_PATH . 'includes/fields-settings/update.php');
@@ -83,6 +84,7 @@ function acfe_init(){
83
  /**
84
  * Modules
85
  */
 
86
  require_once(ACFE_PATH . 'includes/modules/autosync.php');
87
  require_once(ACFE_PATH . 'includes/modules/dynamic-post-type.php');
88
  require_once(ACFE_PATH . 'includes/modules/dynamic-taxonomy.php');
2
  /**
3
  * Plugin Name: Advanced Custom Fields: Extended
4
  * Description: Enhancement Suite which improves Advanced Custom Fields administration
5
+ * Version: 0.5.8
6
  * Author: hwk-fr
7
  * Author URI: https://hwk.fr
8
  * Text Domain: acfe
9
  */
10
+
11
  if(!defined('ABSPATH'))
12
  exit;
13
 
63
  /**
64
  * Fields settings
65
  */
66
+ require_once(ACFE_PATH . 'includes/fields-settings/bidirectional.php');
67
  require_once(ACFE_PATH . 'includes/fields-settings/data.php');
68
  require_once(ACFE_PATH . 'includes/fields-settings/permissions.php');
69
  require_once(ACFE_PATH . 'includes/fields-settings/update.php');
84
  /**
85
  * Modules
86
  */
87
+ require_once(ACFE_PATH . 'includes/modules/author.php');
88
  require_once(ACFE_PATH . 'includes/modules/autosync.php');
89
  require_once(ACFE_PATH . 'includes/modules/dynamic-post-type.php');
90
  require_once(ACFE_PATH . 'includes/modules/dynamic-taxonomy.php');
assets/{fields.js → acf-extended-fields.js} RENAMED
File without changes
assets/acf-extended-fix.css ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * ACFE: Author Label
3
+ */
4
+ .acf-field.acf-field-acfe-author > .acf-label{
5
+ display:none;
6
+ }
7
+
8
+ /*
9
+ * ACF: Label bold fix
10
+ */
11
+ .acf-field .acf-label label{
12
+ font-weight:600 !important;
13
+ }
14
+
15
+ /*
16
+ * ACF: Select2 Fix
17
+ */
18
+ .select2-container .select2-selection{
19
+ border-color: #dfdfdf !important;
20
+ border-radius:0 !important;
21
+ }
22
+
23
+ .select2-container .select2-selection__choice{
24
+ border-color: #dfdfdf !important;
25
+ border-radius:0 !important;
26
+ }
27
+
28
+ .select2-dropdown{
29
+ border-color: #dfdfdf !important;
30
+ border-radius:0 !important;
31
+ }
32
+
33
+ .select2-container .select2-selection--single .select2-selection__arrow,
34
+ .select2-container .select2-selection--single{
35
+ height: 32px !important;
36
+ }
37
+
38
+ .select2-container .select2-selection--single .select2-selection__rendered{
39
+ line-height: 31px !important;
40
+ }
41
+
42
+ .select2-container .select2-selection--single .select2-selection__clear{
43
+ line-height: 30px;
44
+ }
assets/acf-extended.css CHANGED
@@ -1,22 +1,23 @@
1
- .acf-field .acf-label label{
2
- font-weight:600 !important;
3
- }
4
-
5
  .acf-field-setting-acfe_permissions > .acf-input > .acf-fields,
6
  .acf-field-setting-acfe_validate > .acf-input > .acf-fields,
7
  .acf-field-setting-acfe_update > .acf-input > .acf-fields,
8
 
 
9
  .acf-field-setting-acfe_validate > .acf-input > .acf-fields > .acf-field.acf-field-acfe-validate-rules-or,
10
  .acf-field-setting-acfe_update > .acf-input > .acf-fields > .acf-field.acf-field-acfe-update-functions{
11
  border:0;
12
  }
13
 
 
14
  .acf-field-setting-acfe_permissions > .acf-input > .acf-fields > .acf-field,
15
  .acf-field-setting-acfe_validate > .acf-input > .acf-fields > .acf-field,
16
  .acf-field-setting-acfe_update > .acf-input > .acf-fields > .acf-field{
17
  padding:0;
18
  }
19
 
 
 
 
20
  .acf-field-setting-acfe_validate > .acf-input > .acf-fields > .acf-field.acf-field-acfe-validate-activate > .acf-label,
21
  .acf-field-setting-acfe_update > .acf-input > .acf-fields > .acf-field.acf-field-acfe-update-activate > .acf-label{
22
  display:none;
@@ -51,6 +52,10 @@
51
  text-shadow:none;
52
  }
53
 
 
 
 
 
54
  pre {
55
  display: block;
56
  padding: 9.5px;
 
 
 
 
1
  .acf-field-setting-acfe_permissions > .acf-input > .acf-fields,
2
  .acf-field-setting-acfe_validate > .acf-input > .acf-fields,
3
  .acf-field-setting-acfe_update > .acf-input > .acf-fields,
4
 
5
+ .acf-field-setting-acfe_bidirectional > .acf-input > .acf-fields,
6
  .acf-field-setting-acfe_validate > .acf-input > .acf-fields > .acf-field.acf-field-acfe-validate-rules-or,
7
  .acf-field-setting-acfe_update > .acf-input > .acf-fields > .acf-field.acf-field-acfe-update-functions{
8
  border:0;
9
  }
10
 
11
+ .acf-field-setting-acfe_bidirectional > .acf-input > .acf-fields > .acf-field,
12
  .acf-field-setting-acfe_permissions > .acf-input > .acf-fields > .acf-field,
13
  .acf-field-setting-acfe_validate > .acf-input > .acf-fields > .acf-field,
14
  .acf-field-setting-acfe_update > .acf-input > .acf-fields > .acf-field{
15
  padding:0;
16
  }
17
 
18
+
19
+ .acf-field-setting-acfe_bidirectional > .acf-input > .acf-fields > .acf-field.acf-field-acfe-bidirectional-enabled > .acf-label,
20
+ .acf-field-setting-acfe_bidirectional > .acf-input > .acf-fields > .acf-field.acf-field-acfe-bidirectional-related > .acf-label,
21
  .acf-field-setting-acfe_validate > .acf-input > .acf-fields > .acf-field.acf-field-acfe-validate-activate > .acf-label,
22
  .acf-field-setting-acfe_update > .acf-input > .acf-fields > .acf-field.acf-field-acfe-update-activate > .acf-label{
23
  display:none;
52
  text-shadow:none;
53
  }
54
 
55
+ .acf-field-setting-acfe_bidirectional > .acf-input > .acf-fields > .acf-field.acf-field-acfe-bidirectional-related{
56
+ margin-left:10px;
57
+ }
58
+
59
  pre {
60
  display: block;
61
  padding: 9.5px;
includes/core/compatibility.php CHANGED
@@ -14,4 +14,15 @@ function acfe_compatibility_pto_acf_field_group($ignore, $orderby, $query){
14
  $ignore = true;
15
 
16
  return $ignore;
 
 
 
 
 
 
 
 
 
 
 
17
  }
14
  $ignore = true;
15
 
16
  return $ignore;
17
+ }
18
+
19
+
20
+ /**
21
+ * Plugin: Category Order and Taxonomy Terms Order
22
+ * https://wordpress.org/plugins/taxonomy-terms-order/
23
+ * The plugin add a submenu to 'Custom Fields' to order Field Group Categories. It's unecessary
24
+ */
25
+ add_action('admin_menu', 'acfe_compatibility_cotto_submenu', 999);
26
+ function acfe_compatibility_cotto_submenu(){
27
+ remove_submenu_page('edit.php?post_type=acf-field-group', 'to-interface-acf-field-group');
28
  }
includes/core/enqueue.php CHANGED
@@ -8,22 +8,30 @@ if(!defined('ABSPATH'))
8
  */
9
  add_action('admin_enqueue_scripts', 'acfe_enqueue_admin');
10
  function acfe_enqueue_admin(){
 
 
 
 
 
 
 
11
  if(!acf_is_screen(array('edit-acf-field-group', 'acf-field-group')))
12
  return;
13
 
14
  // CSS
15
- wp_enqueue_style('acf-input');
16
  wp_enqueue_style('wp-jquery-ui-dialog');
17
  wp_enqueue_style('acf-extended', plugins_url('assets/acf-extended.css', ACFE_FILE), false, null);
18
 
19
  // JS
20
- wp_enqueue_script('acf-input');
21
  wp_enqueue_script('jquery-ui-core');
22
  wp_enqueue_script('jquery-ui-dialog');
23
  wp_enqueue_script('acf-extended', plugins_url('assets/acf-extended.js', ACFE_FILE), array('jquery'), null);
 
24
  }
25
 
26
  add_action('acf/input/admin_enqueue_scripts', 'acfe_enqueue_fields');
27
  function acfe_enqueue_fields(){
28
- wp_enqueue_script('acfe-fields-js', plugins_url('assets/fields.js', ACFE_FILE), array('jquery'), null);
 
 
29
  }
8
  */
9
  add_action('admin_enqueue_scripts', 'acfe_enqueue_admin');
10
  function acfe_enqueue_admin(){
11
+
12
+ // ACF CSS Fix
13
+ wp_enqueue_style('acf-extended-fix', plugins_url('assets/acf-extended-fix.css', ACFE_FILE), false, null);
14
+
15
+ wp_enqueue_style('acf-input');
16
+ wp_enqueue_script('acf-input');
17
+
18
  if(!acf_is_screen(array('edit-acf-field-group', 'acf-field-group')))
19
  return;
20
 
21
  // CSS
 
22
  wp_enqueue_style('wp-jquery-ui-dialog');
23
  wp_enqueue_style('acf-extended', plugins_url('assets/acf-extended.css', ACFE_FILE), false, null);
24
 
25
  // JS
 
26
  wp_enqueue_script('jquery-ui-core');
27
  wp_enqueue_script('jquery-ui-dialog');
28
  wp_enqueue_script('acf-extended', plugins_url('assets/acf-extended.js', ACFE_FILE), array('jquery'), null);
29
+
30
  }
31
 
32
  add_action('acf/input/admin_enqueue_scripts', 'acfe_enqueue_fields');
33
  function acfe_enqueue_fields(){
34
+
35
+ wp_enqueue_script('acf-extended-fields', plugins_url('assets/acf-extended-fields.js', ACFE_FILE), array('jquery'), null);
36
+
37
  }
includes/core/helpers.php CHANGED
@@ -4,10 +4,10 @@ if(!defined('ABSPATH'))
4
  exit;
5
 
6
  /**
7
- * Print_r
8
  */
9
- if(!function_exists('_print_r')){
10
- function _print_r($data, $args = false){
11
  $args = wp_parse_args($args, array(
12
  'title' => false,
13
  'return' => false,
@@ -39,4 +39,21 @@ if(!function_exists('_print_r')){
39
 
40
  echo $return;
41
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  }
4
  exit;
5
 
6
  /**
7
+ * ACFE: Print
8
  */
9
+ if(!function_exists('acfe_print')){
10
+ function acfe_print($data, $args = false){
11
  $args = wp_parse_args($args, array(
12
  'title' => false,
13
  'return' => false,
39
 
40
  echo $return;
41
  }
42
+ }
43
+
44
+ function acfe_get_field_group_from_field($field){
45
+
46
+ $field_parent = $field['parent'];
47
+
48
+ if(!$field_ancestors = acf_get_field_ancestors($field))
49
+ return acf_get_field_group($field_parent);
50
+
51
+ // Reverse for DESC order (Top field first)
52
+ $field_ancestors = array_reverse($field_ancestors);
53
+
54
+ $field_top_ancestor = $field_ancestors[0];
55
+ $field_top_ancestor = acf_get_field($field_top_ancestor);
56
+
57
+ return acf_get_field_group($field_top_ancestor['parent']);
58
+
59
  }
includes/field-groups/field-group.php CHANGED
@@ -8,6 +8,7 @@ if(!defined('ABSPATH'))
8
  */
9
  add_action('acf/render_field_group_settings', 'acfe_render_field_group_options');
10
  function acfe_render_field_group_options($field_group){
 
11
  acf_render_field_wrap(array(
12
  'label' => __('Note'),
13
  'name' => 'acfe_note',
@@ -17,6 +18,7 @@ function acfe_render_field_group_options($field_group){
17
  'value' => (isset($field_group['acfe_note'])) ? $field_group['acfe_note'] : '',
18
  'required' => false,
19
  ));
 
20
  }
21
 
22
  /**
@@ -24,6 +26,7 @@ function acfe_render_field_group_options($field_group){
24
  */
25
  add_action('acf/field_group/admin_head', 'acfe_render_field_group_settings');
26
  function acfe_render_field_group_settings(){
 
27
  add_meta_box('acf-field-group-acfe', __('Data', 'acfe'), function(){
28
 
29
  global $field_group;
@@ -108,6 +111,7 @@ function acfe_render_field_group_settings(){
108
  </script>
109
  <?php
110
  }, 'acf-field-group', 'normal', 'high');
 
111
  }
112
 
113
  /**
@@ -115,6 +119,7 @@ function acfe_render_field_group_settings(){
115
  */
116
  add_action('post_submitbox_misc_actions', 'acfe_render_field_group_submitbox');
117
  function acfe_render_field_group_submitbox(){
 
118
  if(get_post_type(get_the_ID()) !== 'acf-field-group')
119
  return;
120
 
@@ -129,6 +134,7 @@ function acfe_render_field_group_submitbox(){
129
  })(jQuery);
130
  </script>
131
  <?php
 
132
  }
133
 
134
  /**
@@ -136,6 +142,7 @@ function acfe_render_field_group_submitbox(){
136
  */
137
  add_action('acf/field_group/admin_head', 'acfe_render_field_group_settings_side');
138
  function acfe_render_field_group_settings_side(){
 
139
  add_meta_box('acf-field-group-acfe-side', __('Advanced Settings', 'acfe'), function(){
140
 
141
  global $field_group;
@@ -225,6 +232,7 @@ function acfe_render_field_group_settings_side(){
225
  </script>
226
  <?php
227
  }, 'acf-field-group', 'side');
 
228
  }
229
 
230
  /**
@@ -232,6 +240,7 @@ function acfe_render_field_group_settings_side(){
232
  */
233
  add_action('acf/render_field/name=acfe_sync_available', 'acfe_render_field_sync_available');
234
  function acfe_render_field_sync_available($field){
 
235
  $field_group = acf_get_field_group($field['value']);
236
 
237
  $acfe_autosync_active = 0;
@@ -240,6 +249,7 @@ function acfe_render_field_sync_available($field){
240
 
241
  $nonce = wp_create_nonce('bulk-posts');
242
  echo '<a data-acfe-autosync-json-active="'.$acfe_autosync_active.'" class="button" href="'.admin_url('edit.php?post_type=acf-field-group&post_status=sync&acfsync=' . $field['value'] . '&_wpnonce=' . $nonce).'">Synchronize</a>';
 
243
  }
244
 
245
  /**
@@ -247,6 +257,7 @@ function acfe_render_field_sync_available($field){
247
  */
248
  add_action('acf/render_field', 'acfe_render_field_acfe_sync_warnings', 5);
249
  function acfe_render_field_acfe_sync_warnings($field){
 
250
  if($field['_name'] != 'acfe_autosync')
251
  return;
252
 
@@ -273,7 +284,6 @@ function acfe_render_field_acfe_sync_warnings($field){
273
  acf_disable_filters();
274
 
275
  // Json
276
-
277
  if(!acfe_has_field_group_autosync($field_group, 'json') && acfe_has_field_group_autosync_file($field_group, 'json')){
278
  echo '<p class="description"><span style="color:#ccc;font-size:16px;vertical-align:text-top;" class="dashicons dashicons-warning"></span> <code style="font-size:11px;">' . $field_group['key'] . '.json</code> was found. Activate Json sync to keep it updated</p>';
279
  }
@@ -282,7 +292,6 @@ function acfe_render_field_acfe_sync_warnings($field){
282
  echo '<p class="description"><span style="color:#ccc;font-size:16px;vertical-align:text-top;" class="dashicons dashicons-warning"></span> <code style="font-size:11px;">' . $field_group['key'] . '.json</code> was not found. Update this field group to regenerate it</p>';
283
  }
284
 
285
-
286
  }
287
 
288
  /**
@@ -290,6 +299,7 @@ function acfe_render_field_acfe_sync_warnings($field){
290
  */
291
  add_action('acf/render_field/name=acfe_data', 'acfe_render_field_group_data');
292
  function acfe_render_field_group_data($field){
 
293
  $field_group = acf_get_field_group($field['value']);
294
  if(!$field_group){
295
  echo '<a href="#" class="button disabled" disabled>' . __('Data') . '</a>';
@@ -298,6 +308,7 @@ function acfe_render_field_group_data($field){
298
 
299
  echo '<a href="#" class="button acfe_modal_open" data-modal-key="' . $field_group['key'] . '">' . __('Data') . '</a>';
300
  echo '<div class="acfe_modal acfe_modal_data hidden" data-modal-key="' . $field_group['key'] . '"><pre>' . print_r($field_group, true) . '</pre></div>';
 
301
  }
302
 
303
  /**
@@ -305,6 +316,10 @@ function acfe_render_field_group_data($field){
305
  */
306
  add_filter('acf/get_field_groups', 'acfe_render_field_groups', 999);
307
  function acfe_render_field_groups($field_groups){
 
 
 
 
308
  $check_current_screen = acf_is_screen(array(
309
  'edit-acf-field-group',
310
  'acf-field-group',
@@ -322,6 +337,7 @@ function acfe_render_field_groups($field_groups){
322
  }
323
 
324
  return $field_groups;
 
325
  }
326
 
327
  /**
@@ -329,6 +345,10 @@ function acfe_render_field_groups($field_groups){
329
  */
330
  add_filter('acf/get_field_groups', 'acfe_permissions_field_groups', 999);
331
  function acfe_permissions_field_groups($field_groups){
 
 
 
 
332
  $check_current_screen = acf_is_screen(array(
333
  'edit-acf-field-group',
334
  'acf-field-group',
@@ -364,6 +384,7 @@ function acfe_permissions_field_groups($field_groups){
364
  }
365
 
366
  return $field_groups;
 
367
  }
368
 
369
  /**
@@ -371,8 +392,10 @@ function acfe_permissions_field_groups($field_groups){
371
  */
372
  add_filter('acf/validate_field_group', 'acfc_field_group_default_options');
373
  function acfc_field_group_default_options($field_group){
 
374
  if(!isset($field_group['location']) || empty($field_group['location']))
375
  $field_group['label_placement'] = 'left';
376
 
377
  return $field_group;
 
378
  }
8
  */
9
  add_action('acf/render_field_group_settings', 'acfe_render_field_group_options');
10
  function acfe_render_field_group_options($field_group){
11
+
12
  acf_render_field_wrap(array(
13
  'label' => __('Note'),
14
  'name' => 'acfe_note',
18
  'value' => (isset($field_group['acfe_note'])) ? $field_group['acfe_note'] : '',
19
  'required' => false,
20
  ));
21
+
22
  }
23
 
24
  /**
26
  */
27
  add_action('acf/field_group/admin_head', 'acfe_render_field_group_settings');
28
  function acfe_render_field_group_settings(){
29
+
30
  add_meta_box('acf-field-group-acfe', __('Data', 'acfe'), function(){
31
 
32
  global $field_group;
111
  </script>
112
  <?php
113
  }, 'acf-field-group', 'normal', 'high');
114
+
115
  }
116
 
117
  /**
119
  */
120
  add_action('post_submitbox_misc_actions', 'acfe_render_field_group_submitbox');
121
  function acfe_render_field_group_submitbox(){
122
+
123
  if(get_post_type(get_the_ID()) !== 'acf-field-group')
124
  return;
125
 
134
  })(jQuery);
135
  </script>
136
  <?php
137
+
138
  }
139
 
140
  /**
142
  */
143
  add_action('acf/field_group/admin_head', 'acfe_render_field_group_settings_side');
144
  function acfe_render_field_group_settings_side(){
145
+
146
  add_meta_box('acf-field-group-acfe-side', __('Advanced Settings', 'acfe'), function(){
147
 
148
  global $field_group;
232
  </script>
233
  <?php
234
  }, 'acf-field-group', 'side');
235
+
236
  }
237
 
238
  /**
240
  */
241
  add_action('acf/render_field/name=acfe_sync_available', 'acfe_render_field_sync_available');
242
  function acfe_render_field_sync_available($field){
243
+
244
  $field_group = acf_get_field_group($field['value']);
245
 
246
  $acfe_autosync_active = 0;
249
 
250
  $nonce = wp_create_nonce('bulk-posts');
251
  echo '<a data-acfe-autosync-json-active="'.$acfe_autosync_active.'" class="button" href="'.admin_url('edit.php?post_type=acf-field-group&post_status=sync&acfsync=' . $field['value'] . '&_wpnonce=' . $nonce).'">Synchronize</a>';
252
+
253
  }
254
 
255
  /**
257
  */
258
  add_action('acf/render_field', 'acfe_render_field_acfe_sync_warnings', 5);
259
  function acfe_render_field_acfe_sync_warnings($field){
260
+
261
  if($field['_name'] != 'acfe_autosync')
262
  return;
263
 
284
  acf_disable_filters();
285
 
286
  // Json
 
287
  if(!acfe_has_field_group_autosync($field_group, 'json') && acfe_has_field_group_autosync_file($field_group, 'json')){
288
  echo '<p class="description"><span style="color:#ccc;font-size:16px;vertical-align:text-top;" class="dashicons dashicons-warning"></span> <code style="font-size:11px;">' . $field_group['key'] . '.json</code> was found. Activate Json sync to keep it updated</p>';
289
  }
292
  echo '<p class="description"><span style="color:#ccc;font-size:16px;vertical-align:text-top;" class="dashicons dashicons-warning"></span> <code style="font-size:11px;">' . $field_group['key'] . '.json</code> was not found. Update this field group to regenerate it</p>';
293
  }
294
 
 
295
  }
296
 
297
  /**
299
  */
300
  add_action('acf/render_field/name=acfe_data', 'acfe_render_field_group_data');
301
  function acfe_render_field_group_data($field){
302
+
303
  $field_group = acf_get_field_group($field['value']);
304
  if(!$field_group){
305
  echo '<a href="#" class="button disabled" disabled>' . __('Data') . '</a>';
308
 
309
  echo '<a href="#" class="button acfe_modal_open" data-modal-key="' . $field_group['key'] . '">' . __('Data') . '</a>';
310
  echo '<div class="acfe_modal acfe_modal_data hidden" data-modal-key="' . $field_group['key'] . '"><pre>' . print_r($field_group, true) . '</pre></div>';
311
+
312
  }
313
 
314
  /**
316
  */
317
  add_filter('acf/get_field_groups', 'acfe_render_field_groups', 999);
318
  function acfe_render_field_groups($field_groups){
319
+
320
+ if(!is_admin())
321
+ return $field_groups;
322
+
323
  $check_current_screen = acf_is_screen(array(
324
  'edit-acf-field-group',
325
  'acf-field-group',
337
  }
338
 
339
  return $field_groups;
340
+
341
  }
342
 
343
  /**
345
  */
346
  add_filter('acf/get_field_groups', 'acfe_permissions_field_groups', 999);
347
  function acfe_permissions_field_groups($field_groups){
348
+
349
+ if(!is_admin())
350
+ return $field_groups;
351
+
352
  $check_current_screen = acf_is_screen(array(
353
  'edit-acf-field-group',
354
  'acf-field-group',
384
  }
385
 
386
  return $field_groups;
387
+
388
  }
389
 
390
  /**
392
  */
393
  add_filter('acf/validate_field_group', 'acfc_field_group_default_options');
394
  function acfc_field_group_default_options($field_group){
395
+
396
  if(!isset($field_group['location']) || empty($field_group['location']))
397
  $field_group['label_placement'] = 'left';
398
 
399
  return $field_group;
400
+
401
  }
includes/fields-settings/bidirectional.php ADDED
@@ -0,0 +1,565 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if(!defined('ABSPATH'))
4
+ exit;
5
+
6
+ /**
7
+ * Field Setting
8
+ */
9
+ add_action('acf/render_field_settings/type=relationship', 'acfe_bidirectional_settings');
10
+ add_action('acf/render_field_settings/type=post_object', 'acfe_bidirectional_settings');
11
+ add_action('acf/render_field_settings/type=user', 'acfe_bidirectional_settings');
12
+ add_action('acf/render_field_settings/type=taxonomy', 'acfe_bidirectional_settings');
13
+ function acfe_bidirectional_settings($field){
14
+
15
+ // Settings
16
+ acf_render_field_setting($field, array(
17
+ 'label' => __('Bidirectional'),
18
+ 'key' => 'acfe_bidirectional',
19
+ 'name' => 'acfe_bidirectional',
20
+ 'instructions' => __('Set the field as bidirectional'),
21
+ 'type' => 'group',
22
+ 'required' => false,
23
+ 'conditional_logic' => false,
24
+ 'wrapper' => array(
25
+ 'width' => '',
26
+ 'class' => '',
27
+ 'id' => '',
28
+ ),
29
+ 'layout' => 'block',
30
+ 'sub_fields' => array(
31
+ array(
32
+ 'label' => false,
33
+ 'key' => 'acfe_bidirectional_enabled',
34
+ 'name' => 'acfe_bidirectional_enabled',
35
+ 'type' => 'true_false',
36
+ 'instructions' => '',
37
+ 'required' => false,
38
+ 'wrapper' => array(
39
+ 'width' => 'auto',
40
+ 'class' => '',
41
+ 'id' => '',
42
+ ),
43
+ 'message' => '',
44
+ 'default_value' => false,
45
+ 'ui' => true,
46
+ 'ui_on_text' => '',
47
+ 'ui_off_text' => '',
48
+ 'conditional_logic' => false,
49
+ ),
50
+ array(
51
+ 'label' => false,
52
+ 'key' => 'acfe_bidirectional_related',
53
+ 'name' => 'acfe_bidirectional_related',
54
+ 'type' => 'select',
55
+ 'instructions' => '',
56
+ 'required' => false,
57
+ 'wrapper' => array(
58
+ 'width' => 50,
59
+ 'class' => '',
60
+ 'id' => '',
61
+ ),
62
+ 'choices' => array(),
63
+ 'default_value' => array(),
64
+ 'allow_null' => 1,
65
+ 'multiple' => 0,
66
+ 'ui' => 1,
67
+ 'ajax' => 1,
68
+ 'return_format' => 'value',
69
+ 'placeholder' => '',
70
+ 'conditional_logic' => array(
71
+ array(
72
+ array(
73
+ 'field' => 'acfe_bidirectional_enabled',
74
+ 'operator' => '==',
75
+ 'value' => '1',
76
+ ),
77
+ ),
78
+ ),
79
+ ),
80
+ ),
81
+ ));
82
+
83
+ }
84
+
85
+ /**
86
+ * Field Setting: Ajax Handler
87
+ */
88
+ add_action('wp_ajax_acf/fields/select/query', 'acfe_bidirectional_ajax', 0);
89
+ add_action('wp_ajax_nopriv_acf/fields/select/query', 'acfe_bidirectional_ajax', 0);
90
+ function acfe_bidirectional_ajax(){
91
+
92
+ // Do not die to let ACF handle others ajax requests
93
+ if(!acf_verify_ajax())
94
+ return;
95
+
96
+ $options = acf_parse_args($_POST, array(
97
+ 'post_id' => 0,
98
+ 's' => '',
99
+ 'field_key' => '',
100
+ 'paged' => 1
101
+ ));
102
+
103
+ // Not our field setting. Stop
104
+ if($options['field_key'] != 'acfe_bidirectional_related')
105
+ return;
106
+
107
+ $response = acfe_bidirectional_ajax_query($options);
108
+
109
+ acf_send_ajax_results($response);
110
+
111
+ }
112
+
113
+ /**
114
+ * Field Setting: Ajax Query
115
+ */
116
+ function acfe_bidirectional_ajax_query($options = array()){
117
+
118
+ // Current field group
119
+ $field_group = acf_get_field_group($options['post_id']);
120
+
121
+ // Get field groups
122
+ $r_field_groups = acf_get_field_groups();
123
+ if(empty($r_field_groups))
124
+ return false;
125
+
126
+ $choices = array();
127
+
128
+ foreach($r_field_groups as $r_field_group){
129
+
130
+ // Bypass current field group
131
+ if($r_field_group['key'] == $field_group['key'])
132
+ continue;
133
+
134
+ // Bypass ACFE native groups
135
+ if(in_array($r_field_group['key'], array('group_acfe_author', 'group_acfe_dynamic_post_type', 'group_acfe_dynamic_taxonomy')))
136
+ continue;
137
+
138
+ // Get related fields
139
+ $r_fields = acf_get_fields($r_field_group['key']);
140
+ if(empty($r_fields))
141
+ continue;
142
+
143
+ // Filter & find possible related fields
144
+ foreach($r_fields as $r_field){
145
+
146
+ acfe_bidirectional_setting_find_related($r_field, $r_field_group, $choices);
147
+
148
+ }
149
+
150
+ }
151
+
152
+ // vars
153
+ $results = array();
154
+ $s = null;
155
+
156
+ if(!empty($choices)){
157
+
158
+ // search
159
+ if($options['s'] !== ''){
160
+
161
+ // strip slashes (search may be integer)
162
+ $s = strval($options['s']);
163
+ $s = wp_unslash($s);
164
+
165
+ }
166
+
167
+ foreach($choices as $field_group_title => $childs){
168
+
169
+ $field_group_title = strval($field_group_title);
170
+
171
+ $childrens = array();
172
+ foreach($childs as $child_key => $child_label){
173
+
174
+ $child_label = strval($child_label);
175
+
176
+ // if searching, but doesn't exist
177
+ if(is_string($s) && stripos($child_label, $s) === false && stripos($field_group_title, $s) === false)
178
+ continue(2);
179
+
180
+ $childrens[] = array(
181
+ 'id' => $child_key,
182
+ 'text' => $child_label,
183
+ );
184
+
185
+ }
186
+
187
+ $results[] = array(
188
+ 'text' => $field_group_title,
189
+ 'children' => $childrens
190
+ );
191
+
192
+ }
193
+
194
+ }
195
+
196
+ return array(
197
+ 'results' => $results
198
+ );
199
+
200
+ }
201
+
202
+ function acfe_bidirectional_setting_find_related($r_field, $r_field_group, &$choices){
203
+
204
+ if(in_array($r_field['type'], array('repeater', 'flexible_content')))
205
+ return;
206
+
207
+ // Recursive search for sub_fields (groups & clones)
208
+ if(isset($r_field['sub_fields']) && !empty($r_field['sub_fields'])){
209
+
210
+ foreach($r_field['sub_fields'] as $r_sub_field){
211
+
212
+ // Recursive call
213
+ return acfe_bidirectional_setting_find_related($r_sub_field, $r_field_group, $choices);
214
+
215
+ }
216
+
217
+ }
218
+
219
+ // Allow only specific fields
220
+ $allowed_fields_types = array('relationship', 'post_object', 'user', 'taxonomy');
221
+ if(!in_array($r_field['type'], $allowed_fields_types))
222
+ return false;
223
+
224
+ $choices[$r_field_group['title']][$r_field['key']] = (!empty($r_field['label']) ? $r_field['label'] : $r_field['name']) . ' (' . $r_field['key'] . ')';
225
+
226
+ }
227
+
228
+ /**
229
+ * Field Setting: Default Value
230
+ */
231
+ add_filter('acf/prepare_field/name=acfe_bidirectional_related', 'acfe_bidirectional_setting_value');
232
+ function acfe_bidirectional_setting_value($field){
233
+
234
+ if(!isset($field['value']) || empty($field['value']))
235
+ return $field;
236
+
237
+ // Get related field
238
+ $r_field = acf_get_field($field['value']);
239
+
240
+ // Related field not found
241
+ if(!$r_field){
242
+
243
+ // Unset & updatevalue
244
+ $field['value'] = false;
245
+ acf_update_field($field);
246
+
247
+ return $field;
248
+
249
+ }
250
+
251
+ $r_field_group = acfe_get_field_group_from_field($r_field);
252
+
253
+ $field['choices'] = array($r_field['key'] => (!empty($r_field['label']) ? $r_field['label'] : $r_field['name']) . ' (' . $r_field['key'] . ')');
254
+
255
+ return $field;
256
+
257
+ }
258
+
259
+ /**
260
+ * Field Setting Update
261
+ */
262
+ add_filter('acf/update_field/type=relationship', 'acfe_bidirectional_setting_update');
263
+ add_filter('acf/update_field/type=post_object', 'acfe_bidirectional_setting_update');
264
+ add_filter('acf/update_field/type=user', 'acfe_bidirectional_setting_update');
265
+ add_filter('acf/update_field/type=taxonomy', 'acfe_bidirectional_setting_update');
266
+ function acfe_bidirectional_setting_update($field){
267
+
268
+ $do_update = apply_filters('acfe/bidirectional/setting/update', true);
269
+ if(!$do_update)
270
+ return $field;
271
+
272
+ // Previous setting values
273
+ $_field = acf_get_field($field['key']);
274
+
275
+ // Turning off - Remove related field
276
+ if(acfe_has_field_bidirectional($_field) && !acfe_has_field_bidirectional($field)){
277
+
278
+ // Get related bidirectional related
279
+ $r_field = acf_get_field($_field['acfe_bidirectional']['acfe_bidirectional_related']);
280
+
281
+ // Reset related bidirectional related
282
+ $r_field['acfe_bidirectional']['acfe_bidirectional_enabled'] = false;
283
+ $r_field['acfe_bidirectional']['acfe_bidirectional_related'] = false;
284
+
285
+ add_filter('acfe/bidirectional/setting/update', '__return_false');
286
+
287
+ // Update related bidirectional
288
+ acf_update_field($r_field);
289
+
290
+ remove_filter('acfe/bidirectional/setting/update', '__return_false');
291
+
292
+ return $field;
293
+
294
+ }
295
+
296
+ // Turning on - Add related field
297
+ elseif(!acfe_has_field_bidirectional($_field) && acfe_has_field_bidirectional($field)){
298
+
299
+ // Get related bidirectional related
300
+ $r_field = acf_get_field($field['acfe_bidirectional']['acfe_bidirectional_related']);
301
+
302
+ // Reset related bidirectional related
303
+ $r_field['acfe_bidirectional']['acfe_bidirectional_enabled'] = true;
304
+ $r_field['acfe_bidirectional']['acfe_bidirectional_related'] = $field['key'];
305
+
306
+ add_filter('acfe/bidirectional/setting/update', '__return_false');
307
+
308
+ // Update related bidirectional
309
+ acf_update_field($r_field);
310
+
311
+ remove_filter('acfe/bidirectional/setting/update', '__return_false');
312
+
313
+ return $field;
314
+
315
+ }
316
+
317
+ // Return
318
+ return $field;
319
+
320
+ }
321
+
322
+ /**
323
+ * Field Setting Deleted
324
+ */
325
+ add_action('acf/delete_field/type=relationship', 'acfe_bidirectional_setting_delete');
326
+ add_filter('acf/delete_field/type=post_object', 'acfe_bidirectional_setting_delete');
327
+ add_filter('acf/delete_field/type=user', 'acfe_bidirectional_setting_delete');
328
+ add_filter('acf/delete_field/type=taxonomy', 'acfe_bidirectional_setting_delete');
329
+ function acfe_bidirectional_setting_delete($field){
330
+
331
+ if(!acfe_has_field_bidirectional($field))
332
+ return;
333
+
334
+ // Get related bidirectional related
335
+ $r_field = acf_get_field($field['acfe_bidirectional']['acfe_bidirectional_related']);
336
+
337
+ // Reset related bidirectional related
338
+ $r_field['acfe_bidirectional']['acfe_bidirectional_related'] = false;
339
+
340
+ // Update related bidirectional
341
+ acf_update_field($r_field);
342
+
343
+ }
344
+
345
+ /**
346
+ * Update Value
347
+ */
348
+ add_filter('acf/update_value/type=relationship', 'acfe_bidirectional_update_value', 11, 3);
349
+ add_filter('acf/update_value/type=post_object', 'acfe_bidirectional_update_value', 11, 3);
350
+ add_filter('acf/update_value/type=user', 'acfe_bidirectional_update_value', 11, 3);
351
+ add_filter('acf/update_value/type=taxonomy', 'acfe_bidirectional_update_value', 11, 3);
352
+ function acfe_bidirectional_update_value($value, $post_id, $field){
353
+
354
+ $ignore = apply_filters('acfe/bidirectional/ignore', false, $value, $post_id, $field);
355
+ if($ignore)
356
+ return $value;
357
+
358
+ // Check if bidirectional
359
+ if(!acfe_get_field_bidirectional($field))
360
+ return $value;
361
+
362
+ // Decode current post_id (ie: user_1)
363
+ $request = acf_decode_post_id($post_id);
364
+
365
+ // Values
366
+ $old_values = acf_get_array(acf_get_metadata($post_id, $field['name']));
367
+ $new_values = acf_get_array($value);
368
+
369
+ // Bail early if no difference
370
+ if($old_values == $new_values)
371
+ return $value;
372
+
373
+ // Values have been removed
374
+ if(!empty($old_values)){
375
+ foreach($old_values as $r_id){
376
+
377
+ if(in_array($r_id, $new_values))
378
+ continue;
379
+
380
+ acfe_bidirectional_relationship('remove', $r_id, $field, $request['id']);
381
+
382
+ }
383
+ }
384
+
385
+ // Values have been added
386
+ if(!empty($new_values)){
387
+ foreach($new_values as $r_id){
388
+
389
+ if(in_array($r_id, $old_values))
390
+ continue;
391
+
392
+ acfe_bidirectional_relationship('add', $r_id, $field, $request['id']);
393
+
394
+ }
395
+ }
396
+
397
+ return $value;
398
+
399
+ }
400
+
401
+ /**
402
+ * Establish Relationship
403
+ *
404
+ * $type: add|remove
405
+ * $r_id: the post_id to add the relationship to
406
+ * $p_field: the parent field
407
+ * $p_id: the relationship to add
408
+ */
409
+ function acfe_bidirectional_relationship($type = 'add', $r_id, $p_field, $p_value){
410
+
411
+ // Get Related Field Configuration
412
+ $r_field = acf_get_field($p_field['acfe_bidirectional']['acfe_bidirectional_related']);
413
+
414
+ // Get if bidirectional is active
415
+ if(!acfe_get_field_bidirectional($r_field))
416
+ return;
417
+
418
+ // Get Related Data Type ({post_id}, user_{id} ...)
419
+ $r_mtype = '';
420
+ if($p_field['type'] == 'user')
421
+ $r_mtype = 'user_';
422
+ elseif($p_field['type'] == 'taxonomy')
423
+ $r_mtype = 'term_';
424
+
425
+ // Get Related Field Ancestors
426
+ $r_field_ancestors = acf_get_field_ancestors($r_field);
427
+
428
+ // Ancestors - Complexe field (group|clone)
429
+ if(!empty($r_field_ancestors)){
430
+
431
+ // Get ancestors
432
+ $r_field_ancestors = array_reverse($r_field_ancestors);
433
+ $r_field_ancestors_fields = array_map('acf_get_field', $r_field_ancestors);
434
+
435
+ // Get top ancestor
436
+ $r_ref_field = $r_field_ancestors_fields[0];
437
+ $r_ref_values = acf_get_array(acf_get_value($r_mtype.$r_id, $r_ref_field));
438
+
439
+ // Get values
440
+ $r_values = acf_get_array(acfe_get_value_from_ancestor($r_ref_values, $r_field));
441
+
442
+ // Unset top ancestor for update (not needed)
443
+ unset($r_field_ancestors_fields[0]);
444
+
445
+ // Add related field to get
446
+ $r_values_query = array($r_field['key']);
447
+
448
+ // If > 1 ancestors, return ancestors keys only
449
+ if(!empty($r_field_ancestors_fields)){
450
+
451
+ $r_field_ancestors_keys = array_map(function($field){
452
+ return $field['key'];
453
+ }, $r_field_ancestors_fields);
454
+
455
+ // Add ancestors to get
456
+ $r_values_query = array_merge($r_field_ancestors_keys, $r_values_query);
457
+
458
+ }
459
+
460
+ }
461
+
462
+ // No Ancestors - Simple field
463
+ else{
464
+
465
+ // Refence field
466
+ $r_ref_field = $r_field;
467
+
468
+ // Values
469
+ $r_values = acf_get_array(acf_get_value($r_mtype.$r_id, $r_field));
470
+
471
+ }
472
+
473
+ // Add Value
474
+ if($type == 'add'){
475
+
476
+ if(!in_array($p_value, $r_values))
477
+ $r_values[] = $p_value;
478
+
479
+ }
480
+
481
+ // Remove Value
482
+ elseif($type == 'remove'){
483
+
484
+ $r_new_values = array();
485
+ foreach($r_values as $r_value){
486
+
487
+ if($r_value == $p_value)
488
+ continue;
489
+
490
+ $r_new_values[] = $r_value;
491
+
492
+ }
493
+
494
+ $r_values = $r_new_values;
495
+
496
+ }
497
+
498
+ /*
499
+ * Construct a value array in case of ancestors. ie:
500
+ * $related_values = Array(
501
+ * [field_aaa] => Array(
502
+ * [field_bbb] => Array(
503
+ * [0] => xxxx
504
+ * )
505
+ * )
506
+ * )
507
+ */
508
+ if(!empty($r_field_ancestors)){
509
+
510
+ for($i = count($r_values_query)-1; $i>=0; $i--){
511
+ $r_values = array($r_values_query[$i] => $r_values);
512
+ }
513
+
514
+ }
515
+
516
+ // Filter acf_update_value (to avoid infinite loop)
517
+ add_filter('acfe/bidirectional/ignore', '__return_true');
518
+
519
+ // Update Related Field
520
+ acf_update_value($r_values, $r_mtype.$r_id, $r_ref_field);
521
+
522
+ // Remove acf_update_value filter
523
+ remove_filter('acfe/bidirectional/ignore', '__return_true');
524
+
525
+ }
526
+
527
+ function acfe_get_value_from_ancestor($r_ref_values, $r_field){
528
+
529
+ foreach($r_ref_values as $r_ref_key => $r_ref_value){
530
+
531
+ if($r_ref_key != $r_field['key']){
532
+
533
+ if(is_array($r_ref_value))
534
+ return acfe_get_value_from_ancestor($r_ref_value, $r_field);
535
+
536
+ return false;
537
+
538
+ }
539
+
540
+ return $r_ref_value;
541
+
542
+ }
543
+
544
+ }
545
+
546
+ function acfe_is_field_bidirectional($field){
547
+
548
+ return isset($field['acfe_bidirectional']['acfe_bidirectional_enabled']) && !empty($field['acfe_bidirectional']['acfe_bidirectional_enabled']);
549
+
550
+ }
551
+
552
+ function acfe_has_field_bidirectional($field){
553
+
554
+ return isset($field['acfe_bidirectional']['acfe_bidirectional_related']) && !empty($field['acfe_bidirectional']['acfe_bidirectional_related']);
555
+
556
+ }
557
+
558
+ function acfe_get_field_bidirectional($field){
559
+
560
+ if(!acfe_is_field_bidirectional($field) || !acfe_has_field_bidirectional($field))
561
+ return false;
562
+
563
+ return $field['acfe_bidirectional']['acfe_bidirectional_related'];
564
+
565
+ }
includes/fields-settings/permissions.php CHANGED
@@ -23,6 +23,7 @@ function acfe_permissions_settings($field){
23
 
24
  add_filter('acf/prepare_field', 'acfe_roles_prepare_field');
25
  function acfe_roles_prepare_field($field){
 
26
  if(!isset($field['acfe_permissions']) || empty($field['acfe_permissions']))
27
  return $field;
28
 
@@ -46,9 +47,11 @@ function acfe_roles_prepare_field($field){
46
  return false;
47
 
48
  return $field;
 
49
  }
50
 
51
  function acfe_get_roles(){
 
52
  global $wp_roles;
53
  $choices = array();
54
 
@@ -60,9 +63,11 @@ function acfe_get_roles(){
60
  }
61
 
62
  return $choices;
 
63
  }
64
 
65
  function acfe_get_current_user_roles(){
 
66
  global $current_user;
67
 
68
  if(!is_object($current_user) || !isset($current_user->roles))
@@ -73,4 +78,5 @@ function acfe_get_current_user_roles(){
73
  $roles[] = 'super_admin';
74
 
75
  return $roles;
 
76
  }
23
 
24
  add_filter('acf/prepare_field', 'acfe_roles_prepare_field');
25
  function acfe_roles_prepare_field($field){
26
+
27
  if(!isset($field['acfe_permissions']) || empty($field['acfe_permissions']))
28
  return $field;
29
 
47
  return false;
48
 
49
  return $field;
50
+
51
  }
52
 
53
  function acfe_get_roles(){
54
+
55
  global $wp_roles;
56
  $choices = array();
57
 
63
  }
64
 
65
  return $choices;
66
+
67
  }
68
 
69
  function acfe_get_current_user_roles(){
70
+
71
  global $current_user;
72
 
73
  if(!is_object($current_user) || !isset($current_user->roles))
78
  $roles[] = 'super_admin';
79
 
80
  return $roles;
81
+
82
  }
includes/fields-settings/update.php CHANGED
@@ -8,6 +8,7 @@ if(!defined('ABSPATH'))
8
  */
9
  add_filter('acfe/update/functions', 'acfe_update_functions', 0);
10
  function acfe_update_functions($choices){
 
11
  return array(
12
  'Sanitize' => array(
13
  'sanitize_email' => 'Sanitize email (sanitize_email)',
@@ -22,6 +23,7 @@ function acfe_update_functions($choices){
22
  'sanitize_user' => 'Sanitize user (sanitize_user)',
23
  ),
24
  );
 
25
  }
26
 
27
  /**
@@ -143,8 +145,10 @@ acf_add_filter_variations('acfe/update/exclude', array('type', 'name', 'key'), 1
143
  */
144
  add_filter('acf/update_field', 'acfe_update_value_clone_index');
145
  function acfe_update_value_clone_index($field){
 
146
  if(isset($field['acfe_update']['acfcloneindex']))
147
  $field['acfe_update'] = false;
148
 
149
  return $field;
 
150
  }
8
  */
9
  add_filter('acfe/update/functions', 'acfe_update_functions', 0);
10
  function acfe_update_functions($choices){
11
+
12
  return array(
13
  'Sanitize' => array(
14
  'sanitize_email' => 'Sanitize email (sanitize_email)',
23
  'sanitize_user' => 'Sanitize user (sanitize_user)',
24
  ),
25
  );
26
+
27
  }
28
 
29
  /**
145
  */
146
  add_filter('acf/update_field', 'acfe_update_value_clone_index');
147
  function acfe_update_value_clone_index($field){
148
+
149
  if(isset($field['acfe_update']['acfcloneindex']))
150
  $field['acfe_update'] = false;
151
 
152
  return $field;
153
+
154
  }
includes/fields-settings/validation.php CHANGED
@@ -213,6 +213,7 @@ function acfe_validation_settings($field){
213
  */
214
  add_filter('acf/validate_value', 'acfe_validate_value', 99, 4);
215
  function acfe_validate_value($valid, $value, $field, $input){
 
216
  if(!$valid)
217
  return $valid;
218
 
@@ -295,6 +296,7 @@ function acfe_validate_value($valid, $value, $field, $input){
295
  }
296
 
297
  return $valid;
 
298
  }
299
 
300
  /**
@@ -307,8 +309,10 @@ acf_add_filter_variations('acfe/validate/exclude', array('type', 'name', 'key'),
307
  */
308
  add_filter('acf/update_field', 'acfe_validate_value_clone_index');
309
  function acfe_validate_value_clone_index($field){
 
310
  if(isset($field['acfe_validate']['acfcloneindex']))
311
  $field['acfe_validate'] = false;
312
 
313
  return $field;
 
314
  }
213
  */
214
  add_filter('acf/validate_value', 'acfe_validate_value', 99, 4);
215
  function acfe_validate_value($valid, $value, $field, $input){
216
+
217
  if(!$valid)
218
  return $valid;
219
 
296
  }
297
 
298
  return $valid;
299
+
300
  }
301
 
302
  /**
309
  */
310
  add_filter('acf/update_field', 'acfe_validate_value_clone_index');
311
  function acfe_validate_value_clone_index($field){
312
+
313
  if(isset($field['acfe_validate']['acfcloneindex']))
314
  $field['acfe_validate'] = false;
315
 
316
  return $field;
317
+
318
  }
includes/modules/author.php ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if(!defined('ABSPATH'))
4
+ exit;
5
+
6
+ /**
7
+ * Register Field Group
8
+ */
9
+ add_filter('acf/get_field_groups', 'acfe_author_field_group_permissions', 999);
10
+ function acfe_author_field_group_permissions($field_groups){
11
+
12
+ if(!is_admin())
13
+ return $field_groups;
14
+
15
+ $check_current_screen = acf_is_screen(array(
16
+ 'edit-acf-field-group',
17
+ 'acf-field-group',
18
+ 'acf_page_acf-tools'
19
+ ));
20
+
21
+ if($check_current_screen)
22
+ return $field_groups;
23
+
24
+ global $post;
25
+
26
+ // Get Post ID
27
+ $post_id = get_the_ID();
28
+
29
+ if(empty($post_id) && isset($_REQUEST['post']))
30
+ $post_id = (int) $_REQUEST['post'];
31
+
32
+ if(empty($post_id) && isset($post->ID))
33
+ $post_id = $post->ID;
34
+
35
+ if(empty($post_id))
36
+ return $field_groups;
37
+
38
+ // Get Post Type Object
39
+ $post_type_object = get_post_type_object(get_post_type($post_id));
40
+ if(empty($post_type_object))
41
+ return $field_groups;
42
+
43
+ foreach($field_groups as $key => $field_group){
44
+
45
+ if($field_group['key'] != 'group_acfe_author')
46
+ continue;
47
+
48
+ if(!current_user_can($post_type_object->cap->edit_others_posts))
49
+ unset($field_groups[$key]);
50
+
51
+ }
52
+
53
+ return $field_groups;
54
+
55
+ }
56
+
57
+ /**
58
+ * Register Author Field
59
+ */
60
+ add_action('admin_init', 'acfe_author_field_group');
61
+ function acfe_author_field_group(){
62
+
63
+ // Get Post Types Locations
64
+ $get_post_types = get_post_types_by_support('author');
65
+ if(empty($get_post_types))
66
+ return;
67
+
68
+ // Set Locations
69
+ $locations = array();
70
+
71
+ foreach($get_post_types as $post_type){
72
+ $locations[] = array(
73
+ array(
74
+ 'param' => 'post_type',
75
+ 'operator' => '==',
76
+ 'value' => $post_type,
77
+ )
78
+ );
79
+ }
80
+
81
+ acf_add_local_field_group(array(
82
+ 'title' => __('Author'),
83
+ 'key' => 'group_acfe_author',
84
+ 'menu_order' => 0,
85
+ 'position' => 'side',
86
+ 'style' => 'default',
87
+ 'label_placement' => 'top',
88
+ 'instruction_placement' => 'label',
89
+ 'hide_on_screen' => '',
90
+ 'active' => 1,
91
+ 'description' => '',
92
+ 'location' => $locations,
93
+ 'fields' => array(
94
+ array(
95
+ 'label' => '',
96
+ 'key' => 'acfe_author',
97
+ 'name' => 'acfe_author',
98
+ 'type' => 'user',
99
+ 'instructions' => '',
100
+ 'required' => 0,
101
+ 'conditional_logic' => 0,
102
+ 'allow_null' => 0,
103
+ 'multiple' => 0,
104
+ 'return_format' => 'array',
105
+ 'role' => array('contributor', 'author', 'editor', 'administrator'),
106
+ 'wrapper' => array(
107
+ 'width' => '',
108
+ 'class' => '',
109
+ 'id' => '',
110
+ )
111
+ ),
112
+ )
113
+ ));
114
+
115
+ }
116
+
117
+ /**
118
+ * Remove Native WP Metabox
119
+ */
120
+ add_action('admin_menu','acfe_author_remove_default_metabox');
121
+ function acfe_author_remove_default_metabox(){
122
+
123
+ $get_post_types = get_post_types_by_support('author');
124
+ if(empty($get_post_types))
125
+ return;
126
+
127
+ foreach($get_post_types as $post_type){
128
+
129
+ if(in_array($post_type, array('attachment', 'revision', 'customize_changeset')))
130
+ continue;
131
+
132
+ // Remove Metabox
133
+ remove_meta_box('authordiv', $post_type, 'normal');
134
+
135
+ }
136
+
137
+ }
138
+
139
+ /**
140
+ * Prepare Default Value
141
+ */
142
+ add_filter('acf/prepare_field/name=acfe_author', 'acfe_author_prepare');
143
+ function acfe_author_prepare($field){
144
+
145
+ // Get Post ID
146
+ $post_id = get_the_ID();
147
+ if(empty($post_id))
148
+ return false;
149
+
150
+ // Check Post Type & Permissions
151
+ $post_type_object = get_post_type_object(get_post_type($post_id));
152
+ if(empty($post_type_object) || !current_user_can($post_type_object->cap->edit_others_posts))
153
+ return false;
154
+
155
+ // Set Default
156
+ $author_id = get_post_field('post_author', $post_id);
157
+ $field['value'] = $author_id;
158
+
159
+ return $field;
160
+
161
+ }
162
+
163
+ /**
164
+ * Save Post Action
165
+ */
166
+ add_action('acf/save_post', 'acfe_author_post_save', 0);
167
+ function acfe_author_post_save($post_id){
168
+
169
+ // Check Field Exists
170
+ if(!isset($_POST['acf']['acfe_author']))
171
+ return;
172
+
173
+ // Check Post Type & Permissions
174
+ $post_type_object = get_post_type_object(get_post_type($post_id));
175
+ if(empty($post_type_object) || !current_user_can($post_type_object->cap->edit_others_posts))
176
+ return;
177
+
178
+ // Set & Validate Author
179
+ $author_id = (int) $_POST['acf']['acfe_author'];
180
+ if(!get_user_by('ID', $author_id))
181
+ return;
182
+
183
+ // Update Post Author
184
+ wp_update_post(array(
185
+ 'ID' => $post_id,
186
+ 'post_author' => $author_id
187
+ ));
188
+
189
+ }
190
+
191
+ /**
192
+ * Bypass Metadata Update
193
+ */
194
+ add_filter('acf/pre_update_value', 'acfe_author_meta_update', 10, 4);
195
+ function acfe_author_meta_update($return, $value, $post_id, $field){
196
+ if($field['name'] == 'acfe_author')
197
+ return false;
198
+
199
+ return $return;
200
+ }
includes/modules/dynamic-post-type.php CHANGED
@@ -20,8 +20,7 @@ function acfe_dpt_register(){
20
  'supports' => array('custom-fields'),
21
  'hierarchical' => false,
22
  'public' => false,
23
- //'show_ui' => true,
24
- 'show_ui' => 'ACFE', // Hack to show_ui, but do not list in get_post_types() ie: ACF field group location
25
  'show_in_menu' => 'tools.php',
26
  'menu_icon' => 'dashicons-layout',
27
  'show_in_admin_bar' => false,
@@ -55,6 +54,28 @@ function acfe_dpt_registers(){
55
 
56
  }
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  /**
59
  * Dynamic Post Type Save
60
  */
20
  'supports' => array('custom-fields'),
21
  'hierarchical' => false,
22
  'public' => false,
23
+ 'show_ui' => true,
 
24
  'show_in_menu' => 'tools.php',
25
  'menu_icon' => 'dashicons-layout',
26
  'show_in_admin_bar' => false,
54
 
55
  }
56
 
57
+ /**
58
+ * ACF Exclude Dynamic Post Type from available post types
59
+ */
60
+ add_filter('acf/get_post_types', 'acfe_dpt_exclude', 10, 2);
61
+ function acfe_dpt_exclude($post_types, $args){
62
+
63
+ if(empty($post_types))
64
+ return $post_types;
65
+
66
+ foreach($post_types as $k => $post_type){
67
+
68
+ if($post_type != 'acfe-dpt')
69
+ continue;
70
+
71
+ unset($post_types[$k]);
72
+
73
+ }
74
+
75
+ return $post_types;
76
+
77
+ }
78
+
79
  /**
80
  * Dynamic Post Type Save
81
  */
includes/modules/dynamic-taxonomy.php CHANGED
@@ -20,8 +20,7 @@ function acfe_dt_register(){
20
  'supports' => array('custom-fields'),
21
  'hierarchical' => false,
22
  'public' => false,
23
- //'show_ui' => true,
24
- 'show_ui' => 'ACFE', // Hack to show_ui, but do not list in get_post_types() ie: ACF field group location
25
  'show_in_menu' => 'tools.php',
26
  'menu_icon' => 'dashicons-layout',
27
  'show_in_admin_bar' => false,
@@ -61,6 +60,28 @@ function acfe_dt_registers(){
61
 
62
  }
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  /**
65
  * Dynamic Taxonomy Save
66
  */
20
  'supports' => array('custom-fields'),
21
  'hierarchical' => false,
22
  'public' => false,
23
+ 'show_ui' => true,
 
24
  'show_in_menu' => 'tools.php',
25
  'menu_icon' => 'dashicons-layout',
26
  'show_in_admin_bar' => false,
60
 
61
  }
62
 
63
+ /**
64
+ * ACF Exclude Dynamic Taxonomy from available post types
65
+ */
66
+ add_filter('acf/get_post_types', 'acfe_dt_exclude', 10, 2);
67
+ function acfe_dt_exclude($post_types, $args){
68
+
69
+ if(empty($post_types))
70
+ return $post_types;
71
+
72
+ foreach($post_types as $k => $post_type){
73
+
74
+ if($post_type != 'acfe-dt')
75
+ continue;
76
+
77
+ unset($post_types[$k]);
78
+
79
+ }
80
+
81
+ return $post_types;
82
+
83
+ }
84
+
85
  /**
86
  * Dynamic Taxonomy Save
87
  */
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: acf, custom fields, meta, admin, fields, form, repeater, content
5
  Requires at least: 4.9
6
  Tested up to: 5.1.1
7
  Requires PHP: 5.6
8
- Stable tag: 0.5.5.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -71,6 +71,19 @@ Quick view of field groups keys
71
 
72
  == Fields ==
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  * **Advanced validation**
75
  A more sophisticated validation conditions (AND/OR) with custom error messages in the post edition screen.
76
 
@@ -101,7 +114,7 @@ A slug text input (ie: `my-text-input`)
101
  == ACF Settings ==
102
 
103
  * **Settings page**
104
- Display all ACF settings in one page
105
 
106
  == Dynamic Post Types ==
107
 
@@ -120,6 +133,10 @@ Create and manage taxonomies from your WordPress administration (Tools > Taxonom
120
  * Manage Posts per page, order by and order for the taxonomy administration screen
121
  * Set custom taxonomy template (ie: `my-taxonomy.php`) instead of the native `taxonomy-{taxonomy}.php`
122
 
 
 
 
 
123
  == Options ==
124
 
125
  BETA: Manage all WordPress options from Settings > Options.
@@ -142,6 +159,20 @@ BETA: Manage all WordPress options from Settings > Options.
142
 
143
  Create a folder `/acfe-php/` in your theme. Go to your field group administration, check to 'Sync PHP' option in the sidebar and save the field group.
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  == Screenshots ==
146
 
147
  1. Field Groups List
@@ -155,6 +186,14 @@ Create a folder `/acfe-php/` in your theme. Go to your field group administratio
155
 
156
  == Changelog ==
157
 
 
 
 
 
 
 
 
 
158
  = 0.5.5.1 =
159
  * Module: Dynamic Taxonomy - Fixed Terms PHP warning
160
  * General: Plugin readme
5
  Requires at least: 4.9
6
  Tested up to: 5.1.1
7
  Requires PHP: 5.6
8
+ Stable tag: 0.5.8
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
71
 
72
  == Fields ==
73
 
74
+ * **Bidirectional fields**
75
+ An advanced bidirectional setting (also called post-to-post) is available for the following fields: Relationship, Post object, User & Taxonomy terms.
76
+ Fields will work bidirectionally and automatically updating each others. Works in groups & clones (prefixed field names must be turned off).
77
+
78
+ Usage example:
79
+ - Create a field group "Page: Relation" displaying on the post type: page
80
+ - Inside it, create a relationship field, allowing the post type: post
81
+ - Create an another field group "Post: Relation" displaying on the post type: post
82
+ - Inside it, create a relationship field, allowing the post type: page
83
+ - Activate the "Bidirectional" setting and select the "Page: Relation" relationship field
84
+ - Edit any page, and select any post of the post type post
85
+ - The page is now also saved in the said post
86
+
87
  * **Advanced validation**
88
  A more sophisticated validation conditions (AND/OR) with custom error messages in the post edition screen.
89
 
114
  == ACF Settings ==
115
 
116
  * **Settings page**
117
+ Display all ACF settings in one page.
118
 
119
  == Dynamic Post Types ==
120
 
133
  * Manage Posts per page, order by and order for the taxonomy administration screen
134
  * Set custom taxonomy template (ie: `my-taxonomy.php`) instead of the native `taxonomy-{taxonomy}.php`
135
 
136
+ == Ajax Author Box ==
137
+
138
+ Replaced the native WP Author Metabox with a dynamic version allowing to manage thousands of users without slowing down the post administration.
139
+
140
  == Options ==
141
 
142
  BETA: Manage all WordPress options from Settings > Options.
159
 
160
  Create a folder `/acfe-php/` in your theme. Go to your field group administration, check to 'Sync PHP' option in the sidebar and save the field group.
161
 
162
+ = How the bidirectional field setting works? =
163
+
164
+ An advanced bidirectional setting (also called post-to-post) is available for the following fields: Relationship, Post object, User & Taxonomy terms.
165
+ Fields will work bidirectionally and automatically updating each others. Works in groups & clones (prefixed field names must be turned off).
166
+
167
+ Usage example:
168
+ * Create a field group "Page: Relation" displaying on the post type: page
169
+ * Inside it, create a relationship field, allowing the post type: post
170
+ * Create an another field group "Post: Relation" displaying on the post type: post
171
+ * Inside it, create a relationship field, allowing the post type: page
172
+ * Activate the "Bidirectional" setting and select the "Page: Relation" relationship field
173
+ * Edit any page, and select any post of the post type post
174
+ * The page is now also saved in the said post
175
+
176
  == Screenshots ==
177
 
178
  1. Field Groups List
186
 
187
  == Changelog ==
188
 
189
+ = 0.5.8 =
190
+ * Field: Added Bidirectional setting for the following fields: relationship, post object, user & taxonomy terms
191
+ * Module: Added 'Ajax Author' field to replace the native WP Author Meta Box
192
+ * Module: Dynamic Post Type & Taxonomy - Better exclusion from ACF post types selection (location & fields)
193
+ * General: Fixed ACF Select2 CSS to fit ACF input styles (border-radius, border-color & line-height)
194
+ * General: Renamed ACF-Extended assets for better readability in the browser console resources tab
195
+ * Compatibility: Removed the Taxonomy Order submenu created under ACF for the taxonomy 'Field Group Category' by the plugin 'Category Order and Taxonomy Terms Order'
196
+
197
  = 0.5.5.1 =
198
  * Module: Dynamic Taxonomy - Fixed Terms PHP warning
199
  * General: Plugin readme