Advanced Access Manager - Version 6.3.0

Version Description

  • Fixed Bug: PHP Notice about missing license key https://github.com/aamplugin/advanced-access-manager/issues/12
  • Fixed Bug: Fatal error: Allowed memory size of XXX bytes exhausted https://github.com/aamplugin/advanced-access-manager/issues/15
  • Fixed Bug: PHP Notice: Undefined index: path https://github.com/aamplugin/advanced-access-manager/issues/18
  • Fixed Bug: PHP Notice: Undefined index: password https://github.com/aamplugin/advanced-access-manager/issues/31
  • Fixed Bug: NGIX compatibility for URI Access https://github.com/aamplugin/advanced-access-manager/issues/33
  • Fixed Bug: URI Access service does not protect the homepage https://github.com/aamplugin/advanced-access-manager/issues/17
  • Fixed Bug: New rule is created if URI Access endpoint is updated https://github.com/aamplugin/advanced-access-manager/issues/35
  • Fixed Bug: Conflict with Jatpack plugin https://github.com/aamplugin/advanced-access-manager/issues/25
  • Fixed Bug: Potentially incorrectly used PHP core list function https://github.com/aamplugin/advanced-access-manager/issues/38
  • Added New: Access Policy token PHP_GLOBAL
  • Added New: Access Policy token WP_NETWORK_OPTION
  • Added New: Allow to attach Access Policies to Default subject https://github.com/aamplugin/advanced-access-manager/issues/13
  • Added New: Ability to create new access policy from generated https://github.com/aamplugin/advanced-access-manager/issues/27
Download this release

Release Info

Developer vasyltech
Plugin Icon 128x128 Advanced Access Manager
Version 6.3.0
Comparing to
See all releases

Code changes from version 6.2.2 to 6.3.0

Files changed (35) hide show
  1. aam.php +2 -2
  2. application/Addon/Repository.php +10 -4
  3. application/Backend/Feature/Main/Policy.php +38 -14
  4. application/Backend/Feature/Main/Post.php +6 -3
  5. application/Backend/Feature/Main/Uri.php +21 -10
  6. application/Backend/Feature/Settings/Manager.php +35 -32
  7. application/Backend/Manager.php +2 -60
  8. application/Backend/View.php +25 -3
  9. application/Backend/tmpl/metabox/main-iframe.php +2 -0
  10. application/Backend/tmpl/page/current-subject.php +3 -4
  11. application/Backend/tmpl/partial/access-policy-action.php +13 -0
  12. application/Backend/tmpl/partial/default-principal-subject-tab.php +15 -4
  13. application/Backend/tmpl/partial/multisite-sync-notification.php +15 -0
  14. application/Backend/tmpl/service/policy.php +77 -86
  15. application/Core/API.php +33 -68
  16. application/Core/AccessSettings.php +19 -1
  17. application/Core/Config.php +23 -4
  18. application/Core/ConfigPress.php +3 -13
  19. application/Core/Migration.php +15 -6
  20. application/Core/Object/Uri.php +48 -14
  21. application/Core/Policy/Generator.php +35 -20
  22. application/Core/Policy/Token.php +93 -27
  23. application/Migration/2019_06_30-base.php +9 -11
  24. application/Migration/2019_11_20-base.php +0 -2
  25. application/Migration/2019_12_01-base.php +4 -7
  26. application/Service/AccessPolicy.php +16 -7
  27. application/Service/Content.php +34 -17
  28. application/Service/Jwt.php +7 -6
  29. application/Service/Multisite.php +101 -38
  30. application/Service/Uri.php +13 -5
  31. application/Shortcode/Handler/Content.php +7 -3
  32. media/css/aam.css +2 -2
  33. media/js/aam.js +76 -56
  34. readme.txt +16 -1
  35. vendor/firebase/JWT.php +12 -7
aam.php CHANGED
@@ -3,7 +3,7 @@
3
  /**
4
  * Plugin Name: Advanced Access Manager
5
  * Description: Collection of features to manage your WordPress website authentication, authorization and monitoring
6
- * Version: 6.2.2
7
  * Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  * Author URI: https://vasyltech.com
9
  * Text Domain: advanced-access-manager
@@ -264,7 +264,7 @@ if (defined('ABSPATH')) {
264
  //define few common constants
265
  define('AAM_MEDIA', plugins_url('/media', __FILE__));
266
  define('AAM_KEY', 'advanced-access-manager');
267
- define('AAM_VERSION', '6.2.2');
268
  define('AAM_BASEDIR', __DIR__);
269
 
270
  //load vendor
3
  /**
4
  * Plugin Name: Advanced Access Manager
5
  * Description: Collection of features to manage your WordPress website authentication, authorization and monitoring
6
+ * Version: 6.3.0
7
  * Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  * Author URI: https://vasyltech.com
9
  * Text Domain: advanced-access-manager
264
  //define few common constants
265
  define('AAM_MEDIA', plugins_url('/media', __FILE__));
266
  define('AAM_KEY', 'advanced-access-manager');
267
+ define('AAM_VERSION', '6.3.0');
268
  define('AAM_BASEDIR', __DIR__);
269
 
270
  //load vendor
application/Addon/Repository.php CHANGED
@@ -52,20 +52,26 @@ class AAM_Addon_Repository
52
  *
53
  * @return array
54
  *
 
 
55
  * @since 6.0.5 Added the $license_only argument
56
  * @since 6.0.0 Initial implementation of the method
57
  *
58
  * @access public
59
- * @version 6.0.5
60
  */
61
  public function getRegistry($license_only = false)
62
  {
63
  $response = array();
64
- $registry = AAM_Core_API::getOption(self::DB_OPTION, array(), 'site');
 
 
65
 
66
  if ($license_only === true) {
67
  foreach($registry as $slug => $data) {
68
- $response[$slug] = $data['license'];
 
 
69
  }
70
  } else {
71
  $response = $registry;
@@ -107,7 +113,7 @@ class AAM_Addon_Repository
107
  );
108
 
109
  // Update the registry
110
- return AAM_Core_API::updateOption(self::DB_OPTION, $list);
111
  }
112
 
113
  /**
52
  *
53
  * @return array
54
  *
55
+ * @since 6.3.0 Fixed bug that causes PHP Notice about license index is missing.
56
+ * Optimized for Multisite setup
57
  * @since 6.0.5 Added the $license_only argument
58
  * @since 6.0.0 Initial implementation of the method
59
  *
60
  * @access public
61
+ * @version 6.3.0
62
  */
63
  public function getRegistry($license_only = false)
64
  {
65
  $response = array();
66
+ $registry = AAM_Core_API::getOption(
67
+ self::DB_OPTION, array(), get_main_site_id()
68
+ );
69
 
70
  if ($license_only === true) {
71
  foreach($registry as $slug => $data) {
72
+ if (!empty($data['license'])) {
73
+ $response[$slug] = $data['license'];
74
+ }
75
  }
76
  } else {
77
  $response = $registry;
113
  );
114
 
115
  // Update the registry
116
+ return AAM_Core_API::updateOption(self::DB_OPTION, $list, get_main_site_id());
117
  }
118
 
119
  /**
application/Backend/Feature/Main/Policy.php CHANGED
@@ -10,6 +10,8 @@
10
  /**
11
  * Access Policy UI manager
12
  *
 
 
13
  * @since 6.2.2 Integration with multisite network where user is allowed to manage
14
  * policies only on the main site if Multiste Sync Settings is enabled
15
  * @since 6.2.0 Added ability to generate Access Policy
@@ -17,7 +19,7 @@
17
  * @since 6.0.0 Initial implementation of the class
18
  *
19
  * @package AAM
20
- * @version 6.2.2
21
  */
22
  class AAM_Backend_Feature_Main_Policy
23
  extends AAM_Backend_Feature_Abstract implements AAM_Backend_Feature_ISubjectAware
@@ -51,13 +53,14 @@ extends AAM_Backend_Feature_Abstract implements AAM_Backend_Feature_ISubjectAwar
51
  *
52
  * @return void
53
  *
 
54
  * @since 6.2.0 Registering a new action to allow the Access Policy generation
55
  * @since 6.1.0 Fixed the bug where "Attach to Default" button was not showing at
56
  * all
57
  * @since 6.0.0 Initial implementation of the method
58
  *
59
  * @access public
60
- * @version 6.2.0
61
  */
62
  public function __construct()
63
  {
@@ -87,6 +90,10 @@ extends AAM_Backend_Feature_Abstract implements AAM_Backend_Feature_ISubjectAwar
87
  return $content;
88
  }, 10, 2);
89
 
 
 
 
 
90
  // Hook into Users/Roles Manager and add new action
91
  if (current_user_can(AAM_Backend_Feature_Main_Policy::ACCESS_CAPABILITY)) {
92
  add_filter('aam_top_subject_actions_filter', function($actions) {
@@ -257,12 +264,13 @@ extends AAM_Backend_Feature_Abstract implements AAM_Backend_Feature_ISubjectAwar
257
  *
258
  * @return string
259
  *
 
260
  * @since 6.2.2 Changed the way list of actions is determined for a policy
261
  * @since 6.2.0 Added "delete" action
262
  * @since 6.0.0 Initial implementation of the method
263
  *
264
  * @access protected
265
- * @version 6.2.2
266
  */
267
  protected function preparePolicyActionList($record)
268
  {
@@ -270,13 +278,10 @@ extends AAM_Backend_Feature_Abstract implements AAM_Backend_Feature_ISubjectAwar
270
 
271
  $policy = $subject->getObject(AAM_Core_Object_Policy::OBJECT_TYPE);
272
  $post = $subject->getObject(AAM_Core_Object_Post::OBJECT_TYPE, $record->ID);
273
- $managed = apply_filters('aam_is_managed_policy_filter', true, $record);
274
- $prefix = ($managed ? '' : 'no-');
275
-
276
  $actions = array(
277
- $policy->has($record->ID) ? "{$prefix}detach" : "{$prefix}attach",
278
- $managed && $post->isAllowedTo('edit') ? 'edit' : 'no-edit',
279
- $managed && $post->isAllowedTo('delete') ? 'delete' : 'no-delete'
280
  );
281
 
282
  return implode(',', $actions);
@@ -331,8 +336,11 @@ extends AAM_Backend_Feature_Abstract implements AAM_Backend_Feature_ISubjectAwar
331
  *
332
  * @return string
333
  *
 
 
 
334
  * @access public
335
- * @version 6.2.0
336
  */
337
  public function generate()
338
  {
@@ -350,10 +358,26 @@ extends AAM_Backend_Feature_Abstract implements AAM_Backend_Feature_ISubjectAwar
350
  $title = 'Policy for everybody';
351
  }
352
 
353
- return wp_json_encode(array(
354
- 'title' => $title,
355
- 'policy' => base64_encode($generator->generate())
356
- ));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
357
  }
358
 
359
  /**
10
  /**
11
  * Access Policy UI manager
12
  *
13
+ * @since 6.3.0 Enhanced service to be able to generate policy into new policy
14
+ * post type record
15
  * @since 6.2.2 Integration with multisite network where user is allowed to manage
16
  * policies only on the main site if Multiste Sync Settings is enabled
17
  * @since 6.2.0 Added ability to generate Access Policy
19
  * @since 6.0.0 Initial implementation of the class
20
  *
21
  * @package AAM
22
+ * @version 6.3.0
23
  */
24
  class AAM_Backend_Feature_Main_Policy
25
  extends AAM_Backend_Feature_Abstract implements AAM_Backend_Feature_ISubjectAware
53
  *
54
  * @return void
55
  *
56
+ * @since 6.3.0 Enhanced per https://github.com/aamplugin/advanced-access-manager/issues/27
57
  * @since 6.2.0 Registering a new action to allow the Access Policy generation
58
  * @since 6.1.0 Fixed the bug where "Attach to Default" button was not showing at
59
  * all
60
  * @since 6.0.0 Initial implementation of the method
61
  *
62
  * @access public
63
+ * @version 6.3.0
64
  */
65
  public function __construct()
66
  {
90
  return $content;
91
  }, 10, 2);
92
 
93
+ add_action('aam_top_subject_panel_action', function() {
94
+ echo AAM_Backend_View::loadPartial('access-policy-action');
95
+ });
96
+
97
  // Hook into Users/Roles Manager and add new action
98
  if (current_user_can(AAM_Backend_Feature_Main_Policy::ACCESS_CAPABILITY)) {
99
  add_filter('aam_top_subject_actions_filter', function($actions) {
264
  *
265
  * @return string
266
  *
267
+ * @since 6.3.0 Optimized for Multisite Network setup
268
  * @since 6.2.2 Changed the way list of actions is determined for a policy
269
  * @since 6.2.0 Added "delete" action
270
  * @since 6.0.0 Initial implementation of the method
271
  *
272
  * @access protected
273
+ * @version 6.3.0
274
  */
275
  protected function preparePolicyActionList($record)
276
  {
278
 
279
  $policy = $subject->getObject(AAM_Core_Object_Policy::OBJECT_TYPE);
280
  $post = $subject->getObject(AAM_Core_Object_Post::OBJECT_TYPE, $record->ID);
 
 
 
281
  $actions = array(
282
+ $policy->has($record->ID) ? "detach" : "attach",
283
+ is_main_site() && $post->isAllowedTo('edit') ? 'edit' : 'no-edit',
284
+ is_main_site() && $post->isAllowedTo('delete') ? 'delete' : 'no-delete'
285
  );
286
 
287
  return implode(',', $actions);
336
  *
337
  * @return string
338
  *
339
+ * @since 6.3.0 Enhanced per https://github.com/aamplugin/advanced-access-manager/issues/27
340
+ * @since 6.2.0 Initial implementation of the method
341
+ *
342
  * @access public
343
+ * @version 6.3.0
344
  */
345
  public function generate()
346
  {
358
  $title = 'Policy for everybody';
359
  }
360
 
361
+ $create = $this->getFromPost('createNewPolicy', FILTER_VALIDATE_BOOLEAN);
362
+ $policy = $generator->generate();
363
+
364
+ if ($create) {
365
+ $id = wp_insert_post(array(
366
+ 'post_type' => AAM_Service_AccessPolicy::POLICY_CPT,
367
+ 'post_content' => $policy,
368
+ 'post_title' => $title,
369
+ 'post_status' => 'publish'
370
+ ));
371
+
372
+ $response = array('redirect' => get_edit_post_link($id, 'link'));
373
+ } else {
374
+ $response = array(
375
+ 'title' => $title,
376
+ 'policy' => base64_encode($policy)
377
+ );
378
+ }
379
+
380
+ return wp_json_encode($response);
381
  }
382
 
383
  /**
application/Backend/Feature/Main/Post.php CHANGED
@@ -10,12 +10,14 @@
10
  /**
11
  * Backend posts & terms service UI
12
  *
 
 
13
  * @since 6.2.0 Added more granular control over the HIDDEN access option
14
  * @since 6.0.3 Allowed to manage access to ALL registered post types
15
  * @since 6.0.0 Initial implementation of the class
16
  *
17
  * @package AAM
18
- * @version 6.2.0
19
  */
20
  class AAM_Backend_Feature_Main_Post
21
  extends AAM_Backend_Feature_Abstract implements AAM_Backend_Feature_ISubjectAware
@@ -262,11 +264,12 @@ class AAM_Backend_Feature_Main_Post
262
  *
263
  * @return string
264
  *
 
265
  * @since 6.2.0 Added HIDDEN preview value
266
  * @since 6.0.0 Initial implementation of the method
267
  *
268
  * @access protected
269
- * @version 6.2.0
270
  */
271
  protected function getPreviewValue($option, $value)
272
  {
@@ -288,7 +291,7 @@ class AAM_Backend_Feature_Main_Post
288
  break;
289
 
290
  case 'protected':
291
- $preview = $value['password'];
292
  break;
293
 
294
  case 'ceased':
10
  /**
11
  * Backend posts & terms service UI
12
  *
13
+ * @since 6.3.0 Fixed bug with PHP noticed that was triggered if password was not
14
+ * defined
15
  * @since 6.2.0 Added more granular control over the HIDDEN access option
16
  * @since 6.0.3 Allowed to manage access to ALL registered post types
17
  * @since 6.0.0 Initial implementation of the class
18
  *
19
  * @package AAM
20
+ * @version 6.3.0
21
  */
22
  class AAM_Backend_Feature_Main_Post
23
  extends AAM_Backend_Feature_Abstract implements AAM_Backend_Feature_ISubjectAware
264
  *
265
  * @return string
266
  *
267
+ * @since 6.3.0 Fixed bug https://github.com/aamplugin/advanced-access-manager/issues/31
268
  * @since 6.2.0 Added HIDDEN preview value
269
  * @since 6.0.0 Initial implementation of the method
270
  *
271
  * @access protected
272
+ * @version 6.3.0
273
  */
274
  protected function getPreviewValue($option, $value)
275
  {
291
  break;
292
 
293
  case 'protected':
294
+ $preview = (!empty($value['password']) ? $value['password'] : '');
295
  break;
296
 
297
  case 'ceased':
application/Backend/Feature/Main/Uri.php CHANGED
@@ -5,15 +5,16 @@
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
- * @version 6.0.0
10
  */
11
 
12
  /**
13
  * URI service
14
  *
 
 
 
15
  * @package AAM
16
- * @version 6.0.0
17
  */
18
  class AAM_Backend_Feature_Main_Uri
19
  extends AAM_Backend_Feature_Abstract implements AAM_Backend_Feature_ISubjectAware
@@ -80,18 +81,28 @@ class AAM_Backend_Feature_Main_Uri
80
  *
81
  * @return string
82
  *
 
 
 
83
  * @access public
84
- * @version 6.0.0
85
  */
86
  public function save()
87
  {
88
- $uri = str_replace(site_url(), '', $this->getFromPost('uri'));
89
- $type = $this->getFromPost('type');
90
- $value = $this->getFromPost('value');
91
- $code = $this->getFromPost('code');
 
92
 
93
  $object = AAM_Backend_Subject::getInstance()->getObject(self::OBJECT_TYPE);
94
 
 
 
 
 
 
 
95
  $result = $object->updateOptionItem($uri, array(
96
  'type' => $type,
97
  'action' => $value,
@@ -111,11 +122,11 @@ class AAM_Backend_Feature_Main_Uri
111
  */
112
  public function delete()
113
  {
114
- $uri = filter_input(INPUT_POST, 'uri');
115
  $object = AAM_Backend_Subject::getInstance()->getObject(self::OBJECT_TYPE);
 
116
 
117
  return wp_json_encode(
118
- array('status' => ($object->delete($uri) ? 'success' : 'failure'))
119
  );
120
  }
121
 
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
  * URI service
12
  *
13
+ * @since 6.3.0 Fixed bug with incorrectly handled record editing
14
+ * @since 6.0.0 Initial implementation of the class
15
+ *
16
  * @package AAM
17
+ * @version 6.3.0
18
  */
19
  class AAM_Backend_Feature_Main_Uri
20
  extends AAM_Backend_Feature_Abstract implements AAM_Backend_Feature_ISubjectAware
81
  *
82
  * @return string
83
  *
84
+ * @since 6.3.0 Fixed bug https://github.com/aamplugin/advanced-access-manager/issues/35
85
+ * @since 6.0.0 Initial implementation of the method
86
+ *
87
  * @access public
88
+ * @version 6.3.0
89
  */
90
  public function save()
91
  {
92
+ $uri = str_replace(site_url(), '', $this->getFromPost('uri'));
93
+ $edited = $this->getFromPost('edited_uri');
94
+ $type = $this->getFromPost('type');
95
+ $value = $this->getFromPost('value');
96
+ $code = $this->getFromPost('code');
97
 
98
  $object = AAM_Backend_Subject::getInstance()->getObject(self::OBJECT_TYPE);
99
 
100
+ // If $edited is not empty, then we actually editing existing record. In this
101
+ // case let's delete it and insert new record after that
102
+ if (!empty($edited) && $object->has($edited)) {
103
+ $object->delete($edited);
104
+ }
105
+
106
  $result = $object->updateOptionItem($uri, array(
107
  'type' => $type,
108
  'action' => $value,
122
  */
123
  public function delete()
124
  {
 
125
  $object = AAM_Backend_Subject::getInstance()->getObject(self::OBJECT_TYPE);
126
+ $result = $object->delete($this->getFromPost('uri'));
127
 
128
  return wp_json_encode(
129
+ array('status' => ($result ? 'success' : 'failure'))
130
  );
131
  }
132
 
application/Backend/Feature/Settings/Manager.php CHANGED
@@ -33,13 +33,16 @@ class AAM_Backend_Feature_Settings_Manager extends AAM_Backend_Feature_Abstract
33
  *
34
  * @return string
35
  *
 
 
 
36
  * @access public
37
- * @version 6.0.0
38
  */
39
  public function save()
40
  {
41
  $param = $this->getFromPost('param');
42
- $value = $this->getFromPost('value');
43
 
44
  AAM_Core_Config::set($param, $value);
45
 
@@ -66,31 +69,26 @@ class AAM_Backend_Feature_Settings_Manager extends AAM_Backend_Feature_Abstract
66
  *
67
  * @return string
68
  *
 
 
 
69
  * @access public
70
- * @version 6.2.0
71
  */
72
  public function getSupportMetadata()
73
  {
74
  global $wp_version;
75
 
76
  return wp_json_encode(array(
77
- 'phpVersion' => PHP_VERSION,
78
- 'wpVersion' => $wp_version,
79
- 'aamVersion' => AAM_VERSION,
80
- 'settings' => AAM_Core_API::getOption(
81
- AAM_Core_AccessSettings::DB_OPTION, array()
82
- ),
83
- 'config' => AAM_Core_API::getOption(
84
- AAM_Core_Config::DB_OPTION, array()
85
- ),
86
- 'configpress' => AAM_Core_API::getOption(
87
- AAM_Core_ConfigPress::DB_OPTION, array()
88
- ),
89
- 'roles' => AAM_Core_API::getOption(
90
- AAM_Core_API::getRoles()->role_key, array()
91
- ),
92
- 'addons' => AAM_Addon_Repository::getInstance()->getRegistry(),
93
- 'plugins' => get_plugins()
94
  ));
95
  }
96
 
@@ -99,8 +97,11 @@ class AAM_Backend_Feature_Settings_Manager extends AAM_Backend_Feature_Abstract
99
  *
100
  * @return string
101
  *
 
 
 
102
  * @access public
103
- * @version 6.2.0
104
  */
105
  public function exportSettings()
106
  {
@@ -119,26 +120,28 @@ class AAM_Backend_Feature_Settings_Manager extends AAM_Backend_Feature_Abstract
119
  $groups = array_map('trim', explode(',', $groups));
120
  }
121
 
 
 
122
  foreach($groups as $group) {
123
  switch($group) {
124
  case 'settings':
125
- $data['dataset']['settings'] = AAM_Core_API::getOption(
126
  AAM_Core_AccessSettings::DB_OPTION, array()
127
  );
128
  break;
129
 
130
  case 'config':
131
- $data['dataset']['config'] = AAM_Core_API::getOption(
132
  AAM_Core_Config::DB_OPTION, array()
133
  );
134
- $data['dataset']['configpress'] = AAM_Core_API::getOption(
135
  AAM_Core_ConfigPress::DB_OPTION, array()
136
  );
137
  break;
138
 
139
  case 'roles':
140
- $data['dataset']['roles'] = AAM_Core_API::getOption(
141
- AAM_Core_API::getRoles()->role_key, array()
142
  );
143
  break;
144
 
@@ -170,15 +173,15 @@ class AAM_Backend_Feature_Settings_Manager extends AAM_Backend_Feature_Abstract
170
  foreach($data['dataset'] as $group => $settings) {
171
  switch($group) {
172
  case 'settings':
173
- AAM_Core_API::updateOption(
174
- AAM_Core_AccessSettings::DB_OPTION, $settings
175
- );
176
  break;
177
 
178
  case 'config':
179
- AAM_Core_API::updateOption(
180
- AAM_Core_Config::DB_OPTION, $settings
181
- );
 
 
182
  break;
183
 
184
  case 'roles':
33
  *
34
  * @return string
35
  *
36
+ * @since 6.3.0 Making sure that boolean value is stored
37
+ * @since 6.0.0 Initial implementation of the method
38
+ *
39
  * @access public
40
+ * @version 6.3.0
41
  */
42
  public function save()
43
  {
44
  $param = $this->getFromPost('param');
45
+ $value = $this->getFromPost('value', FILTER_VALIDATE_BOOLEAN);
46
 
47
  AAM_Core_Config::set($param, $value);
48
 
69
  *
70
  * @return string
71
  *
72
+ * @since 6.3.0 Optimized AAM_Core_API::getOption call
73
+ * @since 6.2.0 Initial implementation of the method
74
+ *
75
  * @access public
76
+ * @version 6.3.0
77
  */
78
  public function getSupportMetadata()
79
  {
80
  global $wp_version;
81
 
82
  return wp_json_encode(array(
83
+ 'phpVersion' => PHP_VERSION,
84
+ 'wpVersion' => $wp_version,
85
+ 'aamVersion' => AAM_VERSION,
86
+ 'settings' => AAM_Core_API::getOption(AAM_Core_AccessSettings::DB_OPTION),
87
+ 'config' => AAM_Core_API::getOption(AAM_Core_Config::DB_OPTION),
88
+ 'configpress' => AAM_Core_API::getOption(AAM_Core_ConfigPress::DB_OPTION),
89
+ 'roles' => AAM_Core_API::getOption(AAM_Core_API::getRoles()->role_key),
90
+ 'addons' => AAM_Addon_Repository::getInstance()->getRegistry(),
91
+ 'plugins' => get_plugins()
 
 
 
 
 
 
 
 
92
  ));
93
  }
94
 
97
  *
98
  * @return string
99
  *
100
+ * @since 6.3.0 Optimized AAM_Core_API::getOption call
101
+ * @since 6.2.0 Initial implementation of the method
102
+ *
103
  * @access public
104
+ * @version 6.3.0
105
  */
106
  public function exportSettings()
107
  {
120
  $groups = array_map('trim', explode(',', $groups));
121
  }
122
 
123
+ $dataset = &$data['dataset'];
124
+
125
  foreach($groups as $group) {
126
  switch($group) {
127
  case 'settings':
128
+ $dataset['settings'] = AAM_Core_API::getOption(
129
  AAM_Core_AccessSettings::DB_OPTION, array()
130
  );
131
  break;
132
 
133
  case 'config':
134
+ $dataset['config'] = AAM_Core_API::getOption(
135
  AAM_Core_Config::DB_OPTION, array()
136
  );
137
+ $dataset['configpress'] = AAM_Core_API::getOption(
138
  AAM_Core_ConfigPress::DB_OPTION, array()
139
  );
140
  break;
141
 
142
  case 'roles':
143
+ $dataset['roles'] = AAM_Core_API::getOption(
144
+ AAM_Core_API::getRoles()->role_key
145
  );
146
  break;
147
 
173
  foreach($data['dataset'] as $group => $settings) {
174
  switch($group) {
175
  case 'settings':
176
+ AAM_Core_AccessSettings::getInstance()->replace($settings);
 
 
177
  break;
178
 
179
  case 'config':
180
+ AAM_Core_Config::replace($settings);
181
+ break;
182
+
183
+ case 'configpress':
184
+ AAM_Core_ConfigPress::getInstance()->save($settings);
185
  break;
186
 
187
  case 'roles':
application/Backend/Manager.php CHANGED
@@ -49,18 +49,13 @@ class AAM_Backend_Manager
49
  }
50
 
51
  // Manager Admin Menu
52
- if (is_multisite() && is_network_admin()) {
53
- // Register AAM in the network admin panel
54
- add_action('_network_admin_menu', array($this, 'adminMenu'));
55
- } else {
56
  add_action('_user_admin_menu', array($this, 'adminMenu'));
57
  add_action('_admin_menu', array($this, 'adminMenu'));
58
  }
59
 
60
  // Manager AAM Ajax Requests
61
  add_action('wp_ajax_aam', array($this, 'ajax'));
62
- // Manager AAM Features Content rendering
63
- add_action('admin_action_aamc', array($this, 'renderContent'));
64
 
65
  // Manager user search on the AAM page
66
  add_filter('user_search_columns', function($columns) {
@@ -144,7 +139,6 @@ class AAM_Backend_Manager
144
  'ajaxurl' => esc_url(admin_url('admin-ajax.php')),
145
  'ui' => AAM_Core_Request::get('aamframe', 'main'),
146
  'url' => array(
147
- 'site' => esc_url(admin_url('index.php')),
148
  'editUser' => esc_url(admin_url('user-edit.php')),
149
  'addUser' => esc_url(admin_url('user-new.php')),
150
  'addPolicy' => esc_url(admin_url('post-new.php?post_type=aam_policy'))
@@ -163,7 +157,7 @@ class AAM_Backend_Manager
163
  'caps' => array(
164
  'create_roles' => current_user_can('aam_create_roles'),
165
  'create_users' => current_user_can('create_users'),
166
- 'manage_policies' => is_main_site() || !AAM_Core_Config::get(AAM_Service_Multisite::FEATURE_FLAG, true)
167
  )
168
  ));
169
 
@@ -309,58 +303,6 @@ class AAM_Backend_Manager
309
  );
310
  }
311
 
312
- /**
313
- * Render AAM UI html content
314
- *
315
- * This is more logical separation between JSON response and HTML response with
316
- * some additional check for compression
317
- *
318
- * @return void
319
- *
320
- * @since 6.1.0 Fixed bug with improper response if server config does not match
321
- * PHP executable INI settings
322
- * @since 6.0.0 Initial implementation of the method
323
- *
324
- * @access public
325
- * @version 6.1.0
326
- */
327
- public function renderContent()
328
- {
329
- check_ajax_referer('aam_ajax');
330
-
331
- @ob_clean(); // flush any output buffer
332
-
333
- if (current_user_can('aam_manager')) {
334
- $partial = filter_input(INPUT_POST, 'partial');
335
- $response = AAM_Backend_View::getInstance()->renderContent(
336
- (!empty($partial) ? $partial : 'main')
337
- );
338
-
339
- $accept = AAM_Core_Request::server('HTTP_ACCEPT_ENCODING');
340
- header('Content-Type: text/html; charset=UTF-8');
341
-
342
- $compressed = count(array_intersect(
343
- array('zlib output compression', 'ob_gzhandler'),
344
- ob_list_handlers()
345
- )) > 0;
346
-
347
- if (!empty($accept)) {
348
- header('Vary: Accept-Encoding'); // Handle proxies
349
-
350
- if (false !== stripos($accept, 'gzip') && function_exists('gzencode')) {
351
- header('Content-Encoding: gzip');
352
- $response = ($compressed ? $response : gzencode($response, 3));
353
- }
354
- }
355
-
356
- echo $response;
357
- } else {
358
- echo -1;
359
- }
360
-
361
- exit();
362
- }
363
-
364
  /**
365
  * Handle Ajax calls to AAM
366
  *
49
  }
50
 
51
  // Manager Admin Menu
52
+ if (!is_network_admin()) {
 
 
 
53
  add_action('_user_admin_menu', array($this, 'adminMenu'));
54
  add_action('_admin_menu', array($this, 'adminMenu'));
55
  }
56
 
57
  // Manager AAM Ajax Requests
58
  add_action('wp_ajax_aam', array($this, 'ajax'));
 
 
59
 
60
  // Manager user search on the AAM page
61
  add_filter('user_search_columns', function($columns) {
139
  'ajaxurl' => esc_url(admin_url('admin-ajax.php')),
140
  'ui' => AAM_Core_Request::get('aamframe', 'main'),
141
  'url' => array(
 
142
  'editUser' => esc_url(admin_url('user-edit.php')),
143
  'addUser' => esc_url(admin_url('user-new.php')),
144
  'addPolicy' => esc_url(admin_url('post-new.php?post_type=aam_policy'))
157
  'caps' => array(
158
  'create_roles' => current_user_can('aam_create_roles'),
159
  'create_users' => current_user_can('create_users'),
160
+ 'manage_policies' => is_main_site()
161
  )
162
  ));
163
 
303
  );
304
  }
305
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306
  /**
307
  * Handle Ajax calls to AAM
308
  *
application/Backend/View.php CHANGED
@@ -117,11 +117,33 @@ class AAM_Backend_View
117
  array(AAM_Backend_Feature::getFeatureView($id), $parts[1])
118
  );
119
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  }
121
 
122
- return apply_filters(
123
- 'aam_ajax_filter', $response, $subject->getSubject(), $action
124
- );
125
  }
126
 
127
  /**
117
  array(AAM_Backend_Feature::getFeatureView($id), $parts[1])
118
  );
119
  }
120
+
121
+ $response = apply_filters(
122
+ 'aam_ajax_filter', $response, $subject->getSubject(), $action
123
+ );
124
+ } elseif ($action === 'renderContent') {
125
+ $partial = filter_input(INPUT_POST, 'partial');
126
+ $response = $this->renderContent((!empty($partial) ? $partial : 'main'));
127
+
128
+ $accept = AAM_Core_Request::server('HTTP_ACCEPT_ENCODING');
129
+ header('Content-Type: text/html; charset=UTF-8');
130
+
131
+ $compressed = count(array_intersect(
132
+ array('zlib output compression', 'ob_gzhandler'),
133
+ ob_list_handlers()
134
+ )) > 0;
135
+
136
+ if (!empty($accept)) {
137
+ header('Vary: Accept-Encoding'); // Handle proxies
138
+
139
+ if (false !== stripos($accept, 'gzip') && function_exists('gzencode')) {
140
+ header('Content-Encoding: gzip');
141
+ $response = ($compressed ? $response : gzencode($response, 3));
142
+ }
143
+ }
144
  }
145
 
146
+ return $response;
 
 
147
  }
148
 
149
  /**
application/Backend/tmpl/metabox/main-iframe.php CHANGED
@@ -47,6 +47,8 @@
47
  </div>
48
  <?php } ?>
49
 
 
 
50
  <div class="metabox-holder shared-metabox">
51
  <div class="postbox">
52
  <div class="inside">
47
  </div>
48
  <?php } ?>
49
 
50
+ <?php do_action('aam_top_right_column_action'); ?>
51
+
52
  <div class="metabox-holder shared-metabox">
53
  <div class="postbox">
54
  <div class="inside">
application/Backend/tmpl/page/current-subject.php CHANGED
@@ -1,9 +1,10 @@
1
  <?php
2
  /**
 
3
  * @since 6.2.0 Added `aam_top_subject_actions_filter` hook
4
  * @since 6.0.0 Initial implementation of the template
5
  *
6
- * @version 6.2.0
7
  * */
8
  ?>
9
 
@@ -12,9 +13,7 @@
12
  <div class="col-xs-12 col-md-8">
13
  <div class="aam-current-subject"></div>
14
  <div class="subject-top-actions">
15
- <?php foreach(apply_filters('aam_top_subject_actions_filter', array()) as $action) { ?>
16
- <a href="#" id="<?php echo $action['id']; ?>" data-toggle="tooltip" title="<?php echo $action['tooltip']; ?>"><i class="<?php echo $action['icon']; ?>"></i></a>
17
- <?php } ?>
18
  </div>
19
  </div>
20
  </div>
1
  <?php
2
  /**
3
+ * @since 6.3.0 Refactored to support https://github.com/aamplugin/advanced-access-manager/issues/27
4
  * @since 6.2.0 Added `aam_top_subject_actions_filter` hook
5
  * @since 6.0.0 Initial implementation of the template
6
  *
7
+ * @version 6.3.0
8
  * */
9
  ?>
10
 
13
  <div class="col-xs-12 col-md-8">
14
  <div class="aam-current-subject"></div>
15
  <div class="subject-top-actions">
16
+ <?php do_action('aam_top_subject_panel_action'); ?>
 
 
17
  </div>
18
  </div>
19
  </div>
application/Backend/tmpl/partial/access-policy-action.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php /** @version 6.3.0 */ ?>
2
+
3
+ <?php if (defined('AAM_KEY')) { ?>
4
+ <div class="dropdown">
5
+ <a href="#" id="policy-generator" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="icon-file-code"></i></a>
6
+ <ul class="dropdown-menu">
7
+ <li><a href="#" id="generate-access-policy"><?php echo __('Download as File', AAM_KEY); ?></a></li>
8
+ <li><a href="#" id="create-access-policy"><?php echo __('Create New Policy', AAM_KEY); ?></a></li>
9
+ <li role="separator" class="divider"></li>
10
+ <li><a href="https://aamplugin.com/reference/policy" target="_blank"><?php echo __('Learn More', AAM_KEY); ?></a></li>
11
+ </ul>
12
+ </div>
13
+ <?php }
application/Backend/tmpl/partial/default-principal-subject-tab.php CHANGED
@@ -1,9 +1,20 @@
1
- <?php /** @version 6.0.0 */ ?>
2
 
3
  <?php if (defined('AAM_KEY')) { ?>
4
  <div class="visitor-message">
5
- <p class="aam-notification">
6
- <?php echo AAM_Backend_View_Helper::preparePhrase('This feature is allowed only with [Plus Package] addon.', 'b'); ?>
7
- </p>
 
 
 
 
 
 
 
 
 
 
 
8
  </div>
9
  <?php }
1
+ <?php /** @version 6.3.0 */ ?>
2
 
3
  <?php if (defined('AAM_KEY')) { ?>
4
  <div class="visitor-message">
5
+ <span class="aam-bordered"><?php echo __('Attach current access &amp; security policy to all users, roles and visitors', AAM_KEY); ?>.</span>
6
+ <?php
7
+ $hasPolicy = AAM::api()->getDefault()->getObject(
8
+ AAM_Core_Object_Policy::OBJECT_TYPE
9
+ )->has($params->policyId);
10
+
11
+ $btnStatus = $hasPolicy ? 'detach' : 'attach';
12
+ ?>
13
+
14
+ <?php if ($hasPolicy) { ?>
15
+ <button class="btn btn-primary btn-block" id="attach-policy-default" data-has="1" <?php echo ($btnStatus ? '' : ' disabled'); ?>><?php echo __('Detach Policy From Everybody', AAM_KEY); ?></button>
16
+ <?php } else { ?>
17
+ <button class="btn btn-primary btn-block" id="attach-policy-default" data-has="0" <?php echo ($btnStatus ? '' : ' disabled'); ?>><?php echo __('Attach Policy To Everybody', AAM_KEY); ?></button>
18
+ <?php } ?>
19
  </div>
20
  <?php }
application/Backend/tmpl/partial/multisite-sync-notification.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php /** @version 6.0.0 */ ?>
2
+
3
+ <?php if (defined('AAM_KEY')) { ?>
4
+ <div class="metabox-holder shared-metabox">
5
+ <div class="postbox">
6
+ <div class="inside">
7
+ <div class="aam-postbox-inside">
8
+ <p class="alert alert-danger text-larger">
9
+ <?php echo AAM_Backend_View_Helper::preparePhrase('[Warning!] You are operating on the multisite network main blog. All the settings will be automatically synced across all the blogs in this network.', 'strong'); ?>
10
+ </p>
11
+ </div>
12
+ </div>
13
+ </div>
14
+ </div>
15
+ <?php }
application/Backend/tmpl/service/policy.php CHANGED
@@ -1,113 +1,104 @@
1
  <?php
2
  /**
 
3
  * @since 6.2.0 Enhanced the table with new functionality
4
  * @since 6.0.0 Initial implementation of the template
5
  *
6
- * @version 6.2.0
7
  * */
8
  ?>
9
  <?php if (defined('AAM_KEY')) { ?>
10
  <div class="aam-feature" id="policy-content">
11
- <?php if (defined('AAM_PLUS_PACKAGE') || !AAM_Backend_Subject::getInstance()->isDefault()) { ?>
12
- <div class="row">
13
- <div class="col-xs-12">
14
- <p class="aam-info">
15
- <?php echo sprintf(AAM_Backend_View_Helper::preparePhrase('Manage access and security policies for [%s]. For more information check %sAccess &amp; Security Policy%s page.', 'b'), AAM_Backend_Subject::getInstance()->getName(), '<a href="https://aamplugin.com/reference/policy" target="_blank">', '</a>'); ?>
16
- </p>
17
- </div>
18
  </div>
 
19
 
20
- <div class="row">
21
- <div class="col-xs-12">
22
- <div class="aam-overwrite" id="aam-policy-overwrite" style="display: <?php echo ($this->isOverwritten() ? 'block' : 'none'); ?>">
23
- <span><i class="icon-check"></i> <?php echo __('Policies are customized', AAM_KEY); ?></span>
24
- <span><a href="#" id="policy-reset" class="btn btn-xs btn-primary"><?php echo __('Reset To Default', AAM_KEY); ?></a>
25
- </div>
26
  </div>
27
  </div>
 
28
 
29
- <div class="row">
30
- <div class="col-xs-12">
31
- <table id="policy-list" class="table table-striped table-bordered">
32
- <thead>
33
- <tr>
34
- <th>ID</th>
35
- <th width="80%"><?php echo __('Policy', AAM_KEY); ?></th>
36
- <th><?php echo __('Actions', AAM_KEY); ?></th>
37
- <th>Edit Link</th>
38
- <th>Just Title</th>
39
- </tr>
40
- </thead>
41
- <tbody></tbody>
42
- </table>
43
- </div>
44
  </div>
 
45
 
46
- <div class="modal fade" id="delete-policy-modal" tabindex="-1" role="dialog">
47
- <div class="modal-dialog" role="document">
48
- <div class="modal-content">
49
- <div class="modal-header">
50
- <button type="button" class="close" data-dismiss="modal" aria-label="<?php echo __('Close', AAM_KEY); ?>"><span aria-hidden="true">&times;</span></button>
51
- <h4 class="modal-title"><?php echo __('Delete Policy', AAM_KEY); ?></h4>
52
- </div>
53
- <div class="modal-body">
54
- <p class="text-center aam-confirm-message alert alert-danger" data-message="<?php echo __('You are about to delete the %s policy. Please confirm.', AAM_KEY); ?>"></p>
55
- </div>
56
- <div class="modal-footer">
57
- <button type="button" class="btn btn-danger" id="delete-policy-btn"><?php echo __('Delete Policy', AAM_KEY); ?></button>
58
- <button type="button" class="btn btn-default" data-dismiss="modal"><?php echo __('Close', AAM_KEY); ?></button>
59
- </div>
60
  </div>
61
  </div>
62
  </div>
 
63
 
64
- <div class="modal fade" id="modal-install-policy" tabindex="-1" role="dialog">
65
- <div class="modal-dialog" role="document">
66
- <div class="modal-content">
67
- <div class="modal-header">
68
- <button type="button" class="close" data-dismiss="modal" aria-label="<?php echo __('Close', AAM_KEY); ?>"><span aria-hidden="true">&times;</span></button>
69
- <h4 class="modal-title text-left"><?php echo __('Install Access Policy', AAM_KEY); ?></h4>
70
- </div>
71
- <div class="modal-body">
72
- <p class="alert alert-info"><?php echo sprintf(__('Install an access policy from the official %sAAM Access Policy Hub%s. Insert the policy ID and it will be automatically downloaded and applied to proper assignees.', AAM_KEY), '<a href="https://aamplugin.com/access-policy-hub" target="_blank">', '</a>'); ?></p>
73
-
74
- <div class="input-group aam-outer-top-xs">
75
- <input type="text" class="form-control" placeholder="<?php echo __('Insert Policy ID', AAM_KEY); ?>" id="policy-id" aria-describedby="basic-addon2" />
76
- <span class="input-group-addon" id="basic-addon2"><?php echo __('Fetch', AAM_KEY); ?></span>
77
- </div>
78
 
79
- <table class="table table-striped table-bordered aam-ghost aam-outer-top-xxs" id="policy-details">
80
- <tbody>
81
- <tr>
82
- <th width="30" class="text-muted"><?php echo __('Title', AAM_KEY); ?></th>
83
- <td id="policy-title"></td>
84
- </tr>
85
- <tr>
86
- <th width="30" class="text-muted"><?php echo __('Description', AAM_KEY); ?></th>
87
- <td id="policy-description"></td>
88
- </tr>
89
- <tr>
90
- <th width="30" class="text-muted"><?php echo __('Assignee(s)', AAM_KEY); ?></th>
91
- <td id="policy-subjects"></td>
92
- </tr>
93
- </tbody>
94
- </table>
95
- </div>
96
- <div class="modal-footer">
97
- <button type="button" class="btn btn-success" disabled id="install-policy"><?php echo __('Install', AAM_KEY); ?></button>
98
- <button type="button" class="btn btn-default" data-dismiss="modal"><?php echo __('Close', AAM_KEY); ?></button>
99
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  </div>
101
  </div>
102
  </div>
103
- <?php } else { ?>
104
- <div class="row">
105
- <div class="col-xs-12">
106
- <p class="aam-notification">
107
- <?php echo sprintf(AAM_Backend_View_Helper::preparePhrase('%s[AAM Plus Package]%s extension is required in order to apply Access &amp; Security Policies to everybody all together.', 'b'), '<a href="https://aamplugin.com/extension/plus-package" target="_blank">', '</a>'); ?>
108
- </p>
109
- </div>
110
- </div>
111
- <?php } ?>
112
  </div>
113
  <?php }
1
  <?php
2
  /**
3
+ * @since 6.3.0 Removed limitation to attach policy to Default
4
  * @since 6.2.0 Enhanced the table with new functionality
5
  * @since 6.0.0 Initial implementation of the template
6
  *
7
+ * @version 6.3.0
8
  * */
9
  ?>
10
  <?php if (defined('AAM_KEY')) { ?>
11
  <div class="aam-feature" id="policy-content">
12
+ <div class="row">
13
+ <div class="col-xs-12">
14
+ <p class="aam-info">
15
+ <?php echo sprintf(AAM_Backend_View_Helper::preparePhrase('Manage access and security policies for [%s]. For more information check %sAccess &amp; Security Policy%s page.', 'b'), AAM_Backend_Subject::getInstance()->getName(), '<a href="https://aamplugin.com/reference/policy" target="_blank">', '</a>'); ?>
16
+ </p>
 
 
17
  </div>
18
+ </div>
19
 
20
+ <div class="row">
21
+ <div class="col-xs-12">
22
+ <div class="aam-overwrite" id="aam-policy-overwrite" style="display: <?php echo ($this->isOverwritten() ? 'block' : 'none'); ?>">
23
+ <span><i class="icon-check"></i> <?php echo __('Policies are customized', AAM_KEY); ?></span>
24
+ <span><a href="#" id="policy-reset" class="btn btn-xs btn-primary"><?php echo __('Reset To Default', AAM_KEY); ?></a>
 
25
  </div>
26
  </div>
27
+ </div>
28
 
29
+ <div class="row">
30
+ <div class="col-xs-12">
31
+ <table id="policy-list" class="table table-striped table-bordered">
32
+ <thead>
33
+ <tr>
34
+ <th>ID</th>
35
+ <th width="80%"><?php echo __('Policy', AAM_KEY); ?></th>
36
+ <th><?php echo __('Actions', AAM_KEY); ?></th>
37
+ <th>Edit Link</th>
38
+ <th>Just Title</th>
39
+ </tr>
40
+ </thead>
41
+ <tbody></tbody>
42
+ </table>
 
43
  </div>
44
+ </div>
45
 
46
+ <div class="modal fade" id="delete-policy-modal" tabindex="-1" role="dialog">
47
+ <div class="modal-dialog" role="document">
48
+ <div class="modal-content">
49
+ <div class="modal-header">
50
+ <button type="button" class="close" data-dismiss="modal" aria-label="<?php echo __('Close', AAM_KEY); ?>"><span aria-hidden="true">&times;</span></button>
51
+ <h4 class="modal-title"><?php echo __('Delete Policy', AAM_KEY); ?></h4>
52
+ </div>
53
+ <div class="modal-body">
54
+ <p class="text-center aam-confirm-message alert alert-danger" data-message="<?php echo __('You are about to delete the %s policy. Please confirm.', AAM_KEY); ?>"></p>
55
+ </div>
56
+ <div class="modal-footer">
57
+ <button type="button" class="btn btn-danger" id="delete-policy-btn"><?php echo __('Delete Policy', AAM_KEY); ?></button>
58
+ <button type="button" class="btn btn-default" data-dismiss="modal"><?php echo __('Close', AAM_KEY); ?></button>
 
59
  </div>
60
  </div>
61
  </div>
62
+ </div>
63
 
64
+ <div class="modal fade" id="modal-install-policy" tabindex="-1" role="dialog">
65
+ <div class="modal-dialog" role="document">
66
+ <div class="modal-content">
67
+ <div class="modal-header">
68
+ <button type="button" class="close" data-dismiss="modal" aria-label="<?php echo __('Close', AAM_KEY); ?>"><span aria-hidden="true">&times;</span></button>
69
+ <h4 class="modal-title text-left"><?php echo __('Install Access Policy', AAM_KEY); ?></h4>
70
+ </div>
71
+ <div class="modal-body">
72
+ <p class="alert alert-info"><?php echo sprintf(__('Install an access policy from the official %sAAM Access Policy Hub%s. Insert the policy ID and it will be automatically downloaded and applied to proper assignees.', AAM_KEY), '<a href="https://aamplugin.com/access-policy-hub" target="_blank">', '</a>'); ?></p>
 
 
 
 
 
73
 
74
+ <div class="input-group aam-outer-top-xs">
75
+ <input type="text" class="form-control" placeholder="<?php echo __('Insert Policy ID', AAM_KEY); ?>" id="policy-id" aria-describedby="basic-addon2" />
76
+ <span class="input-group-addon" id="basic-addon2"><?php echo __('Fetch', AAM_KEY); ?></span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  </div>
78
+
79
+ <table class="table table-striped table-bordered aam-ghost aam-outer-top-xxs" id="policy-details">
80
+ <tbody>
81
+ <tr>
82
+ <th width="30" class="text-muted"><?php echo __('Title', AAM_KEY); ?></th>
83
+ <td id="policy-title"></td>
84
+ </tr>
85
+ <tr>
86
+ <th width="30" class="text-muted"><?php echo __('Description', AAM_KEY); ?></th>
87
+ <td id="policy-description"></td>
88
+ </tr>
89
+ <tr>
90
+ <th width="30" class="text-muted"><?php echo __('Assignee(s)', AAM_KEY); ?></th>
91
+ <td id="policy-subjects"></td>
92
+ </tr>
93
+ </tbody>
94
+ </table>
95
+ </div>
96
+ <div class="modal-footer">
97
+ <button type="button" class="btn btn-success" disabled id="install-policy"><?php echo __('Install', AAM_KEY); ?></button>
98
+ <button type="button" class="btn btn-default" data-dismiss="modal"><?php echo __('Close', AAM_KEY); ?></button>
99
  </div>
100
  </div>
101
  </div>
102
+ </div>
 
 
 
 
 
 
 
 
103
  </div>
104
  <?php }
application/Core/API.php CHANGED
@@ -10,13 +10,14 @@
10
  /**
11
  * AAM core API
12
  *
 
13
  * @since 6.2.2 Minor refactoring to the clearSettings method
14
  * @since 6.0.5 Fixed bug with getOption method where incorrect type could be
15
  * returned
16
  * @since 6.0.0 Initial implementation of the class
17
  *
18
  * @package AAM
19
- * @version 6.2.2
20
  */
21
  final class AAM_Core_API
22
  {
@@ -30,57 +31,24 @@ final class AAM_Core_API
30
  *
31
  * @return mixed
32
  *
 
33
  * @since 6.0.5 Fixed the bug where option may not be returned as proper type
34
  * @since 6.0.0 Initial implementation of the method
35
  *
36
  * @access public
37
- * @version 6.0.5
38
  */
39
- public static function getOption($option, $default = null, $blog_id = null)
40
  {
41
  if (is_multisite()) {
42
- if (is_null($blog_id) || get_current_blog_id() === $blog_id) {
43
- $response = self::getCachedOption($option, $default);
44
- } else {
45
- if ($blog_id === 'site') {
46
- $blog = (defined('SITE_ID_CURRENT_SITE') ? SITE_ID_CURRENT_SITE : 1);
47
- } else {
48
- $blog = $blog_id;
49
- }
50
- $response = get_blog_option($blog, $option, $default);
51
- }
52
  } else {
53
- $response = self::getCachedOption($option, $default);
54
  }
55
 
56
- return maybe_unserialize($response);
57
- }
58
-
59
- /**
60
- * Get cached option
61
- *
62
- * This reduces the number of DB queries
63
- *
64
- * @param string $option
65
- * @param mixed $default
66
- *
67
- * @return mixed
68
- *
69
- * @access protected
70
- * @version 6.0.0
71
- */
72
- protected static function getCachedOption($option, $default)
73
- {
74
- $response = $default;
75
- $cache = wp_cache_get('alloptions', 'options');
76
-
77
- if (empty($cache)) {
78
- $response = get_option($option, $default);
79
- } elseif(isset($cache[$option])) {
80
- $response = maybe_unserialize($cache[$option]);
81
- }
82
-
83
- return $response;
84
  }
85
 
86
  /**
@@ -92,26 +60,23 @@ final class AAM_Core_API
92
  *
93
  * @return bool
94
  *
 
 
 
95
  * @access public
96
- * @version 6.0.0
97
  */
98
- public static function updateOption(
99
- $option, $data, $blog_id = null, $autoload = null
100
- ) {
101
  if (is_multisite()) {
102
- if (is_null($blog_id)) {
103
- $blog = get_current_blog_id();
104
- } elseif ($blog_id === 'site') {
105
- $blog = (defined('SITE_ID_CURRENT_SITE') ? SITE_ID_CURRENT_SITE : 1);
106
- } else {
107
- $blog = $blog_id;
108
- }
109
- $response = update_blog_option($blog, $option, $data);
110
  } else {
111
- $response = update_option($option, $data, $autoload);
112
  }
113
 
114
- return $response;
115
  }
116
 
117
  /**
@@ -122,25 +87,23 @@ final class AAM_Core_API
122
  *
123
  * @return bool
124
  *
 
 
 
125
  * @access public
126
- * @version 6.0.0
127
  */
128
  public static function deleteOption($option, $blog_id = null)
129
  {
130
  if (is_multisite()) {
131
- if (is_null($blog_id)) {
132
- $blog = get_current_blog_id();
133
- } elseif ($blog_id == 'site') {
134
- $blog = (defined('SITE_ID_CURRENT_SITE') ? SITE_ID_CURRENT_SITE : 1);
135
- } else {
136
- $blog = $blog_id;
137
- }
138
- $response = delete_blog_option($blog, $option);
139
  } else {
140
- $response = delete_option($option);
141
  }
142
 
143
- return $response;
144
  }
145
 
146
  /**
@@ -276,7 +239,9 @@ final class AAM_Core_API
276
  AAM_Core_AccessSettings::DB_OPTION,
277
  AAM_Core_Config::DB_OPTION,
278
  AAM_Core_ConfigPress::DB_OPTION,
279
- AAM_Core_Migration::DB_OPTION
 
 
280
  );
281
 
282
  foreach($options as $option) {
10
  /**
11
  * AAM core API
12
  *
13
+ * @since 6.3.0 Optimized for Multisite setup
14
  * @since 6.2.2 Minor refactoring to the clearSettings method
15
  * @since 6.0.5 Fixed bug with getOption method where incorrect type could be
16
  * returned
17
  * @since 6.0.0 Initial implementation of the class
18
  *
19
  * @package AAM
20
+ * @version 6.3.0
21
  */
22
  final class AAM_Core_API
23
  {
31
  *
32
  * @return mixed
33
  *
34
+ * @since 6.3.0 Optimized for Multisite setup
35
  * @since 6.0.5 Fixed the bug where option may not be returned as proper type
36
  * @since 6.0.0 Initial implementation of the method
37
  *
38
  * @access public
39
+ * @version 6.3.0
40
  */
41
+ public static function getOption($option, $default = array(), $blog_id = null)
42
  {
43
  if (is_multisite()) {
44
+ $result = get_blog_option(
45
+ ($blog_id ? $blog_id : get_current_blog_id()), $option, $default
46
+ );
 
 
 
 
 
 
 
47
  } else {
48
+ $result = get_option($option, $default);
49
  }
50
 
51
+ return $result;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
53
 
54
  /**
60
  *
61
  * @return bool
62
  *
63
+ * @since 6.3.0 Optimized for Multisite setup
64
+ * @since 6.0.0 Initial implementation of the method
65
+ *
66
  * @access public
67
+ * @version 6.3.0
68
  */
69
+ public static function updateOption($option, $data, $blog_id = null)
70
+ {
 
71
  if (is_multisite()) {
72
+ $result = update_blog_option(
73
+ ($blog_id ? $blog_id : get_current_blog_id()), $option, $data
74
+ );
 
 
 
 
 
75
  } else {
76
+ $result = update_option($option, $data);
77
  }
78
 
79
+ return $result;
80
  }
81
 
82
  /**
87
  *
88
  * @return bool
89
  *
90
+ * @since 6.3.0 Optimized for Multisite setup
91
+ * @since 6.0.0 Initial implementation of the method
92
+ *
93
  * @access public
94
+ * @version 6.3.0
95
  */
96
  public static function deleteOption($option, $blog_id = null)
97
  {
98
  if (is_multisite()) {
99
+ $result = delete_blog_option(
100
+ ($blog_id ? $blog_id : get_current_blog_id()), $option
101
+ );
 
 
 
 
 
102
  } else {
103
+ $result = delete_option($option);
104
  }
105
 
106
+ return $result;
107
  }
108
 
109
  /**
239
  AAM_Core_AccessSettings::DB_OPTION,
240
  AAM_Core_Config::DB_OPTION,
241
  AAM_Core_ConfigPress::DB_OPTION,
242
+ AAM_Core_Migration::DB_OPTION,
243
+ AAM_Service_AdminMenu::CACHE_DB_OPTION,
244
+ AAM_Service_Toolbar::DB_OPTION
245
  );
246
 
247
  foreach($options as $option) {
application/Core/AccessSettings.php CHANGED
@@ -10,11 +10,12 @@
10
  /**
11
  * AAM Access Settings repository
12
  *
 
13
  * @since 6.2.0 Added new hook `aam_updated_access_settings`
14
  * @since 6.0.0 Initial implementation of the class
15
  *
16
  * @package AAM
17
- * @version 6.2.0
18
  */
19
  class AAM_Core_AccessSettings
20
  {
@@ -153,6 +154,23 @@ class AAM_Core_AccessSettings
153
  return $result;
154
  }
155
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  /**
157
  * Reset all the settings
158
  *
10
  /**
11
  * AAM Access Settings repository
12
  *
13
+ * @since 6.3.0 Added new method `replace`
14
  * @since 6.2.0 Added new hook `aam_updated_access_settings`
15
  * @since 6.0.0 Initial implementation of the class
16
  *
17
  * @package AAM
18
+ * @version 6.3.0
19
  */
20
  class AAM_Core_AccessSettings
21
  {
154
  return $result;
155
  }
156
 
157
+ /**
158
+ * Replace all settings with new set
159
+ *
160
+ * @param array $settings
161
+ *
162
+ * @return boolean
163
+ *
164
+ * @access public
165
+ * @version 6.3.0
166
+ */
167
+ public function replace($settings)
168
+ {
169
+ $this->_settings = $settings;
170
+
171
+ return $this->save();
172
+ }
173
+
174
  /**
175
  * Reset all the settings
176
  *
application/Core/Config.php CHANGED
@@ -5,15 +5,16 @@
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
- * @version 6.0.0
10
  */
11
 
12
  /**
13
  * AAM Core Config
14
  *
 
 
 
15
  * @package AAM
16
- * @version 6.0.0
17
  */
18
  class AAM_Core_Config
19
  {
@@ -100,7 +101,25 @@ class AAM_Core_Config
100
  {
101
  self::$config[$option] = $value;
102
 
103
- //save config to database
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  return AAM_Core_API::updateOption(self::DB_OPTION, self::$config);
105
  }
106
 
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
  * AAM Core Config
12
  *
13
+ * @since 6.3.0 Added new method `replace`
14
+ * @since 6.0.0 Initial implementation of the class
15
+ *
16
  * @package AAM
17
+ * @version 6.3.0
18
  */
19
  class AAM_Core_Config
20
  {
101
  {
102
  self::$config[$option] = $value;
103
 
104
+ // Save config to database
105
+ return AAM_Core_API::updateOption(self::DB_OPTION, self::$config);
106
+ }
107
+
108
+ /**
109
+ * Replace the entire config
110
+ *
111
+ * @param array $config
112
+ *
113
+ * @return boolean
114
+ *
115
+ * @access public
116
+ * @version 6.3.0
117
+ */
118
+ public static function replace($config)
119
+ {
120
+ self::$config = $config;
121
+
122
+ // Save config to database
123
  return AAM_Core_API::updateOption(self::DB_OPTION, self::$config);
124
  }
125
 
application/Core/ConfigPress.php CHANGED
@@ -37,16 +37,6 @@ final class AAM_Core_ConfigPress
37
  */
38
  protected $config = null;
39
 
40
- /**
41
- * Raw config text
42
- *
43
- * @var string
44
- *
45
- * @access protected
46
- * @version 6.0.0
47
- */
48
- protected $rawConfig = null;
49
-
50
  /**
51
  * Constructor
52
  *
@@ -58,7 +48,7 @@ final class AAM_Core_ConfigPress
58
  protected function __construct()
59
  {
60
  try {
61
- $reader = new AAM_Core_ConfigPress_Reader;
62
  $this->config = $reader->parseString($this->read());
63
  } catch (Exception $e) {
64
  AAM_Core_Console::add($e->getMessage());
@@ -76,9 +66,9 @@ final class AAM_Core_ConfigPress
76
  */
77
  public function read()
78
  {
79
- $config = AAM_Core_API::getOption(self::DB_OPTION, 'null');
80
 
81
- return ($config === 'null' ? '' : $config);
82
  }
83
 
84
  /**
37
  */
38
  protected $config = null;
39
 
 
 
 
 
 
 
 
 
 
 
40
  /**
41
  * Constructor
42
  *
48
  protected function __construct()
49
  {
50
  try {
51
+ $reader = new AAM_Core_ConfigPress_Reader;
52
  $this->config = $reader->parseString($this->read());
53
  } catch (Exception $e) {
54
  AAM_Core_Console::add($e->getMessage());
66
  */
67
  public function read()
68
  {
69
+ $config = AAM_Core_API::getOption(self::DB_OPTION, null);
70
 
71
+ return (empty($config) ? '' : $config);
72
  }
73
 
74
  /**
application/Core/Migration.php CHANGED
@@ -37,12 +37,15 @@ final class AAM_Core_Migration
37
  *
38
  * @return array
39
  *
 
 
 
40
  * @access public
41
- * @version 6.0.0
42
  */
43
  public static function getPending()
44
  {
45
- $completed = AAM_Core_API::getOption(self::DB_OPTION, array());
46
  $pending = array();
47
 
48
  foreach (self::getDirectoryIterator() as $mg) {
@@ -74,12 +77,15 @@ final class AAM_Core_Migration
74
  *
75
  * @return array
76
  *
 
 
 
77
  * @access public
78
- * @version 6.0.0
79
  */
80
  public static function getFailureLog()
81
  {
82
- return AAM_Core_API::getOption(self::DB_FAILURE_OPTION, array());
83
  }
84
 
85
  /**
@@ -102,12 +108,15 @@ final class AAM_Core_Migration
102
  *
103
  * @return boolean
104
  *
 
 
 
105
  * @access public
106
- * @version 6.0.0
107
  */
108
  public static function storeCompletedScript($file_name)
109
  {
110
- $completed = AAM_Core_API::getOption(self::DB_OPTION, array());
111
  $completed[] = $file_name;
112
 
113
  return AAM_Core_API::updateOption(self::DB_OPTION, $completed);
37
  *
38
  * @return array
39
  *
40
+ * @since 6.3.0 Optimized AAM_Core_API::getOption call
41
+ * @since 6.0.0 Initial implementation of the method
42
+ *
43
  * @access public
44
+ * @version 6.3.0
45
  */
46
  public static function getPending()
47
  {
48
+ $completed = AAM_Core_API::getOption(self::DB_OPTION);
49
  $pending = array();
50
 
51
  foreach (self::getDirectoryIterator() as $mg) {
77
  *
78
  * @return array
79
  *
80
+ * @since 6.3.0 Optimized AAM_Core_API::getOption call
81
+ * @since 6.0.0 Initial implementation of the method
82
+ *
83
  * @access public
84
+ * @version 6.3.0
85
  */
86
  public static function getFailureLog()
87
  {
88
+ return AAM_Core_API::getOption(self::DB_FAILURE_OPTION);
89
  }
90
 
91
  /**
108
  *
109
  * @return boolean
110
  *
111
+ * @since 6.3.0 Optimized AAM_Core_API::getOption call
112
+ * @since 6.0.0 Initial implementation of the method
113
+ *
114
  * @access public
115
+ * @version 6.3.0
116
  */
117
  public static function storeCompletedScript($file_name)
118
  {
119
+ $completed = AAM_Core_API::getOption(self::DB_OPTION);
120
  $completed[] = $file_name;
121
 
122
  return AAM_Core_API::updateOption(self::DB_OPTION, $completed);
application/Core/Object/Uri.php CHANGED
@@ -10,11 +10,12 @@
10
  /**
11
  * URI object
12
  *
 
13
  * @since 6.1.0 Fixed bug with incorrectly halted inheritance mechanism
14
  * @since 6.0.0 Initial implementation of the class
15
  *
16
  * @package AAM
17
- * @version 6.1.0
18
  */
19
  class AAM_Core_Object_Uri extends AAM_Core_Object
20
  {
@@ -55,8 +56,11 @@ class AAM_Core_Object_Uri extends AAM_Core_Object
55
  *
56
  * @return null|array
57
  *
 
 
 
58
  * @access public
59
- * @version 6.0.0
60
  */
61
  public function findMatch($s, $params = array())
62
  {
@@ -71,17 +75,22 @@ class AAM_Core_Object_Uri extends AAM_Core_Object
71
  }
72
 
73
  // Normalize the search and target URIs
74
- $s = rtrim($s, '/');
75
- $meta['path'] = rtrim(isset($meta['path']) ? $meta['path'] : '', '/');
76
- $regex = '@^' . preg_quote($meta['path']) . '$@';
77
 
78
- // Perform the initial match for the base URI
79
- $uri_matched = apply_filters(
80
- 'aam_uri_match_filter', preg_match($regex, $s), $uri, $s
81
- );
 
 
 
 
 
82
 
83
  // Perform the initial match for the query params if defined
84
- $query_matched = empty($out) || (count(array_intersect_assoc($params, $out)) === count($out));
 
85
 
86
  if ($uri_matched && $query_matched) {
87
  $match = $rule;
@@ -91,6 +100,28 @@ class AAM_Core_Object_Uri extends AAM_Core_Object
91
  return $match;
92
  }
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  /**
95
  * Delete specified URI rule
96
  *
@@ -98,20 +129,23 @@ class AAM_Core_Object_Uri extends AAM_Core_Object
98
  *
99
  * @return boolean
100
  *
 
 
 
101
  * @access public
102
- * @version 6.0.0
103
  */
104
  public function delete($uri)
105
  {
106
- $option = $this->getOption();
107
 
108
  if (isset($option[$uri])) {
109
  unset($option[$uri]);
110
 
111
- $this->setOption($option);
112
 
113
  $result = $this->getSubject()->updateOption(
114
- $this->getOption(), self::OBJECT_TYPE
115
  );
116
  }
117
 
10
  /**
11
  * URI object
12
  *
13
+ * @since 6.3.0 Fixed bug where home page could not be protected
14
  * @since 6.1.0 Fixed bug with incorrectly halted inheritance mechanism
15
  * @since 6.0.0 Initial implementation of the class
16
  *
17
  * @package AAM
18
+ * @version 6.3.0
19
  */
20
  class AAM_Core_Object_Uri extends AAM_Core_Object
21
  {
56
  *
57
  * @return null|array
58
  *
59
+ * @since 6.3.0 Fixed bug https://github.com/aamplugin/advanced-access-manager/issues/17
60
+ * @since 6.0.0 Initial implementation of the method
61
+ *
62
  * @access public
63
+ * @version 6.3.0
64
  */
65
  public function findMatch($s, $params = array())
66
  {
75
  }
76
 
77
  // Normalize the search and target URIs
78
+ $s = rtrim($s, '/');
79
+ $path = rtrim(isset($meta['path']) ? $meta['path'] : '', '/');
 
80
 
81
+ // Check if two URIs are equal
82
+ $uri_matched = ($s === $path);
83
+
84
+ // If match already found, no need to do additional checks
85
+ if ($uri_matched === false) {
86
+ $uri_matched = apply_filters(
87
+ 'aam_uri_match_filter', false, $uri, $s
88
+ );
89
+ }
90
 
91
  // Perform the initial match for the query params if defined
92
+ $same = array_intersect_assoc($params, $out);
93
+ $query_matched = empty($out) || (count($same) === count($out));
94
 
95
  if ($uri_matched && $query_matched) {
96
  $match = $rule;
100
  return $match;
101
  }
102
 
103
+ /**
104
+ * Check if exact URI is defined
105
+ *
106
+ * @param string $uri
107
+ * @param boolean $explicit
108
+ *
109
+ * @return boolean
110
+ *
111
+ * @access public
112
+ * @version 6.3.0
113
+ */
114
+ public function has($uri, $explicit = true)
115
+ {
116
+ if ($explicit) {
117
+ $option = $this->getExplicitOption();
118
+ } else {
119
+ $option = $this->getOption();
120
+ }
121
+
122
+ return isset($option[$uri]);
123
+ }
124
+
125
  /**
126
  * Delete specified URI rule
127
  *
129
  *
130
  * @return boolean
131
  *
132
+ * @since 6.3.0 Fixed bug https://github.com/aamplugin/advanced-access-manager/issues/35
133
+ * @since 6.0.0 Initial implementation of the method
134
+ *
135
  * @access public
136
+ * @version 6.3.0
137
  */
138
  public function delete($uri)
139
  {
140
+ $option = $this->getExplicitOption();
141
 
142
  if (isset($option[$uri])) {
143
  unset($option[$uri]);
144
 
145
+ $this->setExplicitOption($option);
146
 
147
  $result = $this->getSubject()->updateOption(
148
+ $this->getExplicitOption(), self::OBJECT_TYPE
149
  );
150
  }
151
 
application/Core/Policy/Generator.php CHANGED
@@ -10,11 +10,13 @@
10
  /**
11
  * AAM core policy generator
12
  *
 
 
13
  * @since 6.2.2 Fixed bug with incompatibility with PHP lower than 7.0.0
14
  * @since 6.2.0 Initial implementation of the class
15
  *
16
  * @package AAM
17
- * @version 6.2.2
18
  */
19
  class AAM_Core_Policy_Generator
20
  {
@@ -304,15 +306,20 @@ class AAM_Core_Policy_Generator
304
  *
305
  * @return array
306
  *
 
307
  * @since 6.2.2 Fixed bug that caused fatal error for PHP lower than 7.0.0
308
  * @since 6.2.0 Initial implementation of the method
309
  *
310
  * @access private
311
- * @version 6.2.2
312
  */
313
  private function _convertToPostStatements($resource, $options)
314
  {
315
- $allowed = $denied = $statements = array();
 
 
 
 
316
 
317
  foreach($options as $option => $settings) {
318
  // Compute Effect property
@@ -362,11 +369,11 @@ class AAM_Core_Policy_Generator
362
  $item['Condition']['Equals'] = $conditions;
363
  }
364
 
365
- $statements[] = $item;
366
  break;
367
 
368
  case 'teaser':
369
- $statements[] = array(
370
  'Effect' => ($effect === 'denied' ? 'deny' : 'allow'),
371
  'Action' => 'Read',
372
  'Resource' => $resource,
@@ -379,7 +386,7 @@ class AAM_Core_Policy_Generator
379
  break;
380
 
381
  case 'limited':
382
- $statements[] = array(
383
  'Effect' => ($effect === 'denied' ? 'deny' : 'allow'),
384
  'Action' => 'Read',
385
  'Resource' => $resource,
@@ -405,8 +412,8 @@ class AAM_Core_Policy_Generator
405
  $metadata['Callback'] = trim($settings['destination']);
406
  }
407
 
408
- $statements[] = array(
409
- 'Effect' => ($effect === 'denied' ? 'deny' : 'allow'),
410
  'Action' => 'Read',
411
  'Resource' => $resource,
412
  'Metadata' => array(
@@ -416,7 +423,7 @@ class AAM_Core_Policy_Generator
416
  break;
417
 
418
  case 'protected':
419
- $statements[] = array(
420
  'Effect' => ($effect === 'denied' ? 'deny' : 'allow'),
421
  'Action' => 'Read',
422
  'Resource' => $resource,
@@ -429,7 +436,7 @@ class AAM_Core_Policy_Generator
429
  break;
430
 
431
  case 'ceased':
432
- $statements[] = array(
433
  'Effect' => ($effect === 'denied' ? 'deny' : 'allow'),
434
  'Action' => 'Read',
435
  'Resource' => $resource,
@@ -442,34 +449,42 @@ class AAM_Core_Policy_Generator
442
  break;
443
 
444
  default:
 
 
 
 
 
 
 
 
445
  break;
446
  }
447
 
448
  if ($action !== null) {
449
  if ($effect === 'allowed') {
450
- $allowed[] = $resource . ':' . $action;
451
  } else {
452
- $denied[] = $resource . ':' . $action;
453
  }
454
  }
455
  }
456
 
457
- // Finally prepare the statements
458
- if (!empty($denied)) {
459
- $statements[] = array(
460
  'Effect' => 'deny',
461
- 'Resource' => $denied
462
  );
463
  }
464
 
465
- if (!empty($allowed)) {
466
- $statements[] = array(
467
  'Effect' => 'allow',
468
- 'Resource' => $allowed
469
  );
470
  }
471
 
472
- return $statements;
473
  }
474
 
475
  /**
10
  /**
11
  * AAM core policy generator
12
  *
13
+ * @since 6.3.0 Refactored post statement generation to cover the bug
14
+ * https://github.com/aamplugin/advanced-access-manager/issues/22
15
  * @since 6.2.2 Fixed bug with incompatibility with PHP lower than 7.0.0
16
  * @since 6.2.0 Initial implementation of the class
17
  *
18
  * @package AAM
19
+ * @version 6.3.0
20
  */
21
  class AAM_Core_Policy_Generator
22
  {
306
  *
307
  * @return array
308
  *
309
+ * @since 6.3.0 Fixed bug https://github.com/aamplugin/advanced-access-manager/issues/22
310
  * @since 6.2.2 Fixed bug that caused fatal error for PHP lower than 7.0.0
311
  * @since 6.2.0 Initial implementation of the method
312
  *
313
  * @access private
314
+ * @version 6.3.0
315
  */
316
  private function _convertToPostStatements($resource, $options)
317
  {
318
+ $tree = (object) array(
319
+ 'allowed' => array(),
320
+ 'denied' => array(),
321
+ 'statements' => array()
322
+ );
323
 
324
  foreach($options as $option => $settings) {
325
  // Compute Effect property
369
  $item['Condition']['Equals'] = $conditions;
370
  }
371
 
372
+ $tree->statements[] = $item;
373
  break;
374
 
375
  case 'teaser':
376
+ $tree->statements[] = array(
377
  'Effect' => ($effect === 'denied' ? 'deny' : 'allow'),
378
  'Action' => 'Read',
379
  'Resource' => $resource,
386
  break;
387
 
388
  case 'limited':
389
+ $tree->statements[] = array(
390
  'Effect' => ($effect === 'denied' ? 'deny' : 'allow'),
391
  'Action' => 'Read',
392
  'Resource' => $resource,
412
  $metadata['Callback'] = trim($settings['destination']);
413
  }
414
 
415
+ $tree->statements[] = array(
416
+ 'Effect' => ($effect === 'denied' ? 'deny' : 'allow'),
417
  'Action' => 'Read',
418
  'Resource' => $resource,
419
  'Metadata' => array(
423
  break;
424
 
425
  case 'protected':
426
+ $tree->statements[] = array(
427
  'Effect' => ($effect === 'denied' ? 'deny' : 'allow'),
428
  'Action' => 'Read',
429
  'Resource' => $resource,
436
  break;
437
 
438
  case 'ceased':
439
+ $tree->statements[] = array(
440
  'Effect' => ($effect === 'denied' ? 'deny' : 'allow'),
441
  'Action' => 'Read',
442
  'Resource' => $resource,
449
  break;
450
 
451
  default:
452
+ do_action(
453
+ 'aam_post_option_to_policy_action',
454
+ $resource,
455
+ $option,
456
+ $effect,
457
+ $settings,
458
+ $tree
459
+ );
460
  break;
461
  }
462
 
463
  if ($action !== null) {
464
  if ($effect === 'allowed') {
465
+ $tree->allowed[] = $resource . ':' . $action;
466
  } else {
467
+ $tree->denied[] = $resource . ':' . $action;
468
  }
469
  }
470
  }
471
 
472
+ // Finally prepare the consolidated statements
473
+ if (!empty($tree->denied)) {
474
+ $tree->statements[] = array(
475
  'Effect' => 'deny',
476
+ 'Resource' => $tree->denied
477
  );
478
  }
479
 
480
+ if (!empty($tree->allowed)) {
481
+ $tree->statements[] = array(
482
  'Effect' => 'allow',
483
+ 'Resource' => $tree->allowed
484
  );
485
  }
486
 
487
+ return $tree->statements;
488
  }
489
 
490
  /**
application/Core/Policy/Token.php CHANGED
@@ -10,6 +10,8 @@
10
  /**
11
  * AAM core policy token evaluator
12
  *
 
 
13
  * @since 6.2.1 Added POLICY_META token
14
  * @since 6.2.0 Enhanced access policy with more tokens. DATETIME now returns time in
15
  * UTC timezone
@@ -17,7 +19,7 @@
17
  * @since 6.0.0 Initial implementation of the class
18
  *
19
  * @package AAM
20
- * @version 6.2.1
21
  */
22
  class AAM_Core_Policy_Token
23
  {
@@ -27,6 +29,8 @@ class AAM_Core_Policy_Token
27
  *
28
  * @var array
29
  *
 
 
30
  * @since 6.2.1 Added `POLICY_META` token
31
  * @since 6.2.0 Added `POLICY_PARAM`, `WP_SITE` token & changed the
32
  * DATETIME callback
@@ -34,27 +38,29 @@ class AAM_Core_Policy_Token
34
  * @since 6.0.0 Initial implementation of the property
35
  *
36
  * @access protected
37
- * @version 6.2.1
38
  */
39
  protected static $map = array(
40
- 'USER' => 'AAM_Core_Policy_Token::getUserValue',
41
- 'USER_OPTION' => 'AAM_Core_Policy_Token::getUserOptionValue',
42
- 'USER_META' => 'AAM_Core_Policy_Token::getUserMetaValue',
43
- 'DATETIME' => 'AAM_Core_Policy_Token::getDatetime',
44
- 'HTTP_GET' => 'AAM_Core_Request::get',
45
- 'HTTP_QUERY' => 'AAM_Core_Request::get',
46
- 'HTTP_POST' => 'AAM_Core_Request::post',
47
- 'HTTP_COOKIE' => 'AAM_Core_Request::cookie',
48
- 'PHP_SERVER' => 'AAM_Core_Request::server',
49
- 'ARGS' => 'AAM_Core_Policy_Token::getArgValue',
50
- 'ENV' => 'getenv',
51
- 'CONST' => 'AAM_Core_Policy_Token::getConstant',
52
- 'WP_OPTION' => 'AAM_Core_API::getOption',
53
- 'JWT' => 'AAM_Core_Policy_Token::getJwtClaim',
54
- 'AAM_CONFIG' => 'AAM_Core_Policy_Token::getConfig',
55
- 'POLICY_PARAM' => 'AAM_Core_Policy_Token::getParam',
56
- 'POLICY_META' => 'AAM_Core_Policy_Token::getPolicyMeta',
57
- 'WP_SITE' => 'AAM_Core_Policy_Token::getSiteParam'
 
 
58
  );
59
 
60
  /**
@@ -125,12 +131,16 @@ class AAM_Core_Policy_Token
125
  *
126
  * @return mixed
127
  *
 
 
 
 
128
  * @access protected
129
- * @version 6.0.0
130
  */
131
  protected static function getUserValue($prop)
132
  {
133
- $user = AAM::getUser();
134
 
135
  switch (strtolower($prop)) {
136
  case 'ip':
@@ -145,7 +155,9 @@ class AAM_Core_Policy_Token
145
 
146
  case 'capabilities':
147
  case 'caps':
148
- foreach ((array) $user->allcaps as $cap => $effect) {
 
 
149
  if (!empty($effect)) {
150
  $value[] = $cap;
151
  }
@@ -153,7 +165,7 @@ class AAM_Core_Policy_Token
153
  break;
154
 
155
  default:
156
- $value = (is_a($user, 'AAM_Core_Subject_User') ? $user->{$prop} : null);
157
  break;
158
  }
159
 
@@ -258,6 +270,27 @@ class AAM_Core_Policy_Token
258
  return (defined($const) ? constant($const) : null);
259
  }
260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  /**
262
  * Get AAM configuration
263
  *
@@ -295,14 +328,17 @@ class AAM_Core_Policy_Token
295
  *
296
  * @return mixed
297
  *
 
 
 
298
  * @access protected
299
- * @version 6.2.1
300
  */
301
  protected static function getPolicyMeta($meta)
302
  {
303
- list($policyId, $param) = explode('.', $meta, 2);
304
 
305
- return get_post_meta($policyId, $param, true);
306
  }
307
 
308
  /**
@@ -355,4 +391,34 @@ class AAM_Core_Policy_Token
355
  return $result;
356
  }
357
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358
  }
10
  /**
11
  * AAM core policy token evaluator
12
  *
13
+ * @since 6.3.0 Fixed bug that was causing fatal error policies that have conditions
14
+ * defined for Capability & Role resources
15
  * @since 6.2.1 Added POLICY_META token
16
  * @since 6.2.0 Enhanced access policy with more tokens. DATETIME now returns time in
17
  * UTC timezone
19
  * @since 6.0.0 Initial implementation of the class
20
  *
21
  * @package AAM
22
+ * @version 6.3.0
23
  */
24
  class AAM_Core_Policy_Token
25
  {
29
  *
30
  * @var array
31
  *
32
+ * @since 6.3.0 Added PHP_GLOBAL, WP_NETWORK_OPTION token and changed
33
+ * WP_OPTION callback
34
  * @since 6.2.1 Added `POLICY_META` token
35
  * @since 6.2.0 Added `POLICY_PARAM`, `WP_SITE` token & changed the
36
  * DATETIME callback
38
  * @since 6.0.0 Initial implementation of the property
39
  *
40
  * @access protected
41
+ * @version 6.3.0
42
  */
43
  protected static $map = array(
44
+ 'USER' => 'AAM_Core_Policy_Token::getUserValue',
45
+ 'USER_OPTION' => 'AAM_Core_Policy_Token::getUserOptionValue',
46
+ 'USER_META' => 'AAM_Core_Policy_Token::getUserMetaValue',
47
+ 'DATETIME' => 'AAM_Core_Policy_Token::getDatetime',
48
+ 'HTTP_GET' => 'AAM_Core_Request::get',
49
+ 'HTTP_QUERY' => 'AAM_Core_Request::get',
50
+ 'HTTP_POST' => 'AAM_Core_Request::post',
51
+ 'HTTP_COOKIE' => 'AAM_Core_Request::cookie',
52
+ 'PHP_SERVER' => 'AAM_Core_Request::server',
53
+ 'PHP_GLOBAL' => 'AAM_Core_Policy_Token::getGlobalVariable',
54
+ 'ARGS' => 'AAM_Core_Policy_Token::getArgValue',
55
+ 'ENV' => 'getenv',
56
+ 'CONST' => 'AAM_Core_Policy_Token::getConstant',
57
+ 'WP_OPTION' => 'AAM_Core_Policy_Token::getWPOption',
58
+ 'JWT' => 'AAM_Core_Policy_Token::getJwtClaim',
59
+ 'AAM_CONFIG' => 'AAM_Core_Policy_Token::getConfig',
60
+ 'POLICY_PARAM' => 'AAM_Core_Policy_Token::getParam',
61
+ 'POLICY_META' => 'AAM_Core_Policy_Token::getPolicyMeta',
62
+ 'WP_SITE' => 'AAM_Core_Policy_Token::getSiteParam',
63
+ 'WP_NETWORK_OPTION' => 'AAM_Core_Policy_Token::getNetworkOption',
64
  );
65
 
66
  /**
131
  *
132
  * @return mixed
133
  *
134
+ * @since 6.3.0 Fixed bug that caused "Fatal error: Allowed memory size of XXX
135
+ * bytes exhausted"
136
+ * @since 6.0.0 Initial implementation of the method
137
+ *
138
  * @access protected
139
+ * @version 6.3.0
140
  */
141
  protected static function getUserValue($prop)
142
  {
143
+ $user = wp_get_current_user();
144
 
145
  switch (strtolower($prop)) {
146
  case 'ip':
155
 
156
  case 'capabilities':
157
  case 'caps':
158
+ $allcaps = is_a($user, 'WP_User') ? (array)$user->allcaps : array();
159
+
160
+ foreach ($allcaps as $cap => $effect) {
161
  if (!empty($effect)) {
162
  $value[] = $cap;
163
  }
165
  break;
166
 
167
  default:
168
+ $value = (is_a($user, 'WP_User') ? $user->{$prop} : null);
169
  break;
170
  }
171
 
270
  return (defined($const) ? constant($const) : null);
271
  }
272
 
273
+ /**
274
+ * Get database option
275
+ *
276
+ * @param string $option
277
+ *
278
+ * @return mixed
279
+ *
280
+ * @access protected
281
+ * @version 6.3.0
282
+ */
283
+ protected static function getWPOption($option)
284
+ {
285
+ if (is_multisite()) {
286
+ $result = get_blog_option(get_current_blog_id(), $option);
287
+ } else {
288
+ $result = get_option($option);
289
+ }
290
+
291
+ return $result;
292
+ }
293
+
294
  /**
295
  * Get AAM configuration
296
  *
328
  *
329
  * @return mixed
330
  *
331
+ * @since 6.3.0 Fixed potential bug https://github.com/aamplugin/advanced-access-manager/issues/38
332
+ * @since 6.2.1 Initial implementation of the method
333
+ *
334
  * @access protected
335
+ * @version 6.3.0
336
  */
337
  protected static function getPolicyMeta($meta)
338
  {
339
+ $parts = explode('.', $meta, 2);
340
 
341
+ return get_post_meta(intval($parts[0]), $parts[1], true);
342
  }
343
 
344
  /**
391
  return $result;
392
  }
393
 
394
+ /**
395
+ * Get global variable's value
396
+ *
397
+ * @param string $var
398
+ *
399
+ * @return mixed
400
+ *
401
+ * @access protected
402
+ * @version 6.3.0
403
+ */
404
+ protected static function getGlobalVariable($var)
405
+ {
406
+ return (isset($GLOBALS[$var]) ? $GLOBALS[$var] : null);
407
+ }
408
+
409
+ /**
410
+ * Get network option
411
+ *
412
+ * @param string $option
413
+ *
414
+ * @return mixed
415
+ *
416
+ * @access protected
417
+ * @version 6.3.0
418
+ */
419
+ protected static function getNetworkOption($option)
420
+ {
421
+ return get_site_option($option, null);
422
+ }
423
+
424
  }
application/Migration/2019_06_30-base.php CHANGED
@@ -14,10 +14,10 @@ namespace AAM\Migration;
14
  use WP_Error,
15
  AAM_Core_API,
16
  AAM_Core_Config,
 
17
  AAM_Core_Migration,
18
  AAM_Core_ConfigPress,
19
  AAM_Addon_Repository,
20
- AAM_Core_AccessSettings,
21
  AAM_Backend_Feature_Settings_Core,
22
  AAM_Core_Contract_MigrationInterface,
23
  AAM_Backend_Feature_Settings_Content,
@@ -238,9 +238,6 @@ class Migration600 implements AAM_Core_Contract_MigrationInterface
238
  AAM_Core_API::deleteOption($option->option_name);
239
  break;
240
 
241
- case AAM_Core_AccessSettings::DB_OPTION:
242
- case AAM_Core_Config::DB_OPTION:
243
- case AAM_Core_ConfigPress::DB_OPTION:
244
  case AAM_Core_Migration::DB_OPTION:
245
  case AAM_Core_Migration::DB_FAILURE_OPTION:
246
  // Silently skip in case somebody forces to rerun the entire
@@ -368,12 +365,13 @@ class Migration600 implements AAM_Core_Contract_MigrationInterface
368
  *
369
  * @return void
370
  *
 
371
  * @since 6.0.1 Fixed the bug with `show_admin_bar` not converted to
372
  * `aam_show_toolbar`
373
  * @since 6.0.0 Initialize implementation of the method
374
  *
375
  * @access protected
376
- * @version 6.0.1
377
  */
378
  protected function convertCapabilities()
379
  {
@@ -433,18 +431,19 @@ class Migration600 implements AAM_Core_Contract_MigrationInterface
433
  *
434
  * @return void
435
  *
 
436
  * @since 6.0.5 Removed error emission
437
  * @since 6.0.1 Any errors are pushed directly to the $this->errors array instead
438
  * of returning them
439
  * @since 6.0.0 Initialize implementation of the method
440
  *
441
  * @access private
442
- * @version 6.0.5
443
  */
444
  private function _convertExtensionRegistry($option)
445
  {
446
  AAM_Core_API::updateOption(
447
- AAM_Addon_Repository::DB_OPTION, $option->option_value, 'site'
448
  );
449
  }
450
 
@@ -455,13 +454,14 @@ class Migration600 implements AAM_Core_Contract_MigrationInterface
455
  *
456
  * @return void
457
  *
 
458
  * @since 6.0.5 Removed error emission
459
  * @since 6.0.1 Any errors are pushed directly to the $this->errors array instead
460
  * of returning them
461
  * @since 6.0.0 Initialize implementation of the method
462
  *
463
  * @access private
464
- * @version 6.0.1
465
  */
466
  private function _convertSettings($option)
467
  {
@@ -502,9 +502,7 @@ class Migration600 implements AAM_Core_Contract_MigrationInterface
502
  }
503
  }
504
 
505
- AAM_Core_API::updateOption(
506
- AAM_Core_Config::DB_OPTION, $converted, 'site'
507
- );
508
  }
509
  }
510
 
14
  use WP_Error,
15
  AAM_Core_API,
16
  AAM_Core_Config,
17
+ AAM_Core_AccessSettings,
18
  AAM_Core_Migration,
19
  AAM_Core_ConfigPress,
20
  AAM_Addon_Repository,
 
21
  AAM_Backend_Feature_Settings_Core,
22
  AAM_Core_Contract_MigrationInterface,
23
  AAM_Backend_Feature_Settings_Content,
238
  AAM_Core_API::deleteOption($option->option_name);
239
  break;
240
 
 
 
 
241
  case AAM_Core_Migration::DB_OPTION:
242
  case AAM_Core_Migration::DB_FAILURE_OPTION:
243
  // Silently skip in case somebody forces to rerun the entire
365
  *
366
  * @return void
367
  *
368
+ * @since 6.3.0 Optimized for multisite setup
369
  * @since 6.0.1 Fixed the bug with `show_admin_bar` not converted to
370
  * `aam_show_toolbar`
371
  * @since 6.0.0 Initialize implementation of the method
372
  *
373
  * @access protected
374
+ * @version 6.3.0
375
  */
376
  protected function convertCapabilities()
377
  {
431
  *
432
  * @return void
433
  *
434
+ * @since 6.3.0 Optimized for Multisite setup
435
  * @since 6.0.5 Removed error emission
436
  * @since 6.0.1 Any errors are pushed directly to the $this->errors array instead
437
  * of returning them
438
  * @since 6.0.0 Initialize implementation of the method
439
  *
440
  * @access private
441
+ * @version 6.3.0
442
  */
443
  private function _convertExtensionRegistry($option)
444
  {
445
  AAM_Core_API::updateOption(
446
+ AAM_Addon_Repository::DB_OPTION, $option->option_value
447
  );
448
  }
449
 
454
  *
455
  * @return void
456
  *
457
+ * @since 6.3.0 Optimized for Multisite setup
458
  * @since 6.0.5 Removed error emission
459
  * @since 6.0.1 Any errors are pushed directly to the $this->errors array instead
460
  * of returning them
461
  * @since 6.0.0 Initialize implementation of the method
462
  *
463
  * @access private
464
+ * @version 6.3.0
465
  */
466
  private function _convertSettings($option)
467
  {
502
  }
503
  }
504
 
505
+ AAM_Core_Config::replace($converted);
 
 
506
  }
507
  }
508
 
application/Migration/2019_11_20-base.php CHANGED
@@ -5,8 +5,6 @@
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
- * @version 6.0.1
10
  */
11
 
12
  namespace AAM\Migration;
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
  namespace AAM\Migration;
application/Migration/2019_12_01-base.php CHANGED
@@ -29,17 +29,16 @@ class Migration610 implements AAM_Core_Contract_MigrationInterface
29
  /**
30
  * @inheritdoc
31
  *
 
32
  * @since 6.2.0 Removed failure log clean-up. Delegating this to the latest
33
  * migration script
34
  * @since 6.1.0 Initial implementation of the method
35
  *
36
- * @version 6.2.0
37
  */
38
  public function run()
39
  {
40
- $list = AAM_Core_API::getOption(
41
- AAM_Addon_Repository::DB_OPTION, array(), 'site'
42
- );
43
 
44
  if (is_array($list)) {
45
  $converted = array();
@@ -58,9 +57,7 @@ class Migration610 implements AAM_Core_Contract_MigrationInterface
58
  }
59
  }
60
 
61
- AAM_Core_API::updateOption(
62
- AAM_Addon_Repository::DB_OPTION, $converted, 'site'
63
- );
64
  }
65
 
66
  // Finally store this script as completed
29
  /**
30
  * @inheritdoc
31
  *
32
+ * @since 6.3.0 Optimized for Multisite setup
33
  * @since 6.2.0 Removed failure log clean-up. Delegating this to the latest
34
  * migration script
35
  * @since 6.1.0 Initial implementation of the method
36
  *
37
+ * @version 6.3.0
38
  */
39
  public function run()
40
  {
41
+ $list = AAM_Core_API::getOption(AAM_Addon_Repository::DB_OPTION);
 
 
42
 
43
  if (is_array($list)) {
44
  $converted = array();
57
  }
58
  }
59
 
60
+ AAM_Core_API::updateOption(AAM_Addon_Repository::DB_OPTION, $converted);
 
 
61
  }
62
 
63
  // Finally store this script as completed
application/Service/AccessPolicy.php CHANGED
@@ -10,12 +10,13 @@
10
  /**
11
  * Access Policy service
12
  *
 
13
  * @since 6.2.0 Bug fixing and enhancements for the multisite support
14
  * @since 6.1.0 Changed the way access policy manager is obtained
15
  * @since 6.0.0 Initial implementation of the class
16
  *
17
  * @package AAM
18
- * @version 6.2.0
19
  */
20
  class AAM_Service_AccessPolicy
21
  {
@@ -124,16 +125,23 @@ class AAM_Service_AccessPolicy
124
  *
125
  * @return array
126
  *
 
 
 
127
  * @access public
128
- * @version 6.0.0
129
  */
130
  public function managePolicyContent($data)
131
  {
132
  if (isset($data['post_type']) && ($data['post_type'] === self::POLICY_CPT)) {
133
  $content = $this->getFromPost('aam-policy');
134
 
135
- if (empty($data['post_content'])) {
136
- $content = AAM_Backend_Feature_Main_Policy::getDefaultPolicy();
 
 
 
 
137
  }
138
 
139
  // Reformat the policy content
@@ -875,11 +883,12 @@ class AAM_Service_AccessPolicy
875
  *
876
  * @return array
877
  *
 
878
  * @since 6.1.0 Changed the way access policy manage is obtained
879
  * @since 6.0.0 Initial implementation of the method
880
  *
881
  * @access public
882
- * @version 6.1.0
883
  */
884
  public function filterPlugins($plugins)
885
  {
@@ -887,8 +896,8 @@ class AAM_Service_AccessPolicy
887
  $filtered = array();
888
 
889
  foreach($plugins as $id => $plugin) {
890
- list($slug) = explode('/', $id);
891
- $resource = AAM_Core_Policy_Resource::PLUGIN . ":{$slug}:WP:list";
892
 
893
  if ($manager->isAllowed($resource) !== false) {
894
  $filtered[$id] = $plugin;
10
  /**
11
  * Access Policy service
12
  *
13
+ * @since 6.3.0 Removed dependency on PHP core `list` function
14
  * @since 6.2.0 Bug fixing and enhancements for the multisite support
15
  * @since 6.1.0 Changed the way access policy manager is obtained
16
  * @since 6.0.0 Initial implementation of the class
17
  *
18
  * @package AAM
19
+ * @version 6.3.0
20
  */
21
  class AAM_Service_AccessPolicy
22
  {
125
  *
126
  * @return array
127
  *
128
+ * @since 6.3.0 Enhanced per https://github.com/aamplugin/advanced-access-manager/issues/27
129
+ * @since 6.0.0 Initial implementation of the method
130
+ *
131
  * @access public
132
+ * @version 6.3.0
133
  */
134
  public function managePolicyContent($data)
135
  {
136
  if (isset($data['post_type']) && ($data['post_type'] === self::POLICY_CPT)) {
137
  $content = $this->getFromPost('aam-policy');
138
 
139
+ if (empty($content)) {
140
+ if (empty($data['post_content'])) {
141
+ $content = AAM_Backend_Feature_Main_Policy::getDefaultPolicy();
142
+ } else {
143
+ $content = $data['post_content'];
144
+ }
145
  }
146
 
147
  // Reformat the policy content
883
  *
884
  * @return array
885
  *
886
+ * @since 6.3.0 Fixed potential bug https://github.com/aamplugin/advanced-access-manager/issues/38
887
  * @since 6.1.0 Changed the way access policy manage is obtained
888
  * @since 6.0.0 Initial implementation of the method
889
  *
890
  * @access public
891
+ * @version 6.3.0
892
  */
893
  public function filterPlugins($plugins)
894
  {
896
  $filtered = array();
897
 
898
  foreach($plugins as $id => $plugin) {
899
+ $parts = explode('/', $id);
900
+ $resource = AAM_Core_Policy_Resource::PLUGIN . ":{$parts[0]}:WP:list";
901
 
902
  if ($manager->isAllowed($resource) !== false) {
903
  $filtered[$id] = $plugin;
application/Service/Content.php CHANGED
@@ -193,7 +193,7 @@ class AAM_Service_Content
193
  add_filter('map_meta_cap', array($this, 'filterMetaMaps'), 999, 4);
194
 
195
  // Get control over commenting stuff
196
- add_filter('comments_open', function($open, $id) {
197
  $object = AAM::getUser()->getObject('post', $id);
198
 
199
  // If Leave Comments option is defined then override the default status.
@@ -209,8 +209,8 @@ class AAM_Service_Content
209
  add_filter('rest_request_before_callbacks', array($this, 'beforeDispatch'), 10, 3);
210
 
211
  // REST API. Control if user is allowed to publish content
212
- add_action('registered_post_type', function($post_type, $obj) {
213
- add_filter("rest_pre_insert_{$post_type}", function($post, $request) {
214
  $status = (isset($request['status']) ? $request['status'] : null);
215
 
216
  if (in_array($status, array('publish', 'future'), true)) {
@@ -227,7 +227,7 @@ class AAM_Service_Content
227
  }, 10, 2);
228
 
229
  // Populate the collection of post type caps
230
- foreach($obj->cap as $cap) {
231
  if (
232
  !in_array($cap, $this->postTypeCaps, true)
233
  && ($cap !== 'do_not_allow')
@@ -257,7 +257,7 @@ class AAM_Service_Content
257
  public function beforeDispatch($response, $handler, $request)
258
  {
259
  // Register hooks that check post access
260
- foreach(get_post_types(array('show_in_rest' => true)) as $type) {
261
  add_filter("rest_prepare_{$type}", array($this, 'authPostAccess'), 10, 3);
262
  }
263
 
@@ -293,11 +293,13 @@ class AAM_Service_Content
293
  public function authPostAccess($response, $post, $request)
294
  {
295
  $object = AAM::getUser()->getObject(
296
- AAM_Core_Object_Post::OBJECT_TYPE, $post->ID
 
297
  );
298
 
299
  $auth = $this->isAuthorizedToReadPost(
300
- $object, (isset($request['_password']) ? $request['_password'] : null)
 
301
  );
302
 
303
  if (is_wp_error($auth)) {
@@ -421,7 +423,7 @@ class AAM_Service_Content
421
  if ($error->get_error_code() === 'post_access_redirected') {
422
  AAM_Core_Redirect::execute('url', $error->get_error_data());
423
  } elseif ($error->get_error_code() !== 'post_access_protected') {
424
- wp_die($error->get_error_message(), 'aam_access_denied');
425
  }
426
  } else {
427
  $this->incrementPostReadCounter($post);
@@ -494,7 +496,9 @@ class AAM_Service_Content
494
  $query = $this->preparePostQuery($object->getSegment('post'), $wp_query);
495
 
496
  $clauses['where'] .= apply_filters(
497
- 'aam_content_visibility_where_clause_filter', $query, $wp_query
 
 
498
  );
499
 
500
  $executing = false;
@@ -703,7 +707,11 @@ class AAM_Service_Content
703
 
704
  if (is_a($post_type, 'WP_Post_Type')) {
705
  $caps = $this->__mapPostTypeCaps(
706
- $post_type, $cap, $caps, $requested, $args
 
 
 
 
707
  );
708
  }
709
  } else {
@@ -730,7 +738,11 @@ class AAM_Service_Content
730
  * @version 6.0.2
731
  */
732
  private function __mapPostTypeCaps(
733
- WP_Post_Type $post_type, $cap, $caps, WP_Post $post, $args
 
 
 
 
734
  ) {
735
 
736
  // Cover the scenario when $cap is not part of the post type capabilities
@@ -818,7 +830,8 @@ class AAM_Service_Content
818
  public function isAuthorizedToPublishPost($post)
819
  {
820
  return AAM::getUser()->getObject(
821
- 'post', (is_a($post, 'WP_Post') ? $post->ID : $post)
 
822
  )->isAllowedTo('publish');
823
  }
824
 
@@ -857,7 +870,8 @@ class AAM_Service_Content
857
  public function isAuthorizedToEditPost($post)
858
  {
859
  $object = AAM::getUser()->getObject(
860
- 'post', (is_a($post, 'WP_Post') ? $post->ID : $post)
 
861
  );
862
  $isDraft = $object->post_status === 'auto-draft';
863
 
@@ -897,7 +911,8 @@ class AAM_Service_Content
897
  public function isAuthorizedToDeletePost($post)
898
  {
899
  return AAM::getUser()->getObject(
900
- 'post', (is_a($post, 'WP_Post') ? $post->ID : $post)
 
901
  )->isAllowedTo('delete');
902
  }
903
 
@@ -934,7 +949,7 @@ class AAM_Service_Content
934
  */
935
  protected function incrementPostReadCounter($post)
936
  {
937
- if(is_user_logged_in() && $post->is('limited')) {
938
  $option = sprintf(self::POST_COUNTER_DB_OPTION, $post->ID);
939
  $counter = intval(get_user_option($option, get_current_user_id()));
940
  update_user_option(get_current_user_id(), $option, ++$counter);
@@ -960,7 +975,8 @@ class AAM_Service_Content
960
  $object = $post;
961
  } else {
962
  $object = AAM::getUser()->getObject(
963
- 'post', (is_a($post, 'WP_Post') ? $post->ID : $post)
 
964
  );
965
  }
966
 
@@ -1189,7 +1205,8 @@ class AAM_Service_Content
1189
  );
1190
 
1191
  $isMatched = AAM_Core_API::prepareHasher()->CheckPassword(
1192
- $protected['password'], $password
 
1193
  );
1194
  } else {
1195
  $isMatched = $protected['password'] === $password;
193
  add_filter('map_meta_cap', array($this, 'filterMetaMaps'), 999, 4);
194
 
195
  // Get control over commenting stuff
196
+ add_filter('comments_open', function ($open, $id) {
197
  $object = AAM::getUser()->getObject('post', $id);
198
 
199
  // If Leave Comments option is defined then override the default status.
209
  add_filter('rest_request_before_callbacks', array($this, 'beforeDispatch'), 10, 3);
210
 
211
  // REST API. Control if user is allowed to publish content
212
+ add_action('registered_post_type', function ($post_type, $obj) {
213
+ add_filter("rest_pre_insert_{$post_type}", function ($post, $request) {
214
  $status = (isset($request['status']) ? $request['status'] : null);
215
 
216
  if (in_array($status, array('publish', 'future'), true)) {
227
  }, 10, 2);
228
 
229
  // Populate the collection of post type caps
230
+ foreach ($obj->cap as $cap) {
231
  if (
232
  !in_array($cap, $this->postTypeCaps, true)
233
  && ($cap !== 'do_not_allow')
257
  public function beforeDispatch($response, $handler, $request)
258
  {
259
  // Register hooks that check post access
260
+ foreach (get_post_types(array('show_in_rest' => true)) as $type) {
261
  add_filter("rest_prepare_{$type}", array($this, 'authPostAccess'), 10, 3);
262
  }
263
 
293
  public function authPostAccess($response, $post, $request)
294
  {
295
  $object = AAM::getUser()->getObject(
296
+ AAM_Core_Object_Post::OBJECT_TYPE,
297
+ $post->ID
298
  );
299
 
300
  $auth = $this->isAuthorizedToReadPost(
301
+ $object,
302
+ (isset($request['_password']) ? $request['_password'] : null)
303
  );
304
 
305
  if (is_wp_error($auth)) {
423
  if ($error->get_error_code() === 'post_access_redirected') {
424
  AAM_Core_Redirect::execute('url', $error->get_error_data());
425
  } elseif ($error->get_error_code() !== 'post_access_protected') {
426
+ wp_die($error->get_error_message(), 'aam_access_denied');
427
  }
428
  } else {
429
  $this->incrementPostReadCounter($post);
496
  $query = $this->preparePostQuery($object->getSegment('post'), $wp_query);
497
 
498
  $clauses['where'] .= apply_filters(
499
+ 'aam_content_visibility_where_clause_filter',
500
+ $query,
501
+ $wp_query
502
  );
503
 
504
  $executing = false;
707
 
708
  if (is_a($post_type, 'WP_Post_Type')) {
709
  $caps = $this->__mapPostTypeCaps(
710
+ $post_type,
711
+ $cap,
712
+ $caps,
713
+ $requested,
714
+ $args
715
  );
716
  }
717
  } else {
738
  * @version 6.0.2
739
  */
740
  private function __mapPostTypeCaps(
741
+ WP_Post_Type $post_type,
742
+ $cap,
743
+ $caps,
744
+ WP_Post $post,
745
+ $args
746
  ) {
747
 
748
  // Cover the scenario when $cap is not part of the post type capabilities
830
  public function isAuthorizedToPublishPost($post)
831
  {
832
  return AAM::getUser()->getObject(
833
+ 'post',
834
+ (is_a($post, 'WP_Post') ? $post->ID : $post)
835
  )->isAllowedTo('publish');
836
  }
837
 
870
  public function isAuthorizedToEditPost($post)
871
  {
872
  $object = AAM::getUser()->getObject(
873
+ 'post',
874
+ (is_a($post, 'WP_Post') ? $post->ID : $post)
875
  );
876
  $isDraft = $object->post_status === 'auto-draft';
877
 
911
  public function isAuthorizedToDeletePost($post)
912
  {
913
  return AAM::getUser()->getObject(
914
+ 'post',
915
+ (is_a($post, 'WP_Post') ? $post->ID : $post)
916
  )->isAllowedTo('delete');
917
  }
918
 
949
  */
950
  protected function incrementPostReadCounter($post)
951
  {
952
+ if (is_user_logged_in() && $post->is('limited')) {
953
  $option = sprintf(self::POST_COUNTER_DB_OPTION, $post->ID);
954
  $counter = intval(get_user_option($option, get_current_user_id()));
955
  update_user_option(get_current_user_id(), $option, ++$counter);
975
  $object = $post;
976
  } else {
977
  $object = AAM::getUser()->getObject(
978
+ 'post',
979
+ (is_a($post, 'WP_Post') ? $post->ID : $post)
980
  );
981
  }
982
 
1205
  );
1206
 
1207
  $isMatched = AAM_Core_API::prepareHasher()->CheckPassword(
1208
+ $protected['password'],
1209
+ $password
1210
  );
1211
  } else {
1212
  $isMatched = $protected['password'] === $password;
application/Service/Jwt.php CHANGED
@@ -10,11 +10,13 @@
10
  /**
11
  * JWT Token service
12
  *
 
 
13
  * @since 6.1.0 Enriched error response with more details
14
  * @since 6.0.0 Initial implementation of the class
15
  *
16
  * @package AAM
17
- * @version 6.1.0
18
  */
19
  class AAM_Service_Jwt
20
  {
@@ -78,8 +80,11 @@ class AAM_Service_Jwt
78
  *
79
  * @return void
80
  *
 
 
 
81
  * @access protected
82
- * @version 6.0.0
83
  */
84
  protected function initializeHooks()
85
  {
@@ -119,9 +124,6 @@ class AAM_Service_Jwt
119
  // WP Core current user definition
120
  add_filter('determine_current_user', array($this, 'determineUser'), PHP_INT_MAX);
121
 
122
- // Disable WP Core cookie and nonce checks to allow JWT authentication
123
- add_filter('rest_authentication_errors', '__return_false', PHP_INT_MAX);
124
-
125
  // Delete JWT cookie if it is set
126
  add_action('wp_logout', function() {
127
  if ($this->getFromCookie('aam_jwt_token')) {
@@ -524,7 +526,6 @@ class AAM_Service_Jwt
524
  */
525
  public function determineUser($userId)
526
  {
527
-
528
  if (empty($userId)) {
529
  $token = $this->extractToken();
530
 
10
  /**
11
  * JWT Token service
12
  *
13
+ * @since 6.3.0 Fixed incompatibility with other plugins that check for RESTful error
14
+ * status through `rest_authentication_errors` filter
15
  * @since 6.1.0 Enriched error response with more details
16
  * @since 6.0.0 Initial implementation of the class
17
  *
18
  * @package AAM
19
+ * @version 6.3.0
20
  */
21
  class AAM_Service_Jwt
22
  {
80
  *
81
  * @return void
82
  *
83
+ * @since 6.3.0 Fixed bug https://github.com/aamplugin/advanced-access-manager/issues/25
84
+ * @since 6.0.0 Initial implementation of the method
85
+ *
86
  * @access protected
87
+ * @version 6.3.0
88
  */
89
  protected function initializeHooks()
90
  {
124
  // WP Core current user definition
125
  add_filter('determine_current_user', array($this, 'determineUser'), PHP_INT_MAX);
126
 
 
 
 
127
  // Delete JWT cookie if it is set
128
  add_action('wp_logout', function() {
129
  if ($this->getFromCookie('aam_jwt_token')) {
526
  */
527
  public function determineUser($userId)
528
  {
 
529
  if (empty($userId)) {
530
  $token = $this->extractToken();
531
 
application/Service/Multisite.php CHANGED
@@ -10,11 +10,12 @@
10
  /**
11
  * Multisite service
12
  *
 
13
  * @since 6.2.2 Fixed the bug where reset settings was not synced across all sites
14
  * @since 6.2.0 Initial implementation of the class
15
  *
16
  * @package AAM
17
- * @version 6.2.2
18
  */
19
  class AAM_Service_Multisite
20
  {
@@ -28,6 +29,18 @@ class AAM_Service_Multisite
28
  */
29
  const FEATURE_FLAG = 'core.service.multisite.enabled';
30
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  /**
32
  * Previously used blog ID
33
  *
@@ -76,39 +89,65 @@ class AAM_Service_Multisite
76
  *
77
  * @return void
78
  *
 
79
  * @since 6.2.2 Hooks to the setting clearing and policy table list
80
  * @since 6.2.0 Initial implementation of the method
81
  *
82
  * @access protected
83
- * @version 6.2.2
84
  */
85
  protected function initializeHooks()
86
  {
87
  $roles = AAM_Core_API::getRoles();
88
 
89
- // Any changes to the user_roles option should be replicated
90
- add_action('update_option_' . $roles->role_key, function($old_value, $value) {
91
- $this->syncOption('%suser_roles', $value);
92
- }, 10, 2);
 
93
 
94
- // Sync changes to config
95
- add_action('update_option_' . AAM_Core_Config::DB_OPTION, function($o, $n) {
96
- $this->syncOption(AAM_Core_Config::DB_OPTION, $n);
97
- });
 
 
 
 
98
 
99
- // Sync changes to ConfigPress
100
- add_action('update_option_' . AAM_Core_ConfigPress::DB_OPTION, function($o, $n) {
101
- $this->syncOption(AAM_Core_ConfigPress::DB_OPTION, $n);
102
- });
 
 
103
 
104
- add_action('aam_updated_access_settings', function($settings) {
105
- $this->syncOption(AAM_Core_AccessSettings::DB_OPTION, $settings);
106
- });
107
 
108
- // Sync settings resetting
109
- add_action('aam_clear_settings_action', function($options) {
110
- $this->resetOptions($options);
111
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
  add_filter('wp_insert_post_data', function($data) {
114
  if (
@@ -135,10 +174,6 @@ class AAM_Service_Multisite
135
  wp_die('Access Denied', 'aam_access_denied');
136
  }
137
  }, 999);
138
-
139
- add_filter('aam_is_managed_policy_filter', function() {
140
- return is_main_site();
141
- });
142
  }
143
 
144
  /**
@@ -156,34 +191,42 @@ class AAM_Service_Multisite
156
  * @global WPDB $wpdb
157
  * @version 6.2.2
158
  */
159
- protected function syncOption($option, $value)
160
  {
161
  global $wpdb;
162
 
163
  foreach($this->getSitList() as $site) {
164
- AAM_Core_API::updateOption(
165
- str_replace('%s', $wpdb->get_blog_prefix($site->blog_id), $option),
166
- $value,
167
- $site->blog_id
168
- );
 
 
169
  }
170
  }
171
 
172
  /**
173
- * Reset settings across all sites
174
  *
175
- * @param array $options
176
  *
177
  * @return void
178
  *
179
  * @access protected
180
- * @version 6.2.2
 
181
  */
182
- protected function resetOptions($options)
183
  {
 
 
184
  foreach($this->getSitList() as $site) {
185
- foreach($options as $option) {
186
- AAM_Core_API::deleteOption($option, $site->blog_id);
 
 
 
187
  }
188
  }
189
  }
@@ -205,7 +248,7 @@ class AAM_Service_Multisite
205
  'site__not_in' => array_merge(
206
  $this->getExcludedBlogs(), array(get_current_blog_id())
207
  )
208
- ));
209
  }
210
 
211
  /**
@@ -232,6 +275,26 @@ class AAM_Service_Multisite
232
  return $excluded;
233
  }
234
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  }
236
 
237
  if (defined('AAM_KEY')) {
10
  /**
11
  * Multisite service
12
  *
13
+ * @since 6.3.0 Rewrote the way options are synced across the network
14
  * @since 6.2.2 Fixed the bug where reset settings was not synced across all sites
15
  * @since 6.2.0 Initial implementation of the class
16
  *
17
  * @package AAM
18
+ * @version 6.3.0
19
  */
20
  class AAM_Service_Multisite
21
  {
29
  */
30
  const FEATURE_FLAG = 'core.service.multisite.enabled';
31
 
32
+ /**
33
+ * Syncing flag
34
+ *
35
+ * Preventing from any unexpected loops
36
+ *
37
+ * @var boolean
38
+ *
39
+ * @access protected
40
+ * @version 6.3.0
41
+ */
42
+ protected $syncing = false;
43
+
44
  /**
45
  * Previously used blog ID
46
  *
89
  *
90
  * @return void
91
  *
92
+ * @since 6.3.0 Optimized for Multisite setup
93
  * @since 6.2.2 Hooks to the setting clearing and policy table list
94
  * @since 6.2.0 Initial implementation of the method
95
  *
96
  * @access protected
97
+ * @version 6.3.0
98
  */
99
  protected function initializeHooks()
100
  {
101
  $roles = AAM_Core_API::getRoles();
102
 
103
+ if (is_main_site()) {
104
+ // Any changes to the user_roles option should be replicated
105
+ add_action('update_option_' . $roles->role_key, function($old, $value) {
106
+ $this->syncUpdatedOption('%suser_roles', $value);
107
+ }, 10, 2);
108
 
109
+ add_action('update_option', function($option, $old, $value) {
110
+ if ($this->syncing === false) {
111
+ $this->syncing = true;
112
+ $list = array(
113
+ AAM_Core_Config::DB_OPTION,
114
+ AAM_Core_ConfigPress::DB_OPTION,
115
+ AAM_Core_AccessSettings::DB_OPTION
116
+ );
117
 
118
+ if (in_array($option, $list, true)) {
119
+ $this->syncUpdatedOption($option, $value);
120
+ }
121
+ $this->syncing = false;
122
+ }
123
+ }, 10, 3);
124
 
125
+ add_action('aam_top_right_column_action', function() {
126
+ echo AAM_Backend_View::loadPartial('multisite-sync-notification');
127
+ });
128
 
129
+ add_action('add_option', function($option, $value) {
130
+ if ($this->syncing === false) {
131
+ $this->syncing = true;
132
+ $list = array(
133
+ AAM_Core_Config::DB_OPTION,
134
+ AAM_Core_ConfigPress::DB_OPTION,
135
+ AAM_Core_AccessSettings::DB_OPTION
136
+ );
137
+
138
+ if (in_array($option, $list, true)) {
139
+ $this->syncUpdatedOption($option, $value);
140
+ }
141
+ $this->syncing = false;
142
+ }
143
+ }, 10, 2);
144
+
145
+ add_action('aam_clear_settings_action', function($options) {
146
+ foreach($options as $option) {
147
+ $this->syncDeletedOption($option);
148
+ }
149
+ }, PHP_INT_MAX);
150
+ }
151
 
152
  add_filter('wp_insert_post_data', function($data) {
153
  if (
174
  wp_die('Access Denied', 'aam_access_denied');
175
  }
176
  }, 999);
 
 
 
 
177
  }
178
 
179
  /**
191
  * @global WPDB $wpdb
192
  * @version 6.2.2
193
  */
194
+ protected function syncUpdatedOption($option, $value)
195
  {
196
  global $wpdb;
197
 
198
  foreach($this->getSitList() as $site) {
199
+ if ($this->isSyncDisabled($site->blog_id) !== true) {
200
+ AAM_Core_API::updateOption(
201
+ str_replace('%s', $wpdb->get_blog_prefix($site->blog_id), $option),
202
+ $value,
203
+ $site->blog_id
204
+ );
205
+ }
206
  }
207
  }
208
 
209
  /**
210
+ * Sync deleted option across all sites
211
  *
212
+ * @param string $option
213
  *
214
  * @return void
215
  *
216
  * @access protected
217
+ * @global WPDB $wpdb
218
+ * @version 6.3.0
219
  */
220
+ protected function syncDeletedOption($option)
221
  {
222
+ global $wpdb;
223
+
224
  foreach($this->getSitList() as $site) {
225
+ if ($this->isSyncDisabled($site->blog_id) !== true) {
226
+ AAM_Core_API::deleteOption(
227
+ str_replace('%s', $wpdb->get_blog_prefix($site->blog_id), $option),
228
+ $site->blog_id
229
+ );
230
  }
231
  }
232
  }
248
  'site__not_in' => array_merge(
249
  $this->getExcludedBlogs(), array(get_current_blog_id())
250
  )
251
+ ));
252
  }
253
 
254
  /**
275
  return $excluded;
276
  }
277
 
278
+ /**
279
+ * Check if blog has sync service disabled
280
+ *
281
+ * @param int $blog_id
282
+ *
283
+ * @return boolean
284
+ *
285
+ * @access protected
286
+ * @version 6.3.0
287
+ */
288
+ protected function isSyncDisabled($blog_id)
289
+ {
290
+ $config = AAM_Core_API::getOption(
291
+ AAM_Core_Config::DB_OPTION, array(), $blog_id
292
+ );
293
+
294
+ return isset($config[self::FEATURE_FLAG])
295
+ && ($config[self::FEATURE_FLAG] === false);
296
+ }
297
+
298
  }
299
 
300
  if (defined('AAM_KEY')) {
application/Service/Uri.php CHANGED
@@ -5,15 +5,18 @@
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
- * @version 6.0.0
10
  */
11
 
12
  /**
13
  * URI access service
14
  *
 
 
 
 
 
15
  * @package AAM
16
- * @version 6.0.0
17
  */
18
  class AAM_Service_Uri
19
  {
@@ -82,11 +85,12 @@ class AAM_Service_Uri
82
  *
83
  * @return boolean
84
  *
 
85
  * @since 6.1.0 The method return boolean `true` if no matches found
86
  * @since 6.0.0 Initial implementation of the method
87
  *
88
  * @access public
89
- * @version 6.1.0
90
  */
91
  public function authorizeUri()
92
  {
@@ -98,7 +102,11 @@ class AAM_Service_Uri
98
  parse_str($uri['query'], $params);
99
  }
100
 
101
- if ($match = $object->findMatch($uri['path'], $params)) {
 
 
 
 
102
  if ($match['type'] !== 'allow') {
103
  AAM_Core_Redirect::execute(
104
  $match['type'],
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
  * URI access service
12
  *
13
+ * @since 6.3.0 Fixed bug that causes PHP Notice if URI has not base
14
+ * (e.g.`?something=1`)
15
+ * @since 6.1.0 The `authorizeUri` returns true if no match found
16
+ * @since 6.0.0 Initial implementation of the class
17
+ *
18
  * @package AAM
19
+ * @version 6.3.0
20
  */
21
  class AAM_Service_Uri
22
  {
85
  *
86
  * @return boolean
87
  *
88
+ * @since 6.3.0 Fixed bug https://github.com/aamplugin/advanced-access-manager/issues/18
89
  * @since 6.1.0 The method return boolean `true` if no matches found
90
  * @since 6.0.0 Initial implementation of the method
91
  *
92
  * @access public
93
+ * @version 6.3.0
94
  */
95
  public function authorizeUri()
96
  {
102
  parse_str($uri['query'], $params);
103
  }
104
 
105
+ // Get base path from URL
106
+ $path = (isset($uri['path']) ? $uri['path'] : null);
107
+ $match = (!empty($path) ? $object->findMatch($path, $params) : false);
108
+
109
+ if (!empty($match)) {
110
  if ($match['type'] !== 'allow') {
111
  AAM_Core_Redirect::execute(
112
  $match['type'],
application/Shortcode/Handler/Content.php CHANGED
@@ -158,8 +158,11 @@ class AAM_Shortcode_Handler_Content
158
  *
159
  * @return boolean
160
  *
 
 
 
161
  * @access protected
162
- * @version 6.0.0
163
  */
164
  protected function checkIP($ip, $userIp)
165
  {
@@ -170,8 +173,9 @@ class AAM_Shortcode_Handler_Content
170
 
171
  foreach ($ipSplit as $i => $group) {
172
  if (strpos($group, '-') !== false) { //range
173
- list($start, $end) = explode('-', $group);
174
- if ($uipSplit[$i] < $start || $uipSplit[$i] > $end) {
 
175
  $match = false;
176
  break;
177
  }
158
  *
159
  * @return boolean
160
  *
161
+ * @since 6.3.0 Fixed potential bug https://github.com/aamplugin/advanced-access-manager/issues/38
162
+ * @since 6.0.0 Initial implementation of the method
163
+ *
164
  * @access protected
165
+ * @version 6.3.0
166
  */
167
  protected function checkIP($ip, $userIp)
168
  {
173
 
174
  foreach ($ipSplit as $i => $group) {
175
  if (strpos($group, '-') !== false) { //range
176
+ $parts = explode('-', $group);
177
+
178
+ if ($uipSplit[$i] < $parts[0] || $uipSplit[$i] > $parts[1]) {
179
  $match = false;
180
  break;
181
  }
media/css/aam.css CHANGED
@@ -429,7 +429,7 @@ a.btn:focus, a.btn:active {
429
  #FFF;
430
  }
431
 
432
- .subject-top-actions a {
433
  color: #FFFFFF !important;
434
  }
435
 
@@ -779,7 +779,7 @@ input[type=radio]:checked + label:before {
779
  .aam-overwrite .btn {
780
  margin-top: -5px;
781
  border: 0;
782
- padding: 6px 10px;
783
  }
784
 
785
  .row.aam-bordered {
429
  #FFF;
430
  }
431
 
432
+ .subject-top-actions a > i {
433
  color: #FFFFFF !important;
434
  }
435
 
779
  .aam-overwrite .btn {
780
  margin-top: -5px;
781
  border: 0;
782
+ padding: 5px 10px;
783
  }
784
 
785
  .row.aam-bordered {
media/js/aam.js CHANGED
@@ -757,9 +757,10 @@
757
 
758
  //add subtitle
759
  var expire = (data[5] ? '; <i class="icon-clock"></i>' : '');
 
760
  $('td:eq(0)', row).append(
761
  $('<i/>', { 'class': 'aam-row-subtitle' }).html(
762
- `${getAAM().__('Role')}: ${data[1]}; ${getAAM().__('ID')}: <b>${data[0]}</b> ${expire}`
763
  )
764
  );
765
 
@@ -1307,6 +1308,35 @@
1307
  });
1308
  }
1309
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1310
  /**
1311
  *
1312
  * @returns {undefined}
@@ -1592,12 +1622,26 @@
1592
 
1593
  // Generate Policy action
1594
  $('#generate-access-policy').bind('click', function() {
1595
- const btn = $('i', this);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1596
 
1597
  btn.attr('class', 'icon-spin4 animate-spin');
1598
- getAAM().generatePolicy(function() {
1599
- btn.attr('class', 'icon-file-code');
1600
- })
1601
  });
1602
 
1603
  getAAM().addHook('init', initialize);
@@ -2503,11 +2547,12 @@
2503
  //show overlay if present
2504
  $('.aam-overlay', container).show();
2505
 
2506
- $.ajax(getLocal().url.site, {
2507
  type: 'POST',
2508
  dataType: 'html',
2509
  data: {
2510
- action: 'aamc',
 
2511
  partial: 'post-access-form',
2512
  _ajax_nonce: getLocal().nonce,
2513
  type: object,
@@ -3673,9 +3718,10 @@
3673
  $('#uri-save-btn').bind('click', function (event) {
3674
  event.preventDefault();
3675
 
3676
- var uri = $('#uri-rule').val();
 
3677
  var type = $('input[name="uri.access.type"]:checked').val();
3678
- var val = $('#uri-access-deny-' + type + '-value').val();
3679
  var code = $('#uri-access-deny-redirect-code-value').val();
3680
 
3681
  if (uri && type) {
@@ -3689,6 +3735,7 @@
3689
  subject: getAAM().getSubject().type,
3690
  subjectId: getAAM().getSubject().id,
3691
  uri: uri,
 
3692
  type: type,
3693
  value: val,
3694
  code: code
@@ -3733,13 +3780,18 @@
3733
  uri: $('#uri-delete-btn').attr('data-uri')
3734
  },
3735
  beforeSend: function () {
3736
- $('#uri-delete-btn').text(getAAM().__('Deleting...')).attr('disabled', true);
 
 
3737
  },
3738
  success: function (response) {
3739
  if (response.status === 'success') {
3740
  $('#uri-list').DataTable().ajax.reload();
3741
  } else {
3742
- getAAM().notification('danger', getAAM().__('Failed to delete URI rule'));
 
 
 
3743
  }
3744
  },
3745
  error: function () {
@@ -3789,6 +3841,7 @@
3789
  .bind('click', function () {
3790
  $('.form-clearable', '#uri-model').val('');
3791
  $('.aam-uri-access-action').hide();
 
3792
  $('input[type="radio"]', '#uri-model').prop('checked', false);
3793
  $('#uri-model').modal('show');
3794
  });
@@ -3808,6 +3861,7 @@
3808
  $('.form-clearable', '#uri-model').val('');
3809
  $('.aam-uri-access-action').hide();
3810
  $('#uri-rule').val(data[0]);
 
3811
  $('input[value="' + data[1] + '"]', '#uri-model').prop('checked', true).trigger('click');
3812
  $('#uri-access-deny-' + data[1] + '-value').val(data[2]);
3813
  $('#uri-access-deny-redirect-code-value').val(data[3]);
@@ -4373,7 +4427,7 @@
4373
  $('input[type="checkbox"]', row).bind('change', function () {
4374
  save(
4375
  $(this).attr('name'),
4376
- ($(this).prop('checked') ? 1 : 0)
4377
  );
4378
  });
4379
  }
@@ -4382,14 +4436,10 @@
4382
  $('input[type="checkbox"]', '.aam-feature.settings').bind('change', function () {
4383
  save(
4384
  $(this).attr('name'),
4385
- ($(this).prop('checked') ? 1 : 0)
4386
  );
4387
  });
4388
 
4389
- $('input[type="text"]', '.aam-feature.settings').bind('change', function () {
4390
- save($(this).attr('name'), $(this).val());
4391
- });
4392
-
4393
  $('#clear-settings').bind('click', function () {
4394
  $.ajax(getLocal().ajaxurl, {
4395
  type: 'POST',
@@ -4397,7 +4447,7 @@
4397
  data: {
4398
  action: 'aam',
4399
  sub_action: 'Settings_Manager.clearSettings',
4400
- _ajax_nonce: getLocal().nonce
4401
  },
4402
  beforeSend: function () {
4403
  $('#clear-settings').prop('disabled', true);
@@ -4467,7 +4517,7 @@
4467
  data: {
4468
  action: 'aam',
4469
  sub_action: 'Settings_Manager.exportSettings',
4470
- _ajax_nonce: getLocal().nonce
4471
  },
4472
  beforeSend: function () {
4473
  $('#export-settings').prop('disabled', true);
@@ -4615,7 +4665,7 @@
4615
  data: {
4616
  action: 'aam',
4617
  sub_action: 'Settings_Manager.getSupportMetadata',
4618
- _ajax_nonce: getLocal().nonce
4619
  },
4620
  success: function(response) {
4621
  request.metadata = response;
@@ -4690,38 +4740,6 @@
4690
  }
4691
  };
4692
 
4693
- /**
4694
- *
4695
- */
4696
- AAM.prototype.generatePolicy = function(cb) {
4697
- $.ajax(getLocal().ajaxurl, {
4698
- type: 'POST',
4699
- dataType: 'json',
4700
- headers: {
4701
- "Accept": "application/json"
4702
- },
4703
- data: {
4704
- action: 'aam',
4705
- sub_action: 'Main_Policy.generate',
4706
- _ajax_nonce: getLocal().nonce,
4707
- subject: getAAM().getSubject().type,
4708
- subjectId: getAAM().getSubject().id
4709
- },
4710
- beforeSend: function () {
4711
- },
4712
- success: function (response) {
4713
- getAAM().downloadFile(
4714
- response.policy,
4715
- response.title + '.json',
4716
- 'application/json'
4717
- )
4718
- },
4719
- complete: function() {
4720
- cb();
4721
- }
4722
- });
4723
- }
4724
-
4725
  /**
4726
  *
4727
  */
@@ -4839,14 +4857,15 @@
4839
  var _this = this;
4840
 
4841
  var data = {
4842
- action: 'aamc',
 
4843
  _ajax_nonce: getLocal().nonce,
4844
  partial: view,
4845
  subject: this.getSubject().type,
4846
  subjectId: this.getSubject().id
4847
  };
4848
 
4849
- $.ajax(getLocal().url.site, {
4850
  type: 'POST',
4851
  dataType: 'html',
4852
  data: data,
@@ -4909,11 +4928,12 @@
4909
  var object = window.location.search.match(/&id\=([^&]*)/);
4910
  var type = window.location.search.match(/&type\=([^&]*)/);
4911
 
4912
- $.ajax(getLocal().url.site, {
4913
  type: 'POST',
4914
  dataType: 'html',
4915
  data: {
4916
- action: 'aamc',
 
4917
  _ajax_nonce: getLocal().nonce,
4918
  partial: view,
4919
  subject: this.getSubject().type,
757
 
758
  //add subtitle
759
  var expire = (data[5] ? '; <i class="icon-clock"></i>' : '');
760
+ var role = (data[1] ? `${getAAM().__('Role')}: ${data[1]}; ` : '');
761
  $('td:eq(0)', row).append(
762
  $('<i/>', { 'class': 'aam-row-subtitle' }).html(
763
+ `${role}${getAAM().__('ID')}: <b>${data[0]}</b> ${expire}`
764
  )
765
  );
766
 
1308
  });
1309
  }
1310
 
1311
+ /**
1312
+ *
1313
+ */
1314
+ function generatePolicy(cb, create) {
1315
+ $.ajax(getLocal().ajaxurl, {
1316
+ type: 'POST',
1317
+ dataType: 'json',
1318
+ headers: {
1319
+ "Accept": "application/json"
1320
+ },
1321
+ data: {
1322
+ action: 'aam',
1323
+ sub_action: 'Main_Policy.generate',
1324
+ _ajax_nonce: getLocal().nonce,
1325
+ createNewPolicy: create,
1326
+ subject: getAAM().getSubject().type,
1327
+ subjectId: getAAM().getSubject().id
1328
+ },
1329
+ beforeSend: function () {
1330
+ },
1331
+ success: function (response) {
1332
+ cb(response);
1333
+ },
1334
+ complete: function() {
1335
+ $('i', '#policy-generator').attr('class', 'icon-file-code')
1336
+ }
1337
+ });
1338
+ }
1339
+
1340
  /**
1341
  *
1342
  * @returns {undefined}
1622
 
1623
  // Generate Policy action
1624
  $('#generate-access-policy').bind('click', function() {
1625
+ const btn = $('i', '#policy-generator');
1626
+
1627
+ btn.attr('class', 'icon-spin4 animate-spin');
1628
+ generatePolicy(function(response) {
1629
+ getAAM().downloadFile(
1630
+ response.policy,
1631
+ response.title + '.json',
1632
+ 'application/json'
1633
+ )
1634
+ }, false)
1635
+ });
1636
+
1637
+ // Create new Policy action
1638
+ $('#create-access-policy').bind('click', function() {
1639
+ const btn = $('i', '#policy-generator');
1640
 
1641
  btn.attr('class', 'icon-spin4 animate-spin');
1642
+ generatePolicy(function(response) {
1643
+ window.open(response.redirect, '_blank');
1644
+ }, true)
1645
  });
1646
 
1647
  getAAM().addHook('init', initialize);
2547
  //show overlay if present
2548
  $('.aam-overlay', container).show();
2549
 
2550
+ $.ajax(getLocal().ajaxurl, {
2551
  type: 'POST',
2552
  dataType: 'html',
2553
  data: {
2554
+ action: 'aam',
2555
+ sub_action: 'renderContent',
2556
  partial: 'post-access-form',
2557
  _ajax_nonce: getLocal().nonce,
2558
  type: object,
3718
  $('#uri-save-btn').bind('click', function (event) {
3719
  event.preventDefault();
3720
 
3721
+ var uri = $('#uri-rule').val();
3722
+ var original = $(this).attr('data-original-uri');
3723
  var type = $('input[name="uri.access.type"]:checked').val();
3724
+ var val = $('#uri-access-deny-' + type + '-value').val();
3725
  var code = $('#uri-access-deny-redirect-code-value').val();
3726
 
3727
  if (uri && type) {
3735
  subject: getAAM().getSubject().type,
3736
  subjectId: getAAM().getSubject().id,
3737
  uri: uri,
3738
+ edited_uri: original,
3739
  type: type,
3740
  value: val,
3741
  code: code
3780
  uri: $('#uri-delete-btn').attr('data-uri')
3781
  },
3782
  beforeSend: function () {
3783
+ $('#uri-delete-btn').text(
3784
+ getAAM().__('Deleting...')
3785
+ ).attr('disabled', true);
3786
  },
3787
  success: function (response) {
3788
  if (response.status === 'success') {
3789
  $('#uri-list').DataTable().ajax.reload();
3790
  } else {
3791
+ getAAM().notification(
3792
+ 'danger',
3793
+ getAAM().__('Failed to delete URI rule')
3794
+ );
3795
  }
3796
  },
3797
  error: function () {
3841
  .bind('click', function () {
3842
  $('.form-clearable', '#uri-model').val('');
3843
  $('.aam-uri-access-action').hide();
3844
+ $('#uri-save-btn').removeAttr('data-original-uri');
3845
  $('input[type="radio"]', '#uri-model').prop('checked', false);
3846
  $('#uri-model').modal('show');
3847
  });
3861
  $('.form-clearable', '#uri-model').val('');
3862
  $('.aam-uri-access-action').hide();
3863
  $('#uri-rule').val(data[0]);
3864
+ $('#uri-save-btn').attr('data-original-uri', data[0]);
3865
  $('input[value="' + data[1] + '"]', '#uri-model').prop('checked', true).trigger('click');
3866
  $('#uri-access-deny-' + data[1] + '-value').val(data[2]);
3867
  $('#uri-access-deny-redirect-code-value').val(data[3]);
4427
  $('input[type="checkbox"]', row).bind('change', function () {
4428
  save(
4429
  $(this).attr('name'),
4430
+ $(this).prop('checked')
4431
  );
4432
  });
4433
  }
4436
  $('input[type="checkbox"]', '.aam-feature.settings').bind('change', function () {
4437
  save(
4438
  $(this).attr('name'),
4439
+ $(this).prop('checked')
4440
  );
4441
  });
4442
 
 
 
 
 
4443
  $('#clear-settings').bind('click', function () {
4444
  $.ajax(getLocal().ajaxurl, {
4445
  type: 'POST',
4447
  data: {
4448
  action: 'aam',
4449
  sub_action: 'Settings_Manager.clearSettings',
4450
+ _ajax_nonce: getLocal().nonce,
4451
  },
4452
  beforeSend: function () {
4453
  $('#clear-settings').prop('disabled', true);
4517
  data: {
4518
  action: 'aam',
4519
  sub_action: 'Settings_Manager.exportSettings',
4520
+ _ajax_nonce: getLocal().nonce,
4521
  },
4522
  beforeSend: function () {
4523
  $('#export-settings').prop('disabled', true);
4665
  data: {
4666
  action: 'aam',
4667
  sub_action: 'Settings_Manager.getSupportMetadata',
4668
+ _ajax_nonce: getLocal().nonce,
4669
  },
4670
  success: function(response) {
4671
  request.metadata = response;
4740
  }
4741
  };
4742
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4743
  /**
4744
  *
4745
  */
4857
  var _this = this;
4858
 
4859
  var data = {
4860
+ action: 'aam',
4861
+ sub_action: 'renderContent',
4862
  _ajax_nonce: getLocal().nonce,
4863
  partial: view,
4864
  subject: this.getSubject().type,
4865
  subjectId: this.getSubject().id
4866
  };
4867
 
4868
+ $.ajax(getLocal().ajaxurl, {
4869
  type: 'POST',
4870
  dataType: 'html',
4871
  data: data,
4928
  var object = window.location.search.match(/&id\=([^&]*)/);
4929
  var type = window.location.search.match(/&type\=([^&]*)/);
4930
 
4931
+ $.ajax(getLocal().ajaxurl, {
4932
  type: 'POST',
4933
  dataType: 'html',
4934
  data: {
4935
+ action: 'aam',
4936
+ sub_action: 'renderContent',
4937
  _ajax_nonce: getLocal().nonce,
4938
  partial: view,
4939
  subject: this.getSubject().type,
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: access control, membership, backend menu, user role, restricted content, s
4
  Requires at least: 4.7.0
5
  Requires PHP: 5.6.0
6
  Tested up to: 5.3.2
7
- Stable tag: 6.2.2
8
 
9
  All you need to manage access to WordPress websites on the frontend, backend and API levels for any role, user or visitors.
10
 
@@ -91,6 +91,21 @@ We take security and privacy very seriously, that is why there are several non-n
91
 
92
  == Changelog ==
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  = 6.2.2 =
95
  * Fixed Bug: Backend Dashboard index.php still could be restricted with Backend Menu service
96
  * Fixed Bug: Policy Generator - Fatal error with PHP lower than 7.0.0
4
  Requires at least: 4.7.0
5
  Requires PHP: 5.6.0
6
  Tested up to: 5.3.2
7
+ Stable tag: 6.3.0
8
 
9
  All you need to manage access to WordPress websites on the frontend, backend and API levels for any role, user or visitors.
10
 
91
 
92
  == Changelog ==
93
 
94
+ = 6.3.0 =
95
+ * Fixed Bug: PHP Notice about missing license key [https://github.com/aamplugin/advanced-access-manager/issues/12](https://github.com/aamplugin/advanced-access-manager/issues/12)
96
+ * Fixed Bug: Fatal error: Allowed memory size of XXX bytes exhausted [https://github.com/aamplugin/advanced-access-manager/issues/15](https://github.com/aamplugin/advanced-access-manager/issues/15)
97
+ * Fixed Bug: PHP Notice: Undefined index: path [https://github.com/aamplugin/advanced-access-manager/issues/18](https://github.com/aamplugin/advanced-access-manager/issues/18)
98
+ * Fixed Bug: PHP Notice: Undefined index: password [https://github.com/aamplugin/advanced-access-manager/issues/31](https://github.com/aamplugin/advanced-access-manager/issues/31)
99
+ * Fixed Bug: NGIX compatibility for URI Access [https://github.com/aamplugin/advanced-access-manager/issues/33](https://github.com/aamplugin/advanced-access-manager/issues/33)
100
+ * Fixed Bug: URI Access service does not protect the homepage [https://github.com/aamplugin/advanced-access-manager/issues/17](https://github.com/aamplugin/advanced-access-manager/issues/17)
101
+ * Fixed Bug: New rule is created if URI Access endpoint is updated [https://github.com/aamplugin/advanced-access-manager/issues/35](https://github.com/aamplugin/advanced-access-manager/issues/35)
102
+ * Fixed Bug: Conflict with Jatpack plugin [https://github.com/aamplugin/advanced-access-manager/issues/25](https://github.com/aamplugin/advanced-access-manager/issues/25)
103
+ * Fixed Bug: Potentially incorrectly used PHP core `list` function [https://github.com/aamplugin/advanced-access-manager/issues/38](https://github.com/aamplugin/advanced-access-manager/issues/38)
104
+ * Added New: Access Policy token [PHP_GLOBAL](https://aamplugin.com/reference/policy#php_global)
105
+ * Added New: Access Policy token [WP_NETWORK_OPTION](https://aamplugin.com/reference/policy#wp_network_option)
106
+ * Added New: Allow to attach Access Policies to Default subject [https://github.com/aamplugin/advanced-access-manager/issues/13](https://github.com/aamplugin/advanced-access-manager/issues/13)
107
+ * Added New: Ability to create new access policy from generated [https://github.com/aamplugin/advanced-access-manager/issues/27](https://github.com/aamplugin/advanced-access-manager/issues/27)
108
+
109
  = 6.2.2 =
110
  * Fixed Bug: Backend Dashboard index.php still could be restricted with Backend Menu service
111
  * Fixed Bug: Policy Generator - Fatal error with PHP lower than 7.0.0
vendor/firebase/JWT.php CHANGED
@@ -77,14 +77,14 @@ class JWT
77
  if (count($tks) != 3) {
78
  throw new UnexpectedValueException('Wrong number of segments');
79
  }
80
- list($headb64, $bodyb64, $cryptob64) = $tks;
81
- if (null === ($header = static::jsonDecode(static::urlsafeB64Decode($headb64)))) {
82
  throw new UnexpectedValueException('Invalid header encoding');
83
  }
84
- if (null === $payload = static::jsonDecode(static::urlsafeB64Decode($bodyb64))) {
85
  throw new UnexpectedValueException('Invalid claims encoding');
86
  }
87
- if (false === ($sig = static::urlsafeB64Decode($cryptob64))) {
88
  throw new UnexpectedValueException('Invalid signature encoding');
89
  }
90
  if (empty($header->alg)) {
@@ -108,7 +108,7 @@ class JWT
108
  }
109
 
110
  // Check the signature
111
- if (!static::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) {
112
  throw new SignatureInvalidException('Signature verification failed');
113
  }
114
 
@@ -193,7 +193,10 @@ class JWT
193
  if (empty(static::$supported_algs[$alg])) {
194
  throw new DomainException('Algorithm not supported');
195
  }
196
- list($function, $algorithm) = static::$supported_algs[$alg];
 
 
 
197
  switch($function) {
198
  case 'hash_hmac':
199
  return hash_hmac($algorithm, $msg, $key, true);
@@ -229,7 +232,9 @@ class JWT
229
  throw new DomainException('Algorithm not supported');
230
  }
231
 
232
- list($function, $algorithm) = static::$supported_algs[$alg];
 
 
233
  switch($function) {
234
  case 'openssl':
235
  $success = openssl_verify($msg, $signature, $key, $algorithm);
77
  if (count($tks) != 3) {
78
  throw new UnexpectedValueException('Wrong number of segments');
79
  }
80
+
81
+ if (null === ($header = static::jsonDecode(static::urlsafeB64Decode($tks[0])))) {
82
  throw new UnexpectedValueException('Invalid header encoding');
83
  }
84
+ if (null === $payload = static::jsonDecode(static::urlsafeB64Decode($tks[1]))) {
85
  throw new UnexpectedValueException('Invalid claims encoding');
86
  }
87
+ if (false === ($sig = static::urlsafeB64Decode($tks[2]))) {
88
  throw new UnexpectedValueException('Invalid signature encoding');
89
  }
90
  if (empty($header->alg)) {
108
  }
109
 
110
  // Check the signature
111
+ if (!static::verify("{$tks[0]}.{$tks[1]}", $sig, $key, $header->alg)) {
112
  throw new SignatureInvalidException('Signature verification failed');
113
  }
114
 
193
  if (empty(static::$supported_algs[$alg])) {
194
  throw new DomainException('Algorithm not supported');
195
  }
196
+
197
+ $function = static::$supported_algs[$alg][0];
198
+ $algorithm = static::$supported_algs[$alg][1];
199
+
200
  switch($function) {
201
  case 'hash_hmac':
202
  return hash_hmac($algorithm, $msg, $key, true);
232
  throw new DomainException('Algorithm not supported');
233
  }
234
 
235
+ $function = static::$supported_algs[$alg][0];
236
+ $algorithm = static::$supported_algs[$alg][1];
237
+
238
  switch($function) {
239
  case 'openssl':
240
  $success = openssl_verify($msg, $signature, $key, $algorithm);