PluginProbe ʕ •ᴥ•ʔ
Advanced Access Manager – Access Governance for WordPress / trunk
Advanced Access Manager – Access Governance for WordPress vtrunk
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 / Migration / Migration_700.php
advanced-access-manager / application / Migration Last commit date
Migration_700.php 1 year ago
Migration_700.php
1125 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 * Migration to AAM 7.0.0
12 *
13 * @package AAM
14 * @version 7.0.0
15 */
16 final class AAM_Migration_700
17 {
18
19 /**
20 * Redirect type aliases
21 *
22 * @version 7.0.0
23 */
24 const REDIRECT_TYPE_ALIAS = [
25 'default' => 'default',
26 'login' => 'login_redirect',
27 'message' => 'custom_message',
28 'page' => 'page_redirect',
29 'url' => 'url_redirect',
30 'callback' => 'trigger_callback'
31 ];
32
33 /**
34 * Run the migration
35 *
36 * @return void
37 *
38 * @access public
39 * @version 7.0.0
40 */
41 public function run()
42 {
43 // Convert configs to new names
44 $this->_transform_legacy_config_names();
45
46 // Convert Backend Menu settings to new format
47 $this->_transform_legacy_settings(
48 'menu',
49 AAM_Framework_Type_Resource::BACKEND_MENU,
50 function($data) {
51 return $this->_convert_legacy_backend_menu($data);
52 }
53 );
54
55 // Convert Admin Toolbar settings to new format
56 $this->_transform_legacy_settings(
57 'toolbar',
58 AAM_Framework_Type_Resource::TOOLBAR,
59 function($data) {
60 return $this->_convert_legacy_admin_toolbar($data);
61 }
62 );
63
64 // Convert URL Access rules to new format
65 $this->_transform_legacy_settings(
66 'uri',
67 AAM_Framework_Type_Resource::URL,
68 function($data) {
69 return $this->_convert_legacy_url_rules($data);
70 }
71 );
72
73 // Convert Login Redirect settings to new format
74 $this->_transform_legacy_settings(
75 'loginRedirect',
76 AAM_Framework_Type_Preference::LOGIN_REDIRECT,
77 function($data) {
78 return $this->_convert_legacy_login_redirect($data);
79 }
80 );
81
82 // Convert Logout Redirect settings to new format
83 $this->_transform_legacy_settings(
84 'logoutRedirect',
85 AAM_Framework_Type_Preference::LOGOUT_REDIRECT,
86 function($data) {
87 return $this->_convert_legacy_logout_redirect($data);
88 }
89 );
90
91 // Convert Access Denied Redirect settings to new format
92 $this->_transform_legacy_settings(
93 'redirect',
94 AAM_Framework_Type_Preference::ACCESS_DENIED_REDIRECT,
95 function($data) {
96 return $this->_convert_legacy_access_denied_redirect($data);
97 }
98 );
99
100 // Convert 404 Redirect settings to new format
101 $this->_transform_legacy_settings(
102 'notFoundRedirect',
103 AAM_Framework_Type_Preference::NOT_FOUND_REDIRECT,
104 function($data) {
105 return $this->_convert_legacy_not_found_redirect($data);
106 }
107 );
108
109 // Convert Post settings to new format
110 $this->_transform_legacy_settings(
111 'post',
112 AAM_Framework_Type_Resource::POST,
113 function($data) {
114 return $this->_convert_legacy_post_settings($data);
115 }
116 );
117
118 // Convert Post Type settings to new format
119 $this->_transform_legacy_settings(
120 'type',
121 AAM_Framework_Type_Resource::POST_TYPE,
122 function($data) {
123 return $this->_convert_legacy_post_type_settings($data);
124 }
125 );
126
127 // Convert Taxonomy settings to new format
128 $this->_transform_legacy_settings(
129 'taxonomy',
130 AAM_Framework_Type_Resource::TAXONOMY,
131 function($data) {
132 return $this->_convert_legacy_taxonomy_settings($data);
133 }
134 );
135
136 // Convert Term settings to new format
137 $this->_transform_legacy_settings(
138 'term',
139 AAM_Framework_Type_Resource::TERM,
140 function($data) {
141 return $this->_convert_legacy_term_settings($data);
142 }
143 );
144 }
145
146 /**
147 * Rename legacy config keys with new
148 *
149 * @return void
150 *
151 * @access private
152 * @version 7.0.0
153 */
154 private function _transform_legacy_config_names()
155 {
156 $service = AAM::api()->config;
157 $configs = $service->get();
158 $configpress = AAM::api()->db->read(AAM_Service_Core::DB_OPTION, '');
159
160 // The list of changes
161 $changes = [
162 'core.settings.multiSubject' => 'core.settings.multi_access_levels',
163 'core.service.login-redirect.enabled' => 'service.log_redirect.enabled',
164 'core.service.logout-redirect.enabled' => 'service.logout_redirect.enabled',
165 'core.service.denied-redirect.enabled' => 'service.access_denied_redirect.enabled',
166 'core.service.404-redirect.enabled' => 'service.not_found_redirect.enabled',
167 'core.service.content.enabled' => 'service.content.enabled',
168 'core.service.content.manageAllPostTypes' => 'service.post_types.manage_all_post_types',
169 'core.service.content.manageAllTaxonomies' => 'service.taxonomies.manage_all',
170 'core.settings.tips' => 'core.settings.ui.tips',
171 'ui.settings.renderAccessMetabox' => 'core.settings.ui.render_access_metabox',
172 'core.settings.inheritParentPost' => 'service.content.inherit_from_parent_post',
173 'core.service.content.exclude.taxonomies' => 'service.content.exclude.taxonomies',
174 'feature.post.password.expires' => 'service.content.password_ttl',
175 'geoapi.adapter' => 'service.geo_lookup.geoapi.adapter',
176 'ipstack.license' => 'service.geo_lookup.geoapi.api_key',
177 'geoapi.api_key' => 'service.geo_lookup.geoapi.api_key',
178 'geoapi.test_ip' => 'service.geo_lookup.geoapi.test_ip',
179 'ipstack.schema' => 'service.geo_lookup.ipstack.schema',
180 'ipstack.fields' => 'service.geo_lookup.ipstack.fields',
181 'service.uri.enabled' => 'service.url.enabled',
182 'core.service.admin-menu.enabled' => 'service.backend_menu.enabled',
183 'core.service.metabox.enabled' => 'service.metabox.enabled',
184 'core.service.toolbar.enabled' => 'service.admin_toolbar.enabled',
185 'core.service.route.enabled' => 'service.api_route.enabled',
186 'core.service.identity-governance.enabled' => 'service.identity.enabled',
187 'core.service.jwt.enabled' => 'service.jwt.enabled',
188 'core.service.capability.enabled' => 'service.capability.enabled',
189 'core.settings.editCapabilities' => 'service.capability.edit_caps',
190 'core.service.secure-login.enabled' => 'service.secure_login.enabled',
191 'service.secureLogin.feature.singleSession' => 'service.secure_login.single_session',
192 'service.secureLogin.feature.bruteForceLockout' => 'service.secure_login.brute_force_lockout',
193 'core.settings.xmlrpc' => 'core.settings.xmlrpc_enabled',
194 'core.settings.restful' => 'core.settings.restful_enabled',
195 'core.service.welcome.enabled' => 'service.welcome.enabled',
196 'addon.protected-media-files.settings.deniedRedirect' => 'addon.protected_media_files.settings.denied_redirect',
197 'addon.protected-media-files.settings.absolutePath' => 'addon.protected_media_files.settings.absolute_path',
198 'core.settings.menu.merge.preference' => 'core.settings.backend_menu.merge.preference',
199 'core.settings.toolbar.merge.preference' => 'core.settings.admin_toolbar.merge.preference',
200 'core.settings.route.merge.preference' => 'core.settings.api_route.merge.preference',
201 'core.settings.type.merge.preference' => 'core.settings.post_type.merge.preference',
202 'core.settings.uri.merge.preference' => 'core.settings.url.merge.preference',
203 ];
204
205 foreach($changes as $legacy => $new) {
206 if (isset($configs[$legacy])) {
207 $configs[$new] = $configs[$legacy];
208
209 unset($configs[$legacy]);
210 }
211
212 $configpress = str_replace($legacy, $new, $configpress);
213 }
214
215 $service->set($configs);
216 AAM::api()->db->write(AAM_Service_Core::DB_OPTION, $configpress);
217 }
218
219 /**
220 * Transform legacy resource settings to new format
221 *
222 * @param string $legacy_type
223 * @param string $new_type
224 * @param callback $cb
225 *
226 * @return void
227 * @access private
228 *
229 * @version 7.0.0
230 */
231 private function _transform_legacy_settings($legacy_type, $new_type, $cb)
232 {
233 // Let's get all the settings first
234 $legacy = AAM::api()->db->read('aam_access_settings', []);
235 $settings = AAM::api()->db->read(AAM_Framework_Service_Settings::DB_OPTION);
236
237 // Iterating of the list of all settings and modify the URL Access rule
238 foreach($legacy as $access_level => &$level) {
239 if (in_array($access_level, ['role', 'user'])) {
240 foreach($level as $id => $data) {
241 if ($this->_access_level_exists($access_level, $id)
242 && array_key_exists($legacy_type, $data)
243 ) {
244 $settings[$access_level][$id][$new_type] = $cb(
245 $data[$legacy_type]
246 );
247 }
248 }
249 } else {
250 if (array_key_exists($legacy_type, $level)) {
251 $settings[$access_level][$new_type] = $cb($level[$legacy_type]);
252 }
253 }
254 }
255
256 // Save changes
257 if (!empty($settings)) {
258 AAM::api()->db->write(
259 AAM_Framework_Service_Settings::DB_OPTION,
260 $settings
261 );
262 }
263 }
264
265 /**
266 * Determine if access level exists
267 *
268 * @param string $type
269 * @param string|int $id
270 *
271 * @return bool
272 * @access private
273 *
274 * @version 7.0.0
275 */
276 private function _access_level_exists($type, $id)
277 {
278 if ($type === 'role') {
279 $exists = wp_roles()->is_role($id);
280 } else {
281 $exists = is_a(get_user_by('id', $id), WP_User::class);
282 }
283
284 return $exists;
285 }
286
287 /**
288 * Convert legacy backend menu settings
289 *
290 * @param array $data
291 *
292 * @return array
293 * @access private
294 *
295 * @version 7.0.0
296 */
297 private function _convert_legacy_backend_menu($data)
298 {
299 $result = [];
300
301 if (is_array($data)) {
302 foreach($data as $id => $effect) {
303 $parsed_slug = $this->_normalize_backend_menu_slug($id);
304
305 $result[urldecode(str_replace('menu-', 'menu/', $parsed_slug))] = [
306 'access' => [
307 'effect' => $this->_convert_to_effect($effect)
308 ]
309 ];
310 }
311 }
312
313 return $result;
314 }
315
316 /**
317 * Normalize the backend menu slug
318 *
319 * @param string $menu_slug
320 *
321 * @return string
322 * @access private
323 *
324 * @version 7.0.0
325 */
326 private function _normalize_backend_menu_slug($menu_slug)
327 {
328 if (strpos($menu_slug, '.php') !== false) {
329 $parsed_url = wp_parse_url($menu_slug);
330 $parsed_slug = $parsed_url['path'];
331
332 if (isset($parsed_url['query'])) {
333 parse_str($parsed_url['query'], $query_params);
334
335 // Removing some redundant query params
336 $redundant_params = apply_filters(
337 'aam_ignored_backend_menu_item_query_params_filter',
338 ['return', 'path']
339 );
340
341 foreach($redundant_params as $to_remove) {
342 if (array_key_exists($to_remove, $query_params)) {
343 unset($query_params[$to_remove]);
344 }
345 }
346
347 // Finally, sort the list of query params in alphabetical order to
348 // ensure consistent order
349 ksort($query_params);
350
351 if (count($query_params)) {
352 $parsed_slug .= '?' . http_build_query($query_params);
353 }
354 }
355 } else {
356 $parsed_slug = trim($menu_slug);
357 }
358
359 return urldecode($parsed_slug);
360 }
361
362 /**
363 * Convert legacy admin toolbar settings
364 *
365 * @param array $data
366 *
367 * @return array
368 * @access private
369 *
370 * @version 7.0.0
371 */
372 private function _convert_legacy_admin_toolbar($data)
373 {
374 $result = [];
375
376 if (is_array($data)) {
377 foreach($data as $id => $effect) {
378 $result[str_replace('toolbar-', '', $id)] = [
379 'list' => [
380 'effect' => $this->_convert_to_effect($effect)
381 ]
382 ];
383 }
384 }
385
386 return $result;
387 }
388
389 /**
390 * Convert legacy login redirect
391 *
392 * @param array $data
393 *
394 * @return array
395 * @access private
396 *
397 * @version 7.0.0
398 */
399 private function _convert_legacy_login_redirect($data)
400 {
401 $type = $data['login.redirect.type'];
402
403 if ($type === 'page') {
404 $result = [
405 'type' => 'page_redirect',
406 'redirect_page_id' => intval($data['login.redirect.page'])
407 ];
408 } elseif ($type === 'url') {
409 $result = [
410 'type' => 'url_redirect',
411 'redirect_url' => $data['login.redirect.url']
412 ];
413 } elseif ($type === 'callback') {
414 $result = [
415 'type' => 'trigger_callback',
416 'callback' => $data['login.redirect.callback']
417 ];
418 } else {
419 $result = [
420 'type' => 'default'
421 ];
422 }
423
424 return $result;
425 }
426
427 /**
428 * Convert legacy logout redirect
429 *
430 * @param array $data
431 *
432 * @return array
433 *
434 * @access private
435 * @version 7.0.0
436 */
437 private function _convert_legacy_logout_redirect($data)
438 {
439 $type = $data['logout.redirect.type'];
440
441 if ($type === 'page') {
442 $result = [
443 'type' => 'page_redirect',
444 'redirect_page_id' => intval($data['logout.redirect.page'])
445 ];
446 } elseif ($type === 'url') {
447 $result = [
448 'type' => 'url_redirect',
449 'redirect_url' => $data['logout.redirect.url']
450 ];
451 } elseif ($type === 'callback') {
452 $result = [
453 'type' => 'trigger_callback',
454 'callback' => $data['logout.redirect.callback']
455 ];
456 } else {
457 $result = [
458 'type' => 'default'
459 ];
460 }
461
462 return $result;
463 }
464
465 /**
466 * Convert legacy access denied redirect
467 *
468 * @param array $data
469 *
470 * @return array
471 *
472 * @access private
473 * @version 7.0.0
474 */
475 private function _convert_legacy_access_denied_redirect($data)
476 {
477 $result = [];
478
479 // Group frontend and backend settings
480 $settings = [
481 'frontend' => [],
482 'backend' => []
483 ];
484
485 foreach(['frontend', 'backend'] as $area) {
486 foreach($data as $key => $value) {
487 if (strpos($key, $area) === 0) {
488 $settings[$area][str_replace("{$area}.", '' , $key)] = $value;
489 }
490 }
491 }
492
493 // Do the actual conversion
494 foreach($settings as $area => $setting) {
495 if (!empty($setting)) {
496 $redirect = [];
497
498 $type = $setting['redirect.type'];
499
500 if ($type === 'message') {
501 $redirect['type'] = 'custom_message';
502 $redirect['message'] = $setting['redirect.message'];
503
504 if (isset($setting['redirect.message.code'])) {
505 $redirect['http_status_code'] = intval(
506 $setting['redirect.message.code']
507 );
508 }
509 } elseif ($type === 'page') {
510 $redirect = [
511 'type' => 'page_redirect',
512 'redirect_page_id' => intval($setting['redirect.page'])
513 ];
514 } elseif ($type === 'url') {
515 $redirect = [
516 'type' => 'url_redirect',
517 'redirect_url' => $setting['redirect.url']
518 ];
519 } elseif ($type === 'callback') {
520 $redirect = [
521 'type' => 'trigger_callback',
522 'callback' => $setting['redirect.callback']
523 ];
524 } elseif ($type === 'login') {
525 $redirect = [ 'type' => 'login_redirect' ];
526 } else {
527 $redirect['type'] = 'default';
528
529 if (isset($setting['redirect.default.code'])) {
530 $redirect['http_status_code'] = intval(
531 $setting['redirect.default.code']
532 );
533 }
534 }
535
536 $result[$area] = $redirect;
537 }
538 }
539
540 return $result;
541 }
542
543 /**
544 * Convert legacy 404 (Not Found) Redirect
545 *
546 * @param array $data
547 *
548 * @return array
549 *
550 * @access private
551 * @version 7.0.0
552 */
553 private function _convert_legacy_not_found_redirect($data)
554 {
555 $type = $data['404.redirect.type'];
556
557 if ($type === 'page') {
558 $result = [
559 'type' => 'page_redirect',
560 'redirect_page_id' => intval($data['404.redirect.page'])
561 ];
562 } elseif ($type === 'url') {
563 $result = [
564 'type' => 'url_redirect',
565 'redirect_url' => $data['404.redirect.url']
566 ];
567 } elseif ($type === 'callback') {
568 $result = [
569 'type' => 'trigger_callback',
570 'callback' => $data['404.redirect.callback']
571 ];
572 } elseif ($type !== 'login_redirect') {
573 $result = [
574 'type' => 'default'
575 ];
576 }
577
578 return $result;
579 }
580
581 /**
582 * Convert legacy URL Access rules to new format
583 *
584 * @param array $rules
585 *
586 * @return array
587 *
588 * @access private
589 * @version 7.0.0
590 */
591 private function _convert_legacy_url_rules($rules)
592 {
593 $result = [];
594
595 foreach($rules as $url => $rule) {
596 $new_url = AAM::api()->misc->sanitize_url($url);
597
598 if ($rule['type'] === 'allow') {
599 $result[$new_url] = [
600 'access' => [
601 'effect' => 'allow'
602 ]
603 ];
604 } elseif ($rule['type'] === 'default') {
605 $result[$new_url] = [
606 'access' => [
607 'effect' => 'deny'
608 ]
609 ];
610 } else {
611 $redirect = [
612 'type' => $this->_convert_legacy_redirect_type(
613 $rule['type']
614 )
615 ];
616
617 if ($redirect['type'] === 'trigger_callback') {
618 $redirect['callback'] = $rule['action'];
619 } elseif ($redirect['type'] === 'url_redirect') {
620 $redirect['redirect_url'] = $rule['action'];
621 } elseif ($redirect['type'] === 'page_redirect') {
622 $redirect['redirect_page_id'] = $rule['action'];
623 } elseif ($redirect['type'] === 'custom_message') {
624 $redirect['message'] = $rule['action'];
625 }
626
627 // Add HTTP Redirect Code if provided
628 if (in_array($redirect['type'], ['url_redirect', 'page_redirect'], true)
629 && isset($rule['code'])
630 ) {
631 $redirect['http_status_code'] = intval($rule['code']);
632 }
633
634 $new_rule = [
635 'effect' => 'deny',
636 'redirect' => $redirect
637 ];
638
639 // Adding also conditions if specified
640 $condition = $this->_prepare_url_access_rule_condition($rule);
641
642 if (!empty($condition)) {
643 $new_rule['condition'] = $condition;
644 }
645
646 $result[$new_url] = [ 'access' => $new_rule ];
647 }
648 }
649
650 return $result;
651 }
652
653 /**
654 * Convert legacy URL Access Rule type to new
655 *
656 * @param string $type
657 *
658 * @return string
659 *
660 * @access private
661 * @version 7.0.0
662 */
663 private function _convert_legacy_redirect_type($type)
664 {
665 if (isset(self::REDIRECT_TYPE_ALIAS[$type])) {
666 $type = self::REDIRECT_TYPE_ALIAS[$type];
667 }
668
669 return $type;
670 }
671
672 /**
673 * Prepare URL Access Rule condition
674 *
675 * @param array $rule
676 *
677 * @return array|null
678 * @access private
679 *
680 * @version 7.0.0
681 */
682 private function _prepare_url_access_rule_condition($rule)
683 {
684 $condition = [];
685 $data_points = 0; // Count number of data points
686
687 if (isset($rule['metadata'])) {
688 if (!empty($rule['metadata']['reference_condition_type'])) {
689 $condition['type'] = $rule['metadata']['reference_condition_type'];
690 $data_points++;
691 }
692
693 if (!empty($rule['metadata']['reference_criteria_type'])) {
694 $condition['criteria'] = $rule['metadata']['reference_criteria_type'];
695 $data_points++;
696 }
697
698 if (!empty($rule['metadata']['reference_query_param_name'])) {
699 $condition['query_param'] = $rule['metadata']['reference_query_param_name'];
700 }
701
702 if (!empty($rule['metadata']['reference_condition_value'])) {
703 $condition['value'] = $rule['metadata']['reference_condition_value'];
704 $data_points++;
705 }
706 }
707
708 // Condition has to be valid in order to be translated
709 return $data_points === 3 ? $condition : null;
710 }
711
712 /**
713 * Convert legacy post access controls to new format
714 *
715 * @param array $settings
716 *
717 * @return array
718 * @access private
719 *
720 * @version 7.0.0
721 */
722 private function _convert_legacy_post_settings($settings)
723 {
724 $result = [];
725
726 foreach($settings as $id => $data) {
727 $post = get_post($id);
728
729 if (is_a($post, WP_Post::class)) {
730 $new_id = strpos($id, '|') ? $id : $id . '|' . $post->post_type;
731 $result[$new_id] = $this->_convert_legacy_post_object($data);
732 }
733 }
734
735 return $result;
736 }
737
738 /**
739 * Convert legacy post access controls to new format
740 *
741 * @param array $settings
742 *
743 * @return array
744 * @access private
745 *
746 * @version 7.0.0
747 */
748 private function _convert_legacy_post_type_settings($settings)
749 {
750 $result = [];
751
752 foreach($settings as $id => $data) {
753 // Group by scopes
754 $scopes = [
755 'post' => [],
756 'term' => [] // We are going to ignore these settings
757 ];
758
759 foreach($data as $action => $d) {
760 list($scope, $a) = explode('/', $action);
761 $scopes[$scope][$a] = $d;
762 }
763
764 $result[$id] = [];
765
766 if (!empty($scopes['post'])) {
767 $result[$id] = $this->_convert_legacy_post_object(
768 $scopes['post']
769 );
770 }
771 }
772
773 return $result;
774 }
775
776 /**
777 * Convert legacy taxonomy access controls to new format
778 *
779 * @param array $settings
780 *
781 * @return array
782 *
783 * @access private
784 * @version 7.0.0
785 */
786 private function _convert_legacy_taxonomy_settings($settings)
787 {
788 $result = [];
789
790 foreach($settings as $id => $data) {
791 // Group by scopes
792 $scopes = [
793 'term' => []
794 ];
795
796 foreach($data as $action => $d) {
797 list($scope, $a) = explode('/', $action);
798
799 if ($scope === 'term') {
800 $scopes[$scope][$a] = $d;
801 }
802 }
803
804 $result[$id] = [];
805
806 if (!empty($scopes['term'])) {
807 $result[$id] = $this->_convert_legacy_term_object(
808 $scopes['term']
809 );
810 }
811 }
812
813 return $result;
814 }
815
816 /**
817 * Convert legacy term access controls to new format
818 *
819 * @param array $settings
820 *
821 * @return array
822 *
823 * @access private
824 * @version 7.0.0
825 */
826 private function _convert_legacy_term_settings($settings)
827 {
828 $result = [];
829
830 foreach($settings as $id => $data) {
831 // Group by scopes
832 $scopes = [
833 'post' => [],
834 'term' => []
835 ];
836
837 foreach($data as $action => $d) {
838 list($scope, $a) = explode('/', $action);
839 $scopes[$scope][$a] = $d;
840 }
841
842 $result[$id] = [];
843
844 if (!empty($scopes['post'])) {
845 $result[$id] = $this->_convert_legacy_post_object(
846 $scopes['post']
847 );
848 } elseif (!empty($scopes['term'])) {
849 $result[$id] = $this->_convert_legacy_term_object(
850 $scopes['term']
851 );
852 }
853 }
854
855 return $result;
856 }
857
858 /**
859 * Convert legacy post actions to permissions
860 *
861 * @param array $data
862 *
863 * @return array
864 * @access private
865 *
866 * @version 7.0.6
867 */
868 private function _convert_legacy_post_object($data)
869 {
870 $result = [];
871
872 // The following actions compete for the same permission. If there are more
873 // then one competing action defined - ignore others.
874 $read_permissions = [
875 'restricted', // Simply restricted without any conditions
876 'protected', // Password-protected
877 'teaser', // Show custom wp_die message
878 'redirected', // Redirected to a different location
879 'ceased' // Deny access after certain day/time
880 ];
881
882 // Prepare the filtered list of actions
883 $filtered_list = [];
884 $ignore_other_reads = false;
885 $first_read = null;
886
887 foreach($data as $action => $settings) {
888 if (in_array($action, $read_permissions, true)) {
889 // Covering scenario when all "read" controls are unchecked and
890 // we need to pick the first one
891 if ($first_read === null) {
892 $first_read = [ $action => $settings ];
893 }
894
895 $enabled = $this->_convert_to_boolean($settings);
896
897 if (!$ignore_other_reads && $enabled) {
898 $filtered_list[$action] = $settings;
899 $ignore_other_reads = true;
900 $first_read = false; // We chose the read option
901 }
902 } elseif ($action !== 'limited') {
903 $filtered_list[$action] = $settings;
904 }
905 }
906
907 // If all "read" controls are unchecked, pick the first one
908 if (!empty($first_read)) {
909 $filtered_list = array_merge($filtered_list, $first_read);
910 }
911
912 // Convert the filtered list of actions to new format
913 foreach($filtered_list as $action => $settings) {
914 if (in_array($action, ['hidden', 'hidden_others'], true)) {
915 // Determine the areas the post is hidden on
916 $areas = $this->_prepare_visibility_areas($settings);
917 $item = [ 'effect' => $this->_convert_to_effect($settings) ];
918
919 if (!empty($areas)) {
920 $item['on'] = $areas;
921 }
922
923 if ($action !== 'hidden') {
924 $item['exclude_authors'] = true;
925 }
926
927 $result['list'] = $item;
928 } elseif (in_array($action, ['restricted', 'restricted_others'], true)) {
929 $item = [
930 'effect' => $this->_convert_to_effect($settings),
931 'restriction_type' => 'default'
932 ];
933
934 if ($action !== 'restricted') {
935 $item['exclude_authors'] = true;
936 }
937
938 $result['read'] = $item;
939 } elseif (in_array($action, ['edit', 'edit_others'], true)) {
940 $item = [
941 'effect' => $this->_convert_to_effect($settings)
942 ];
943
944 if ($action !== 'edit') {
945 $item['exclude_authors'] = true;
946 }
947
948 $result['edit'] = $item;
949 } elseif (in_array($action, ['delete', 'delete_others'], true)) {
950 $item = [
951 'effect' => $this->_convert_to_effect($settings)
952 ];
953
954 if ($action !== 'delete') {
955 $item['exclude_authors'] = true;
956 }
957
958 $result['delete'] = $item;
959 } elseif (in_array($action, ['publish', 'publish_others'], true)) {
960 $item = [
961 'effect' => $this->_convert_to_effect($settings)
962 ];
963
964 if ($action !== 'publish') {
965 $item['exclude_authors'] = true;
966 }
967
968 $result['publish'] = $item;
969 } elseif ($action === 'comment') {
970 $result['comment'] = [
971 'effect' => $this->_convert_to_effect($settings)
972 ];
973 } elseif ($action === 'teaser') {
974 $result['read'] = [
975 'effect' => $this->_convert_to_effect($settings),
976 'restriction_type' => 'teaser_message',
977 'message' => $settings['message']
978 ];
979 } elseif ($action === 'redirected') {
980 $redirect = [
981 'type' => $this->_convert_legacy_redirect_type($settings['type'])
982 ];
983
984 if (isset($settings['httpCode'])) {
985 $redirect['http_status_code'] = intval($settings['httpCode']);
986 }
987
988 if ($redirect['type'] === 'page_redirect') {
989 $redirect['redirect_page_id'] = intval($settings['destination']);
990 } elseif($redirect['type'] === 'url_redirect') {
991 $redirect['redirect_url'] = trim($settings['destination']);
992 } elseif($redirect['type'] === 'trigger_callback') {
993 $redirect['callback'] = trim($settings['destination']);
994 }
995
996 $result['read'] = [
997 'effect' => $this->_convert_to_effect($settings),
998 'restriction_type' => 'redirect',
999 'redirect' => $redirect
1000 ];
1001 } elseif ($action === 'protected') {
1002 $result['read'] = [
1003 'effect' => $this->_convert_to_effect($settings),
1004 'restriction_type' => 'password_protected',
1005 'password' => $settings['password']
1006 ];
1007 } elseif ($action === 'ceased') {
1008 $result['read'] = [
1009 'effect' => $this->_convert_to_effect($settings),
1010 'restriction_type' => 'expire',
1011 'expires_after' => intval($settings['after'])
1012 ];
1013 }
1014 }
1015
1016 return $result;
1017 }
1018
1019 /**
1020 * Convert term actions into new format
1021 *
1022 * @param array $data
1023 *
1024 * @return array
1025 * @access private
1026 *
1027 * @version 7.0.0
1028 */
1029 private function _convert_legacy_term_object($data)
1030 {
1031 $result = [];
1032
1033 foreach($data as $action => $settings) {
1034 if ($action === 'restricted') {
1035 $result['browse'] = [
1036 'effect' => $this->_convert_to_effect($settings)
1037 ];
1038 } elseif ($action === 'hidden') {
1039 $result['list'] = [
1040 'effect' => $this->_convert_to_effect($settings),
1041 'on' => $this->_prepare_visibility_areas($settings)
1042 ];
1043 } elseif (in_array($action, ['create', 'edit', 'delete', 'assign'], true)) {
1044 $result[$action] = [
1045 'effect' => $this->_convert_to_effect($settings)
1046 ];
1047 }
1048 }
1049
1050 return $result;
1051 }
1052
1053 /**
1054 * Get "HIDDEN" access control areas
1055 *
1056 * @param array $settings
1057 *
1058 * @return array
1059 * @access private
1060 *
1061 * @version 7.0.0
1062 */
1063 private function _prepare_visibility_areas($settings)
1064 {
1065 $areas = [];
1066
1067 foreach(['frontend', 'backend', 'api'] as $area) {
1068 if (isset($settings[$area])
1069 && ($settings[$area] || $settings[$area] === '1')
1070 ) {
1071 array_push($areas, $area);
1072 }
1073 }
1074
1075 return $areas;
1076 }
1077
1078 /**
1079 * Convert AAM access control flag to permission effect
1080 *
1081 * @param mixed $setting
1082 *
1083 * @return boolean
1084 * @access private
1085 *
1086 * @version 7.0.0
1087 */
1088 private function _convert_to_boolean($setting)
1089 {
1090 $response = false;
1091
1092 if(is_bool($setting)) {
1093 $response = $setting;
1094 } elseif(is_numeric($setting)) { // Legacy
1095 $response = intval($setting) === 1;
1096 } elseif(is_array($setting)) {
1097 $response = $this->_convert_to_boolean(
1098 isset($setting['enabled']) ? $setting['enabled'] : false
1099 );
1100 }
1101
1102 return $response;
1103 }
1104
1105 /**
1106 * Convert to effect value
1107 *
1108 * @param mixed $setting
1109 *
1110 * @return string
1111 * @access private
1112 *
1113 * @version 7.0.0
1114 */
1115 private function _convert_to_effect($setting)
1116 {
1117 return $this->_convert_to_boolean($setting) ? 'deny' : 'allow';
1118 }
1119
1120 }
1121
1122 if (defined('ABSPATH')) {
1123 $migration = new AAM_Migration_700();
1124 $migration->run();
1125 }