Advanced Access Manager - Version 5.3.2

Version Description

  • Fixed the bug that triggers PHP warnings when blocked user is trying to login
  • Fixed the bug with get current post method in the core API
  • WARNING Experimental approach! to the post access that enormously improve AAM performance
  • Added custom capability "edit_permalink" that control ability to edit post permalink
Download this release

Release Info

Developer vasyl_m
Plugin Icon 128x128 Advanced Access Manager
Version 5.3.2
Comparing to
See all releases

Code changes from version 5.3.1 to 5.3.2

Application/Backend/Feature/Settings/Tools.php CHANGED
@@ -36,7 +36,7 @@ class AAM_Backend_Feature_Settings_Tools extends AAM_Backend_Feature_Abstract {
36
  'content' => base64_encode(json_encode($exporter->run()))
37
  ));
38
  }
39
-
40
  /**
41
  *
42
  * @return type
@@ -108,4 +108,4 @@ class AAM_Backend_Feature_Settings_Tools extends AAM_Backend_Feature_Abstract {
108
  ));
109
  }
110
 
111
- }
36
  'content' => base64_encode(json_encode($exporter->run()))
37
  ));
38
  }
39
+
40
  /**
41
  *
42
  * @return type
108
  ));
109
  }
110
 
111
+ }
Application/Backend/Filter.php CHANGED
@@ -24,11 +24,6 @@ class AAM_Backend_Filter {
24
  */
25
  private static $_instance = null;
26
 
27
- /**
28
- * pre_get_posts flag
29
- */
30
- protected $skip = false;
31
-
32
  /**
33
  * Initialize backend filters
34
  *
@@ -58,11 +53,6 @@ class AAM_Backend_Filter {
58
  //default category filder
59
  add_filter('pre_option_default_category', array($this, 'filterDefaultCategory'));
60
 
61
- //add post filter for LIST restriction
62
- if (!AAM::isAAM() && AAM_Core_Config::get('core.settings.checkPostVisibility', true)) {
63
- add_filter('found_posts', array($this, 'filterPostCount'), 999, 2);
64
- }
65
-
66
  add_action('pre_post_update', array($this, 'prePostUpdate'), 10, 2);
67
 
68
  //user/role filters
@@ -285,47 +275,6 @@ class AAM_Backend_Filter {
285
  return ($default ? $default : $category);
286
  }
287
 
288
- /**
289
- * Filter post count for pagination
290
- *
291
- * @param int $counter
292
- * @param WP_Query $query
293
- *
294
- * @return array
295
- *
296
- * @access public
297
- */
298
- public function filterPostCount($counter, $query) {
299
- $filtered = array();
300
- $subject = AAM::getUser();
301
-
302
- foreach ($query->posts as $post) {
303
- if (isset($post->post_type)) {
304
- $type = $post->post_type;
305
- } else {
306
- $type = AAM_Core_API::getQueryPostType($query);
307
- }
308
-
309
- $object = $subject->getObject(
310
- 'post', (is_a($post, 'WP_Post') ? $post->ID : $post)
311
- );
312
-
313
- $hidden = $object->get('backend.hidden');
314
- $list = $object->get('backend.list');
315
-
316
- if (empty($hidden) && empty($list)) {
317
- $filtered[] = $post;
318
- } else {
319
- $counter--;
320
- $query->post_count--;
321
- }
322
- }
323
-
324
- $query->posts = $filtered;
325
-
326
- return $counter;
327
- }
328
-
329
  /**
330
  * Post update hook
331
  *
24
  */
25
  private static $_instance = null;
26
 
 
 
 
 
 
27
  /**
28
  * Initialize backend filters
29
  *
53
  //default category filder
54
  add_filter('pre_option_default_category', array($this, 'filterDefaultCategory'));
55
 
 
 
 
 
 
56
  add_action('pre_post_update', array($this, 'prePostUpdate'), 10, 2);
57
 
58
  //user/role filters
275
  return ($default ? $default : $category);
276
  }
277
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  /**
279
  * Post update hook
280
  *
Application/Backend/Manager.php CHANGED
@@ -54,6 +54,9 @@ class AAM_Backend_Manager {
54
  //post title decorator
55
  add_filter('the_title', array($this, 'theTitle'), 999, 2);
56
 
 
 
 
57
  //screen options & contextual help hooks
58
  add_filter('screen_options_show_screen', array($this, 'screenOptions'));
59
  add_filter('contextual_help', array($this, 'helpOptions'), 10, 3);
@@ -151,6 +154,13 @@ class AAM_Backend_Manager {
151
  'On ConfigPress tab, change [extention.directory] option to [core.extention.directory]', 'b', 'b'
152
  );
153
  }
 
 
 
 
 
 
 
154
  }
155
 
156
  /**
@@ -169,6 +179,20 @@ class AAM_Backend_Manager {
169
  return $caps;
170
  }
171
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  /**
173
  * Profile updated hook
174
  *
54
  //post title decorator
55
  add_filter('the_title', array($this, 'theTitle'), 999, 2);
56
 
57
+ //permalink manager
58
+ add_filter('get_sample_permalink_html', array($this, 'getPermalinkHtml'), 10, 5);
59
+
60
  //screen options & contextual help hooks
61
  add_filter('screen_options_show_screen', array($this, 'screenOptions'));
62
  add_filter('contextual_help', array($this, 'helpOptions'), 10, 3);
154
  'On ConfigPress tab, change [extention.directory] option to [core.extention.directory]', 'b', 'b'
155
  );
156
  }
157
+
158
+ $tmpl = AAM_Core_Config::get('login.shortcode.template', null);
159
+ if (!empty($tmpl)) {
160
+ AAM_Core_Console::add(
161
+ 'On ConfigPress tab, change [login.shortcode.template] option to [feature.secureLogin.shortcode.template]', 'b', 'b'
162
+ );
163
+ }
164
  }
165
 
166
  /**
179
  return $caps;
180
  }
181
 
182
+ /**
183
+ *
184
+ * @param string $html
185
+ * @return string
186
+ */
187
+ public function getPermalinkHtml($html) {
188
+ if (AAM_Core_API::capabilityExists('edit_permalink')
189
+ && !AAM::getUser()->hasCapability('edit_permalink')) {
190
+ $html = '';
191
+ }
192
+
193
+ return $html;
194
+ }
195
+
196
  /**
197
  * Profile updated hook
198
  *
Application/Core/API.php CHANGED
@@ -368,49 +368,6 @@ final class AAM_Core_API {
368
  return (!empty($version) ? $version : null);
369
  }
370
 
371
- /**
372
- * Get filtered post list
373
- *
374
- * Return only posts that are restricted to LIST or LIST TO OTHERS for the
375
- * current user. This function is shared by both frontend and backend
376
- *
377
- * @param WP_Query $query
378
- * @param string $area
379
- *
380
- * @return array
381
- *
382
- * @access public
383
- */
384
- public static function getFilteredPostList($query) {
385
- $filtered = array();
386
-
387
- $type = self::getQueryPostType($query);
388
- $area = AAM_Core_Api_Area::get();
389
-
390
- if ($type) {
391
- $cache = AAM::getUser()->getObject('cache')->getMergedOption();
392
- $posts = (isset($cache['post']) ? $cache['post'] : array());
393
-
394
- foreach($posts as $id => $option) {
395
- if (!empty($option["{$area}.list"])
396
- || !empty($option["{$area}.hidden"])) {
397
- $filtered[] = $id;
398
- }
399
- }
400
- }
401
-
402
- if (is_single()) {
403
- $post = self::getCurrentPost();
404
- $in = ($post ? array_search($post->ID, $filtered) : false);
405
-
406
- if ($in !== false) {
407
- $filtered = array_splice($filtered, $in, 1);
408
- }
409
- }
410
-
411
- return (is_array($filtered) ? $filtered : array());
412
- }
413
-
414
  /**
415
  * Get Query post type
416
  *
@@ -459,6 +416,10 @@ final class AAM_Core_API {
459
  break;
460
  }
461
  }
 
 
 
 
462
  }
463
 
464
  $user = AAM::getUser();
368
  return (!empty($version) ? $version : null);
369
  }
370
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
371
  /**
372
  * Get Query post type
373
  *
416
  break;
417
  }
418
  }
419
+ } elseif (!empty($wp_query->query_vars['p'])) {
420
+ $res = get_post($wp_query->query_vars['p']);
421
+ } elseif (!empty($wp_query->query_vars['page_id'])) {
422
+ $res = get_post($wp_query->query_vars['page_id']);
423
  }
424
 
425
  $user = AAM::getUser();
Application/Core/Gateway.php CHANGED
@@ -217,6 +217,18 @@ final class AAM_Core_Gateway implements AAM_Core_Contract_Api {
217
  return $subject;
218
  }
219
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  /**
221
  * Get instance of the API gateway
222
  *
217
  return $subject;
218
  }
219
 
220
+ /**
221
+ * Log any critical message
222
+ *
223
+ * @param string $message
224
+ * @param string $markers...
225
+ *
226
+ * @access public
227
+ */
228
+ public function log() {
229
+ call_user_func_array('AAM_Core_Console::add', func_get_args());
230
+ }
231
+
232
  /**
233
  * Get instance of the API gateway
234
  *
Application/Core/Object/Cache.php CHANGED
@@ -72,7 +72,7 @@ class AAM_Core_Object_Cache extends AAM_Core_Object {
72
  *
73
  * @access public
74
  */
75
- public function get($type, $id, $default = array()) {
76
  $option = $this->getOption();
77
 
78
  return (isset($option[$type][$id]) ? $option[$type][$id] : $default);
@@ -101,31 +101,6 @@ class AAM_Core_Object_Cache extends AAM_Core_Object {
101
  return $this->getSubject()->deleteOption('cache');
102
  }
103
 
104
- /**
105
- *
106
- * @return type
107
- */
108
- public function getMergedOption() {
109
- $options = array($this->getOption());
110
- $subject = $this->getSubject();
111
-
112
- while($subject = $subject->getParent()) {
113
- $options[] = $subject->getObject('cache')->getOption();
114
- }
115
-
116
- $merged = array();
117
-
118
- // Important to reverse as lower subject level overrides higher. For example,
119
- // Role level overrides Default level.
120
- foreach(array_reverse($options) as $option) {
121
- if (is_array($option)) {
122
- $merged = array_replace_recursive($merged, $option);
123
- }
124
- }
125
-
126
- return $merged;
127
- }
128
-
129
  /**
130
  * Read object from parent subject
131
  *
72
  *
73
  * @access public
74
  */
75
+ public function get($type, $id = 0, $default = array()) {
76
  $option = $this->getOption();
77
 
78
  return (isset($option[$type][$id]) ? $option[$type][$id] : $default);
101
  return $this->getSubject()->deleteOption('cache');
102
  }
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  /**
105
  * Read object from parent subject
106
  *
Application/Core/Object/Post.php CHANGED
@@ -141,37 +141,6 @@ class AAM_Core_Object_Post extends AAM_Core_Object {
141
  $subject->getObject('cache')->add('post', $post->ID, false);
142
  } else {
143
  $subject->getObject('cache')->add('post', $post->ID, $option);
144
-
145
- // Determine if post is hidden or not. This is more complex calculation
146
- // as it is based on the combination of several options
147
- // TODO: this check does not belong here
148
- if (in_array($subject::UID, array('user'))) {
149
- $this->determineVisibility($post, 'frontend', $option);
150
- $this->determineVisibility($post, 'backend', $option);
151
- $this->determineVisibility($post, 'api', $option);
152
- }
153
- }
154
- }
155
-
156
- /**
157
- * Determine if post is visible for current subject
158
- *
159
- * @param WP_Post $post
160
- * @param string $area
161
- *
162
- * @param boolean $option
163
- *
164
- * @access protected
165
- */
166
- protected function determineVisibility($post, $area, &$option) {
167
- $list = !empty($option["{$area}.list"]);
168
- $others = !empty($option["{$area}.list_others"]);
169
-
170
- if ($list || ($others && ($post->post_author != $this->getSubject()->ID))) {
171
- $option["{$area}.hidden"] = true;
172
-
173
- // Cache result but only if visibility is true!
174
- $this->getSubject()->getObject('cache')->add('post', $post->ID, $option);
175
  }
176
  }
177
 
141
  $subject->getObject('cache')->add('post', $post->ID, false);
142
  } else {
143
  $subject->getObject('cache')->add('post', $post->ID, $option);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  }
145
  }
146
 
Application/Core/Object/Visibility.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * ======================================================================
5
+ * LICENSE: This file is subject to the terms and conditions defined in *
6
+ * file 'license.txt', which is part of this source code package. *
7
+ * ======================================================================
8
+ */
9
+
10
+ /**
11
+ * Post visibility object
12
+ *
13
+ * @package AAM
14
+ * @author Vasyl Martyniuk <vasyl@vasyltech.com>
15
+ */
16
+ class AAM_Core_Object_Visibility extends AAM_Core_Object {
17
+
18
+ /**
19
+ * Constructor
20
+ *
21
+ * @param AAM_Core_Subject $subject
22
+ *
23
+ * @return void
24
+ *
25
+ * @access public
26
+ */
27
+ public function __construct(AAM_Core_Subject $subject) {
28
+ parent::__construct($subject);
29
+
30
+ $this->initialize();
31
+ }
32
+
33
+ /**
34
+ *
35
+ * @global type $wpdb
36
+ */
37
+ public function initialize() {
38
+ global $wpdb;
39
+
40
+ $subject = $this->getSubject();
41
+
42
+ // Read cache first
43
+ $option = $subject->getObject('cache')->get('visibility');
44
+ if ($option === false) { //if false, then the cache is empty but exists
45
+ $option = array();
46
+ } elseif (empty($option)) {
47
+ $query = "SELECT pm.`post_id`, pm.`meta_value`, p.`post_type` FROM {$wpdb->postmeta} AS pm ";
48
+ $query .= "LEFT JOIN {$wpdb->posts} AS p ON (pm.`post_id` = p.ID) ";
49
+ $query .= "WHERE pm.`meta_key` = %s";
50
+
51
+ if ($wpdb->query($wpdb->prepare($query, $this->getOptionName('post')))) {
52
+ foreach($wpdb->last_result as $row) {
53
+ $settings = maybe_unserialize($row->meta_value);
54
+ $this->pushOptions('post', $row->post_id . '|' . $row->post_type, $settings);
55
+ }
56
+ }
57
+
58
+ // Override the frontend.list for current post
59
+ $post = AAM_Core_API::getCurrentPost(); // current post
60
+ if ($post) {
61
+ $option = $this->getOption();
62
+ $option['post'][$post->ID . '|' . $post->post_type]['frontend.list'] = 0;
63
+ $this->setOption($option);
64
+ }
65
+
66
+ do_action('aam-visibility-initialize-action', $this);
67
+
68
+ // inherit settings from parent
69
+ $option = $subject->inheritFromParent('visibility', 0);
70
+ if (!empty($option)) {
71
+ $option = array_replace_recursive($option, $this->getOption());
72
+ } else {
73
+ $option = $this->getOption();
74
+ }
75
+
76
+ if (in_array($subject::UID, array('user', 'visitor'))) {
77
+ $subject->getObject('cache')->add(
78
+ 'visibility', 0, empty($option) ? false : $option
79
+ );
80
+ }
81
+ }
82
+
83
+ $this->setOption($option);
84
+ }
85
+
86
+ /**
87
+ *
88
+ * @param type $object
89
+ * @param type $id
90
+ * @param type $options
91
+ * @return type
92
+ */
93
+ public function pushOptions($object, $id, $options) {
94
+ $filtered = array();
95
+ $listOptions = apply_filters(
96
+ 'aam-post-list-options-filter',
97
+ array('frontend.list', 'backend.list', 'api.list')
98
+ );
99
+
100
+ foreach($options as $key => $value) {
101
+ if (in_array($key, $listOptions)) {
102
+ $filtered[$key] = $value;
103
+ }
104
+ }
105
+
106
+ if (!empty($filtered)) {
107
+ $option = $this->getOption();
108
+ if (isset($option[$object][$id])) {
109
+ $option[$object][$id] = array_merge($option[$object][$id], $filtered);
110
+ } else {
111
+ $option[$object][$id] = $filtered;
112
+ }
113
+ $this->setOption($option);
114
+ }
115
+
116
+ return $filtered;
117
+ }
118
+
119
+ /**
120
+ *
121
+ * @param type $object
122
+ * @param type $id
123
+ * @return type
124
+ */
125
+ public function has($object, $id = null) {
126
+ $option = $this->getOption();
127
+
128
+ return (is_null($id) ? isset($option[$object]) : isset($option[$object][$id]));
129
+ }
130
+
131
+ /**
132
+ * Generate option name
133
+ *
134
+ * @return string
135
+ *
136
+ * @access protected
137
+ */
138
+ protected function getOptionName($object) {
139
+ $subject = $this->getSubject();
140
+
141
+ //prepare option name
142
+ $meta_key = 'aam-' . $object . '-access-' . $subject->getUID();
143
+ $meta_key .= ($subject->getId() ? $subject->getId() : '');
144
+
145
+ return $meta_key;
146
+ }
147
+
148
+ }
Application/Core/Subject/User.php CHANGED
@@ -20,15 +20,6 @@ class AAM_Core_Subject_User extends AAM_Core_Subject {
20
  */
21
  const UID = 'user';
22
 
23
- /**
24
- * Skip initialization
25
- *
26
- * Avoid recurring loop when user is locked
27
- *
28
- * @var type
29
- */
30
- protected static $skipInit = false;
31
-
32
  /**
33
  * AAM Capability Key
34
  *
@@ -51,7 +42,7 @@ class AAM_Core_Subject_User extends AAM_Core_Subject {
51
  public function __construct($id) {
52
  parent::__construct($id);
53
 
54
- if (get_current_user_id() == $id && !self::$skipInit) {
55
  //check if user is expired
56
  $expired = get_user_option('aam_user_expiration');
57
  if (!empty($expired)) {
@@ -61,13 +52,6 @@ class AAM_Core_Subject_User extends AAM_Core_Subject {
61
  }
62
  }
63
 
64
- //check if user is locked
65
- if ($this->user_status == 1) {
66
- self::$skipInit = true;
67
- wp_logout();
68
- self::$skipInit = false;
69
- }
70
-
71
  //check if user's role expired
72
  $roleExpire = get_user_option('aam-role-expires');
73
  if ($roleExpire && ($roleExpire <= time())) {
20
  */
21
  const UID = 'user';
22
 
 
 
 
 
 
 
 
 
 
23
  /**
24
  * AAM Capability Key
25
  *
42
  public function __construct($id) {
43
  parent::__construct($id);
44
 
45
+ if (get_current_user_id() == $id) {
46
  //check if user is expired
47
  $expired = get_user_option('aam_user_expiration');
48
  if (!empty($expired)) {
52
  }
53
  }
54
 
 
 
 
 
 
 
 
55
  //check if user's role expired
56
  $roleExpire = get_user_option('aam-role-expires');
57
  if ($roleExpire && ($roleExpire <= time())) {
Application/Extension/List.php CHANGED
@@ -22,7 +22,7 @@ class AAM_Extension_List {
22
  'description' => 'Get the complete list of all available premium extensions in one package. Any new premium extensions in the future will be available for no additional cost.',
23
  'url' => 'https://aamplugin.com/complete-package',
24
  'version' => (defined('AAM_COMPLETE_PACKAGE') ? constant('AAM_COMPLETE_PACKAGE') : null),
25
- 'latest' => '3.7.2'
26
  ),
27
  'AAM_PLUS_PACKAGE' => array(
28
  'title' => 'Plus Package',
@@ -31,7 +31,7 @@ class AAM_Extension_List {
31
  'description' => 'The best selling extension with the most advanced content management features for the WordPress CMS. Manage granular access to any post, page, custom post type, category, custom hierarchical taxonomy or define the default access to all your content for all users, roles and visitors.',
32
  'url' => 'https://aamplugin.com/extension/plus-package',
33
  'version' => (defined('AAM_PLUS_PACKAGE') ? constant('AAM_PLUS_PACKAGE') : null),
34
- 'latest' => '3.6.2'
35
  ),
36
  'AAM_IP_CHECK' => array(
37
  'title' => 'IP Check',
@@ -95,7 +95,7 @@ class AAM_Extension_List {
95
  'type' => 'GNU',
96
  'tag' => 'ALPHA',
97
  'license' => 'AAMSOCIALLOGIN',
98
- 'description' => 'Login to your website with social networks like Facebook, Twitter, Instagram etc. This is the open source solution and you can find it on the <a href="https://github.com/aamplugin/social-login-extension" target="_blank">Github here</a>.',
99
  'version' => (defined('AAM_SOCIAL_LOGIN') ? constant('AAM_SOCIAL_LOGIN') : null),
100
  'latest' => '0.1'
101
  ),
22
  'description' => 'Get the complete list of all available premium extensions in one package. Any new premium extensions in the future will be available for no additional cost.',
23
  'url' => 'https://aamplugin.com/complete-package',
24
  'version' => (defined('AAM_COMPLETE_PACKAGE') ? constant('AAM_COMPLETE_PACKAGE') : null),
25
+ 'latest' => '3.7.3' // TODO - Increase version after Plus Package feedback loop
26
  ),
27
  'AAM_PLUS_PACKAGE' => array(
28
  'title' => 'Plus Package',
31
  'description' => 'The best selling extension with the most advanced content management features for the WordPress CMS. Manage granular access to any post, page, custom post type, category, custom hierarchical taxonomy or define the default access to all your content for all users, roles and visitors.',
32
  'url' => 'https://aamplugin.com/extension/plus-package',
33
  'version' => (defined('AAM_PLUS_PACKAGE') ? constant('AAM_PLUS_PACKAGE') : null),
34
+ 'latest' => '3.7'
35
  ),
36
  'AAM_IP_CHECK' => array(
37
  'title' => 'IP Check',
95
  'type' => 'GNU',
96
  'tag' => 'ALPHA',
97
  'license' => 'AAMSOCIALLOGIN',
98
+ 'description' => 'Login to your website with social networks like Facebook, Twitter, Instagram etc. <a href="https://aamplugin.com/help/how-does-aam-social-login-works" target="_blank">Read more.</a> This is the open source solution and you can find it on the <a href="https://github.com/aamplugin/social-login-extension" target="_blank">Github here</a>.',
99
  'version' => (defined('AAM_SOCIAL_LOGIN') ? constant('AAM_SOCIAL_LOGIN') : null),
100
  'latest' => '0.1'
101
  ),
Application/Frontend/Filter.php CHANGED
@@ -41,8 +41,12 @@ class AAM_Frontend_Filter {
41
 
42
  //important to keep this option optional for optimization reasons
43
  if (AAM_Core_Config::get('core.settings.checkPostVisibility', true)) {
 
 
44
  //filter navigation pages & taxonomies
45
  add_filter('wp_get_nav_menu_items', array($this, 'getNavigationMenu'), 999);
 
 
46
  }
47
 
48
  //widget filters
@@ -124,10 +128,10 @@ class AAM_Frontend_Filter {
124
  foreach ($pages as $i => $page) {
125
  if (in_array($page->type, array('post_type', 'custom'))) {
126
  $object = AAM::getUser()->getObject('post', $page->object_id);
127
- $hidden = $object->get('frontend.hidden');
128
  $list = $object->get('frontend.list');
129
 
130
- if ($hidden || $list) {
131
  unset($pages[$i]);
132
  }
133
  }
@@ -137,6 +141,40 @@ class AAM_Frontend_Filter {
137
  return $pages;
138
  }
139
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  /**
141
  * Filter frontend widgets
142
  *
41
 
42
  //important to keep this option optional for optimization reasons
43
  if (AAM_Core_Config::get('core.settings.checkPostVisibility', true)) {
44
+ // TODO: figure out how to remove these two hooks and inject "visibility"
45
+ // object instead
46
  //filter navigation pages & taxonomies
47
  add_filter('wp_get_nav_menu_items', array($this, 'getNavigationMenu'), 999);
48
+ // filter navigation pages & taxonomies
49
+ add_filter('get_pages', array($this, 'filterPages'), 999);
50
  }
51
 
52
  //widget filters
128
  foreach ($pages as $i => $page) {
129
  if (in_array($page->type, array('post_type', 'custom'))) {
130
  $object = AAM::getUser()->getObject('post', $page->object_id);
131
+ $others = $object->get('frontend.list_others');
132
  $list = $object->get('frontend.list');
133
 
134
+ if (($others && ($object->post_author != get_current_user_id())) || $list) {
135
  unset($pages[$i]);
136
  }
137
  }
141
  return $pages;
142
  }
143
 
144
+ /**
145
+ * Filter posts from the list
146
+ *
147
+ * @param array $pages
148
+ *
149
+ * @return array
150
+ *
151
+ * @access public
152
+ */
153
+ public function filterPages($pages) {
154
+ $current = AAM_Core_API::getCurrentPost();
155
+
156
+ if (is_array($pages)) {
157
+ $area = AAM_Core_Api_Area::get();
158
+
159
+ foreach ($pages as $i => $post) {
160
+ if ($current && ($current->ID == $post->ID)) { continue; }
161
+
162
+ // TODO: refactor this to AAM API standalone
163
+ $object = AAM::getUser()->getObject('post', $post->ID);
164
+ $list = $object->get($area. '.list');
165
+ $others = $object->get($area. '.list_others');
166
+
167
+ if ($list || ($others && ($post->post_author != get_current_user_id()))) {
168
+ unset($pages[$i]);
169
+ }
170
+ }
171
+
172
+ $pages = array_values($pages);
173
+ }
174
+
175
+ return $pages;
176
+ }
177
+
178
  /**
179
  * Filter frontend widgets
180
  *
Application/Shared/Manager.php CHANGED
@@ -61,12 +61,12 @@ class AAM_Shared_Manager {
61
  // Control post visibility
62
  //important to keep this option optional for optimization reasons
63
  if (AAM_Core_Config::get('core.settings.checkPostVisibility', true)) {
64
- // filter navigation pages & taxonomies
65
- add_filter('get_pages', array(self::$_instance, 'filterPostList'), 999);
66
- // add post filter for LIST restriction
67
- add_filter('the_posts', array(self::$_instance, 'filterPostList'), 999);
68
- // pre post query builder
69
- add_action('pre_get_posts', array(self::$_instance, 'preparePostQuery'), 999);
70
  }
71
 
72
  //filter post content
@@ -76,6 +76,72 @@ class AAM_Shared_Manager {
76
  return self::$_instance;
77
  }
78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  /**
80
  * Disable REST API
81
  *
@@ -143,71 +209,6 @@ class AAM_Shared_Manager {
143
  return $caps;
144
  }
145
 
146
- /**
147
- * Filter posts from the list
148
- *
149
- * @param array $posts
150
- *
151
- * @return array
152
- *
153
- * @access public
154
- */
155
- public function filterPostList($posts) {
156
- $current = AAM_Core_API::getCurrentPost();
157
-
158
- if (is_array($posts)) {
159
- $area = AAM_Core_Api_Area::get();
160
-
161
- foreach ($posts as $i => $post) {
162
- if ($current && ($current->ID == $post->ID)) { continue; }
163
-
164
- // TODO: refactor this to AAM API standalone
165
- $object = AAM::getUser()->getObject('post', $post->ID);
166
- $hidden = $object->get($area. '.hidden');
167
- $list = $object->get($area. '.list');
168
-
169
- if ($hidden || $list) {
170
- unset($posts[$i]);
171
- }
172
- }
173
-
174
- $posts = array_values($posts);
175
- }
176
-
177
- return $posts;
178
- }
179
-
180
- /**
181
- * Build pre-post query request
182
- *
183
- * This is used to solve the problem or pagination
184
- *
185
- * @param stdClass $query
186
- *
187
- * @return void
188
- *
189
- * @access public
190
- */
191
- public function preparePostQuery($query) {
192
- static $skip = false;
193
-
194
- if ($skip === false) { // avoid loop
195
- $skip = true;
196
- // TODO: refactor this to AAM API standalone
197
- $filtered = AAM_Core_API::getFilteredPostList($query);
198
- $skip = false;
199
-
200
- if (isset($query->query_vars['post__not_in'])
201
- && is_array($query->query_vars['post__not_in'])) {
202
- $query->query_vars['post__not_in'] = array_merge(
203
- $query->query_vars['post__not_in'], $filtered
204
- );
205
- } else {
206
- $query->query_vars['post__not_in'] = $filtered;
207
- }
208
- }
209
- }
210
-
211
  /**
212
  * Filter pages fields
213
  *
61
  // Control post visibility
62
  //important to keep this option optional for optimization reasons
63
  if (AAM_Core_Config::get('core.settings.checkPostVisibility', true)) {
64
+ add_filter(
65
+ 'posts_clauses_request',
66
+ array(self::$_instance, 'filterPostQuery'),
67
+ 999,
68
+ 2
69
+ );
70
  }
71
 
72
  //filter post content
76
  return self::$_instance;
77
  }
78
 
79
+ /**
80
+ *
81
+ * @global WPDB $wpdb
82
+ * @param type $clauses
83
+ * @param type $wpQuery
84
+ * @return type
85
+ */
86
+ public function filterPostQuery($clauses, $wpQuery) {
87
+ global $wpdb;
88
+
89
+ $query = '';
90
+ $option = AAM::getUser()->getObject('visibility')->getOption();
91
+
92
+ //echo '<pre>'; print_r($option);
93
+
94
+ if (!empty($option['post'])) {
95
+ if (!empty($wpQuery->query['post_type'])) {
96
+ $postType = $wpQuery->query['post_type'];
97
+ } elseif (!empty($wpQuery->query_vars['post_type'])) {
98
+ $postType = $wpQuery->query_vars['post_type'];
99
+ } elseif ($wpQuery->is_attachment) {
100
+ $postType = 'attachment';
101
+ } elseif ($wpQuery->is_page) {
102
+ $postType = 'page';
103
+ } else {
104
+ $postType = 'post';
105
+ }
106
+
107
+ $not = array();
108
+ $area = AAM_Core_Api_Area::get();
109
+
110
+ foreach($option['post'] as $id => $access) {
111
+ $chunks = explode('|', $id);
112
+
113
+ if ($postType == $chunks[1]) {
114
+ if (!empty($access["{$area}.list"])) {
115
+ $not[] = $chunks[0];
116
+ }
117
+ }
118
+ }
119
+
120
+ $chunks = array();
121
+ if (!empty($not)) {
122
+ $query .= " AND {$wpdb->posts}.ID NOT IN (" . implode(',', $not) . ")";
123
+ }
124
+ }
125
+
126
+ $clauses['where'] .= apply_filters(
127
+ 'aam-post-where-clause-filter', $query, $wpQuery, $option
128
+ );
129
+
130
+ if (strpos($clauses['where'], $wpdb->term_relationships) !== false) {
131
+ if (strpos($clauses['join'], $wpdb->term_relationships) === false) {
132
+ $clauses['join'] .= " LEFT JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id)";
133
+ }
134
+
135
+ if (empty($clauses['groupby'])) {
136
+ $clauses['groupby'] = "{$wpdb->posts}.ID";
137
+ }
138
+ }
139
+
140
+ //echo '<pre>'; print_r($clauses); die();
141
+
142
+ return $clauses;
143
+ }
144
+
145
  /**
146
  * Disable REST API
147
  *
209
  return $caps;
210
  }
211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  /**
213
  * Filter pages fields
214
  *
aam.php CHANGED
@@ -3,7 +3,7 @@
3
  /**
4
  Plugin Name: Advanced Access Manager
5
  Description: All you need to manage access to your WordPress website
6
- Version: 5.3.1
7
  Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  Author URI: https://vasyltech.com
9
 
@@ -141,10 +141,17 @@ class AAM {
141
  */
142
  public static function getInstance() {
143
  if (is_null(self::$_instance)) {
 
 
 
 
 
 
 
 
144
  load_plugin_textdomain(
145
  AAM_KEY, false, dirname(plugin_basename(__FILE__)) . '/Lang/'
146
  );
147
- self::$_instance = new self;
148
 
149
  //load all installed extension
150
  AAM_Extension_Repository::getInstance()->load();
3
  /**
4
  Plugin Name: Advanced Access Manager
5
  Description: All you need to manage access to your WordPress website
6
+ Version: 5.3.2
7
  Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  Author URI: https://vasyltech.com
9
 
141
  */
142
  public static function getInstance() {
143
  if (is_null(self::$_instance)) {
144
+ self::$_instance = new self;
145
+
146
+ // Logout user if he/she is blocked
147
+ $user = self::$_instance->getUser();
148
+ if ($user->getUID() == 'user' && $user->user_status == 1) {
149
+ wp_logout();
150
+ }
151
+
152
  load_plugin_textdomain(
153
  AAM_KEY, false, dirname(plugin_basename(__FILE__)) . '/Lang/'
154
  );
 
155
 
156
  //load all installed extension
157
  AAM_Extension_Repository::getInstance()->load();
media/js/aam.js CHANGED
@@ -2715,7 +2715,7 @@
2715
  }
2716
  });
2717
  }
2718
-
2719
  /**
2720
  *
2721
  * @returns {undefined}
@@ -2768,7 +2768,7 @@
2768
  }
2769
  });
2770
  });
2771
-
2772
  $('#clear-cache').bind('click', function () {
2773
  $.ajax(aamLocal.ajaxurl, {
2774
  type: 'POST',
2715
  }
2716
  });
2717
  }
2718
+
2719
  /**
2720
  *
2721
  * @returns {undefined}
2768
  }
2769
  });
2770
  });
2771
+
2772
  $('#clear-cache').bind('click', function () {
2773
  $.ajax(aamLocal.ajaxurl, {
2774
  type: 'POST',
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: vasyltech
3
  Tags: access, role, user, capability, page access, post access, content access, comments, security, login redirect, membership, backend lockdown, wp-admin, 404, rest api, xml rpc
4
  Requires at least: 4.0
5
  Tested up to: 4.9.6
6
- Stable tag: 5.3.1
7
 
8
  The most powerful access management plugin for WordPress websites.
9
 
@@ -66,6 +66,12 @@ https://www.youtube.com/watch?v=yiOhjaacNJc
66
 
67
  == Changelog ==
68
 
 
 
 
 
 
 
69
  = 5.3.1 =
70
  * Fixed bug with deprecated cache object to keep it backward compatible
71
  * Fixed bug with teaser message on none latin alphabet
3
  Tags: access, role, user, capability, page access, post access, content access, comments, security, login redirect, membership, backend lockdown, wp-admin, 404, rest api, xml rpc
4
  Requires at least: 4.0
5
  Tested up to: 4.9.6
6
+ Stable tag: 5.3.2
7
 
8
  The most powerful access management plugin for WordPress websites.
9
 
66
 
67
  == Changelog ==
68
 
69
+ = 5.3.2 =
70
+ * Fixed the bug that triggers PHP warnings when blocked user is trying to login
71
+ * Fixed the bug with get current post method in the core API
72
+ * WARNING Experimental approach! to the post access that enormously improve AAM performance
73
+ * Added custom capability "edit_permalink" that control ability to edit post permalink
74
+
75
  = 5.3.1 =
76
  * Fixed bug with deprecated cache object to keep it backward compatible
77
  * Fixed bug with teaser message on none latin alphabet