PluginProbe ʕ •ᴥ•ʔ
Advanced Access Manager – Access Governance for WordPress / 5.3
Advanced Access Manager – Access Governance for WordPress v5.3
6.8.4 6.8.5 6.9.0 6.9.1 6.9.10 6.9.11 6.9.12 6.9.13 6.9.14 6.9.15 6.9.16 6.9.17 6.9.18 6.9.19 6.9.2 6.9.20 6.9.21 6.9.22 6.9.23 6.9.24 6.9.25 6.9.26 6.9.27 6.9.28 6.9.29 6.9.3 6.9.30 6.9.31 6.9.32 6.9.33 6.9.34 6.9.35 6.9.36 6.9.37 6.9.38 6.9.39 6.9.4 6.9.41 6.9.42 6.9.43 6.9.44 6.9.45 6.9.46 6.9.47 6.9.48 6.9.49 6.9.5 6.9.51 6.9.6 6.9.7 6.9.8 6.9.9 7.0.0 7.0.0-alpha.6 7.0.0-alpha.7 7.0.0-beta.1 7.0.0-rc1 7.0.0-rc2 7.0.0-rc3 7.0.1 7.0.10 7.0.11 7.0.2 7.0.3 7.0.4 7.0.5 7.0.6 7.0.7 7.0.8 7.0.9 7.1.0 7.1.1 trunk 3.0 4.0 4.0.1 4.1 4.2 4.3 4.4 4.4.1 4.5 4.6 4.6.1 4.6.2 4.7 4.7.1 4.7.2 4.7.5 4.7.6 4.8 4.8.1 4.9 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 4.9.5.1 4.9.5.2 5.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1 5.1.1 5.10 5.11 5.2 5.2.1 5.2.5 5.2.6 5.2.7 5.3 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.4 5.4.1 5.4.2 5.4.3 5.4.3.1 5.4.3.2 5.5 5.5.1 5.5.2 5.6 5.6.1 5.6.1.1 5.7 5.7.1 5.7.2 5.7.3 5.8 5.8.1 5.8.2 5.8.3 5.9 5.9.1 5.9.1.1 5.9.2 5.9.2.1 5.9.3 5.9.4 5.9.5 5.9.6 5.9.6.1 5.9.6.2 5.9.6.3 5.9.7 5.9.7.1 5.9.7.2 5.9.7.3 5.9.8 5.9.8.1 5.9.9 5.9.9.1 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.1.0 6.1.1 6.2.0 6.2.1 6.2.2 6.3.0 6.3.1 6.3.2 6.3.3 6.4.0 6.4.1 6.4.2 6.4.3 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.6.0 6.6.1 6.6.2 6.6.3 6.6.4 6.7.0 6.7.1 6.7.2 6.7.3 6.7.4 6.7.5 6.7.6 6.7.7 6.7.8 6.7.9 6.8.0 6.8.1 6.8.2 6.8.3
advanced-access-manager / Application / Backend / Filter.php
advanced-access-manager / Application / Backend Last commit date
Feature 8 years ago View 8 years ago Widget 8 years ago phtml 8 years ago Authorization.php 8 years ago Feature.php 8 years ago Filter.php 8 years ago Manager.php 8 years ago Subject.php 8 years ago View.php 8 years ago
Filter.php
434 lines
1 <?php
2
3 /**
4 * ======================================================================
5 * LICENSE: This file is subject to the terms and conditions defined in *
6 * file 'license.txt', which is part of this source code package. *
7 * ======================================================================
8 */
9
10 /**
11 * Backend manager
12 *
13 * @package AAM
14 * @author Vasyl Martyniuk <vasyl@vasyltech.com>
15 */
16 class AAM_Backend_Filter {
17
18 /**
19 * Instance of itself
20 *
21 * @var AAM_Backend_Filter
22 *
23 * @access private
24 */
25 private static $_instance = null;
26
27 /**
28 * pre_get_posts flag
29 */
30 protected $skip = false;
31
32 /**
33 * Initialize backend filters
34 *
35 * @return void
36 *
37 * @access protected
38 */
39 protected function __construct() {
40 //menu filter
41 add_filter('parent_file', array($this, 'filterMenu'), 999, 1);
42
43 //manager WordPress metaboxes
44 add_action("in_admin_header", array($this, 'metaboxes'), 999);
45
46 //control admin area
47 add_action('admin_notices', array($this, 'adminNotices'), -1);
48 add_action('network_admin_notices', array($this, 'adminNotices'), -1);
49 add_action('user_admin_notices', array($this, 'adminNotices'), -1);
50
51 //admin bar
52 add_action('wp_before_admin_bar_render', array($this, 'filterAdminBar'), 999);
53
54 //post restrictions
55 add_filter('page_row_actions', array($this, 'postRowActions'), 10, 2);
56 add_filter('post_row_actions', array($this, 'postRowActions'), 10, 2);
57
58 //default category filder
59 add_filter('pre_option_default_category', array($this, 'filterDefaultCategory'));
60
61 //add post filter for LIST restriction
62 if (!AAM::isAAM() && AAM_Core_Config::get('check-post-visibility', true)) {
63 add_filter('found_posts', array($this, 'filterPostCount'), 999, 2);
64 }
65
66 add_action('pre_post_update', array($this, 'prePostUpdate'), 10, 2);
67
68 //user/role filters
69 if (!is_multisite() || !is_super_admin()) {
70 add_filter('editable_roles', array($this, 'filterRoles'));
71 add_action('pre_get_users', array($this, 'filterUserQuery'), 999);
72 add_filter('views_users', array($this, 'filterViews'));
73 }
74
75 // Check if user has ability to perform certain task based on provided
76 // capability and meta data
77 if (AAM_Core_Config::get('backend-access-control', true)) {
78 add_filter(
79 'user_has_cap',
80 array(AAM_Shared_Manager::getInstance(), 'userHasCap'),
81 999,
82 3
83 );
84 }
85
86 AAM_Backend_Authorization::bootstrap(); //bootstrap backend authorization
87 }
88
89 /**
90 * Filter the Admin Menu
91 *
92 * @param string $parent_file
93 *
94 * @return string
95 *
96 * @access public
97 */
98 public function filterMenu($parent_file) {
99 //filter admin menu
100 AAM::getUser()->getObject('menu')->filter();
101
102 return $parent_file;
103 }
104
105 /**
106 * Handle metabox initialization process
107 *
108 * @return void
109 *
110 * @access public
111 */
112 public function metaboxes() {
113 global $post;
114
115 //make sure that nobody is playing with screen options
116 if (is_a($post, 'WP_Post')) {
117 $screen = $post->post_type;
118 } elseif ($screen_object = get_current_screen()) {
119 $screen = $screen_object->id;
120 } else {
121 $screen = '';
122 }
123
124 if (AAM_Core_Request::get('init') != 'metabox') {
125 AAM::getUser()->getObject('metabox')->filterBackend($screen);
126 }
127 }
128
129 /**
130 * Manage notifications visibility
131 *
132 * @return void
133 *
134 * @access public
135 */
136 public function adminNotices() {
137 if (AAM_Core_API::capabilityExists('show_admin_notices')) {
138 if (!AAM::getUser()->hasCapability('show_admin_notices')) {
139 remove_all_actions('admin_notices');
140 remove_all_actions('network_admin_notices');
141 remove_all_actions('user_admin_notices');
142 }
143 }
144 }
145
146 /**
147 * Filter top admin bar
148 *
149 * The filter will be performed based on the Backend Menu access settings
150 *
151 * @return void
152 *
153 * @access public
154 * @global WP_Admin_Bar $wp_admin_bar
155 */
156 public function filterAdminBar() {
157 global $wp_admin_bar;
158
159 $menu = AAM::getUser()->getObject('menu');
160 foreach($wp_admin_bar->get_nodes() as $id => $node) {
161 if (!empty($node->href)) {
162 $suffix = str_replace(admin_url(), '', $node->href);
163 if ($menu->has($suffix, true)) {
164 if (empty($node->parent) && $this->hasChildren($id)) { //root level
165 $node->href = '#';
166 $wp_admin_bar->add_node($node);
167 } else {
168 $wp_admin_bar->remove_menu($id);
169 }
170 }
171 }
172 }
173 }
174
175 /**
176 * Check if specified top bar item has children
177 *
178 * @param string $id
179 *
180 * @return boolean
181 *
182 * @access protected
183 * @global WP_Admin_Bar $wp_admin_bar
184 */
185 protected function hasChildren($id) {
186 global $wp_admin_bar;
187
188 $has = false;
189
190 foreach($wp_admin_bar->get_nodes() as $node) {
191 if ($node->parent == $id) {
192 $has = true;
193 break;
194 }
195 }
196
197 return $has;
198 }
199
200 /**
201 * Post Quick Menu Actions Filtering
202 *
203 * @param array $actions
204 * @param WP_Post $post
205 *
206 * @return array
207 *
208 * @access public
209 */
210 public function postRowActions($actions, $post) {
211 $object = AAM::getUser()->getObject('post', $post->ID, $post);
212
213 //filter edit menu
214 if (!$this->isAllowed('backend.edit', $object)) {
215 if (isset($actions['edit'])) {
216 unset($actions['edit']);
217 }
218 if (isset($actions['inline hide-if-no-js'])) {
219 unset($actions['inline hide-if-no-js']);
220 }
221 }
222
223 //filter delete menu
224 if (!$this->isAllowed('backend.delete', $object)) {
225 if (isset($actions['trash'])) { unset($actions['trash']); }
226 if (isset($actions['delete'])) { unset($actions['delete']); }
227 }
228
229 //filter edit menu
230 if (!$this->isAllowed('backend.publish', $object)) {
231 if (isset($actions['inline hide-if-no-js'])) {
232 unset($actions['inline hide-if-no-js']);
233 }
234 }
235
236 return $actions;
237 }
238
239 /**
240 * Check if action is allowed
241 *
242 * This method will take in consideration also *_others action
243 *
244 * @param string $action
245 * @param AAM_Core_Object_Post $object
246 *
247 * @return boolean
248 *
249 * @access protected
250 */
251 protected function isAllowed($action, $object) {
252 $edit = $object->has($action);
253 $others = $object->has("{$action}_others");
254 $author = ($object->post_author == get_current_user_id());
255
256 return ($edit || ($others && !$author)) ? false : true;
257 }
258
259 /**
260 * Override default category if defined
261 *
262 * @param type $category
263 *
264 * @return int
265 *
266 * @access public
267 * @staticvar type $default
268 */
269 public function filterDefaultCategory($category) {
270 static $default = null;
271
272 if (is_null($default)) {
273 //check if user category is defined
274 $id = get_current_user_id();
275 $default = AAM_Core_Config::get('default.category.user.' . $id , null);
276 $roles = AAM::getUser()->roles;
277
278 if (is_null($default) && count($roles)) {
279 $default = AAM_Core_Config::get(
280 'default.category.role.' . array_shift($roles), false
281 );
282 }
283 }
284
285 return ($default ? $default : $category);
286 }
287
288 /**
289 * Filter post count for pagination
290 *
291 * @param int $counter
292 * @param WP_Query $query
293 *
294 * @return array
295 *
296 * @access public
297 */
298 public function filterPostCount($counter, $query) {
299 $filtered = array();
300 $subject = AAM::getUser();
301
302 foreach ($query->posts as $post) {
303 if (isset($post->post_type)) {
304 $type = $post->post_type;
305 } else {
306 $type = AAM_Core_API::getQueryPostType($query);
307 }
308
309 $object = $subject->getObject(
310 'post', (is_a($post, 'WP_Post') ? $post->ID : $post)
311 );
312
313 $hidden = $object->get('backend.hidden');
314 $list = $object->get('backend.list');
315
316 if (empty($hidden) && empty($list)) {
317 $filtered[] = $post;
318 } else {
319 $counter--;
320 $query->post_count--;
321 }
322 }
323
324 $query->posts = $filtered;
325
326 return $counter;
327 }
328
329 /**
330 * Post update hook
331 *
332 * Clear cache if post owner changed
333 *
334 * @param int $id
335 * @param array $data
336 *
337 * @return void
338 *
339 * @access public
340 */
341 public function prePostUpdate($id, $data) {
342 $post = get_post($id);
343
344 if ($post->post_author != $data['post_author']) {
345 AAM_Core_API::clearCache();
346 }
347 }
348
349 /**
350 * Filter roles
351 *
352 * @param array $roles
353 *
354 * @return array
355 */
356 public function filterRoles($roles) {
357 $userLevel = AAM_Core_API::maxLevel(AAM::getUser()->allcaps);
358
359 //filter roles
360 foreach($roles as $id => $role) {
361 if (!empty($role['capabilities']) && is_array($role['capabilities'])) {
362 $roleLevel = AAM_Core_API::maxLevel($role['capabilities']);
363 if ($userLevel < $roleLevel) {
364 unset($roles[$id]);
365 }
366 }
367 }
368
369 return $roles;
370 }
371
372 /**
373 * Filter user query
374 *
375 * Exclude all users that have higher user level
376 *
377 * @param object $query
378 *
379 * @access public
380 *
381 * @return void
382 */
383 public function filterUserQuery($query) {
384 //current user max level
385 $max = AAM_Core_API::maxLevel(AAM::getUser()->allcaps);
386 $exclude = array();
387 $roles = AAM_Core_API::getRoles();
388
389 foreach($roles->role_objects as $id => $role) {
390 if (AAM_Core_API::maxLevel($role->capabilities) > $max) {
391 $exclude[] = $id;
392 }
393 }
394
395 $query->query_vars['role__not_in'] = $exclude;
396 }
397
398 /**
399 * Filter user list view options
400 *
401 * @param array $views
402 *
403 * @return array
404 *
405 * @access public
406 */
407 public function filterViews($views) {
408 $max = AAM_Core_API::maxLevel(AAM::getUser()->allcaps);
409 $roles = AAM_Core_API::getRoles();
410
411 foreach($roles->role_objects as $id => $role) {
412 if (isset($views[$id])
413 && AAM_Core_API::maxLevel($role->capabilities) > $max) {
414 unset($views[$id]);
415 }
416 }
417
418 return $views;
419 }
420
421 /**
422 * Register backend filters and actions
423 *
424 * @return void
425 *
426 * @access public
427 */
428 public static function register() {
429 if (is_null(self::$_instance)) {
430 self::$_instance = new self;
431 }
432 }
433
434 }