Advanced Access Manager - Version 5.6

Version Description

  • Fixed the bug with encoding on Safari when gzip is enabled
  • Fixed the bug with double caching
  • Added URI Access feature that allows to manage access to any website URI
  • Improved UI a little bit
Download this release

Release Info

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

Code changes from version 5.5.2 to 5.6

Application/Backend/Feature/Main/Capability.php CHANGED
@@ -54,7 +54,7 @@ class AAM_Backend_Feature_Main_Capability extends AAM_Backend_Feature_Abstract {
54
  'aam_manage_404_redirect', 'aam_manage_ip_check', 'aam_manage_admin_toolbar',
55
  'aam_manage_default', 'aam_manage_visitors', 'aam_manage_roles', 'aam_manage_users',
56
  'aam_edit_roles', 'aam_delete_roles', 'aam_toggle_users', 'aam_switch_users',
57
- 'aam_manage_configpress', 'aam_manage_api_routes'
58
  )
59
  );
60
 
54
  'aam_manage_404_redirect', 'aam_manage_ip_check', 'aam_manage_admin_toolbar',
55
  'aam_manage_default', 'aam_manage_visitors', 'aam_manage_roles', 'aam_manage_users',
56
  'aam_edit_roles', 'aam_delete_roles', 'aam_toggle_users', 'aam_switch_users',
57
+ 'aam_manage_configpress', 'aam_manage_api_routes', 'aam_manage_uri'
58
  )
59
  );
60
 
Application/Backend/Feature/Main/Uri.php ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * WordPress API manager
12
+ *
13
+ * @package AAM
14
+ * @author Vasyl Martyniuk <vasyl@vasyltech.com>
15
+ */
16
+ class AAM_Backend_Feature_Main_Uri extends AAM_Backend_Feature_Abstract {
17
+
18
+ /**
19
+ *
20
+ * @return type
21
+ */
22
+ public function getTable() {
23
+ return wp_json_encode($this->retrieveAllRules());
24
+ }
25
+
26
+ /**
27
+ *
28
+ * @return type
29
+ */
30
+ public function save() {
31
+ $uri = filter_input(INPUT_POST, 'uri');
32
+ $id = filter_input(INPUT_POST, 'id');
33
+ $type = filter_input(INPUT_POST, 'type');
34
+ $value = filter_input(INPUT_POST, 'value');
35
+
36
+ $object = AAM_Backend_Subject::getInstance()->getObject('uri');
37
+
38
+ if (empty($id)) {
39
+ $id = uniqid();
40
+ }
41
+
42
+ $object->save($id, str_replace(site_url(), '', $uri), $type, $value);
43
+
44
+ return wp_json_encode(array('status' => 'success'));
45
+ }
46
+
47
+ /**
48
+ *
49
+ * @return type
50
+ */
51
+ public function delete() {
52
+ $id = filter_input(INPUT_POST, 'id');
53
+ $object = AAM_Backend_Subject::getInstance()->getObject('uri');
54
+
55
+ $object->delete($id);
56
+
57
+ return wp_json_encode(array('status' => 'success'));
58
+ }
59
+
60
+ /**
61
+ * @inheritdoc
62
+ */
63
+ public static function getTemplate() {
64
+ return 'main/uri.phtml';
65
+ }
66
+
67
+ /**
68
+ *
69
+ * @return type
70
+ */
71
+ public function isVisitor() {
72
+ $subject = AAM_Backend_Subject::getInstance();
73
+
74
+ return $subject->getUID() === AAM_Core_Subject_Visitor::UID;
75
+ }
76
+
77
+ /**
78
+ *
79
+ * @return type
80
+ */
81
+ protected function retrieveAllRules() {
82
+ $rules = AAM_Backend_Subject::getInstance()->getObject('uri')->getOption();
83
+
84
+ $response = array(
85
+ 'recordsTotal' => count($rules),
86
+ 'recordsFiltered' => count($rules),
87
+ 'draw' => AAM_Core_Request::request('draw'),
88
+ 'data' => array(),
89
+ );
90
+
91
+ foreach($rules as $id => $rule) {
92
+ $response['data'][] = array(
93
+ $id,
94
+ $rule['uri'],
95
+ $rule['type'],
96
+ $rule['action'],
97
+ 'edit,delete'
98
+ );
99
+ }
100
+
101
+ return $response;
102
+ }
103
+
104
+ /**
105
+ * Check inheritance status
106
+ *
107
+ * Check if menu settings are overwritten
108
+ *
109
+ * @return boolean
110
+ *
111
+ * @access protected
112
+ */
113
+ protected function isOverwritten() {
114
+ $object = AAM_Backend_Subject::getInstance()->getObject('uri');
115
+
116
+ return $object->isOverwritten();
117
+ }
118
+
119
+ /**
120
+ * Register Menu feature
121
+ *
122
+ * @return void
123
+ *
124
+ * @access public
125
+ */
126
+ public static function register() {
127
+ AAM_Backend_Feature::registerFeature((object) array(
128
+ 'uid' => 'uri',
129
+ 'position' => 55,
130
+ 'title' => __('URI Access', AAM_KEY) . '<span class="badge">NEW</span>',
131
+ 'capability' => 'aam_manage_uri',
132
+ 'type' => 'main',
133
+ 'subjects' => array(
134
+ AAM_Core_Subject_Role::UID,
135
+ AAM_Core_Subject_User::UID,
136
+ AAM_Core_Subject_Visitor::UID,
137
+ AAM_Core_Subject_Default::UID
138
+ ),
139
+ 'option' => 'core.settings.backendAccessControl,core.settings.frontendAccessControl',
140
+ 'view' => __CLASS__
141
+ ));
142
+ }
143
+
144
+ }
Application/Backend/Filter.php CHANGED
@@ -71,6 +71,28 @@ class AAM_Backend_Filter {
71
  );
72
 
73
  AAM_Backend_Authorization::bootstrap(); //bootstrap backend authorization
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  }
75
 
76
  /**
71
  );
72
 
73
  AAM_Backend_Authorization::bootstrap(); //bootstrap backend authorization
74
+
75
+ //check URI
76
+ $this->checkURIAccess();
77
+ }
78
+
79
+ /**
80
+ *
81
+ */
82
+ protected function checkURIAccess() {
83
+ $uri = wp_parse_url(AAM_Core_Request::server('REQUEST_URI'));
84
+ $object = AAM::api()->getUser()->getObject('uri');
85
+ $params = array();
86
+
87
+ if (isset($uri['query'])) {
88
+ parse_str($uri['query'], $params);
89
+ }
90
+
91
+ if ($match = $object->findMatch($uri['path'], $params)) {
92
+ if ($match['type'] !== 'allow') {
93
+ AAM::api()->redirect($match['type'], $match['action']);
94
+ }
95
+ }
96
  }
97
 
98
  /**
Application/Backend/Manager.php CHANGED
@@ -792,7 +792,7 @@ class AAM_Backend_Manager {
792
  AAM_Core_Request::post('uiType', 'main')
793
  );
794
 
795
- $accept = explode(',', AAM_Core_Request::server('HTTP_ACCEPT_ENCODING'));
796
  header('Content-Type: text/html; charset=UTF-8');
797
 
798
  $zlib = strtolower(ini_get('zlib.output_compression'));
@@ -804,10 +804,7 @@ class AAM_Backend_Manager {
804
  if (in_array($zlib, array('1', 'on'), true) && !empty($accept)) {
805
  header('Vary: Accept-Encoding'); // Handle proxies
806
 
807
- if ( false !== stripos($accept[0], 'deflate') && function_exists('gzdeflate')) {
808
- header('Content-Encoding: deflate');
809
- $response = ($compressed ? $response : gzdeflate($response, 3));
810
- } elseif ( false !== stripos($accept[0], 'gzip') && function_exists('gzencode') ) {
811
  header('Content-Encoding: gzip');
812
  $response = ($compressed ? $response : gzencode($response, 3));
813
  }
792
  AAM_Core_Request::post('uiType', 'main')
793
  );
794
 
795
+ $accept = AAM_Core_Request::server('HTTP_ACCEPT_ENCODING');
796
  header('Content-Type: text/html; charset=UTF-8');
797
 
798
  $zlib = strtolower(ini_get('zlib.output_compression'));
804
  if (in_array($zlib, array('1', 'on'), true) && !empty($accept)) {
805
  header('Vary: Accept-Encoding'); // Handle proxies
806
 
807
+ if ( false !== stripos($accept, 'gzip') && function_exists('gzencode') ) {
 
 
 
808
  header('Content-Encoding: gzip');
809
  $response = ($compressed ? $response : gzencode($response, 3));
810
  }
Application/Backend/View.php CHANGED
@@ -44,6 +44,7 @@ class AAM_Backend_View {
44
  AAM_Backend_Feature_Main_LoginRedirect::register();
45
  AAM_Backend_Feature_Main_LogoutRedirect::register();
46
  AAM_Backend_Feature_Main_404Redirect::register();
 
47
 
48
  AAM_Backend_Feature_Settings_Core::register();
49
  AAM_Backend_Feature_Settings_Content::register();
44
  AAM_Backend_Feature_Main_LoginRedirect::register();
45
  AAM_Backend_Feature_Main_LogoutRedirect::register();
46
  AAM_Backend_Feature_Main_404Redirect::register();
47
+ AAM_Backend_Feature_Main_Uri::register();
48
 
49
  AAM_Backend_Feature_Settings_Core::register();
50
  AAM_Backend_Feature_Settings_Content::register();
Application/Backend/phtml/main/get-started.phtml CHANGED
@@ -8,8 +8,10 @@
8
  <p class="text-larger"><span class="aam-highlight"><?php echo __('Please Note!', AAM_KEY); ?></span> <?php echo sprintf(AAM_Backend_View_Helper::preparePhrase('Power comes with responsibility. Make sure you have good understanding of %sWordPress Roles & Capabilities%s because AAM is very closely integrated with WordPress core. It is also recommended to have a backup of your database before you start working with AAM. There is no need to backup your files; AAM does not modify any physical files on your server and never did.'), '<a href="https://aamplugin.com/help/wordpress-roles-and-capabilities" target="_blank">', '</a>'); ?></p>
9
  <p class="text-larger"><?php echo sprintf(__('AAM was thoroughly tested on the fresh installation of WordPress and in the latest versions of Chrome, Safari, IE and Firefox. If you have any issues, the most typical case is a conflict with other plugins or themes. In this case please do not hesitate to contact us directly on our website %saamplugin.com%s', AAM_KEY), '<a href="https://aamplugin.com" target="_blank">', '</a>'); ?></p>
10
  <p class="text-larger"><?php echo sprintf(__('If you are not sure where to start, please check our %s"Get Started"%s page to learn more about core concepts that will definitely help you to manage access to your WordPress website more effectively.', AAM_KEY), '<a href="https://aamplugin.com/get-started" target="_blank">', '</a>'); ?></p>
11
- <p class="text-center"><a href="https://aamplugin.com/get-started" class="btn btn-primary" target="_blank"><?php echo __('Get Started', AAM_KEY); ?></a></p>
12
- <p class="text-center"><small><sup>*</sup> <?php echo __('To remove the "Get Started" tab you may go to Settings Area and disable "Get Started Tab" option.', AAM_KEY); ?></small></p>
 
 
13
  </div>
14
  </div>
15
  </div>
8
  <p class="text-larger"><span class="aam-highlight"><?php echo __('Please Note!', AAM_KEY); ?></span> <?php echo sprintf(AAM_Backend_View_Helper::preparePhrase('Power comes with responsibility. Make sure you have good understanding of %sWordPress Roles & Capabilities%s because AAM is very closely integrated with WordPress core. It is also recommended to have a backup of your database before you start working with AAM. There is no need to backup your files; AAM does not modify any physical files on your server and never did.'), '<a href="https://aamplugin.com/help/wordpress-roles-and-capabilities" target="_blank">', '</a>'); ?></p>
9
  <p class="text-larger"><?php echo sprintf(__('AAM was thoroughly tested on the fresh installation of WordPress and in the latest versions of Chrome, Safari, IE and Firefox. If you have any issues, the most typical case is a conflict with other plugins or themes. In this case please do not hesitate to contact us directly on our website %saamplugin.com%s', AAM_KEY), '<a href="https://aamplugin.com" target="_blank">', '</a>'); ?></p>
10
  <p class="text-larger"><?php echo sprintf(__('If you are not sure where to start, please check our %s"Get Started"%s page to learn more about core concepts that will definitely help you to manage access to your WordPress website more effectively.', AAM_KEY), '<a href="https://aamplugin.com/get-started" target="_blank">', '</a>'); ?></p>
11
+ <p class="text-center">
12
+ <a href="https://aamplugin.com/get-started" class="btn btn-primary" target="_blank"><?php echo __('Go To "Get Started" Page', AAM_KEY); ?></a><br/><br/>
13
+ <a href="#" class="text-success" id="ack-get-started"><?php echo __('OK, got it', AAM_KEY); ?></a>
14
+ </p>
15
  </div>
16
  </div>
17
  </div>
Application/Backend/phtml/main/uri.phtml ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (defined('AAM_KEY')) { ?>
2
+ <div class="aam-feature" id="uri-content">
3
+ <?php $subject = AAM_Backend_Subject::getInstance(); ?>
4
+
5
+ <div class="row">
6
+ <div class="col-xs-12">
7
+ <p class="aam-info">
8
+ <?php echo sprintf(AAM_Backend_View_Helper::preparePhrase('Manage access to the website URL(s) for the [%s]. However, note! All entered URLs have to belong to this particular website and processed by the WordPress core. For more information check %sHow to restrict access to any WordPress website URL%s.', 'b'), AAM_Backend_Subject::getInstance()->getName(), '<a href="https://aamplugin.com/help/how-to-restrict-access-to-any-wordpress-website-url" target="_blank">', '</a>'); ?>
9
+ </p>
10
+ </div>
11
+ </div>
12
+
13
+ <div class="row">
14
+ <div class="col-xs-12">
15
+ <div class="aam-overwrite" id="aam-uri-overwrite" style="display: <?php echo ($this->isOverwritten() ? 'block' : 'none'); ?>">
16
+ <span><i class="icon-check"></i> <?php echo __('Settings are customized', AAM_KEY); ?></span>
17
+ <span><a href="#" id="uri-reset" class="btn btn-xs btn-primary"><?php echo __('Reset To Default', AAM_KEY); ?></a>
18
+ </div>
19
+ </div>
20
+ </div>
21
+
22
+ <div class="modal fade" id="uri-model" tabindex="-1" role="dialog">
23
+ <div class="modal-dialog" role="document">
24
+ <div class="modal-content">
25
+ <div class="modal-header">
26
+ <button type="button" class="close" data-dismiss="modal" aria-label="<?php echo __('Close', AAM_KEY); ?>"><span aria-hidden="true">&times;</span></button>
27
+ <h4 class="modal-title"><?php echo __('URI Access Rule', AAM_KEY); ?></h4>
28
+ </div>
29
+ <div class="modal-body">
30
+ <div class="form-group">
31
+ <label><?php echo AAM_Backend_View_Helper::preparePhrase('Enter URL [(wildcard * is available with Plus Package extension)]', 'small'); ?></label>
32
+ <input type="text" class="form-control form-clearable" id="uri-rule" placeholder="Enter valid URL" />
33
+ </div>
34
+
35
+ <label><?php echo __('How to redirect user when match?', AAM_KEY); ?></label><br/>
36
+
37
+ <div class="radio">
38
+ <input type="radio" name="uri.access.type" id="uri-access-allow" value="allow" data-action="none" />
39
+ <label for="uri-access-allow"><?php echo __('Allow Access', AAM_KEY); ?></label>
40
+ </div>
41
+ <div class="radio">
42
+ <input type="radio" name="uri.access.type" id="uri-access-deny" value="deny" data-action="none" />
43
+ <label for="uri-access-deny"><?php echo AAM_Backend_View_Helper::preparePhrase('Deny Access [(show "Access Denied" message)]', 'small'); ?></label>
44
+ </div>
45
+ <div class="radio">
46
+ <input type="radio" name="uri.access.type" id="uri-access-deny-message" data-action="#uri-access-deny-message-action" value="message" />
47
+ <label for="uri-access-deny-message"><?php echo AAM_Backend_View_Helper::preparePhrase('Show customized message [(plain text or HTML)]', 'small'); ?></label>
48
+ </div>
49
+ <?php if ($this->isVisitor()) { ?>
50
+ <div class="radio">
51
+ <input type="radio" name="uri.access.type" id="uri-access-deny-login" value="login" />
52
+ <label for="uri-access-deny-login"><?php echo AAM_Backend_View_Helper::preparePhrase('Redirect to the login page [(after login, user will be redirected back to the restricted page)]', 'small'); ?></label>
53
+ </div>
54
+ <?php } ?>
55
+ <div class="radio">
56
+ <input type="radio" name="uri.access.type" id="uri-access-deny-page" data-action="#uri-access-deny-page-action" value="page" />
57
+ <label for="uri-access-deny-page"><?php echo AAM_Backend_View_Helper::preparePhrase('Redirected to existing page [(select from the drop-down)]', 'small'); ?></label>
58
+ </div>
59
+ <div class="radio">
60
+ <input type="radio" name="uri.access.type" id="uri-access-deny-url" data-action="#uri-access-deny-url-action" value="url" />
61
+ <label for="uri-access-deny-url"><?php echo AAM_Backend_View_Helper::preparePhrase('Redirected to the URL [(enter valid URL starting from http or https)]', 'small'); ?></label>
62
+ </div>
63
+ <div class="radio">
64
+ <input type="radio" name="uri.access.type" id="uri-access-deny-callback" data-action="#uri-access-deny-callback-action" value="callback" />
65
+ <label for="uri-access-deny-callback"><?php echo sprintf(AAM_Backend_View_Helper::preparePhrase('Trigger PHP callback function [(valid %sPHP callback%s is required)]', 'small'), '<a href="http://php.net/manual/en/language.types.callable.php" target="_blank">', '</a>'); ?></label>
66
+ </div>
67
+
68
+ <div class="form-group aam-uri-access-action" id="uri-access-deny-message-action" style="display: none;">
69
+ <label><?php echo __('Customized Message', AAM_KEY); ?></label>
70
+ <textarea class="form-control form-clearable" rows="3" id="uri-access-deny-message-value" placeholder="<?php echo __('Enter message...', AAM_KEY); ?>"></textarea>
71
+ </div>
72
+
73
+ <div class="form-group aam-uri-access-action" id="uri-access-deny-page-action" style="display: none;">
74
+ <label><?php echo __('Existing Page', AAM_KEY); ?></label>
75
+ <?php
76
+ wp_dropdown_pages(array(
77
+ 'depth' => 99,
78
+ 'echo' => 1,
79
+ 'id' => 'uri-access-deny-page-value', // string
80
+ 'class' => 'form-control form-clearable', // string
81
+ 'show_option_none' => __('-- Select Page --', AAM_KEY) // string
82
+ ));
83
+ ?>
84
+ </div>
85
+
86
+ <div class="form-group aam-uri-access-action" id="uri-access-deny-url-action" style="display: none;">
87
+ <label><?php echo __('The Valid Redirect URL', AAM_KEY); ?></label>
88
+ <input type="text" class="form-control form-clearable" placeholder="https://" id="uri-access-deny-url-value" />
89
+ </div>
90
+
91
+ <div class="form-group aam-uri-access-action" id="uri-access-deny-callback-action" style="display: none;">
92
+ <label><?php echo __('PHP Callback Function', AAM_KEY); ?></label>
93
+ <input type="text" class="form-control form-clearable" placeholder="Enter valid callback" id="uri-access-deny-callback-value" />
94
+ </div>
95
+ </div>
96
+ <div class="modal-footer">
97
+ <button type="button" class="btn btn-success" id="uri-save-btn"><?php echo __('Save', 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
+
104
+ <div class="modal fade" id="uri-delete-model" tabindex="-1" role="dialog">
105
+ <div class="modal-dialog modal-sm" role="document">
106
+ <div class="modal-content">
107
+ <div class="modal-header">
108
+ <button type="button" class="close" data-dismiss="modal" aria-label="<?php echo __('Close', AAM_KEY); ?>"><span aria-hidden="true">&times;</span></button>
109
+ <h4 class="modal-title"><?php echo __('Delete URI Rule', AAM_KEY); ?></h4>
110
+ </div>
111
+ <div class="modal-body">
112
+ <div class="form-group">
113
+ <p class="aam-notification">
114
+ You are about to delete the URI Rule. Please confirm!
115
+ </p>
116
+ </div>
117
+ </div>
118
+ <div class="modal-footer">
119
+ <button type="button" class="btn btn-danger" id="uri-delete-btn"><?php echo __('Delete', AAM_KEY); ?></button>
120
+ <button type="button" class="btn btn-default" data-dismiss="modal"><?php echo __('Close', AAM_KEY); ?></button>
121
+ </div>
122
+ </div>
123
+ </div>
124
+ </div>
125
+
126
+ <div class="row">
127
+ <div class="col-xs-12">
128
+ <table id="uri-list" class="table table-striped table-bordered">
129
+ <thead>
130
+ <tr>
131
+ <th>ID</th>
132
+ <th width="80%"><?php echo __('URI', AAM_KEY); ?></th>
133
+ <th><?php echo __('Type', AAM_KEY); ?></th>
134
+ <th><?php echo __('Action', AAM_KEY); ?></th>
135
+ <th><?php echo __('Actions', AAM_KEY); ?></th>
136
+ </tr>
137
+ </thead>
138
+ <tbody></tbody>
139
+ </table>
140
+ </div>
141
+ </div>
142
+ </div>
143
+ <?php }
Application/Core/API.php CHANGED
@@ -314,7 +314,7 @@ final class AAM_Core_API {
314
  $object = AAM::getUser()->getObject('redirect');
315
  $type = $object->get("{$area}.redirect.type");
316
 
317
- if (!empty($type) && ($type === 'login')) {
318
  $redirect = add_query_arg(
319
  array('reason' => 'restricted'),
320
  wp_login_url(AAM_Core_Request::server('REQUEST_URI'))
314
  $object = AAM::getUser()->getObject('redirect');
315
  $type = $object->get("{$area}.redirect.type");
316
 
317
+ if ($type === 'login') {
318
  $redirect = add_query_arg(
319
  array('reason' => 'restricted'),
320
  wp_login_url(AAM_Core_Request::server('REQUEST_URI'))
Application/Core/Gateway.php CHANGED
@@ -91,6 +91,60 @@ final class AAM_Core_Gateway {
91
  AAM_Core_API::reject(AAM_Core_Api_Area::get(), $params);
92
  }
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  /**
95
  * Check if capability exists
96
  *
91
  AAM_Core_API::reject(AAM_Core_Api_Area::get(), $params);
92
  }
93
 
94
+ /**
95
+ * Redirect request
96
+ *
97
+ * @param string $type
98
+ * @param mixed $arg
99
+ *
100
+ * @return void
101
+ *
102
+ * @access public
103
+ */
104
+ public function redirect($type, $arg = null) {
105
+ $area = AAM_Core_Api_Area::get();
106
+
107
+ switch($type) {
108
+ case 'login':
109
+ wp_redirect(add_query_arg(
110
+ array('reason' => 'restricted'),
111
+ wp_login_url(AAM_Core_Request::server('REQUEST_URI'))
112
+ ), 307);
113
+ break;
114
+
115
+ case 'page':
116
+ $page = AAM_Core_API::getCurrentPost();
117
+ if(empty($page) || ($page->ID !== intval($arg))) {
118
+ wp_safe_redirect(get_page_link($arg), 307);
119
+ }
120
+ break;
121
+
122
+ case 'message':
123
+ wp_die($arg);
124
+ break;
125
+
126
+ case 'url':
127
+ if (stripos($arg, AAM_Core_Request::server('REQUEST_URI')) === false) {
128
+ wp_redirect($arg, 307);
129
+ }
130
+ break;
131
+
132
+ case 'callback':
133
+ if (is_callable($arg)) {
134
+ call_user_func($arg);
135
+ }
136
+ break;
137
+
138
+ default:
139
+ wp_die(AAM_Core_Config::get(
140
+ "{$area}.access.deny.redirectRule", __('Access Denied', AAM_KEY)
141
+ ));
142
+ break;
143
+ }
144
+
145
+ exit; // Halt the execution
146
+ }
147
+
148
  /**
149
  * Check if capability exists
150
  *
Application/Core/Object/Uri.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * URI object
12
+ *
13
+ * @package AAM
14
+ * @author Vasyl Martyniuk <vasyl@vasyltech.com>
15
+ */
16
+ class AAM_Core_Object_Uri 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
+ $option = $this->getSubject()->readOption('uri');
31
+
32
+ if (empty($option)) {
33
+ $option = $this->getSubject()->inheritFromParent('uri');
34
+ } else {
35
+ $this->setOverwritten(true);
36
+ }
37
+
38
+ $this->setOption($option);
39
+ }
40
+
41
+ /**
42
+ *
43
+ * @param type $uri
44
+ *
45
+ * @return null|array
46
+ */
47
+ public function findMatch($s, $params = array()) {
48
+ $match = null;
49
+ $options = $this->getOption();
50
+
51
+ if (!empty($options)) {
52
+ foreach($options as $rule) {
53
+ $uri = wp_parse_url($rule['uri']);
54
+ $out = array();
55
+
56
+ if (!empty($uri['query'])) {
57
+ parse_str($uri['query'], $out);
58
+ }
59
+
60
+ $regex = '@^' . preg_quote($uri['path']) . '$@';
61
+
62
+ if (apply_filters('aam-uri-match-filter', preg_match($regex, $s), $uri, $s)
63
+ && (empty($out) || count(array_intersect_assoc($params, $out)) === count($out))) {
64
+ $match = $rule;
65
+ break;
66
+ }
67
+ }
68
+ }
69
+
70
+ return $match;
71
+ }
72
+
73
+ /**
74
+ * Save menu option
75
+ *
76
+ * @return bool
77
+ *
78
+ * @access public
79
+ */
80
+ public function save($id, $uri, $type, $action = null) {
81
+ $option = $this->getOption();
82
+ $option[$id] = array(
83
+ 'uri' => $uri,
84
+ 'type' => $type,
85
+ 'action' => $action
86
+ );
87
+ $this->setOption($option);
88
+
89
+ return $this->getSubject()->updateOption($this->getOption(), 'uri');
90
+ }
91
+
92
+ /**
93
+ *
94
+ * @param type $id
95
+ *
96
+ * @return type
97
+ */
98
+ public function delete($id) {
99
+ $option = $this->getOption();
100
+ if (isset($option[$id])) {
101
+ unset($option[$id]);
102
+ }
103
+ $this->setOption($option);
104
+
105
+ return $this->getSubject()->updateOption($this->getOption(), 'uri');
106
+ }
107
+
108
+ /**
109
+ * Reset default settings
110
+ *
111
+ * @return bool
112
+ *
113
+ * @access public
114
+ */
115
+ public function reset() {
116
+ return $this->getSubject()->deleteOption('uri');
117
+ }
118
+
119
+ }
Application/Core/Subject.php CHANGED
@@ -238,7 +238,7 @@ abstract class AAM_Core_Subject {
238
  $id = (is_scalar($id) ? $id : 'none'); //prevent from any surprises
239
 
240
  //check if there is an object with specified ID
241
- if (!isset($this->_objects[$type][$id])) {
242
  $classname = 'AAM_Core_Object_' . ucfirst($type);
243
 
244
  if (class_exists($classname)) {
238
  $id = (is_scalar($id) ? $id : 'none'); //prevent from any surprises
239
 
240
  //check if there is an object with specified ID
241
+ if (!isset($this->_objects[$type][$id]) || ($type === 'cache')) {
242
  $classname = 'AAM_Core_Object_' . ucfirst($type);
243
 
244
  if (class_exists($classname)) {
Application/Extension/List.php CHANGED
@@ -22,7 +22,7 @@ class AAM_Extension_List {
22
  'description' => 'Get the complete list of all premium AAM extensions in one package and all future premium extensions already included for now additional cost.',
23
  'url' => 'https://aamplugin.com/complete-package',
24
  'version' => (defined('AAM_COMPLETE_PACKAGE') ? constant('AAM_COMPLETE_PACKAGE') : null),
25
- 'latest' => '3.8.8'
26
  ),
27
  'AAM_PLUS_PACKAGE' => array(
28
  'title' => 'Plus Package',
@@ -31,7 +31,7 @@ class AAM_Extension_List {
31
  'description' => 'Manage access to your WordPress website posts, pages, media, custom post types, categories and hierarchical taxonomies for any role, individual user, visitors or even define default access for everybody; and do this separately for frontend, backend or API levels. As the bonus, define more granular access to how comments can be managed on the backend by other users.',
32
  'url' => 'https://aamplugin.com/extension/plus-package',
33
  'version' => (defined('AAM_PLUS_PACKAGE') ? constant('AAM_PLUS_PACKAGE') : null),
34
- 'latest' => '3.8.2'
35
  ),
36
  'AAM_IP_CHECK' => array(
37
  'title' => 'IP Check',
22
  'description' => 'Get the complete list of all premium AAM extensions in one package and all future premium extensions already included for now additional cost.',
23
  'url' => 'https://aamplugin.com/complete-package',
24
  'version' => (defined('AAM_COMPLETE_PACKAGE') ? constant('AAM_COMPLETE_PACKAGE') : null),
25
+ 'latest' => '3.8.9'
26
  ),
27
  'AAM_PLUS_PACKAGE' => array(
28
  'title' => 'Plus Package',
31
  'description' => 'Manage access to your WordPress website posts, pages, media, custom post types, categories and hierarchical taxonomies for any role, individual user, visitors or even define default access for everybody; and do this separately for frontend, backend or API levels. As the bonus, define more granular access to how comments can be managed on the backend by other users.',
32
  'url' => 'https://aamplugin.com/extension/plus-package',
33
  'version' => (defined('AAM_PLUS_PACKAGE') ? constant('AAM_PLUS_PACKAGE') : null),
34
+ 'latest' => '3.8.3'
35
  ),
36
  'AAM_IP_CHECK' => array(
37
  'title' => 'IP Check',
Application/Frontend/Filter.php CHANGED
@@ -51,6 +51,28 @@ class AAM_Frontend_Filter {
51
 
52
  //get control over commenting stuff
53
  add_filter('comments_open', array($this, 'commentOpen'), 10, 2);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  }
55
 
56
  /**
51
 
52
  //get control over commenting stuff
53
  add_filter('comments_open', array($this, 'commentOpen'), 10, 2);
54
+
55
+ //check URI
56
+ $this->checkURIAccess();
57
+ }
58
+
59
+ /**
60
+ *
61
+ */
62
+ protected function checkURIAccess() {
63
+ $uri = wp_parse_url(AAM_Core_Request::server('REQUEST_URI'));
64
+ $object = AAM::api()->getUser()->getObject('uri');
65
+ $params = array();
66
+
67
+ if (isset($uri['query'])) {
68
+ parse_str($uri['query'], $params);
69
+ }
70
+
71
+ if ($match = $object->findMatch($uri['path'], $params)) {
72
+ if ($match['type'] !== 'allow') {
73
+ AAM::api()->redirect($match['type'], $match['action']);
74
+ }
75
+ }
76
  }
77
 
78
  /**
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.5.2
7
  Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  Author URI: https://vasyltech.com
9
 
3
  /**
4
  Plugin Name: Advanced Access Manager
5
  Description: All you need to manage access to your WordPress website
6
+ Version: 5.6
7
  Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  Author URI: https://vasyltech.com
9
 
media/js/aam.js CHANGED
@@ -2868,6 +2868,206 @@
2868
  getAAM().addHook('init', initialize);
2869
 
2870
  })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2871
 
2872
  /**
2873
  * Extensions Interface
@@ -2943,7 +3143,7 @@
2943
  );
2944
  },
2945
  complete: function () {
2946
- getAAM().fetchContent('extensions');
2947
  }
2948
  });
2949
  });
@@ -3115,6 +3315,57 @@
3115
  getAAM().addHook('init', initialize);
3116
 
3117
  })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3118
 
3119
 
3120
  /**
2868
  getAAM().addHook('init', initialize);
2869
 
2870
  })(jQuery);
2871
+
2872
+ /**
2873
+ * URI Interface
2874
+ *
2875
+ * @param {jQuery} $
2876
+ *
2877
+ * @returns {void}
2878
+ */
2879
+ (function ($) {
2880
+ function initialize() {
2881
+ var container = '#uri-content';
2882
+
2883
+ if ($(container).length) {
2884
+ $('input[type="radio"]', container).each(function () {
2885
+ $(this).bind('click', function () {
2886
+ $('.aam-uri-access-action').hide();
2887
+ if ($(this).data('action')) {
2888
+ $($(this).data('action')).show();
2889
+ }
2890
+ });
2891
+ });
2892
+
2893
+ //reset button
2894
+ $('#uri-reset').bind('click', function () {
2895
+ aam.reset('uri', $(this));
2896
+ });
2897
+
2898
+ $('#uri-save-btn').bind('click', function(event) {
2899
+ event.preventDefault();
2900
+
2901
+ var uri = $('#uri-rule').val();
2902
+ var type = $('input[name="uri.access.type"]:checked').val();
2903
+ var val = $('#uri-access-deny-' + type + '-value').val();
2904
+
2905
+ if (uri && type) {
2906
+ $.ajax(aamLocal.ajaxurl, {
2907
+ type: 'POST',
2908
+ dataType: 'json',
2909
+ data: {
2910
+ action: 'aam',
2911
+ sub_action: 'Main_Uri.save',
2912
+ _ajax_nonce: aamLocal.nonce,
2913
+ subject: aam.getSubject().type,
2914
+ subjectId: aam.getSubject().id,
2915
+ uri: uri,
2916
+ type: type,
2917
+ value: val,
2918
+ id: $('#uri-save-btn').attr('data-id')
2919
+ },
2920
+ beforeSend: function () {
2921
+ $('#uri-save-btn').text(aam.__('Saving...')).attr('disabled', true);
2922
+ },
2923
+ success: function (response) {
2924
+ if (response.status === 'success') {
2925
+ $('#uri-list').DataTable().ajax.reload();
2926
+ } else {
2927
+ aam.notification(
2928
+ 'danger', aam.__('Failed to save URI rule')
2929
+ );
2930
+ }
2931
+ },
2932
+ error: function () {
2933
+ aam.notification('danger', aam.__('Application error'));
2934
+ },
2935
+ complete: function () {
2936
+ $('#uri-model').modal('hide');
2937
+ $('#uri-save-btn').text(aam.__('Save')).attr('disabled', false);
2938
+ }
2939
+ });
2940
+ }
2941
+ });
2942
+
2943
+ $('#uri-delete-btn').bind('click', function (event) {
2944
+ event.preventDefault();
2945
+
2946
+ $.ajax(aamLocal.ajaxurl, {
2947
+ type: 'POST',
2948
+ dataType: 'json',
2949
+ data: {
2950
+ action: 'aam',
2951
+ sub_action: 'Main_Uri.delete',
2952
+ _ajax_nonce: aamLocal.nonce,
2953
+ subject: aam.getSubject().type,
2954
+ subjectId: aam.getSubject().id,
2955
+ id: $('#uri-delete-btn').data('id')
2956
+ },
2957
+ beforeSend: function () {
2958
+ $('#uri-delete-btn').text(aam.__('Deleting...')).attr('disabled', true);
2959
+ },
2960
+ success: function (response) {
2961
+ if (response.status === 'success') {
2962
+ $('#uri-list').DataTable().ajax.reload();
2963
+ } else {
2964
+ aam.notification('danger', aam.__('Failed to delete URI rule'));
2965
+ }
2966
+ },
2967
+ error: function () {
2968
+ aam.notification('danger', aam.__('Application error'));
2969
+ },
2970
+ complete: function () {
2971
+ $('#uri-delete-model').modal('hide');
2972
+ $('#uri-delete-btn').text(aam.__('Delete')).attr('disabled', false);
2973
+ }
2974
+ });
2975
+ });
2976
+
2977
+ $('#uri-list').DataTable({
2978
+ autoWidth: false,
2979
+ ordering: false,
2980
+ dom: 'ftrip',
2981
+ pagingType: 'simple',
2982
+ processing: true,
2983
+ stateSave: true,
2984
+ serverSide: false,
2985
+ ajax: {
2986
+ url: aamLocal.ajaxurl,
2987
+ type: 'POST',
2988
+ dataType: 'json',
2989
+ data: {
2990
+ action: 'aam',
2991
+ sub_action: 'Main_Uri.getTable',
2992
+ _ajax_nonce: aamLocal.nonce,
2993
+ subject: aam.getSubject().type,
2994
+ subjectId: aam.getSubject().id
2995
+ }
2996
+ },
2997
+ language: {
2998
+ search: '_INPUT_',
2999
+ searchPlaceholder: aam.__('Search URI'),
3000
+ info: aam.__('_TOTAL_ URI(s)'),
3001
+ infoFiltered: ''
3002
+ },
3003
+ columnDefs: [
3004
+ {visible: false, targets: [0,2,3]}
3005
+ ],
3006
+ initComplete: function () {
3007
+ var create = $('<a/>', {
3008
+ 'href': '#',
3009
+ 'class': 'btn btn-primary'
3010
+ }).html('<i class="icon-plus"></i> ' + aam.__('Create'))
3011
+ .bind('click', function () {
3012
+ $('.form-clearable', '#uri-model').val('');
3013
+ $('.aam-uri-access-action').hide();
3014
+ $('input[type="radio"]', '#uri-model').prop('checked', false);
3015
+ $('#uri-save-btn').removeAttr('data-id');
3016
+ $('#uri-model').modal('show');
3017
+ });
3018
+
3019
+ $('.dataTables_filter', '#uri-list_wrapper').append(create);
3020
+ },
3021
+ createdRow: function (row, data) {
3022
+ var actions = data[4].split(',');
3023
+
3024
+ var container = $('<div/>', {'class': 'aam-row-actions'});
3025
+ $.each(actions, function (i, action) {
3026
+ switch (action) {
3027
+ case 'edit':
3028
+ $(container).append($('<i/>', {
3029
+ 'class': 'aam-row-action icon-pencil text-warning'
3030
+ }).bind('click', function () {
3031
+ $('.form-clearable', '#uri-model').val('');
3032
+ $('.aam-uri-access-action').hide();
3033
+ $('#uri-rule').val(data[1]);
3034
+ $('input[value="' + data[2] + '"]', '#uri-model').prop('checked', true).trigger('click');
3035
+ $('#uri-access-deny-' + data[2] + '-value').val(data[3]);
3036
+ $('#uri-save-btn').attr('data-id', data[0]);
3037
+ $('#uri-model').modal('show');
3038
+ }).attr({
3039
+ 'data-toggle': "tooltip",
3040
+ 'title': aam.__('Edit Rule')
3041
+ }));
3042
+ break;
3043
+
3044
+ case 'delete':
3045
+ $(container).append($('<i/>', {
3046
+ 'class': 'aam-row-action icon-trash-empty text-danger'
3047
+ }).bind('click', function () {
3048
+ $('#uri-delete-btn').attr('data-id', data[0]);
3049
+ $('#uri-delete-model').modal('show');
3050
+ }).attr({
3051
+ 'data-toggle': "tooltip",
3052
+ 'title': aam.__('Delete Rule')
3053
+ }));
3054
+ break;
3055
+
3056
+ default:
3057
+ break;
3058
+ }
3059
+ });
3060
+ $('td:eq(1)', row).html(container);
3061
+
3062
+ $('td:eq(0)', row).html(data[1]);
3063
+ }
3064
+ });
3065
+ }
3066
+ }
3067
+
3068
+ getAAM().addHook('init', initialize);
3069
+
3070
+ })(jQuery);
3071
 
3072
  /**
3073
  * Extensions Interface
3143
  );
3144
  },
3145
  complete: function () {
3146
+ location.reload();
3147
  }
3148
  });
3149
  });
3315
  getAAM().addHook('init', initialize);
3316
 
3317
  })(jQuery);
3318
+
3319
+ /**
3320
+ * Get Started Interface
3321
+ *
3322
+ * @param {type} $
3323
+ *
3324
+ * @returns {undefined}
3325
+ */
3326
+ (function ($) {
3327
+
3328
+ /**
3329
+ *
3330
+ * @returns {undefined}
3331
+ */
3332
+ function initialize() {
3333
+ $('#ack-get-started').bind('click', function () {
3334
+ getAAM().queueRequest(function() {
3335
+ $.ajax(getLocal().ajaxurl, {
3336
+ type: 'POST',
3337
+ dataType: 'json',
3338
+ data: {
3339
+ action: 'aam',
3340
+ sub_action: 'Settings_Manager.save',
3341
+ _ajax_nonce: getLocal().nonce,
3342
+ param: 'core.settings.getStarted',
3343
+ value: 0
3344
+ },
3345
+ beforeSend: function() {
3346
+ $('#ack-get-started').text(
3347
+ getAAM().__('Saving...')
3348
+ );
3349
+ },
3350
+ success: function() {
3351
+ location.reload();
3352
+ },
3353
+ error: function () {
3354
+ getAAM().notification(
3355
+ 'danger', getAAM().__('Application Error')
3356
+ );
3357
+ $('#ack-get-started').text(
3358
+ getAAM().__('OK, got it')
3359
+ );
3360
+ }
3361
+ });
3362
+ });
3363
+ });
3364
+ }
3365
+
3366
+ getAAM().addHook('init', initialize);
3367
+
3368
+ })(jQuery);
3369
 
3370
 
3371
  /**
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: vasyltech,noelalvarez
3
  Tags: access control, membership, backend menu, user role, restricted content
4
  Requires at least: 4.0
5
  Tested up to: 4.9.7
6
- Stable tag: 5.5.2
7
 
8
  All you need to manage access to you WordPress websites on frontend, backend and API levels for any role, user or visitors.
9
 
@@ -77,6 +77,12 @@ https://www.youtube.com/watch?v=mj5Xa_Wc16Y
77
 
78
  == Changelog ==
79
 
 
 
 
 
 
 
80
  = 5.5.2 =
81
  * Improved performance for website with large amount of posts/pages
82
  * Prepared few changes forward for the upcoming AAM 5.6 release
3
  Tags: access control, membership, backend menu, user role, restricted content
4
  Requires at least: 4.0
5
  Tested up to: 4.9.7
6
+ Stable tag: 5.6
7
 
8
  All you need to manage access to you WordPress websites on frontend, backend and API levels for any role, user or visitors.
9
 
77
 
78
  == Changelog ==
79
 
80
+ = 5.6 =
81
+ * Fixed the bug with encoding on Safari when gzip is enabled
82
+ * Fixed the bug with double caching
83
+ * Added URI Access feature that allows to manage access to any website URI
84
+ * Improved UI a little bit
85
+
86
  = 5.5.2 =
87
  * Improved performance for website with large amount of posts/pages
88
  * Prepared few changes forward for the upcoming AAM 5.6 release