Advanced Access Manager - Version 5.9.7

Version Description

  • Prep for upcoming AAM v6 release. Converting all extensions to plugins
  • Covered odd use-case when some plugins decide to register CPT capabilities during plugin activation
  • Improved Backend Menu feature functionality
Download this release

Release Info

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

Code changes from version 5.9.6.3 to 5.9.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: 5.9.6.3
7
  * Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  * Author URI: https://vasyltech.com
9
  * Text Domain: advanced-access-manager
3
  /**
4
  * Plugin Name: Advanced Access Manager
5
  * Description: Collection of features to manage your WordPress website authentication, authorization and monitoring
6
+ * Version: 5.9.7
7
  * Author: Vasyl Martyniuk <vasyl@vasyltech.com>
8
  * Author URI: https://vasyltech.com
9
  * Text Domain: advanced-access-manager
application/Backend/Feature/Main/Menu.php CHANGED
@@ -81,9 +81,7 @@ class AAM_Backend_Feature_Main_Menu extends AAM_Backend_Feature_Abstract {
81
 
82
  $submenu = $this->getSubmenu($item[2]);
83
 
84
- $allowed = AAM_Backend_Subject::getInstance()->hasCapability($item[1]);
85
-
86
- if ($allowed || count($submenu) > 0) {
87
  $menuItem = array(
88
  //add menu- prefix to define that this is the top level menu
89
  //WordPress by default gives the same menu id to the first
@@ -143,7 +141,7 @@ class AAM_Backend_Feature_Main_Menu extends AAM_Backend_Feature_Abstract {
143
 
144
  if (array_key_exists($menu, $submenu) && is_array($submenu[$menu])) {
145
  foreach ($submenu[$menu] as $item) {
146
- if ($subject->hasCapability($item[1]) || $isDefault) {
147
  $id = $this->normalizeItem($item[2]);
148
  $menuItem = array(
149
  'id' => $id,
@@ -159,6 +157,19 @@ class AAM_Backend_Feature_Main_Menu extends AAM_Backend_Feature_Abstract {
159
 
160
  return $response;
161
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
  /**
164
  * Filter menu name
81
 
82
  $submenu = $this->getSubmenu($item[2]);
83
 
84
+ if ($this->isItemAllowed($item[1]) || count($submenu) > 0) {
 
 
85
  $menuItem = array(
86
  //add menu- prefix to define that this is the top level menu
87
  //WordPress by default gives the same menu id to the first
141
 
142
  if (array_key_exists($menu, $submenu) && is_array($submenu[$menu])) {
143
  foreach ($submenu[$menu] as $item) {
144
+ if ($this->isItemAllowed($item[1]) || $isDefault) {
145
  $id = $this->normalizeItem($item[2]);
146
  $menuItem = array(
147
  'id' => $id,
157
 
158
  return $response;
159
  }
160
+
161
+ /**
162
+ * Undocumented function
163
+ *
164
+ * @param [type] $cap
165
+ * @return boolean
166
+ */
167
+ protected function isItemAllowed($cap) {
168
+ $subject = AAM_Backend_Subject::getInstance();
169
+ $exists = AAM_Core_API::capabilityExists($cap);
170
+
171
+ return !$exists || $subject->hasCapability($cap);
172
+ }
173
 
174
  /**
175
  * Filter menu name
application/Backend/Manager.php CHANGED
@@ -54,6 +54,9 @@ class AAM_Backend_Manager {
54
 
55
  //post title decorator
56
  add_filter('the_title', array($this, 'theTitle'), 999, 2);
 
 
 
57
 
58
  //permalink manager
59
  add_filter('get_sample_permalink_html', array($this, 'getPermalinkHtml'), 10, 5);
@@ -150,6 +153,33 @@ class AAM_Backend_Manager {
150
  }
151
  }
152
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  /**
154
  * Undocumented function
155
  *
@@ -803,7 +833,7 @@ class AAM_Backend_Manager {
803
  public function printJavascript() {
804
  if (AAM::isAAM()) {
805
  wp_enqueue_script('aam-vendor', AAM_MEDIA . '/js/vendor.js');
806
- wp_enqueue_script('aam-main', AAM_MEDIA . '/js/aam-5.9.6.js');
807
 
808
  //add plugin localization
809
  $this->printLocalization('aam-main');
@@ -819,6 +849,7 @@ class AAM_Backend_Manager {
819
  global $menu, $submenu;
820
 
821
  if (AAM::isAAM()) {
 
822
  $script = '<script type="text/javascript">';
823
  $script .= 'var aamEnvData = ' . wp_json_encode(array(
824
  'menu' => base64_encode(json_encode($menu)),
@@ -841,8 +872,9 @@ class AAM_Backend_Manager {
841
  * @access protected
842
  */
843
  protected function printLocalization($localKey) {
844
- $subject = AAM_Backend_Subject::getInstance();
845
- $endpoint = getenv('AAM_ENDPOINT');
 
846
 
847
  $locals = array(
848
  'nonce' => wp_create_nonce('aam_ajax'),
@@ -863,9 +895,10 @@ class AAM_Backend_Manager {
863
  'blog' => get_current_blog_id()
864
  ),
865
  'system' => array(
866
- 'domain' => wp_parse_url(site_url(), PHP_URL_HOST),
867
- 'uid' => AAM_Core_API::getOption('aam-uid', null, 'site'),
868
- 'apiEndpoint' => ($endpoint ? $endpoint : AAM_Core_Server::SERVER_URL)
 
869
  ),
870
  'translation' => AAM_Backend_View_Localization::get(),
871
  'caps' => array(
54
 
55
  //post title decorator
56
  add_filter('the_title', array($this, 'theTitle'), 999, 2);
57
+
58
+ //cover any kind of surprize things by other funky plugins
59
+ add_filter('pre_update_option', array($this, 'updateOption'), 10, 3);
60
 
61
  //permalink manager
62
  add_filter('get_sample_permalink_html', array($this, 'getPermalinkHtml'), 10, 5);
153
  }
154
  }
155
 
156
+ /**
157
+ * Undocumented function
158
+ *
159
+ * @param [type] $value
160
+ * @param [type] $option
161
+ * @param [type] $old_value
162
+ * @return void
163
+ */
164
+ public function updateOption($value, $option, $old_value) {
165
+ global $wpdb;
166
+
167
+ if ($option === $wpdb->prefix . 'user_roles') {
168
+ //Remove all phseudo capabilities from list of caps
169
+ foreach($value as &$role) {
170
+ foreach($role['capabilities'] as $cap => $granted) {
171
+ if (strpos($cap, 'aam|') === 0) {
172
+ $parts = explode('|', $cap);
173
+ unset($role['capabilities'][$cap]);
174
+ $role['capabilities'][$parts[2]] = $granted;
175
+ }
176
+ }
177
+ }
178
+ }
179
+
180
+ return $value;
181
+ }
182
+
183
  /**
184
  * Undocumented function
185
  *
833
  public function printJavascript() {
834
  if (AAM::isAAM()) {
835
  wp_enqueue_script('aam-vendor', AAM_MEDIA . '/js/vendor.js');
836
+ wp_enqueue_script('aam-main', AAM_MEDIA . '/js/aam-5.9.7.js');
837
 
838
  //add plugin localization
839
  $this->printLocalization('aam-main');
849
  global $menu, $submenu;
850
 
851
  if (AAM::isAAM()) {
852
+
853
  $script = '<script type="text/javascript">';
854
  $script .= 'var aamEnvData = ' . wp_json_encode(array(
855
  'menu' => base64_encode(json_encode($menu)),
872
  * @access protected
873
  */
874
  protected function printLocalization($localKey) {
875
+ $subject = AAM_Backend_Subject::getInstance();
876
+ $endpoint1 = getenv('AAM_V1_ENDPOINT');
877
+ $endpoint2 = getenv('AAM_V2_ENDPOINT');
878
 
879
  $locals = array(
880
  'nonce' => wp_create_nonce('aam_ajax'),
895
  'blog' => get_current_blog_id()
896
  ),
897
  'system' => array(
898
+ 'domain' => wp_parse_url(site_url(), PHP_URL_HOST),
899
+ 'uid' => AAM_Core_API::getOption('aam-uid', null, 'site'),
900
+ 'apiV1Endpoint' => ($endpoint1 ? $endpoint1 : AAM_Core_Server::SERVER_V1_URL),
901
+ 'apiV2Endpoint' => ($endpoint2 ? $endpoint2 : AAM_Core_Server::SERVER_V2_URL)
902
  ),
903
  'translation' => AAM_Backend_View_Localization::get(),
904
  'caps' => array(
application/Backend/phtml/extensions.phtml CHANGED
@@ -16,7 +16,17 @@
16
  </div>
17
  </div>
18
  <div class="col-xs-4">
19
- <button class="btn btn-primary btn-block" id="install-extension"><i class="icon-download-cloud"></i> <?php echo __('Submit', AAM_KEY); ?></button>
 
 
 
 
 
 
 
 
 
 
20
  </div>
21
  </div>
22
 
@@ -45,7 +55,13 @@
45
  </p>
46
  </td>
47
  <td class="text-center">
48
- <?php if ($product['status'] == AAM_Extension_Repository::STATUS_INSTALLED) { ?>
 
 
 
 
 
 
49
  <?php if ($product['title'] === 'Complete Package') { ?>
50
  <a href="#" class="btn btn-sm btn-success btn-block disabled"><i class="icon-check"></i> <?php echo __('Installed', AAM_KEY); ?></a>
51
  <?php } else { ?>
16
  </div>
17
  </div>
18
  <div class="col-xs-4">
19
+ <div class="btn-group">
20
+ <button type="button" class="btn btn-primary btn-block dropdown-toggle" id="download-software" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
21
+ <i class="icon-download-cloud"></i> <?php echo __('Download', AAM_KEY); ?> <span class="caret"></span>
22
+ </button>
23
+ <ul class="dropdown-menu">
24
+ <li><a href="#" id="install-extension"><?php echo __('As extension (legacy)', AAM_KEY); ?></a></li>
25
+ <li><a href="#" id="download-plugin"><?php echo __('As standard WP plugin', AAM_KEY); ?></a></li>
26
+ <li role="separator" class="divider"></li>
27
+ <li><a href="https://aamplugin.com/article/aam-extensions-become-plugins" target="_blank"><?php echo __('Learn more', AAM_KEY); ?></a></li>
28
+ </ul>
29
+ </div>
30
  </div>
31
  </div>
32
 
55
  </p>
56
  </td>
57
  <td class="text-center">
58
+ <?php if (!is_null($product['pluginStatus'])) { ?>
59
+ <?php if ($product['pluginStatus'] === true) { ?>
60
+ <a href="#" class="btn btn-sm btn-success btn-block disabled"><i class="icon-check"></i> <?php echo __('Plugin Active', AAM_KEY); ?></a>
61
+ <?php } else { ?>
62
+ <a href="#" class="btn btn-sm btn-info btn-block disabled"><i class="icon-attention-circled"></i> <?php echo __('Plugin Inactive', AAM_KEY); ?></a>
63
+ <?php } ?>
64
+ <?php } elseif ($product['status'] == AAM_Extension_Repository::STATUS_INSTALLED) { ?>
65
  <?php if ($product['title'] === 'Complete Package') { ?>
66
  <a href="#" class="btn btn-sm btn-success btn-block disabled"><i class="icon-check"></i> <?php echo __('Installed', AAM_KEY); ?></a>
67
  <?php } else { ?>
application/Core/Server.php CHANGED
@@ -20,7 +20,8 @@ final class AAM_Core_Server {
20
  /**
21
  * Server endpoint
22
  */
23
- const SERVER_URL = 'https://aamplugin.com/api/v1';
 
24
 
25
  /**
26
  * Fetch the extension list
@@ -67,7 +68,7 @@ final class AAM_Core_Server {
67
  protected static function send($request, $params, $timeout = 10) {
68
  $response = self::parseResponse(
69
  AAM_Core_API::cURL(
70
- self::SERVER_URL . $request, $params, $timeout
71
  )
72
  );
73
 
20
  /**
21
  * Server endpoint
22
  */
23
+ const SERVER_V1_URL = 'https://aamplugin.com/api/v1';
24
+ const SERVER_V2_URL = 'https://api.aamplugin.com/v2';
25
 
26
  /**
27
  * Fetch the extension list
68
  protected static function send($request, $params, $timeout = 10) {
69
  $response = self::parseResponse(
70
  AAM_Core_API::cURL(
71
+ self::SERVER_V1_URL . $request, $params, $timeout
72
  )
73
  );
74
 
application/Extension/List.php CHANGED
@@ -18,6 +18,7 @@ class AAM_Extension_List {
18
  'AAM_COMPLETE_PACKAGE' => array(
19
  'title' => 'Complete Package',
20
  'id' => 'AAM_COMPLETE_PACKAGE',
 
21
  'type' => 'commercial',
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',
@@ -27,6 +28,7 @@ class AAM_Extension_List {
27
  'AAM_PLUS_PACKAGE' => array(
28
  'title' => 'Plus Package',
29
  'id' => 'AAM_PLUS_PACKAGE',
 
30
  'type' => 'commercial',
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',
@@ -36,6 +38,7 @@ class AAM_Extension_List {
36
  'AAM_IP_CHECK' => array(
37
  'title' => 'IP Check',
38
  'id' => 'AAM_IP_CHECK',
 
39
  'type' => 'commercial',
40
  'description' => 'Manage access to your WordPress website by visitor\'s IP address and referred hosts or completely lockdown the entire website and allow only certain IP ranges.',
41
  'url' => 'https://aamplugin.com/extension/ip-check',
@@ -45,6 +48,7 @@ class AAM_Extension_List {
45
  'AAM_ROLE_HIERARCHY' => array(
46
  'title' => 'Role Hierarchy',
47
  'id' => 'AAM_ROLE_HIERARCHY',
 
48
  'type' => 'commercial',
49
  'description' => 'Define and manage complex WordPress role hierarchy where child role inherits all access settings from its parent with ability to override setting for any specific role.',
50
  'url' => 'https://aamplugin.com/extension/role-hierarchy',
@@ -54,6 +58,7 @@ class AAM_Extension_List {
54
  'AAM_ECOMMERCE' => array(
55
  'title' => 'E-Commerce',
56
  'id' => 'AAM_ECOMMERCE',
 
57
  'type' => 'commercial',
58
  'new' => true,
59
  'description' => 'Start monetizing access to your premium content. Restrict access to read any WordPress post, page or custom post type until user purchase access to it.',
18
  'AAM_COMPLETE_PACKAGE' => array(
19
  'title' => 'Complete Package',
20
  'id' => 'AAM_COMPLETE_PACKAGE',
21
+ 'plugin' => 'aam-complete-package/bootstrap.php',
22
  'type' => 'commercial',
23
  'description' => 'Get the complete list of all premium AAM extensions in one package and all future premium extensions already included for now additional cost.',
24
  'url' => 'https://aamplugin.com/complete-package',
28
  'AAM_PLUS_PACKAGE' => array(
29
  'title' => 'Plus Package',
30
  'id' => 'AAM_PLUS_PACKAGE',
31
+ 'plugin' => 'aam-plus-package/bootstrap.php',
32
  'type' => 'commercial',
33
  '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.',
34
  'url' => 'https://aamplugin.com/extension/plus-package',
38
  'AAM_IP_CHECK' => array(
39
  'title' => 'IP Check',
40
  'id' => 'AAM_IP_CHECK',
41
+ 'plugin' => 'aam-ip-check/bootstrap.php',
42
  'type' => 'commercial',
43
  'description' => 'Manage access to your WordPress website by visitor\'s IP address and referred hosts or completely lockdown the entire website and allow only certain IP ranges.',
44
  'url' => 'https://aamplugin.com/extension/ip-check',
48
  'AAM_ROLE_HIERARCHY' => array(
49
  'title' => 'Role Hierarchy',
50
  'id' => 'AAM_ROLE_HIERARCHY',
51
+ 'plugin' => 'aam-role-hierarchy/bootstrap.php',
52
  'type' => 'commercial',
53
  'description' => 'Define and manage complex WordPress role hierarchy where child role inherits all access settings from its parent with ability to override setting for any specific role.',
54
  'url' => 'https://aamplugin.com/extension/role-hierarchy',
58
  'AAM_ECOMMERCE' => array(
59
  'title' => 'E-Commerce',
60
  'id' => 'AAM_ECOMMERCE',
61
+ 'plugin' => 'aam-ecommerce/bootstrap.php',
62
  'type' => 'commercial',
63
  'new' => true,
64
  'description' => 'Start monetizing access to your premium content. Restrict access to read any WordPress post, page or custom post type until user purchase access to it.',
application/Extension/Repository.php CHANGED
@@ -299,6 +299,10 @@ class AAM_Extension_Repository {
299
  $item['license'] = '';
300
  }
301
  }
 
 
 
 
302
 
303
  //update extension status
304
  $item['status'] = $this->checkStatus($item, $check, $index);
@@ -309,6 +313,21 @@ class AAM_Extension_Repository {
309
 
310
  return $this->list;
311
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
312
 
313
  /**
314
  *
299
  $item['license'] = '';
300
  }
301
  }
302
+
303
+ if (!empty($item['plugin'])) {
304
+ $item['pluginStatus'] = $this->getPluginStatus($item['plugin']);
305
+ }
306
 
307
  //update extension status
308
  $item['status'] = $this->checkStatus($item, $check, $index);
313
 
314
  return $this->list;
315
  }
316
+
317
+ protected function getPluginStatus($plugin) {
318
+ if (file_exists(ABSPATH . 'wp-admin/includes/plugin.php')) {
319
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
320
+ }
321
+
322
+ $filename = WP_PLUGIN_DIR . '/' . $plugin;
323
+ $status = null;
324
+
325
+ if (function_exists('get_plugin_data') && file_exists($filename)) {
326
+ $status = is_plugin_active($plugin);
327
+ }
328
+
329
+ return $status;
330
+ }
331
 
332
  /**
333
  *
application/Shared/Manager.php CHANGED
@@ -447,7 +447,7 @@ class AAM_Shared_Manager {
447
 
448
  $objectId = (isset($args[0]) ? $args[0] : null);
449
 
450
- // First of all delete all artificial capability from the $caps
451
  foreach($caps as $i => $capability) {
452
  if (strpos($capability, 'aam|') === 0) {
453
  // Remove this capability from the mapped array and let WP Core
447
 
448
  $objectId = (isset($args[0]) ? $args[0] : null);
449
 
450
+ // First of all delete all artificial capabilities from the $caps
451
  foreach($caps as $i => $capability) {
452
  if (strpos($capability, 'aam|') === 0) {
453
  // Remove this capability from the mapped array and let WP Core
application/Shortcode/Strategy/Content.php CHANGED
@@ -57,7 +57,7 @@ class AAM_Shortcode_Strategy_Content implements AAM_Shortcode_Strategy_Interface
57
  public function run() {
58
  //prepare user
59
  if (get_current_user_id()) {
60
- $roles = reset(AAM::getUser()->roles);
61
 
62
  if (AAM::api()->getConfig('core.settings.multiSubject', false)) {
63
  $parts = array_merge(array((string)AAM::getUser()->ID), $roles);
@@ -72,7 +72,7 @@ class AAM_Shortcode_Strategy_Content implements AAM_Shortcode_Strategy_Interface
72
  $limit = $this->getAccess('limit');
73
  $hide = $this->getAccess('hide');
74
  $msg = $this->getMessage();
75
-
76
  if (!empty($this->args['callback'])) {
77
  $content = call_user_func($this->args['callback'], $this);
78
  } else {
@@ -93,7 +93,7 @@ class AAM_Shortcode_Strategy_Content implements AAM_Shortcode_Strategy_Interface
93
  $content = $this->content;
94
  }
95
  }
96
-
97
  return $content;
98
  }
99
 
57
  public function run() {
58
  //prepare user
59
  if (get_current_user_id()) {
60
+ $roles = array_merge(AAM::getUser()->roles);
61
 
62
  if (AAM::api()->getConfig('core.settings.multiSubject', false)) {
63
  $parts = array_merge(array((string)AAM::getUser()->ID), $roles);
72
  $limit = $this->getAccess('limit');
73
  $hide = $this->getAccess('hide');
74
  $msg = $this->getMessage();
75
+
76
  if (!empty($this->args['callback'])) {
77
  $content = call_user_func($this->args['callback'], $this);
78
  } else {
93
  $content = $this->content;
94
  }
95
  }
96
+
97
  return $content;
98
  }
99
 
media/js/{aam-5.9.6.js → aam-5.9.7.js} RENAMED
@@ -1402,7 +1402,7 @@
1402
  * @returns {undefined}
1403
  */
1404
  function downloadLicense(data, cb) {
1405
- $.ajax(getLocal().system.apiEndpoint + '/download', {
1406
  type: 'GET',
1407
  dataType: 'json',
1408
  data: {
@@ -4081,6 +4081,54 @@
4081
 
4082
  var dump = null;
4083
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4084
  /**
4085
  *
4086
  * @param {type} data
@@ -4088,7 +4136,7 @@
4088
  * @returns {undefined}
4089
  */
4090
  function downloadExtension(data, cb) {
4091
- $.ajax(getLocal().system.apiEndpoint + '/download', {
4092
  type: 'GET',
4093
  dataType: 'json',
4094
  data: {
@@ -4140,6 +4188,33 @@
4140
  }
4141
  });
4142
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4143
 
4144
  /**
4145
  *
@@ -4205,7 +4280,6 @@
4205
  $('#install-extension').bind('click', function () {
4206
  $('#extension-key').parent().removeClass('error');
4207
 
4208
- var _this = $(this);
4209
  var license = $.trim($('#extension-key').val());
4210
 
4211
  if (!license) {
@@ -4214,14 +4288,31 @@
4214
  return;
4215
  }
4216
 
4217
- $('i', _this).attr('class', 'icon-spin4 animate-spin');
4218
  downloadExtension({
4219
  action: 'aam',
4220
  sub_action: 'Extension_Manager.install',
4221
  _ajax_nonce: getLocal().nonce,
4222
  license: $('#extension-key').val()
4223
  }, function() {
4224
- $('i', _this).attr('class', 'icon-download-cloud');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4225
  });
4226
  });
4227
 
1402
  * @returns {undefined}
1403
  */
1404
  function downloadLicense(data, cb) {
1405
+ $.ajax(getLocal().system.apiV1Endpoint + '/download', {
1406
  type: 'GET',
1407
  dataType: 'json',
1408
  data: {
4081
 
4082
  var dump = null;
4083
 
4084
+ /**
4085
+ *
4086
+ * @param {*} base64
4087
+ */
4088
+ function base64ToArrayBuffer(base64) {
4089
+ const binaryString = window.atob(base64); // Comment this if not using base64
4090
+ const bytes = new Uint8Array(binaryString.length);
4091
+
4092
+ return bytes.map((byte, i) => binaryString.charCodeAt(i));
4093
+ }
4094
+
4095
+ /**
4096
+ *
4097
+ * @param {*} data
4098
+ * @param {*} filename
4099
+ * @param {*} mime
4100
+ */
4101
+ function download(data, filename, mime) {
4102
+ var blob = new Blob([data], {type: mime || 'application/octet-stream'});
4103
+ if (typeof window.navigator.msSaveBlob !== 'undefined') {
4104
+ // IE workaround for "HTML7007: One or more blob URLs were
4105
+ // revoked by closing the blob for which they were created.
4106
+ // These URLs will no longer resolve as the data backing
4107
+ // the URL has been freed."
4108
+ window.navigator.msSaveBlob(blob, filename);
4109
+ }
4110
+ else {
4111
+ var blobURL = window.URL.createObjectURL(blob);
4112
+ var tempLink = document.createElement('a');
4113
+ tempLink.style.display = 'none';
4114
+ tempLink.href = blobURL;
4115
+ tempLink.setAttribute('download', filename);
4116
+
4117
+ // Safari thinks _blank anchor are pop ups. We only want to set _blank
4118
+ // target if the browser does not support the HTML5 download attribute.
4119
+ // This allows you to download files in desktop safari if pop up blocking
4120
+ // is enabled.
4121
+ if (typeof tempLink.download === 'undefined') {
4122
+ tempLink.setAttribute('target', '_blank');
4123
+ }
4124
+
4125
+ document.body.appendChild(tempLink);
4126
+ tempLink.click();
4127
+ document.body.removeChild(tempLink);
4128
+ window.URL.revokeObjectURL(blobURL);
4129
+ }
4130
+ }
4131
+
4132
  /**
4133
  *
4134
  * @param {type} data
4136
  * @returns {undefined}
4137
  */
4138
  function downloadExtension(data, cb) {
4139
+ $.ajax(getLocal().system.apiV1Endpoint + '/download', {
4140
  type: 'GET',
4141
  dataType: 'json',
4142
  data: {
4188
  }
4189
  });
4190
  }
4191
+
4192
+ /**
4193
+ *
4194
+ * @param {*} license
4195
+ * @param {*} cb
4196
+ */
4197
+ function downloadPlugin(license, cb) {
4198
+ $.ajax(getLocal().system.apiV2Endpoint + '/download/' + license , {
4199
+ type: 'GET',
4200
+ dataType: 'json',
4201
+ headers: {
4202
+ "Accept": "application/json"
4203
+ },
4204
+ success: function (package) {
4205
+ download(
4206
+ base64ToArrayBuffer(package.content),
4207
+ `${package.title}.zip`
4208
+ );
4209
+ cb();
4210
+ },
4211
+ error: function (response) {
4212
+ getAAM().notification(
4213
+ 'danger', response.responseJSON.reason
4214
+ );
4215
+ }
4216
+ });
4217
+ }
4218
 
4219
  /**
4220
  *
4280
  $('#install-extension').bind('click', function () {
4281
  $('#extension-key').parent().removeClass('error');
4282
 
 
4283
  var license = $.trim($('#extension-key').val());
4284
 
4285
  if (!license) {
4288
  return;
4289
  }
4290
 
4291
+ $('i', '#download-software').attr('class', 'icon-spin4 animate-spin');
4292
  downloadExtension({
4293
  action: 'aam',
4294
  sub_action: 'Extension_Manager.install',
4295
  _ajax_nonce: getLocal().nonce,
4296
  license: $('#extension-key').val()
4297
  }, function() {
4298
+ $('i', '#download-software').attr('class', 'icon-download-cloud');
4299
+ });
4300
+ });
4301
+
4302
+ $('#download-plugin').bind('click', function () {
4303
+ $('#extension-key').parent().removeClass('error');
4304
+
4305
+ var license = $.trim($('#extension-key').val());
4306
+
4307
+ if (!license) {
4308
+ $('#extension-key').parent().addClass('error');
4309
+ $('#extension-key').focus();
4310
+ return;
4311
+ }
4312
+
4313
+ $('i', '#download-software').attr('class', 'icon-spin4 animate-spin');
4314
+ downloadPlugin($('#extension-key').val(), function() {
4315
+ $('i', '#download-software').attr('class', 'icon-download-cloud');
4316
  });
4317
  });
4318
 
media/js/vendor.js CHANGED
@@ -215,9 +215,6 @@ type:"inline"}};var m=e.fn.dataTable.Api;m.register("responsive()",function(){re
215
  h.version="1.0.7";e.fn.dataTable.Responsive=h;e.fn.DataTable.Responsive=h;e(p).on("init.dt.dtr",function(d,a){if("dt"===d.namespace&&(e(a.nTable).hasClass("responsive")||e(a.nTable).hasClass("dt-responsive")||a.oInit.responsive||k.defaults.responsive)){var c=a.oInit.responsive;!1!==c&&new h(a,e.isPlainObject(c)?c:{})}});return h};"function"===typeof define&&define.amd?define(["jquery","datatables"],o):"object"===typeof exports?o(require("jquery"),require("datatables")):jQuery&&!jQuery.fn.dataTable.Responsive&&
216
  o(jQuery,jQuery.fn.dataTable)})(window,document);
217
 
218
- //download.js v4.2, by dandavis; 2008-2017. [MIT] see https://danml.com/download.html for tests/usage
219
- ;(function(r,l){"function"==typeof define&&define.amd?define([],l):"object"==typeof exports?module.exports=l():r.download=l()})(this,function(){return function l(a,e,k){function q(a){var h=a.split(/[:;,]/);a=h[1];var h=("base64"==h[2]?atob:decodeURIComponent)(h.pop()),d=h.length,b=0,c=new Uint8Array(d);for(b;b<d;++b)c[b]=h.charCodeAt(b);return new f([c],{type:a})}function m(a,b){if("download"in d)return d.href=a,d.setAttribute("download",n),d.className="download-js-link",d.innerHTML="downloading...",d.style.display="none",document.body.appendChild(d),setTimeout(function(){d.click(),document.body.removeChild(d),!0===b&&setTimeout(function(){g.URL.revokeObjectURL(d.href)},250)},66),!0;if(/(Version)\/(\d+)\.(\d+)(?:\.(\d+))?.*Safari\//.test(navigator.userAgent))return/^data:/.test(a)&&(a="data:"+a.replace(/^data:([\w\/\-\+]+)/,"application/octet-stream")),!window.open(a)&&confirm("Displaying New Document\n\nUse Save As... to download, then click back to return to this page.")&&(location.href=a),!0;var c=document.createElement("iframe");document.body.appendChild(c),!b&&/^data:/.test(a)&&(a="data:"+a.replace(/^data:([\w\/\-\+]+)/,"application/octet-stream")),c.src=a,setTimeout(function(){document.body.removeChild(c)},333)}var g=window,b=k||"application/octet-stream",c=!e&&!k&&a,d=document.createElement("a");k=function(a){return String(a)};var f=g.Blob||g.MozBlob||g.WebKitBlob||k,n=e||"download",f=f.call?f.bind(g):Blob;"true"===String(this)&&(a=[a,b],b=a[0],a=a[1]);if(c&&2048>c.length&&(n=c.split("/").pop().split("?")[0],d.href=c,-1!==d.href.indexOf(c))){var p=new XMLHttpRequest;return p.open("GET",c,!0),p.responseType="blob",p.onload=function(a){l(a.target.response,n,"application/octet-stream")},setTimeout(function(){p.send()},0),p}if(/^data:([\w+-]+\/[\w+.-]+)?[,;]/.test(a)){if(!(2096103.424<a.length&&f!==k))return navigator.msSaveBlob?navigator.msSaveBlob(q(a),n):m(a);a=q(a),b=a.type||"application/octet-stream"}else if(/([\x80-\xff])/.test(a)){e=0;var c=new Uint8Array(a.length),t=c.length;for(e;e<t;++e)c[e]=a.charCodeAt(e);a=new f([c],{type:b})}a=a instanceof f?a:new f([a],{type:b});if(navigator.msSaveBlob)return navigator.msSaveBlob(a,n);if(g.URL)m(g.URL.createObjectURL(a),!0);else{if("string"==typeof a||a.constructor===k)try{return m("data:"+b+";base64,"+g.btoa(a))}catch(h){return m("data:"+b+","+encodeURIComponent(a))}b=new FileReader,b.onload=function(a){m(this.result)},b.readAsDataURL(a)}return!0}});
220
-
221
  /*! ========================================================================
222
  * Bootstrap Toggle: bootstrap-toggle.js v2.2.0
223
  * https://www.bootstraptoggle.com
215
  h.version="1.0.7";e.fn.dataTable.Responsive=h;e.fn.DataTable.Responsive=h;e(p).on("init.dt.dtr",function(d,a){if("dt"===d.namespace&&(e(a.nTable).hasClass("responsive")||e(a.nTable).hasClass("dt-responsive")||a.oInit.responsive||k.defaults.responsive)){var c=a.oInit.responsive;!1!==c&&new h(a,e.isPlainObject(c)?c:{})}});return h};"function"===typeof define&&define.amd?define(["jquery","datatables"],o):"object"===typeof exports?o(require("jquery"),require("datatables")):jQuery&&!jQuery.fn.dataTable.Responsive&&
216
  o(jQuery,jQuery.fn.dataTable)})(window,document);
217
 
 
 
 
218
  /*! ========================================================================
219
  * Bootstrap Toggle: bootstrap-toggle.js v2.2.0
220
  * https://www.bootstraptoggle.com
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: vasyltech
3
  Tags: access control, membership, backend menu, user role, restricted content, security, jwt
4
  Requires at least: 4.0
5
  Tested up to: 5.2
6
- Stable tag: 5.9.6.3
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
 
@@ -80,6 +80,11 @@ https://www.youtube.com/watch?v=mj5Xa_Wc16Y
80
 
81
  == Changelog ==
82
 
 
 
 
 
 
83
  = 5.9.6.3 =
84
  * Fixed the bug with merging access settings for multiple roles
85
  * Improved the way capabilities are managed internally by AAM
3
  Tags: access control, membership, backend menu, user role, restricted content, security, jwt
4
  Requires at least: 4.0
5
  Tested up to: 5.2
6
+ Stable tag: 5.9.7
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
 
80
 
81
  == Changelog ==
82
 
83
+ = 5.9.7 =
84
+ * Prep for upcoming AAM v6 release. Converting all extensions to plugins
85
+ * Covered odd use-case when some plugins decide to register CPT capabilities during plugin activation
86
+ * Improved Backend Menu feature functionality
87
+
88
  = 5.9.6.3 =
89
  * Fixed the bug with merging access settings for multiple roles
90
  * Improved the way capabilities are managed internally by AAM