← All changes
|
includes/features/Protected_Content/Protected_Content.php
+90
-21
51.1.44
→
51.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. |