1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Carbon_Fields\Container; |
4
|
|
|
|
5
|
|
|
use Carbon_Fields\Datastore\Meta_Datastore; |
6
|
|
|
use Carbon_Fields\Datastore\User_Meta_Datastore; |
7
|
|
|
|
8
|
|
|
class User_Meta_Container extends Container { |
9
|
|
|
protected $user_id; |
10
|
|
|
|
11
|
|
|
public $settings = array( |
12
|
|
|
'show_on' => array( |
13
|
|
|
'role' => array(), |
14
|
|
|
), |
15
|
|
|
'show_for' => array( |
16
|
|
|
'capabilities' => array( 'edit_users' ), |
17
|
|
|
), |
18
|
|
|
); |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Create a new user meta container |
22
|
|
|
* |
23
|
|
|
* @param string $title Unique title of the container |
24
|
|
|
**/ |
25
|
|
|
public function __construct( $title ) { |
26
|
|
|
parent::__construct( $title ); |
27
|
|
|
|
28
|
|
|
if ( ! $this->get_datastore() ) { |
29
|
|
|
$this->set_datastore( new User_Meta_Datastore() ); |
30
|
|
|
} |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* Bind attach() and save() to the appropriate WordPress actions. |
35
|
|
|
**/ |
36
|
|
|
public function init() { |
37
|
|
|
add_action( 'admin_init', array( $this, '_attach' ) ); |
38
|
|
|
add_action( 'profile_update', array( $this, '_save' ), 10, 1 ); |
39
|
|
|
add_action( 'user_register', array( $this, '_save' ), 10, 1 ); |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Perform save operation after successful is_valid_save() check. |
44
|
|
|
* The call is propagated to all fields in the container. |
45
|
|
|
* |
46
|
|
|
* @param int $user_id ID of the user against which save() is ran |
47
|
|
|
**/ |
48
|
|
|
public function save( $user_id ) { |
49
|
|
|
// Unhook action to garantee single save |
50
|
|
|
remove_action( 'profile_update', array( $this, '_save' ) ); |
51
|
|
|
|
52
|
|
|
$this->set_user_id( $user_id ); |
53
|
|
|
|
54
|
|
|
foreach ( $this->fields as $field ) { |
55
|
|
|
$field->set_value_from_input(); |
56
|
|
|
$field->save(); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
do_action( 'carbon_after_save_user_meta', $user_id ); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Checks whether the current request is valid |
64
|
|
|
* |
65
|
|
|
* @return bool |
66
|
|
|
**/ |
67
|
|
|
public function is_valid_save( $user_id = 0 ) { |
68
|
|
View Code Duplication |
if ( ! isset( $_REQUEST[ $this->get_nonce_name() ] ) || ! wp_verify_nonce( $_REQUEST[ $this->get_nonce_name() ], $this->get_nonce_name() ) ) { // Input var okay. |
|
|
|
|
69
|
|
|
return false; |
70
|
|
|
} else if ( ! $this->is_valid_attach() ) { |
71
|
|
|
return false; |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
return $this->is_valid_save_conditions( $user_id ); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Perform checks whether the current save() request is valid |
79
|
|
|
* |
80
|
|
|
* @param int $user_id ID of the user against which save() is ran |
81
|
|
|
* @return bool |
82
|
|
|
**/ |
83
|
|
|
public function is_valid_save_conditions( $user_id ) { |
84
|
|
|
$valid = true; |
85
|
|
|
$user = get_userdata( $user_id ); |
86
|
|
|
|
87
|
|
|
if ( empty( $user->roles ) ) { |
88
|
|
|
return; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
// Check user role |
92
|
|
|
if ( ! empty( $this->settings['show_on']['role'] ) ) { |
93
|
|
|
$allowed_roles = (array) $this->settings['show_on']['role']; |
94
|
|
|
|
95
|
|
|
// array_shift removed the returned role from the $user_profile->roles |
96
|
|
|
// $roles_to_shift prevents changing of the $user_profile->roles variable |
97
|
|
|
$roles_to_shift = $user->roles; |
98
|
|
|
$profile_role = array_shift( $roles_to_shift ); |
99
|
|
|
if ( ! in_array( $profile_role, $allowed_roles ) ) { |
100
|
|
|
$valid = false; |
101
|
|
|
} |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
return $valid; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Show the container only on users who have the $role role. |
109
|
|
|
* |
110
|
|
|
* @param string $role |
111
|
|
|
* @return object $this |
112
|
|
|
**/ |
113
|
|
|
public function show_on_user_role( $role ) { |
114
|
|
|
$this->settings['show_on']['role'] = (array) $role; |
115
|
|
|
|
116
|
|
|
return $this; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Show the container only for users who have either capabilities or roles setup |
121
|
|
|
* |
122
|
|
|
* @param array $show_for |
123
|
|
|
* @return object $this |
124
|
|
|
**/ |
125
|
|
|
public function show_for( $show_for ) { |
126
|
|
|
// Filter empty values and unexpected attributes |
127
|
|
|
$show_for = shortcode_atts( $show_for , array( |
128
|
|
|
'capabilities' => array(), |
129
|
|
|
'roles' => array(), |
130
|
|
|
) ); |
131
|
|
|
|
132
|
|
|
if ( empty( $show_for ) ) { |
133
|
|
|
return $this; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
$this->settings['show_for'] = $show_for; |
137
|
|
|
|
138
|
|
|
return $this; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* Add the container to the user |
143
|
|
|
**/ |
144
|
|
|
public function attach() { |
145
|
|
|
add_action( 'show_user_profile', array( $this, 'render' ), 10, 1 ); |
146
|
|
|
add_action( 'edit_user_profile', array( $this, 'render' ), 10, 1 ); |
147
|
|
|
add_action( 'user_new_form', array( $this, 'render' ), 10, 1 ); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* Whether we're on the user profile page |
152
|
|
|
**/ |
153
|
|
|
public function is_profile_page() { |
154
|
|
|
global $pagenow; |
155
|
|
|
|
156
|
|
|
return $pagenow === 'profile.php' || $pagenow === 'user-new.php' || $pagenow === 'user-edit.php'; |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* Perform checks whether the container should be attached during the current request |
161
|
|
|
* |
162
|
|
|
* @return bool True if the container is allowed to be attached |
163
|
|
|
**/ |
164
|
|
|
public function is_valid_attach() { |
165
|
|
|
$user = wp_get_current_user(); |
166
|
|
|
|
167
|
|
|
$is_valid_capability = true; |
168
|
|
View Code Duplication |
if ( !empty( $this->settings['show_for']['capabilities'] ) ) { |
|
|
|
|
169
|
|
|
$is_valid_capability = array_intersect( (array) $this->settings['show_for']['capabilities'], $user->allcaps ); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
$is_valid_role = true; |
173
|
|
View Code Duplication |
if ( !empty( $this->settings['show_for']['roles'] ) ) { |
|
|
|
|
174
|
|
|
$is_valid_role = array_intersect( (array) $this->settings['show_for']['roles'], $user->roles ); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
if ( ! $this->is_profile_page() || ! $is_valid_capability || ! $is_valid_role ) { |
178
|
|
|
return false; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
return true; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* Output the container markup |
186
|
|
|
**/ |
187
|
|
|
public function render( $user_profile = null ) { |
188
|
|
|
$profile_role = ''; |
189
|
|
|
|
190
|
|
|
if ( is_object( $user_profile ) ) { |
191
|
|
|
$this->set_user_id( $user_profile->ID ); |
192
|
|
|
|
193
|
|
|
// array_shift removed the returned role from the $user_profile->roles |
194
|
|
|
// $roles_to_shift prevents changing of the $user_profile->roles variable |
195
|
|
|
$roles_to_shift = $user_profile->roles; |
196
|
|
|
$profile_role = array_shift( $roles_to_shift ); |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
include \Carbon_Fields\DIR . '/templates/Container/user_meta.php'; |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* Set the user ID the container will operate with. |
204
|
|
|
* |
205
|
|
|
* @param int $user_id |
206
|
|
|
**/ |
207
|
|
|
public function set_user_id( $user_id ) { |
208
|
|
|
$this->user_id = $user_id; |
209
|
|
|
$this->store->set_id( $user_id ); |
210
|
|
|
} |
211
|
|
|
} |
212
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.