PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.83
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.83
51.1.84 51.1.85 51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 All 39 releases
← All changes | includes/features/Protected_Content/Protected_Content.php +90 -21 51.1.4451.1.83 View file →
@@ -125,8 +125,13 @@
125 125 'kingAddonsProtectedContent',
126 126 [
127 127 'ajaxUrl' => admin_url('admin-ajax.php'),
128 128 'nonce' => wp_create_nonce('king_addons_protected_content'),
129 + 'strings' => [
130 + 'enterPassword' => esc_html__('Please enter a password', 'king-addons'),
131 + 'incorrectPassword' => esc_html__('Incorrect password', 'king-addons'),
132 + 'errorOccurred' => esc_html__('An error occurred. Please try again.', 'king-addons'),
133 + ],
129 134 ]
130 135 );
131 136 }
132 137
@@ -1030,19 +1035,29 @@
1030 1035 if (!$this->can_use_pro()) {
1031 1036 wp_send_json_error(['message' => esc_html__('Pro feature', 'king-addons')]);
1032 1037 }
1033 1038
1034 - $password = isset($_POST['password']) ? sanitize_text_field($_POST['password']) : '';
1035 - $element_id = isset($_POST['element_id']) ? sanitize_text_field($_POST['element_id']) : '';
1039 + // phpcs:ignore WordPress.Security.NonceVerification.Missing
1040 + $password = isset($_POST['password']) ? sanitize_text_field(wp_unslash($_POST['password'])) : '';
1041 + // phpcs:ignore WordPress.Security.NonceVerification.Missing
1042 + $element_id = isset($_POST['element_id']) ? sanitize_text_field(wp_unslash($_POST['element_id'])) : '';
1036 1043 $post_id = isset($_POST['post_id']) ? absint($_POST['post_id']) : 0;
1037 - $scope = isset($_POST['scope']) ? sanitize_text_field($_POST['scope']) : 'element';
1038 - $global_key = isset($_POST['global_key']) ? sanitize_text_field($_POST['global_key']) : '';
1044 + // phpcs:ignore WordPress.Security.NonceVerification.Missing
1045 + $scope = isset($_POST['scope']) ? sanitize_text_field(wp_unslash($_POST['scope'])) : 'element';
1046 + // phpcs:ignore WordPress.Security.NonceVerification.Missing
1047 + $global_key = isset($_POST['global_key']) ? sanitize_text_field(wp_unslash($_POST['global_key'])) : '';
1039 1048 $days = isset($_POST['days']) ? absint($_POST['days']) : 7;
1040 1049
1041 - if (empty($password) || empty($post_id)) {
1050 + $days = max(1, min(365, $days));
1051 +
1052 + if (empty($password) || empty($post_id) || empty($element_id)) {
1042 1053 wp_send_json_error(['message' => esc_html__('Invalid request', 'king-addons')]);
1043 1054 }
1044 1055
1056 + if (!in_array($scope, ['element', 'global'], true)) {
1057 + wp_send_json_error(['message' => esc_html__('Invalid request', 'king-addons')]);
1058 + }
1059 +
1045 1060 // Get element settings from post meta.
1046 1061 $elementor_data = get_post_meta($post_id, '_elementor_data', true);
1047 1062 if (empty($elementor_data)) {
1048 1063 wp_send_json_error(['message' => esc_html__('Element not found', 'king-addons')]);
@@ -1047,21 +1062,54 @@
1047 1062 if (empty($elementor_data)) {
1048 1063 wp_send_json_error(['message' => esc_html__('Element not found', 'king-addons')]);
1049 1064 }
1050 1065
1051 - $data = json_decode($elementor_data, true);
1066 + if (is_array($elementor_data)) {
1067 + $data = $elementor_data;
1068 + } else {
1069 + $data = json_decode((string) $elementor_data, true);
1070 + }
1052 1071 if (!is_array($data)) {
1053 1072 wp_send_json_error(['message' => esc_html__('Invalid data', 'king-addons')]);
1054 1073 }
1055 1074
1056 - // Find element and get stored password.
1057 - $stored_password = $this->find_element_password($data, $element_id, $scope, $global_key);
1075 + // Find element settings.
1076 + $settings = $this->find_element_settings($data, $element_id);
1077 + if (null === $settings) {
1078 + wp_send_json_error(['message' => esc_html__('Element not found', 'king-addons')]);
1079 + }
1058 1080
1059 - if (null === $stored_password) {
1081 + // Validate password mode configuration.
1082 + $mode = $settings['protected_content_mode'] ?? '';
1083 + $enabled = $settings['protected_content_enable'] ?? '';
1084 + if ('yes' !== $enabled || 'password' !== $mode) {
1060 1085 wp_send_json_error(['message' => esc_html__('Configuration error', 'king-addons')]);
1061 1086 }
1062 1087
1063 - if ($password !== $stored_password) {
1088 + $stored_scope = $settings['protected_content_password_type'] ?? 'element';
1089 + if (!in_array($stored_scope, ['element', 'global'], true)) {
1090 + $stored_scope = 'element';
1091 + }
1092 +
1093 + if ($stored_scope !== $scope) {
1094 + wp_send_json_error(['message' => esc_html__('Configuration error', 'king-addons')]);
1095 + }
1096 +
1097 + if ('global' === $scope) {
1098 + $stored_key = isset($settings['protected_content_password_key']) ? sanitize_text_field((string) $settings['protected_content_password_key']) : '';
1099 + if (empty($stored_key) || empty($global_key) || sanitize_key($stored_key) !== sanitize_key($global_key)) {
1100 + wp_send_json_error(['message' => esc_html__('Configuration error', 'king-addons')]);
1101 + }
1102 + $stored_password = $settings['protected_content_password_global_password'] ?? null;
1103 + } else {
1104 + $stored_password = $settings['protected_content_password'] ?? null;
1105 + }
1106 +
1107 + if (empty($stored_password) || !is_string($stored_password)) {
1108 + wp_send_json_error(['message' => esc_html__('Configuration error', 'king-addons')]);
1109 + }
1110 +
1111 + if (!hash_equals((string) $stored_password, (string) $password)) {
1064 1112 wp_send_json_error(['message' => esc_html__('Incorrect password', 'king-addons')]);
1065 1113 }
1066 1114
1067 1115 // Set cookie.
@@ -1077,18 +1125,16 @@
1077 1125 wp_send_json_success(['message' => esc_html__('Access granted', 'king-addons')]);
1078 1126 }
1079 1127
1080 1128 /**
1081 - * Find element password in Elementor data.
1129 + * Find element settings in Elementor data.
1082 1130 *
1083 1131 * @param array<mixed> $data Elementor data.
1084 1132 * @param string $element_id Element ID.
1085 - * @param string $scope Scope (element/global).
1086 - * @param string $global_key Global key.
1087 1133 *
1088 - * @return string|null
1134 + * @return array<string,mixed>|null
1089 1135 */
1090 - private function find_element_password(array $data, string $element_id, string $scope, string $global_key): ?string
1136 + private function find_element_settings(array $data, string $element_id): ?array
1091 1137 {
1092 1138 foreach ($data as $element) {
1093 1139 if (!is_array($element)) {
1094 1140 continue;
@@ -1097,17 +1143,14 @@
1097 1143 $id = $element['id'] ?? '';
1098 1144 $settings = $element['settings'] ?? [];
1099 1145
1100 1146 if ($id === $element_id) {
1101 - if ('global' === $scope) {
1102 - return $settings['protected_content_password_global_password'] ?? null;
1103 - }
1104 - return $settings['protected_content_password'] ?? null;
1147 + return is_array($settings) ? $settings : [];
1105 1148 }
1106 1149
1107 1150 // Recursively search in children.
1108 1151 if (!empty($element['elements']) && is_array($element['elements'])) {
1109 - $found = $this->find_element_password($element['elements'], $element_id, $scope, $global_key);
1152 + $found = $this->find_element_settings($element['elements'], $element_id);
1110 1153 if (null !== $found) {
1111 1154 return $found;
1112 1155 }
1113 1156 }
@@ -1130,14 +1173,21 @@
1130 1173 $global_key = $settings['protected_content_password_key'] ?? '';
1131 1174 $days = (int) ($settings['protected_content_password_cookie_days'] ?? 7);
1132 1175 $message = $settings['protected_content_fallback_msg'] ?? esc_html__('This content is password protected.', 'king-addons');
1133 1176
1177 + $document_post_id = $this->get_current_elementor_document_id();
1178 + if ($document_post_id <= 0) {
1179 + $document_post_id = (int) get_queried_object_id();
1180 + }
1181 +
1182 + $days = max(1, min(365, $days));
1183 +
1134 1184 ?>
1135 1185 <div class="king-addons-protected-fallback king-addons-protected-password-form">
1136 1186 <div class="king-addons-protected-password-message"><?php echo esc_html($message); ?></div>
1137 1187 <form class="king-addons-password-form"
1138 1188 data-element-id="<?php echo esc_attr($element->get_id()); ?>"
1139 - data-post-id="<?php echo esc_attr(get_the_ID()); ?>"
1189 + data-post-id="<?php echo esc_attr($document_post_id); ?>"
1140 1190 data-scope="<?php echo esc_attr($scope); ?>"
1141 1191 data-global-key="<?php echo esc_attr($global_key); ?>"
1142 1192 data-days="<?php echo esc_attr($days); ?>">
1143 1193 <div class="king-addons-password-input-wrap">
@@ -1226,8 +1276,27 @@
1226 1276 return true;
1227 1277 }
1228 1278
1229 1279 return false;
1280 + }
1281 +
1282 + /**
1283 + * Get current Elementor document post ID (important for Theme Builder templates).
1284 + *
1285 + * @return int
1286 + */
1287 + private function get_current_elementor_document_id(): int
1288 + {
1289 + if (!class_exists('\Elementor\Plugin') || !Plugin::$instance || !isset(Plugin::$instance->documents)) {
1290 + return 0;
1291 + }
1292 +
1293 + $document = Plugin::$instance->documents->get_current();
1294 + if ($document && method_exists($document, 'get_main_id')) {
1295 + return (int) $document->get_main_id();
1296 + }
1297 +
1298 + return 0;
1230 1299 }
1231 1300
1232 1301 /**
1233 1302 * Get protection info for editor badge.