PluginProbe
Advanced Access Manager – Access Governance for WordPress / 6.9.26
Advanced Access Manager – Access Governance for WordPress v6.9.26
7.1.4 7.1.2 7.1.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 All 210 releases
advanced-access-manager / application / Service / Metabox.php
Metabox.php
392 lines 11.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 * Metaboxes & Widgets service
12 *
13 * @since 6.9.17 https://github.com/aamplugin/advanced-access-manager/issues/319
14 * @since 6.9.16 https://github.com/aamplugin/advanced-access-manager/issues/315
15 * @since 6.9.13 https://github.com/aamplugin/advanced-access-manager/issues/301
16 * @since 6.4.0 https://github.com/aamplugin/advanced-access-manager/issues/76
17 * @since 6.0.0 Initial implementation of the class
18 *
19 * @package AAM
20 * @version 6.9.17
21 */
22 class AAM_Service_Metabox
23 {
24 use AAM_Core_Contract_ServiceTrait;
25
26 /**
27 * AAM configuration setting that is associated with the service
28 *
29 * @version 6.0.0
30 */
31 const FEATURE_FLAG = 'core.service.metabox.enabled';
32
33 /**
34 * Constructor
35 *
36 * @return void
37 *
38 * @access protected
39 * @version 6.0.0
40 */
41 protected function __construct()
42 {
43 if (is_admin()) {
44 add_filter('aam_service_list_filter', function ($services) {
45 $services[] = array(
46 'title' => __('Metaboxes & Widgets', AAM_KEY),
47 'description' => __('Manage visibility for the classic (not Gutenberg blocks) backend metaboxes, dashboard and frontend widgets for any role, user or visitors. The service ONLY removes unwanted metaboxes and widgets and does not prevent from direct data spoofing.', AAM_KEY),
48 'setting' => self::FEATURE_FLAG
49 );
50
51 return $services;
52 }, 30);
53 }
54
55 if (AAM_Core_Config::get(self::FEATURE_FLAG, true)) {
56 if (is_admin()) {
57 // Hook that initialize the AAM UI part of the service
58 add_action('aam_init_ui_action', function () {
59 AAM_Backend_Feature_Main_Metabox::register();
60 }, 10);
61 }
62
63 $this->initializeHooks();
64 }
65 }
66
67 /**
68 * Generate Metabox & Widget policy statements
69 *
70 * @param array $policy
71 * @param string $resource_type
72 * @param array $options
73 * @param AAM_Core_Policy_Generator $generator
74 *
75 * @return array
76 *
77 * @access public
78 * @version 6.4.0
79 */
80 public function generatePolicy($policy, $resource_type, $options, $generator)
81 {
82 if ($resource_type === AAM_Core_Object_Metabox::OBJECT_TYPE) {
83 if (!empty($options)) {
84 $metaboxes = $widgets = array();
85
86 foreach($options as $id => $effect) {
87 $parts = explode('|', $id);
88
89 if (in_array($parts[0], array('dashboard', 'widgets'), true)) {
90 $widgets[$id] = !empty($effect);
91 } else {
92 $metaboxes[$id] = !empty($effect);
93 }
94 }
95
96 $policy['Statement'] = array_merge(
97 $policy['Statement'],
98 $generator->generateBasicStatements($widgets, 'Widget'),
99 $generator->generateBasicStatements($metaboxes, 'Metabox')
100 );
101 }
102 }
103
104 return $policy;
105 }
106
107 /**
108 * Handle metabox initialization process
109 *
110 * @return void
111 *
112 * @access public
113 * @version 6.0.0
114 */
115 public function filterMetaboxes()
116 {
117 global $post;
118
119 // Make sure that nobody is playing with screen options
120 if (is_a($post, 'WP_Post')) {
121 $id = $post->post_type;
122 } else {
123 $screen = get_current_screen();
124 $id = ($screen ? $screen->id : null);
125 }
126
127 if (filter_input(INPUT_GET, 'init') !== 'metabox') {
128 if ($id !== 'widgets') {
129 $this->filterBackend($id);
130 } else {
131 $this->filterAppearanceWidgets();
132 }
133 }
134 }
135
136 /**
137 * Filter frontend widgets
138 *
139 * @param array $widgets
140 *
141 * @return array
142 *
143 * @access public
144 * @version 6.0.0
145 */
146 public function filterWidgets($widgets)
147 {
148 global $wp_registered_widgets;
149
150 $object = AAM::getUser()->getObject('metabox');
151
152 if (is_array($wp_registered_widgets)) {
153 foreach ($wp_registered_widgets as $id => $widget) {
154 $callback = $this->getWidgetCallback($widget);
155 if ($object->isHidden('widgets', $callback)) {
156 unregister_widget($callback);
157 // Remove it from registered widget global var!!
158 // INFORM: Why Unregister Widget does not clear global var?
159 unset($wp_registered_widgets[$id]);
160 }
161 }
162 }
163
164 return $widgets;
165 }
166
167 /**
168 * Get list of all cached components
169 *
170 * @return array
171 *
172 * @since 6.9.17 https://github.com/aamplugin/advanced-access-manager/issues/319
173 * @since 6.9.13 Initial implementation of the method
174 *
175 * @access public
176 * @version 6.9.17
177 */
178 public function getComponentsCache()
179 {
180 global $wp_post_types;
181
182 $response = AAM_Core_Cache::get(
183 AAM_Backend_Feature_Main_Metabox::DB_CACHE_OPTION
184 );
185
186 if (!is_array($response)) {
187 $response = array();
188 }
189
190 // Filter non-existing metaboxes
191 foreach (array_keys($response) as $id) {
192 if (
193 !in_array($id, array('dashboard', 'widgets'), true)
194 && empty($wp_post_types[$id])
195 ) {
196 unset($response[$id]);
197 }
198 }
199
200 return $response;
201 }
202
203 /**
204 * Initialize Metaboxes & Widgets hooks
205 *
206 * @return void
207 *
208 * @since 6.9.16 https://github.com/aamplugin/advanced-access-manager/issues/315
209 * @since 6.4.0 https://github.com/aamplugin/advanced-access-manager/issues/76
210 * @since 6.0.0 Initial implementation of the method
211 *
212 * @access protected
213 * @version 6.9.16
214 */
215 protected function initializeHooks()
216 {
217 if (is_admin()) {
218 // Manager WordPress metaboxes
219 add_action("in_admin_header", function () {
220 global $post;
221
222 if (AAM_Core_Request::get('init') === 'metabox') {
223 //make sure that nobody is playing with screen options
224 if (is_a($post, 'WP_Post')) {
225 $id = $post->post_type;
226 } else {
227 $screen = get_current_screen();
228 $id = ($screen ? $screen->id : '');
229 }
230
231 $model = new AAM_Backend_Feature_Main_Metabox;
232 $model->initialize($id);
233 }
234 }, 999);
235
236 // Manage Navigation Menu page to support
237 add_filter('nav_menu_meta_box_object', function ($obj) {
238 if (is_object($obj)) {
239 $obj->_default_query['suppress_filters'] = false;
240 }
241
242 return $obj;
243 });
244
245 // Manager WordPress metaboxes - Classic Editor
246 add_action("in_admin_header", array($this, 'filterMetaboxes'), 999);
247
248 // Manage Dashboard widgets
249 add_action("widgets_admin_page", array($this, 'filterMetaboxes'), 999);
250 } else {
251 // Widget filters
252 add_filter('sidebars_widgets', array($this, 'filterWidgets'), 999);
253 }
254
255 // Policy generation hook
256 add_filter(
257 'aam_generated_policy_filter', array($this, 'generatePolicy'), 10, 4
258 );
259
260 // Register RESTful API endpoints
261 AAM_Core_Restful_ComponentService::bootstrap();
262 }
263
264 /**
265 * Filter backend metaboxes and widgets
266 *
267 * @param string $screen
268 *
269 * @since 6.4.0 Making the method protected
270 * @since 6.0.0 Initial implementation of the method
271 *
272 * @access protected
273 * @global array $wp_meta_boxes
274 * @version 6.0.0
275 */
276 protected function filterBackend($screen)
277 {
278 global $wp_meta_boxes;
279
280 if (is_array($wp_meta_boxes)) {
281 foreach ($wp_meta_boxes as $screen_id => $zones) {
282 if ($screen === $screen_id) {
283 $this->filterZones($zones, $screen_id);
284 }
285 }
286 }
287 }
288
289 /**
290 * Filter of widgets on the Appearance->Widgets screen
291 *
292 * @access protected
293 *
294 * @since 6.4.0 Making the method protected
295 * @since 6.0.0 Initial implementation of the method
296 *
297 * @return void
298 * @global array $wp_registered_widgets
299 * @version 6.0.0
300 */
301 protected function filterAppearanceWidgets()
302 {
303 global $wp_registered_widgets;
304
305 $object = AAM::getUser()->getObject('metabox');
306
307 foreach ($wp_registered_widgets as $id => $widget) {
308 $callback = $this->getWidgetCallback($widget);
309 if ($object->isHidden('widgets', $callback)) {
310 unregister_widget($callback);
311 unset($wp_registered_widgets[$id]);
312 }
313 }
314 }
315
316 /**
317 * Filter metaboxes based on screen
318 *
319 * @param array $zones
320 * @param string $screen_id
321 *
322 * @return void
323 *
324 * @access protected
325 * @version 6.0.0
326 */
327 protected function filterZones($zones, $screen_id)
328 {
329 foreach ($zones as $zone => $priorities) {
330 foreach ($priorities as $metaboxes) {
331 $this->removeMetaboxes($zone, $metaboxes, $screen_id);
332 }
333 }
334 }
335
336 /**
337 * Filter list of metaboxes on the screen
338 *
339 * @param string $zone
340 * @param array $metaboxes
341 * @param string $screen_id
342 *
343 * @return void
344 *
345 * @access protected
346 * @version 6.0.0
347 */
348 protected function removeMetaboxes($zone, $metaboxes, $screen_id)
349 {
350 $object = AAM::getUser()->getObject('metabox');
351
352 foreach (array_keys($metaboxes) as $id) {
353 if ($object->isHidden($screen_id, $id)) {
354 remove_meta_box($id, $screen_id, $zone);
355 }
356 }
357 }
358
359 /**
360 * Get widget's callback
361 *
362 * The callback is used as unique widget identifier
363 *
364 * @param mixed $widget
365 *
366 * @return string
367 *
368 * @access protected
369 * @version 6.0.0
370 */
371 protected function getWidgetCallback($widget)
372 {
373 if (is_array($widget['callback'])) {
374 if (is_object($widget['callback'][0])) {
375 $callback = get_class($widget['callback'][0]);
376 } elseif (is_string($widget['callback'][0])) {
377 $callback = $widget['callback'][0];
378 }
379 }
380
381 if (empty($callback)) {
382 $callback = isset($widget['classname']) ? $widget['classname'] : null;
383 }
384
385 return $callback;
386 }
387
388 }
389
390 if (defined('AAM_KEY')) {
391 AAM_Service_Metabox::bootstrap();
392 }