| @@ -1,263 +1,263 @@ | ||
| 1 | -<?php | |
| 2 | -/** | |
| 3 | - * Server-side rendering for the Protected Content block. | |
| 4 | - * | |
| 5 | - * @package Passster | |
| 6 | - * | |
| 7 | - * @var array $attributes Block attributes. | |
| 8 | - * @var string $content Block content (inner blocks). | |
| 9 | - * @var WP_Block $block Block instance. | |
| 10 | - */ | |
| 11 | - | |
| 12 | -defined( 'ABSPATH' ) || exit; | |
| 13 | - | |
| 14 | -// Early exit if classes not loaded yet (edge case). | |
| 15 | -if ( ! class_exists( 'passster\PS_Conditional' ) || ! class_exists( 'passster\PS_Form' ) ) { | |
| 16 | - echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
| 17 | - return; | |
| 18 | -} | |
| 19 | - | |
| 20 | -// Ensure we have a valid block ID. | |
| 21 | -if ( empty( $attributes['blockId'] ) ) { | |
| 22 | - $attributes['blockId'] = 'ps-' . wp_generate_password( 8, false ); | |
| 23 | -} | |
| 24 | - | |
| 25 | -// Find the synced Protected Area by block ID. | |
| 26 | -$synced_area_id = 0; | |
| 27 | -$synced_areas = get_posts( array( | |
| 28 | - 'post_type' => 'protected_areas', | |
| 29 | - 'posts_per_page' => 1, | |
| 30 | - 'fields' => 'ids', | |
| 31 | - 'meta_query' => array( | |
| 32 | - array( | |
| 33 | - 'key' => '_passster_block_id', | |
| 34 | - 'value' => $attributes['blockId'], | |
| 35 | - ), | |
| 36 | - ), | |
| 37 | -) ); | |
| 38 | -if ( ! empty( $synced_areas ) ) { | |
| 39 | - $synced_area_id = $synced_areas[0]; | |
| 40 | -} | |
| 41 | - | |
| 42 | -use passster\PS_Conditional; | |
| 43 | -use passster\PS_Form; | |
| 44 | - | |
| 45 | -// Get block attributes. | |
| 46 | -$block_id = ! empty( $attributes['blockId'] ) ? sanitize_text_field( $attributes['blockId'] ) : ''; | |
| 47 | -$protection_type = ! empty( $attributes['protectionType'] ) ? sanitize_text_field( $attributes['protectionType'] ) : 'password'; | |
| 48 | -$password = ! empty( $attributes['password'] ) ? $attributes['password'] : ''; | |
| 49 | -$passwords = ! empty( $attributes['passwords'] ) ? $attributes['passwords'] : ''; | |
| 50 | -$password_list = ! empty( $attributes['passwordList'] ) ? absint( $attributes['passwordList'] ) : 0; | |
| 51 | - | |
| 52 | -// User Restriction attributes. | |
| 53 | -$user_restriction = ! empty( $attributes['userRestriction'] ); | |
| 54 | -$user_restriction_type = ! empty( $attributes['userRestrictionType'] ) ? sanitize_text_field( $attributes['userRestrictionType'] ) : 'username'; | |
| 55 | -$user_restriction_value = ! empty( $attributes['userRestrictionValue'] ) ? sanitize_text_field( $attributes['userRestrictionValue'] ) : ''; | |
| 56 | - | |
| 57 | -// Override Defaults attributes. | |
| 58 | -$overwrite_defaults = ! empty( $attributes['overwriteDefaults'] ); | |
| 59 | -$headline = ! empty( $attributes['headline'] ) ? sanitize_text_field( $attributes['headline'] ) : ''; | |
| 60 | -$instruction = ! empty( $attributes['instruction'] ) ? wp_kses_post( $attributes['instruction'] ) : ''; | |
| 61 | -$placeholder = ! empty( $attributes['placeholder'] ) ? sanitize_text_field( $attributes['placeholder'] ) : ''; | |
| 62 | -$button_label = ! empty( $attributes['buttonLabel'] ) ? sanitize_text_field( $attributes['buttonLabel'] ) : ''; | |
| 63 | -$form_id = ! empty( $attributes['formId'] ) ? sanitize_text_field( $attributes['formId'] ) : ''; | |
| 64 | - | |
| 65 | -// Advanced Options attributes. | |
| 66 | -$advanced_options = ! empty( $attributes['advancedOptions'] ); | |
| 67 | -$redirect_url = ! empty( $attributes['redirectUrl'] ) ? esc_url( $attributes['redirectUrl'] ) : ''; | |
| 68 | -$hide_form = ! empty( $attributes['hideForm'] ); | |
| 69 | - | |
| 70 | -// Schedule attributes (PRO only). | |
| 71 | -$schedule_enabled = ! empty( $attributes['scheduleEnabled'] ); | |
| 72 | -$schedule_start = ! empty( $attributes['scheduleStart'] ) ? $attributes['scheduleStart'] : ''; | |
| 73 | -$schedule_end = ! empty( $attributes['scheduleEnd'] ) ? $attributes['scheduleEnd'] : ''; | |
| 74 | - | |
| 75 | -// Check schedule - if outside the scheduled period, show content without protection. | |
| 76 | -if ( $schedule_enabled && \passster_fs()->is_plan_or_trial__premium_only( 'pro' ) ) { | |
| 77 | - $now = current_time( 'timestamp' ); | |
| 78 | - $is_within_schedule = true; | |
| 79 | - | |
| 80 | - if ( ! empty( $schedule_start ) ) { | |
| 81 | - $start_time = strtotime( $schedule_start ); | |
| 82 | - if ( $now < $start_time ) { | |
| 83 | - $is_within_schedule = false; | |
| 84 | - } | |
| 85 | - } | |
| 86 | - | |
| 87 | - if ( ! empty( $schedule_end ) ) { | |
| 88 | - $end_time = strtotime( $schedule_end ); | |
| 89 | - if ( $now > $end_time ) { | |
| 90 | - $is_within_schedule = false; | |
| 91 | - } | |
| 92 | - } | |
| 93 | - | |
| 94 | - // If outside schedule, show content without protection. | |
| 95 | - if ( ! $is_within_schedule ) { | |
| 96 | - echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
| 97 | - return; | |
| 98 | - } | |
| 99 | -} | |
| 100 | - | |
| 101 | -// If no protection is set, just render the content. | |
| 102 | -if ( 'password' === $protection_type && empty( $password ) ) { | |
| 103 | - echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
| 104 | - return; | |
| 105 | -} | |
| 106 | - | |
| 107 | -if ( 'passwords' === $protection_type && empty( $passwords ) ) { | |
| 108 | - echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
| 109 | - return; | |
| 110 | -} | |
| 111 | - | |
| 112 | -if ( 'password_list' === $protection_type && empty( $password_list ) ) { | |
| 113 | - echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
| 114 | - return; | |
| 115 | -} | |
| 116 | - | |
| 117 | -// Build attributes array for validation. | |
| 118 | -$atts = array(); | |
| 119 | - | |
| 120 | -switch ( $protection_type ) { | |
| 121 | - case 'password': | |
| 122 | - $atts['password'] = $password; | |
| 123 | - break; | |
| 124 | - case 'passwords': | |
| 125 | - $atts['passwords'] = $passwords; | |
| 126 | - break; | |
| 127 | - case 'password_list': | |
| 128 | - $atts['password_list'] = $password_list; | |
| 129 | - break; | |
| 130 | -} | |
| 131 | - | |
| 132 | -// Add user restriction to validation attributes if enabled. | |
| 133 | -if ( $user_restriction && ! empty( $user_restriction_value ) && 'no-role' !== $user_restriction_value ) { | |
| 134 | - if ( 'user-role' === $user_restriction_type ) { | |
| 135 | - $atts['role'] = $user_restriction_value; | |
| 136 | - } else { | |
| 137 | - $atts['user'] = $user_restriction_value; | |
| 138 | - } | |
| 139 | -} | |
| 140 | - | |
| 141 | -// Check if already unlocked. | |
| 142 | -$is_unlocked = false; | |
| 143 | -if ( class_exists( PS_Conditional::class ) ) { | |
| 144 | - $is_unlocked = PS_Conditional::is_valid( $atts ); | |
| 145 | -} | |
| 146 | - | |
| 147 | -// If unlocked, show content. | |
| 148 | -if ( $is_unlocked ) { | |
| 149 | - echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
| 150 | - return; | |
| 151 | -} | |
| 152 | - | |
| 153 | -if ( $advanced_options && $hide_form ) { | |
| 154 | - return; | |
| 155 | -} | |
| 156 | - | |
| 157 | -// Get global options for form defaults. | |
| 158 | -$options = get_option( 'passster', array() ); | |
| 159 | - | |
| 160 | -// Build the protection form using global settings. | |
| 161 | -$form = PS_Form::get_password_form(); | |
| 162 | - | |
| 163 | -// Form ID - use custom ID if set, otherwise block ID. | |
| 164 | -$final_form_id = ! empty( $form_id ) ? $form_id : 'ps-block-' . $block_id; | |
| 165 | -$form = str_replace( '[PASSSTER_ID]', esc_attr( $final_form_id ), $form ); | |
| 166 | - | |
| 167 | -// Hide form placeholder. | |
| 168 | -$form = str_replace( '[PASSSTER_HIDE]', '', $form ); | |
| 169 | - | |
| 170 | -// Redirect URL. | |
| 171 | -if ( $advanced_options && ! empty( $redirect_url ) ) { | |
| 172 | - $form = str_replace( '[PASSSTER_REDIRECT]', esc_url( $redirect_url ), $form ); | |
| 173 | -} else { | |
| 174 | - $form = str_replace( '[PASSSTER_REDIRECT]', '', $form ); | |
| 175 | -} | |
| 176 | - | |
| 177 | -// Label. | |
| 178 | -$form = str_replace( '[PASSSTER_LABEL]', esc_html__( 'Enter your password', 'content-protector' ), $form ); | |
| 179 | - | |
| 180 | -// Headline tag. | |
| 181 | -$allowed_headline_tags = array( 'span', 'p', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ); | |
| 182 | -$headline_tag = isset( $options['headline_tag'] ) && in_array( $options['headline_tag'], $allowed_headline_tags, true ) ? $options['headline_tag'] : 'span'; | |
| 183 | -$form = str_replace( '[PASSSTER_HEADLINE_TAG]', $headline_tag, $form ); | |
| 184 | - | |
| 185 | -// Headline - use override if enabled and set, otherwise global. | |
| 186 | -if ( ! empty( $options['hide_headline'] ) ) { | |
| 187 | - $form = str_replace( '[PASSSTER_FORM_HEADLINE]', '', $form ); | |
| 188 | -} elseif ( $overwrite_defaults && ! empty( $headline ) ) { | |
| 189 | - $form = str_replace( '[PASSSTER_FORM_HEADLINE]', esc_html( $headline ), $form ); | |
| 190 | -} else { | |
| 191 | - $form = str_replace( '[PASSSTER_FORM_HEADLINE]', esc_html( $options['headline'] ?? '' ), $form ); | |
| 192 | -} | |
| 193 | - | |
| 194 | -// Instruction - use override if enabled and set, otherwise global. | |
| 195 | -if ( $overwrite_defaults && ! empty( $instruction ) ) { | |
| 196 | - $form = str_replace( '[PASSSTER_FORM_INSTRUCTIONS]', wp_kses_post( $instruction ), $form ); | |
| 197 | -} else { | |
| 198 | - $form = str_replace( '[PASSSTER_FORM_INSTRUCTIONS]', wp_kses_post( $options['instruction'] ?? '' ), $form ); | |
| 199 | -} | |
| 200 | - | |
| 201 | -// Placeholder - use override if enabled and set, otherwise global. | |
| 202 | -if ( $overwrite_defaults && ! empty( $placeholder ) ) { | |
| 203 | - $form = str_replace( '[PASSSTER_PLACEHOLDER]', esc_attr( $placeholder ), $form ); | |
| 204 | -} else { | |
| 205 | - $form = str_replace( '[PASSSTER_PLACEHOLDER]', esc_attr( $options['placeholder'] ?? '' ), $form ); | |
| 206 | -} | |
| 207 | - | |
| 208 | -// Button label - use override if enabled and set, otherwise global. | |
| 209 | -if ( $overwrite_defaults && ! empty( $button_label ) ) { | |
| 210 | - $form = str_replace( '[PASSSTER_BUTTON_LABEL]', esc_html( $button_label ), $form ); | |
| 211 | -} else { | |
| 212 | - $form = str_replace( '[PASSSTER_BUTTON_LABEL]', esc_html( $options['button_label'] ?? '' ), $form ); | |
| 213 | -} | |
| 214 | - | |
| 215 | -// Protection type placeholder. | |
| 216 | -$form = str_replace( '[PASSSTER_TYPE]', esc_attr( $protection_type ), $form ); | |
| 217 | - | |
| 218 | -// Protection mode - 'block' for Content Lock blocks (REST API validates from block attributes). | |
| 219 | -$form = str_replace( '[PASSSTER_PROTECTION]', 'block', $form ); | |
| 220 | - | |
| 221 | -// Password list placeholders. | |
| 222 | -$form = str_replace( '[PASSSTER_LIST]', esc_attr( $password_list ), $form ); | |
| 223 | -$form = str_replace( '[PASSSTER_LISTS]', '', $form ); | |
| 224 | - | |
| 225 | -// Area placeholder (set to 0 for blocks - we use block_id instead). | |
| 226 | -$form = str_replace( '[PASSSTER_AREA]', '0', $form ); | |
| 227 | - | |
| 228 | -// ACF placeholder (not used in blocks). | |
| 229 | -$form = str_replace( '[PASSSTER_ACF]', '', $form ); | |
| 230 | - | |
| 231 | -// Wrapper classes. | |
| 232 | -$wrapper_classes = array( 'passster-protected-content', 'wp-block-passster-protected-content' ); | |
| 233 | -if ( ! empty( $attributes['align'] ) ) { | |
| 234 | - $wrapper_classes[] = 'align' . $attributes['align']; | |
| 235 | -} | |
| 236 | -if ( ! empty( $attributes['className'] ) ) { | |
| 237 | - $wrapper_classes[] = $attributes['className']; | |
| 238 | -} | |
| 239 | - | |
| 240 | -// Data attributes for JS handling. | |
| 241 | -$data_attrs = array( | |
| 242 | - 'block-id' => $block_id, | |
| 243 | - 'protection-type' => $protection_type, | |
| 244 | - 'post-id' => get_the_ID(), | |
| 245 | -); | |
| 246 | - | |
| 247 | -if ( $advanced_options && ! empty( $redirect_url ) ) { | |
| 248 | - $data_attrs['redirect'] = $redirect_url; | |
| 249 | -} | |
| 250 | - | |
| 251 | -// Output. | |
| 252 | -?> | |
| 253 | -<div | |
| 254 | - class="<?php echo esc_attr( implode( ' ', $wrapper_classes ) ); ?>" | |
| 255 | - <?php foreach ( $data_attrs as $key => $value ) : ?> | |
| 256 | - data-<?php echo esc_attr( $key ); ?>="<?php echo esc_attr( $value ); ?>" | |
| 257 | - <?php endforeach; ?> | |
| 258 | -> | |
| 259 | - <div class="passster-protected-content__form"> | |
| 260 | - <?php echo $form; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> | |
| 261 | - </div> | |
| 262 | -</div> | |
| 263 | -<?php | |
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * Server-side rendering for the Protected Content block. | |
| 4 | + * | |
| 5 | + * @package Passster | |
| 6 | + * | |
| 7 | + * @var array $attributes Block attributes. | |
| 8 | + * @var string $content Block content (inner blocks). | |
| 9 | + * @var WP_Block $block Block instance. | |
| 10 | + */ | |
| 11 | + | |
| 12 | +defined( 'ABSPATH' ) || exit; | |
| 13 | + | |
| 14 | +// Early exit if classes not loaded yet (edge case). | |
| 15 | +if ( ! class_exists( 'passster\PS_Conditional' ) || ! class_exists( 'passster\PS_Form' ) ) { | |
| 16 | + echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
| 17 | + return; | |
| 18 | +} | |
| 19 | + | |
| 20 | +// Ensure we have a valid block ID. | |
| 21 | +if ( empty( $attributes['blockId'] ) ) { | |
| 22 | + $attributes['blockId'] = 'ps-' . wp_generate_password( 8, false ); | |
| 23 | +} | |
| 24 | + | |
| 25 | +// Find the synced Protected Area by block ID. | |
| 26 | +$synced_area_id = 0; | |
| 27 | +$synced_areas = get_posts( array( | |
| 28 | + 'post_type' => 'protected_areas', | |
| 29 | + 'posts_per_page' => 1, | |
| 30 | + 'fields' => 'ids', | |
| 31 | + 'meta_query' => array( | |
| 32 | + array( | |
| 33 | + 'key' => '_passster_block_id', | |
| 34 | + 'value' => $attributes['blockId'], | |
| 35 | + ), | |
| 36 | + ), | |
| 37 | +) ); | |
| 38 | +if ( ! empty( $synced_areas ) ) { | |
| 39 | + $synced_area_id = $synced_areas[0]; | |
| 40 | +} | |
| 41 | + | |
| 42 | +use passster\PS_Conditional; | |
| 43 | +use passster\PS_Form; | |
| 44 | + | |
| 45 | +// Get block attributes. | |
| 46 | +$block_id = ! empty( $attributes['blockId'] ) ? sanitize_text_field( $attributes['blockId'] ) : ''; | |
| 47 | +$protection_type = ! empty( $attributes['protectionType'] ) ? sanitize_text_field( $attributes['protectionType'] ) : 'password'; | |
| 48 | +$password = ! empty( $attributes['password'] ) ? $attributes['password'] : ''; | |
| 49 | +$passwords = ! empty( $attributes['passwords'] ) ? $attributes['passwords'] : ''; | |
| 50 | +$password_list = ! empty( $attributes['passwordList'] ) ? absint( $attributes['passwordList'] ) : 0; | |
| 51 | + | |
| 52 | +// User Restriction attributes. | |
| 53 | +$user_restriction = ! empty( $attributes['userRestriction'] ); | |
| 54 | +$user_restriction_type = ! empty( $attributes['userRestrictionType'] ) ? sanitize_text_field( $attributes['userRestrictionType'] ) : 'username'; | |
| 55 | +$user_restriction_value = ! empty( $attributes['userRestrictionValue'] ) ? sanitize_text_field( $attributes['userRestrictionValue'] ) : ''; | |
| 56 | + | |
| 57 | +// Override Defaults attributes. | |
| 58 | +$overwrite_defaults = ! empty( $attributes['overwriteDefaults'] ); | |
| 59 | +$headline = ! empty( $attributes['headline'] ) ? sanitize_text_field( $attributes['headline'] ) : ''; | |
| 60 | +$instruction = ! empty( $attributes['instruction'] ) ? wp_kses_post( $attributes['instruction'] ) : ''; | |
| 61 | +$placeholder = ! empty( $attributes['placeholder'] ) ? sanitize_text_field( $attributes['placeholder'] ) : ''; | |
| 62 | +$button_label = ! empty( $attributes['buttonLabel'] ) ? sanitize_text_field( $attributes['buttonLabel'] ) : ''; | |
| 63 | +$form_id = ! empty( $attributes['formId'] ) ? sanitize_text_field( $attributes['formId'] ) : ''; | |
| 64 | + | |
| 65 | +// Advanced Options attributes. | |
| 66 | +$advanced_options = ! empty( $attributes['advancedOptions'] ); | |
| 67 | +$redirect_url = ! empty( $attributes['redirectUrl'] ) ? esc_url( $attributes['redirectUrl'] ) : ''; | |
| 68 | +$hide_form = ! empty( $attributes['hideForm'] ); | |
| 69 | + | |
| 70 | +// Schedule attributes (PRO only). | |
| 71 | +$schedule_enabled = ! empty( $attributes['scheduleEnabled'] ); | |
| 72 | +$schedule_start = ! empty( $attributes['scheduleStart'] ) ? $attributes['scheduleStart'] : ''; | |
| 73 | +$schedule_end = ! empty( $attributes['scheduleEnd'] ) ? $attributes['scheduleEnd'] : ''; | |
| 74 | + | |
| 75 | +// Check schedule - if outside the scheduled period, show content without protection. | |
| 76 | +if ( $schedule_enabled && \passster_fs()->is_plan_or_trial__premium_only( 'pro' ) ) { | |
| 77 | + $now = current_time( 'timestamp' ); | |
| 78 | + $is_within_schedule = true; | |
| 79 | + | |
| 80 | + if ( ! empty( $schedule_start ) ) { | |
| 81 | + $start_time = strtotime( $schedule_start ); | |
| 82 | + if ( $now < $start_time ) { | |
| 83 | + $is_within_schedule = false; | |
| 84 | + } | |
| 85 | + } | |
| 86 | + | |
| 87 | + if ( ! empty( $schedule_end ) ) { | |
| 88 | + $end_time = strtotime( $schedule_end ); | |
| 89 | + if ( $now > $end_time ) { | |
| 90 | + $is_within_schedule = false; | |
| 91 | + } | |
| 92 | + } | |
| 93 | + | |
| 94 | + // If outside schedule, show content without protection. | |
| 95 | + if ( ! $is_within_schedule ) { | |
| 96 | + echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
| 97 | + return; | |
| 98 | + } | |
| 99 | +} | |
| 100 | + | |
| 101 | +// If no protection is set, just render the content. | |
| 102 | +if ( 'password' === $protection_type && empty( $password ) ) { | |
| 103 | + echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
| 104 | + return; | |
| 105 | +} | |
| 106 | + | |
| 107 | +if ( 'passwords' === $protection_type && empty( $passwords ) ) { | |
| 108 | + echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
| 109 | + return; | |
| 110 | +} | |
| 111 | + | |
| 112 | +if ( 'password_list' === $protection_type && empty( $password_list ) ) { | |
| 113 | + echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
| 114 | + return; | |
| 115 | +} | |
| 116 | + | |
| 117 | +// Build attributes array for validation. | |
| 118 | +$atts = array(); | |
| 119 | + | |
| 120 | +switch ( $protection_type ) { | |
| 121 | + case 'password': | |
| 122 | + $atts['password'] = $password; | |
| 123 | + break; | |
| 124 | + case 'passwords': | |
| 125 | + $atts['passwords'] = $passwords; | |
| 126 | + break; | |
| 127 | + case 'password_list': | |
| 128 | + $atts['password_list'] = $password_list; | |
| 129 | + break; | |
| 130 | +} | |
| 131 | + | |
| 132 | +// Add user restriction to validation attributes if enabled. | |
| 133 | +if ( $user_restriction && ! empty( $user_restriction_value ) && 'no-role' !== $user_restriction_value ) { | |
| 134 | + if ( 'user-role' === $user_restriction_type ) { | |
| 135 | + $atts['role'] = $user_restriction_value; | |
| 136 | + } else { | |
| 137 | + $atts['user'] = $user_restriction_value; | |
| 138 | + } | |
| 139 | +} | |
| 140 | + | |
| 141 | +// Check if already unlocked. | |
| 142 | +$is_unlocked = false; | |
| 143 | +if ( class_exists( PS_Conditional::class ) ) { | |
| 144 | + $is_unlocked = PS_Conditional::is_valid( $atts ); | |
| 145 | +} | |
| 146 | + | |
| 147 | +// If unlocked, show content. | |
| 148 | +if ( $is_unlocked ) { | |
| 149 | + echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
| 150 | + return; | |
| 151 | +} | |
| 152 | + | |
| 153 | +if ( $advanced_options && $hide_form ) { | |
| 154 | + return; | |
| 155 | +} | |
| 156 | + | |
| 157 | +// Get global options for form defaults. | |
| 158 | +$options = get_option( 'passster', array() ); | |
| 159 | + | |
| 160 | +// Build the protection form using global settings. | |
| 161 | +$form = PS_Form::get_password_form(); | |
| 162 | + | |
| 163 | +// Form ID - use custom ID if set, otherwise block ID. | |
| 164 | +$final_form_id = ! empty( $form_id ) ? $form_id : 'ps-block-' . $block_id; | |
| 165 | +$form = str_replace( '[PASSSTER_ID]', esc_attr( $final_form_id ), $form ); | |
| 166 | + | |
| 167 | +// Hide form placeholder. | |
| 168 | +$form = str_replace( '[PASSSTER_HIDE]', '', $form ); | |
| 169 | + | |
| 170 | +// Redirect URL. | |
| 171 | +if ( $advanced_options && ! empty( $redirect_url ) ) { | |
| 172 | + $form = str_replace( '[PASSSTER_REDIRECT]', esc_url( $redirect_url ), $form ); | |
| 173 | +} else { | |
| 174 | + $form = str_replace( '[PASSSTER_REDIRECT]', '', $form ); | |
| 175 | +} | |
| 176 | + | |
| 177 | +// Label. | |
| 178 | +$form = str_replace( '[PASSSTER_LABEL]', esc_html__( 'Enter your password', 'content-protector' ), $form ); | |
| 179 | + | |
| 180 | +// Headline tag. | |
| 181 | +$allowed_headline_tags = array( 'span', 'p', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ); | |
| 182 | +$headline_tag = isset( $options['headline_tag'] ) && in_array( $options['headline_tag'], $allowed_headline_tags, true ) ? $options['headline_tag'] : 'span'; | |
| 183 | +$form = str_replace( '[PASSSTER_HEADLINE_TAG]', $headline_tag, $form ); | |
| 184 | + | |
| 185 | +// Headline - use override if enabled and set, otherwise global. | |
| 186 | +if ( ! empty( $options['hide_headline'] ) ) { | |
| 187 | + $form = str_replace( '[PASSSTER_FORM_HEADLINE]', '', $form ); | |
| 188 | +} elseif ( $overwrite_defaults && ! empty( $headline ) ) { | |
| 189 | + $form = str_replace( '[PASSSTER_FORM_HEADLINE]', esc_html( $headline ), $form ); | |
| 190 | +} else { | |
| 191 | + $form = str_replace( '[PASSSTER_FORM_HEADLINE]', esc_html( $options['headline'] ?? '' ), $form ); | |
| 192 | +} | |
| 193 | + | |
| 194 | +// Instruction - use override if enabled and set, otherwise global. | |
| 195 | +if ( $overwrite_defaults && ! empty( $instruction ) ) { | |
| 196 | + $form = str_replace( '[PASSSTER_FORM_INSTRUCTIONS]', wp_kses_post( $instruction ), $form ); | |
| 197 | +} else { | |
| 198 | + $form = str_replace( '[PASSSTER_FORM_INSTRUCTIONS]', wp_kses_post( $options['instruction'] ?? '' ), $form ); | |
| 199 | +} | |
| 200 | + | |
| 201 | +// Placeholder - use override if enabled and set, otherwise global. | |
| 202 | +if ( $overwrite_defaults && ! empty( $placeholder ) ) { | |
| 203 | + $form = str_replace( '[PASSSTER_PLACEHOLDER]', esc_attr( $placeholder ), $form ); | |
| 204 | +} else { | |
| 205 | + $form = str_replace( '[PASSSTER_PLACEHOLDER]', esc_attr( $options['placeholder'] ?? '' ), $form ); | |
| 206 | +} | |
| 207 | + | |
| 208 | +// Button label - use override if enabled and set, otherwise global. | |
| 209 | +if ( $overwrite_defaults && ! empty( $button_label ) ) { | |
| 210 | + $form = str_replace( '[PASSSTER_BUTTON_LABEL]', esc_html( $button_label ), $form ); | |
| 211 | +} else { | |
| 212 | + $form = str_replace( '[PASSSTER_BUTTON_LABEL]', esc_html( $options['button_label'] ?? '' ), $form ); | |
| 213 | +} | |
| 214 | + | |
| 215 | +// Protection type placeholder. | |
| 216 | +$form = str_replace( '[PASSSTER_TYPE]', esc_attr( $protection_type ), $form ); | |
| 217 | + | |
| 218 | +// Protection mode - 'block' for Content Lock blocks (REST API validates from block attributes). | |
| 219 | +$form = str_replace( '[PASSSTER_PROTECTION]', 'block', $form ); | |
| 220 | + | |
| 221 | +// Password list placeholders. | |
| 222 | +$form = str_replace( '[PASSSTER_LIST]', esc_attr( $password_list ), $form ); | |
| 223 | +$form = str_replace( '[PASSSTER_LISTS]', '', $form ); | |
| 224 | + | |
| 225 | +// Area placeholder (set to 0 for blocks - we use block_id instead). | |
| 226 | +$form = str_replace( '[PASSSTER_AREA]', '0', $form ); | |
| 227 | + | |
| 228 | +// ACF placeholder (not used in blocks). | |
| 229 | +$form = str_replace( '[PASSSTER_ACF]', '', $form ); | |
| 230 | + | |
| 231 | +// Wrapper classes. | |
| 232 | +$wrapper_classes = array( 'passster-protected-content', 'wp-block-passster-protected-content' ); | |
| 233 | +if ( ! empty( $attributes['align'] ) ) { | |
| 234 | + $wrapper_classes[] = 'align' . $attributes['align']; | |
| 235 | +} | |
| 236 | +if ( ! empty( $attributes['className'] ) ) { | |
| 237 | + $wrapper_classes[] = $attributes['className']; | |
| 238 | +} | |
| 239 | + | |
| 240 | +// Data attributes for JS handling. | |
| 241 | +$data_attrs = array( | |
| 242 | + 'block-id' => $block_id, | |
| 243 | + 'protection-type' => $protection_type, | |
| 244 | + 'post-id' => get_the_ID(), | |
| 245 | +); | |
| 246 | + | |
| 247 | +if ( $advanced_options && ! empty( $redirect_url ) ) { | |
| 248 | + $data_attrs['redirect'] = $redirect_url; | |
| 249 | +} | |
| 250 | + | |
| 251 | +// Output. | |
| 252 | +?> | |
| 253 | +<div | |
| 254 | + class="<?php echo esc_attr( implode( ' ', $wrapper_classes ) ); ?>" | |
| 255 | + <?php foreach ( $data_attrs as $key => $value ) : ?> | |
| 256 | + data-<?php echo esc_attr( $key ); ?>="<?php echo esc_attr( $value ); ?>" | |
| 257 | + <?php endforeach; ?> | |
| 258 | +> | |
| 259 | + <div class="passster-protected-content__form"> | |
| 260 | + <?php echo $form; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> | |
| 261 | + </div> | |
| 262 | +</div> | |
| 263 | +<?php | |