├── .gitignore ├── screenshot-1.png ├── composer.json ├── README.md ├── readme.txt └── acf-user-role-field-setting.php /.gitignore: -------------------------------------------------------------------------------- 1 | _notes 2 | *.LCK 3 | __assets 4 | -------------------------------------------------------------------------------- /screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hube2/acf-user-role-field-setting/master/screenshot-1.png -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hube2/acf-user-role-field-setting", 3 | "description": "acf-user-role-field-setting", 4 | "type": "wordpress-plugin", 5 | "authors": [ 6 | { 7 | "name": "John A. Huebner II" 8 | } 9 | ], 10 | "minimum-stability": "dev" 11 | } 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ACF User Role Field Setting 2 | 3 | ***This plugin requires Advanced Custom Fields (ACF) Version >= 5.5.0 4 | This plugin will not provide any functionality if ACF 5 is not installed and active. 5 | 6 | This plugin adds a field setting to all field types that allows for the selection of WP User Roles 7 | that should be allowed to manage the value of the field. Fields that the current user does not have 8 | permission to edit are removed from the field group when it's fields are loaded. 9 | 10 | ***Caution:*** It is possible to set a field so that it can never be edited by anyone. This can be done 11 | in several ways. The first example is easy, simply do not select any user role that can edit the field. 12 | The second example is less obvious. If you have a field that appears on "Posts" and you set this field 13 | so that only "Subscribers" can edit the field, since subscribers cannot by default edit a post in the 14 | admin, then you have effectively made this field uneditable. However, allowing only subscribers to edit 15 | a field could be useful on a front end form where you want extra field for subscribers that are not 16 | available to visitors that are not logged in. 17 | 18 | ### Exclude Field Types 19 | 20 | The Tab and Clone fields have been excluded from having the user role setting added to them. 21 | 22 | Most of the time it would not make sense for a tab field, unless all of the fields in the tab were set 23 | the same, in other words, removing a tab should remove all the fields in that tab. That's not something 24 | that I can do. You would need to enable the tab field and set the user role for the tab and all fields that should appear in the tab. 25 | 26 | I'm not sure about the clone field, I haven't worked with it much. You can test it out if you want and let me know what happens. 27 | 28 | There is a filter so that you can adjust the types of fields that are excluded 29 | ``` 30 | add_filter('acf/user_role_setting/exclude_field_types', 'user_role_setting_excluded_field_types'); 31 | function user_role_setting_excluded_field_types($exclude) { 32 | /* 33 | $exclude holds an array of field types to exclude from adding user role settings 34 | default value: 35 | $exclude = array('tab' => 'tab', 'clone' => 'clone'); 36 | */ 37 | 38 | // remove tab field from exclude 39 | if (isset($exclude['tab'])) { 40 | unset($exclude['tab']); 41 | } 42 | 43 | // add message field to exclude 44 | $exclude['message'] = 'message'; 45 | 46 | return $exclude; 47 | } 48 | ``` -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | === ACF User Role Field Setting === 2 | Contributors: Hube2 3 | Tags: acf, advanced custom fields, user role, setting, security, multisite 4 | Requires at least: 4.0 5 | Tested up to: 5.5 6 | Stable tag: 4.0.2 7 | License: GPLv2 or later 8 | License URI: http://www.gnu.org/licenses/gpl-2.0.html 9 | 10 | User Role Setting for ACF 11 | 12 | 13 | == Description == 14 | 15 | ***Warning: Support for Sub Fields Removed as of Version 4.0.0*** 16 | 17 | This is an add on plugin for Advanced Custom Fields (ACF) Version 5. 18 | 19 | ***This plugin will not provide any functionality if ACF5 is not installed.*** 20 | 21 | This plugin adds a field setting to all field types so that user roles allowed to edit the field can 22 | be selected. Only those roles selected for the field will be able to edit the field. 23 | 24 | 25 | == Installation == 26 | 27 | Install like any other plugin 28 | 29 | == Screenshots == 30 | 31 | 1. Field setting on example field 32 | 33 | 34 | == Frequently Asked Questions == 35 | 36 | Nothing yet 37 | 38 | == Other Notes == 39 | 40 | == Github Repository == 41 | 42 | This plugin is also on GitHub 43 | [https://github.com/Hube2/acf-user-role-field-setting](https://github.com/Hube2/acf-user-role-field-setting) 44 | 45 | == Excluded Field Types == 46 | 47 | Most of the time it would not make sense for a tab field, unless all of the fields in the tab were set the same, in other words, removing a tab should remove all the fields in that tab. That's not something that I can do at this point. 48 | 49 | I'm not sure about the clone field, I haven't worked with it much. You can test it out if you want. 50 | 51 | I have also removed support for repeater, group and flexible content fields because I cannot preserver the values of these fields if they are not editable in the ACF interface. Please note that I do not know what the effect of allowing user role settings on these fields will be. 52 | 53 | There is a filter so that you can adjust the types of fields that are excluded. Here is an example 54 | ` 55 | 'tab', 'clone' => 'clone'); 63 | */ 64 | 65 | // remove tab field from exclude 66 | if (isset($exclude['tab'])) { 67 | unset($exclude['tab']); 68 | } 69 | 70 | // add message field to exclude 71 | $exclude['message'] = 'message'; 72 | 73 | return $exclude; 74 | } 75 | 76 | ?> 77 | ` 78 | 79 | == Changelog == 80 | 81 | = 4.0.2 = 82 | * Fixed but caused by last change 83 | 84 | = 4.0.1 = 85 | * Validate exlcuded field types from filter is an array to prevent errors do to user filter rerurning invalid value. 86 | 87 | = 4.0.0 = 88 | * Removed support for repeater sub fields 89 | * Various bug fixes 90 | 91 | = 3.0.2 = 92 | * Changed super admin test permission from "update_core" to "manage_network" 93 | 94 | = 3.0.1 = 95 | * Corrected issue with getting property of non object 96 | * Corrected issues with fields that have array values 97 | * Re-enabled repeaters 98 | 99 | = 3.0.0 = 100 | * removed support for ACF < Version 5.5.0 101 | * removed user role setting from repeater, group and flexibe content fields (these can be re-enabled using available filter, however doing so may not be safe) 102 | * corrected issue with repeater sub field reordering 103 | * no longer filtering $_POST to corect repeater reordering issue 104 | 105 | = 2.1.15 = 106 | * added composer support 107 | * removed donation nag 108 | 109 | = 2.1.14 = 110 | * resolving version # issue with WP SVN 111 | 112 | = 2.1.13 = 113 | * corrected issue w/deleting repeater rows when sub fields is removed 114 | * Correct issue w/ACF 5.7.0 115 | 116 | = 2.1.12 = 117 | * minor code reorganiztion in prepare_field filter 118 | * other code cleanup 119 | * reverted to acf/save_post for $_POST filtering (corrected in ACF) 120 | * corrected an issue with repeater sub fields when reordered 121 | * PLEASE NOTE THAT VERSION 3 WILL REMOVE SUPPORT FOR ACF < 5.5.0 122 | 123 | = 2.1.11 = 124 | * corrected issue - field values not saved when fields set for specifice user roles 125 | 126 | = 2.1.10 = 127 | * corrected warning call_user_func_array() expects parameter 1 to be a valid callback 128 | 129 | = 2.1.9 = 130 | * changed plugins_loaded funtion to run on after_setup_theme to ensure that if ACF is loaded as part 131 | or the theme that it is loaded before running 132 | * changed when $_POST filtering runs to deal with changes in ACF >= 5.6; 133 | 134 | = 2.1.8 = 135 | * corrected bug w/ACF version >= 5.6.0 136 | 137 | = 2.1.7 = 138 | * correct call to undefined function acf_get_setting() 139 | 140 | = 2.1.6 = 141 | * corrects issue with setting not appearing during js field initialization cause by 2.1.5 update 142 | 143 | = 2.1.5 = 144 | * altered field setting initialization to deal with non-standard ACF add on field types that do not initialize their fields when they are supposed on the correct ACF hooks 145 | 146 | = 2.1.4 = 147 | * removed github updater support 148 | 149 | = 2.1.3 = 150 | * initial release as a WordPress Plugin 151 | 152 | -------------------------------------------------------------------------------- /acf-user-role-field-setting.php: -------------------------------------------------------------------------------- 1 | 'tab' 24 | ); 25 | 26 | public function __construct() { 27 | add_action('init', array($this, 'init'), 1); 28 | add_action('acf/init', array($this, 'add_actions')); 29 | add_action('after_setup_theme', array($this, 'after_setup_theme')); 30 | } // end public function __construct 31 | 32 | public function after_setup_theme() { 33 | // check the ACF version 34 | // if >= 5.5.0 use the acf/prepare_field hook to remove fields 35 | if (!function_exists('acf_get_setting')) { 36 | // acf is not installed/active 37 | return; 38 | } 39 | $acf_version = acf_get_setting('version'); 40 | if (version_compare($acf_version, '5.5.0', '>=')) { 41 | add_filter('acf/prepare_field', array($this, 'prepare_field'), 99); 42 | } 43 | } // end public function after_setup_theme 44 | 45 | private function user_can_edit($field) { 46 | $exclude = apply_filters('acf/user_role_setting/exclude_field_types', $this->exclude_field_types); 47 | if (is_array($exclude) && in_array($field['type'], $exclude)) { 48 | return true; 49 | } 50 | if (isset($field['user_roles'])) { 51 | if (!empty($field['user_roles']) && is_array($field['user_roles'])) { 52 | foreach ($field['user_roles'] as $role) { 53 | if ($role == 'all' || in_array($role, $this->current_user)) { 54 | return true; 55 | } 56 | } 57 | } else { 58 | // no user roles have been selected for this field 59 | // it will never be displayed, this is probably an error 60 | return false; 61 | } 62 | } else { 63 | // user roles not set for this field 64 | // this field was created before this plugin was in use 65 | // or user roles is otherwise disabled for this field 66 | return true; 67 | } 68 | return false; 69 | } // end private function user_can_edit 70 | 71 | public function prepare_field($field) { 72 | global $post; 73 | if (is_a($post, 'WP_Post')) { 74 | $post_type = get_post_type($post->ID); 75 | if ($post_type == 'acf-field' || $post_type == 'acf-field-group') { 76 | return $field; 77 | } 78 | } 79 | //echo '
'; print_r($field); echo ''; 80 | if ($this->user_can_edit($field)) { 81 | return $field; 82 | } 83 | //$this->output_hidden_fields($field['name'], $field['value']); 84 | return false; 85 | } // end public function prepare_field 86 | 87 | private function output_hidden_fields($field_name, $value) { 88 | // outputting of hidden fields removed as of 4.0.0 89 | if (is_array($value)) { 90 | foreach ($value as $i => $v) { 91 | $this->output_hidden_fields($field_name.'['.$i.']', $v); 92 | } 93 | } else { 94 | ?>get_roles(); 100 | $this->current_user_roles(); 101 | } // end public function init 102 | 103 | public function add_actions() { 104 | if (!function_exists('acf_get_setting')) { 105 | return; 106 | } 107 | $acf_version = acf_get_setting('version'); 108 | if (version_compare($acf_version, '5.5.0', '<')) { 109 | return; 110 | } 111 | $exclude = apply_filters('acf/user_role_setting/exclude_field_types', $this->exclude_field_types); 112 | $sections = acf_get_field_types(); 113 | if (version_compare($acf_version, '5.6.0', '>=') && version_compare($acf_version, '5.7.0', '<')) { 114 | foreach ($sections as $section) { 115 | foreach ($section as $type => $label) { 116 | if (empty($exclude[$type])) { 117 | add_action('acf/render_field_settings/type='.$type, array($this, 'render_field_settings'), 1); 118 | } 119 | } 120 | } 121 | } else { 122 | // >= 5.5.0 || < 5.6.0 123 | foreach ($sections as $type => $settings) { 124 | if (empty($exclude[$type])) { 125 | add_action('acf/render_field_settings/type='.$type, array($this, 'render_field_settings'), 1); 126 | } 127 | } 128 | } 129 | } // end public function add_actions 130 | 131 | private function current_user_roles() { 132 | global $current_user; 133 | if (is_object($current_user) && isset($current_user->roles)) { 134 | $this->current_user = $current_user->roles; 135 | } 136 | if (is_multisite() && current_user_can('manage_network')) { 137 | $this->current_user[] = 'super_admin'; 138 | } 139 | } // end private function current_user_roles 140 | 141 | private function get_roles() { 142 | if (count($this->choices)) { 143 | return; 144 | } 145 | global $wp_roles; 146 | $choices = array('all' => 'All'); 147 | if (is_multisite()) { 148 | $choices['super_admin'] = 'Super Admin'; 149 | } 150 | foreach ($wp_roles->roles as $role => $settings) { 151 | $choices[$role] = $settings['name']; 152 | } 153 | $this->choices = $choices; 154 | } // end private function get_roles 155 | 156 | public function render_field_settings($field) { 157 | $sub_field = false; 158 | $parent = $field['parent']; 159 | if (is_numeric($parent)) { 160 | $post = get_post($parent); 161 | if (!is_a($post, 'WP_Post') || $post->post_type != 'acf-field-group') { 162 | $sub_field = true; 163 | } 164 | } elseif (substr($field['parent'], 0, 6) != 'group_') { 165 | $sub_field = true; 166 | } 167 | if ($sub_field) { 168 | return; 169 | } 170 | $args = array( 171 | 'type' => 'checkbox', 172 | 'label' => 'User Roles', 173 | 'name' => 'user_roles', 174 | 'instructions' => 'Select the User Roles that are allowed to view and edit this field.'. 175 | ' This field will be removed for any user type not selected.'. 176 | ' If nothing is selected then this field will never be'. 177 | ' included in the field group.', 178 | 'required' => 0, 179 | 'default_value' => array('all'), 180 | 'choices' => $this->choices, 181 | 'layout' => 'horizontal' 182 | ); 183 | acf_render_field_setting($field, $args, false); 184 | } // end public function render_field_settings 185 | 186 | } // end class acf_user_type_field_settings 187 | 188 | ?> --------------------------------------------------------------------------------