PluginProbe
Passster – Password Protect Pages and Content / 4.3.16
Passster – Password Protect Pages and Content v4.3.16
4.3.16 4.3.15 4.3.14 4.3.12 4.3.13 4.3.11 4.3.10 4.3.9 4.3.8 4.3.7 4.3.6 4.3.5 trunk 3.5.4 3.5.5.2 3.5.5.8 3.5.5.9 4.0 4.1.4 4.2.10 4.2.11 4.2.12 4.2.13 4.2.14 4.2.15 All 48 releases
← All changes | inc/class-ps-public.php +268 -157 4.04.3.16 View file →
@@ -1,50 +1,65 @@
1 1 <?php
2 2
3 3 namespace passster;
4 4
5 -use Exception ;
6 -class PS_Public
7 -{
5 +use Exception;
6 +class PS_Public {
8 7 /**
9 8 * Contains instance or null
10 9 *
11 10 * @var object|null
12 11 */
13 - private static $instance = null ;
12 + private static $instance = null;
13 +
14 14 /**
15 + * Track which posts have already had their protection form rendered
16 + * to prevent duplicate forms on page builders like Avada.
17 + *
18 + * @var array
19 + */
20 + private static $rendered_protection = array();
21 +
22 + /**
15 23 * Constructor for PS_Public
16 24 */
17 - public function __construct()
18 - {
19 - add_shortcode( 'content_protector', array( $this, 'render_shortcode' ) );
20 - add_shortcode( 'passster', array( $this, 'render_shortcode' ) );
21 - add_filter( 'the_content', array( $this, 'filter_the_content' ) );
22 - add_filter( 'acf_the_content', array( $this, 'filter_the_content' ) );
23 - add_filter( 'get_the_excerpt', array( $this, 'filter_the_content' ) );
24 - add_filter(
25 - 'passster_compatibility_actions',
26 - array( $this, 'add_compatibilities' ),
27 - 10,
28 - 2
29 - );
30 - add_action( 'template_redirect', array( $this, 'check_global_proctection' ) );
25 + public function __construct() {
26 + add_shortcode( 'content_protector', array($this, 'render_shortcode') );
27 + add_shortcode( 'passster', array($this, 'render_shortcode') );
28 + add_filter( 'the_content', array($this, 'filter_the_content') );
29 + add_filter( 'acf_the_content', array($this, 'filter_the_content') );
30 + add_filter( 'get_the_excerpt', array($this, 'filter_the_content') );
31 + add_action( 'template_redirect', array($this, 'check_global_proctection') );
32 + add_action( 'wp_enqueue_scripts', array($this, 'add_public_scripts'), 9999 );
31 33 }
32 -
34 +
33 35 /**
34 36 * Returns instance of PS_Public.
35 37 *
36 38 * @return object
37 39 */
38 - public static function get_instance()
39 - {
40 + public static function get_instance() {
40 41 if ( null === self::$instance ) {
41 42 self::$instance = new self();
42 43 }
43 44 return self::$instance;
44 45 }
45 -
46 +
46 47 /**
48 + * Avoids re-entering the_content recursively.
49 + *
50 + * @param string $content the unlocked content.
51 + *
52 + * @return string
53 + */
54 + private function render_unlocked_content( string $content ) : string {
55 + if ( doing_filter( 'the_content' ) ) {
56 + return wpautop( do_shortcode( $content ) );
57 + }
58 + return apply_filters( 'the_content', $content );
59 + }
60 +
61 + /**
47 62 * Render the Passster shortcode.
48 63 *
49 64 * @param array $atts array of attributes.
50 65 * @param string|null $content the current content.
@@ -50,125 +65,153 @@
50 65 * @param string|null $content the current content.
51 66 *
52 67 * @return string
53 68 */
54 - public function render_shortcode( array $atts, string $content = null ) : string
55 - {
69 + public function render_shortcode( array $atts, string $content = null ) : string {
70 + // Schedule check for protected areas (PRO only).
71 + if ( !empty( $atts['area'] ) && \passster_fs()->is_plan_or_trial__premium_only( 'pro' ) ) {
72 + $area_id = absint( $atts['area'] );
73 + $schedule_enabled = get_post_meta( $area_id, 'passster_schedule_enabled', true );
74 + if ( $schedule_enabled ) {
75 + $schedule_start = get_post_meta( $area_id, 'passster_schedule_start', true );
76 + $schedule_end = get_post_meta( $area_id, 'passster_schedule_end', true );
77 + $now = current_time( 'timestamp' );
78 + $in_schedule = true;
79 + if ( !empty( $schedule_start ) && $now < strtotime( $schedule_start ) ) {
80 + $in_schedule = false;
81 + }
82 + if ( !empty( $schedule_end ) && $now > strtotime( $schedule_end ) ) {
83 + $in_schedule = false;
84 + }
85 + if ( !$in_schedule ) {
86 + $area = get_post( $area_id );
87 + if ( $area && ('publish' === $area->post_status || current_user_can( 'edit_post', $area_id )) ) {
88 + return $this->render_unlocked_content( str_replace( '{post-id}', get_the_id(), $area->post_content ) );
89 + }
90 + return $content ?? '';
91 + }
92 + }
93 + }
56 94 // check if valid before restrict anything.
57 95 $valid = PS_Conditional::is_valid( $atts );
58 96 $options = get_option( 'passster' );
59 97 if ( $valid ) {
60 -
61 - if ( !empty($atts['area']) ) {
98 + if ( !empty( $atts['area'] ) ) {
62 99 $area_id = esc_html( $atts['area'] );
63 100 $area = get_post( $area_id );
64 - $content = apply_filters( 'passster_compatibility_actions', $area->post_content, $area_id );
65 - do_action( 'passster_content_unlocked' );
66 - return apply_filters( 'the_content', str_replace( '{post-id}', get_the_id(), $content ) );
101 + if ( 'publish' === $area->post_status || current_user_can( 'edit_post', $area_id ) ) {
102 + $content = $area->post_content;
103 + do_action( 'passster_content_unlocked' );
104 + return $this->render_unlocked_content( str_replace( '{post-id}', get_the_id(), $content ) );
105 + }
67 106 } else {
68 - $content = apply_filters( 'the_content', $content );
107 + $content = $this->render_unlocked_content( $content );
69 108 do_action( 'passster_content_unlocked' );
70 109 return apply_filters( 'passster_content', $content );
71 110 }
72 -
73 111 }
74 112 // do nothing if no atts.
75 - if ( empty($atts) ) {
113 + if ( empty( $atts ) ) {
76 114 return $content;
77 115 }
78 116 // Set default form.
79 117 $form = PS_Form::get_password_form();
80 118 // Password.
81 -
82 - if ( !empty($atts['password']) ) {
119 + if ( !empty( $atts['password'] ) ) {
83 120 $form = PS_Form::get_password_form();
84 121 $form = str_replace( '[PASSSTER_TYPE]', 'password', $form );
85 122 }
86 -
87 123 // Area.
88 -
89 - if ( !empty($atts['area']) ) {
90 - $area_id = esc_html( $atts['area'] );
124 + if ( !empty( $atts['area'] ) ) {
125 + $area_id = absint( $atts['area'] );
91 126 $form = str_replace( '[PASSSTER_AREA]', $area_id, $form );
92 127 }
93 -
94 128 // Page.
95 -
96 - if ( !empty($atts['protection']) ) {
129 + if ( !empty( $atts['protection'] ) ) {
97 130 $form = str_replace( '[PASSSTER_PROTECTION]', 'full', $form );
98 - } else {
99 - if ( !empty($atts['area']) ) {
100 - $form = str_replace( '[PASSSTER_PROTECTION]', 'area', $form );
101 - }
131 + } elseif ( !empty( $atts['area'] ) ) {
132 + $form = str_replace( '[PASSSTER_PROTECTION]', 'area', $form );
102 133 }
103 -
104 134 // Redirect.
105 -
106 - if ( !empty($atts['redirect']) ) {
107 - $form = str_replace( '[PASSSTER_REDIRECT]', $atts['redirect'], $form );
135 + if ( !empty( $atts['redirect'] ) ) {
136 + $form = str_replace( '[PASSSTER_REDIRECT]', esc_url( $atts['redirect'] ), $form );
108 137 } else {
109 138 $form = str_replace( '[PASSSTER_REDIRECT]', '', $form );
110 139 }
111 -
140 + // headline tag.
141 + $allowed_headline_tags = array(
142 + 'span',
143 + 'p',
144 + 'div',
145 + 'h1',
146 + 'h2',
147 + 'h3',
148 + 'h4',
149 + 'h5',
150 + 'h6'
151 + );
152 + $headline_tag = ( isset( $options['headline_tag'] ) && in_array( $options['headline_tag'], $allowed_headline_tags, true ) ? $options['headline_tag'] : 'span' );
153 + $form = str_replace( '[PASSSTER_HEADLINE_TAG]', $headline_tag, $form );
112 154 // headline.
113 -
114 - if ( !empty($atts['headline']) ) {
155 + if ( !empty( $options['hide_headline'] ) ) {
156 + $form = str_replace( '[PASSSTER_FORM_HEADLINE]', '', $form );
157 + } elseif ( !empty( $atts['headline'] ) ) {
115 158 $form = str_replace( '[PASSSTER_FORM_HEADLINE]', esc_html( $atts['headline'] ), $form );
116 159 } else {
117 - $form = str_replace( '[PASSSTER_FORM_HEADLINE]', $options['headline'], $form );
160 + $form = str_replace( '[PASSSTER_FORM_HEADLINE]', esc_html( $options['headline'] ), $form );
118 161 }
119 -
120 162 // instruction.
121 -
122 - if ( !empty($atts['instruction']) ) {
123 - $form = str_replace( '[PASSSTER_FORM_INSTRUCTIONS]', esc_html( $atts['instruction'] ), $form );
163 + if ( !empty( $atts['instruction'] ) ) {
164 + $decoded_instruction = base64_decode( $atts['instruction'] );
165 + $decoded_instruction = html_entity_decode( $decoded_instruction );
166 + $sanitized_instruction = wp_kses_post( $decoded_instruction );
167 + $form = str_replace( '[PASSSTER_FORM_INSTRUCTIONS]', $sanitized_instruction, $form );
124 168 } else {
125 - $form = str_replace( '[PASSSTER_FORM_INSTRUCTIONS]', $options['instruction'], $form );
169 + $form = str_replace( '[PASSSTER_FORM_INSTRUCTIONS]', wp_kses_post( $options['instruction'] ), $form );
126 170 }
127 -
128 171 // placeholder.
129 -
130 - if ( !empty($atts['placeholder']) ) {
131 - $form = str_replace( '[PASSSTER_PLACEHOLDER]', esc_html( $atts['placeholder'] ), $form );
172 + if ( !empty( $atts['placeholder'] ) ) {
173 + $form = str_replace( '[PASSSTER_PLACEHOLDER]', esc_attr( $atts['placeholder'] ), $form );
132 174 } else {
133 - $form = str_replace( '[PASSSTER_PLACEHOLDER]', $options['placeholder'], $form );
175 + $form = str_replace( '[PASSSTER_PLACEHOLDER]', esc_attr( $options['placeholder'] ), $form );
134 176 }
135 -
177 + // label.
178 + $form = str_replace( '[PASSSTER_LABEL]', esc_html__( 'Enter your password', 'content-protector' ), $form );
136 179 // button.
137 -
138 - if ( !empty($atts['button']) ) {
180 + if ( !empty( $atts['button'] ) ) {
139 181 $form = str_replace( '[PASSSTER_BUTTON_LABEL]', esc_html( $atts['button'] ), $form );
140 182 } else {
141 - $form = str_replace( '[PASSSTER_BUTTON_LABEL]', $options['button_label'], $form );
183 + $form = str_replace( '[PASSSTER_BUTTON_LABEL]', esc_html( $options['button_label'] ), $form );
142 184 }
143 -
144 185 // modify id.
145 -
146 - if ( !empty($atts['id']) ) {
147 - $form = str_replace( '[PASSSTER_ID]', 'ps-' . esc_html( $atts['id'] ), $form );
186 + if ( !empty( $atts['id'] ) ) {
187 + $form = str_replace( '[PASSSTER_ID]', 'ps-' . esc_attr( $atts['id'] ), $form );
148 188 } else {
149 189 $form = str_replace( '[PASSSTER_ID]', 'ps-' . wp_rand( 10, 1000 ), $form );
150 190 }
151 -
191 + // post id (per-form, for correct REST unlock on archive pages with multiple protected posts).
192 + $form = str_replace( '[PASSSTER_POST_ID]', absint( get_the_ID() ), $form );
193 + // term id (for category archive protection — passed to REST API so it can validate against term meta).
194 + $term_id_val = ( !empty( $atts['term_id'] ) ? absint( $atts['term_id'] ) : 0 );
195 + $form = str_replace( '[PASSSTER_TERM_ID]', $term_id_val, $form );
196 + // post type (for post type archive protection — passed to REST API so it can validate against post type config).
197 + $post_type_val = ( !empty( $atts['post_type'] ) ? sanitize_key( $atts['post_type'] ) : '' );
198 + $form = str_replace( '[PASSSTER_POST_TYPE]', esc_attr( $post_type_val ), $form );
152 199 // hide or not.
153 -
154 - if ( !empty($atts['hide']) ) {
200 + if ( !empty( $atts['hide'] ) ) {
155 201 $form = str_replace( '[PASSSTER_HIDE]', ' passster-hide', $form );
156 202 } else {
157 203 $form = str_replace( '[PASSSTER_HIDE]', '', $form );
158 204 }
159 -
160 205 // ACF field.
161 -
162 - if ( !empty($atts['acf']) ) {
163 - $form = str_replace( '[PASSSTER_ACF]', ' data-acf="' . esc_html( $atts['acf'] ) . '"', $form );
206 + if ( !empty( $atts['acf'] ) ) {
207 + $form = str_replace( '[PASSSTER_ACF]', ' data-acf="' . esc_url( $atts['acf'] ) . '"', $form );
164 208 } else {
165 209 $form = str_replace( '[PASSSTER_ACF]', '', $form );
166 210 }
167 -
168 211 return $form;
169 212 }
170 -
213 +
171 214 /**
172 215 * Filters the_content with Passster.
173 216 *
174 217 * @param string $content given content.
@@ -175,11 +218,28 @@
175 218 *
176 219 * @return string
177 220 * @throws Exception
178 221 */
179 - public function filter_the_content( string $content ) : string
180 - {
222 + public function filter_the_content( string $content ) : string {
181 223 $post_id = get_the_id();
224 + // Prevent duplicate form rendering (fixes issue with Avada and other page builders)
225 + if ( isset( self::$rendered_protection[$post_id] ) ) {
226 + // Already rendered the protection form for this post, return protected content placeholder
227 + // or the form that was already generated
228 + return self::$rendered_protection[$post_id]['form'] ?? $content;
229 + }
230 + $parent_id = wp_get_post_parent_id( $post_id );
231 + if ( $parent_id ) {
232 + $activate_protection = get_post_meta( $parent_id, 'passster_activate_protection', true );
233 + $children_protection = get_post_meta( $parent_id, 'passster_protect_child_pages', true );
234 + if ( $activate_protection && $children_protection ) {
235 + $post_id = $parent_id;
236 + // Check parent too
237 + if ( isset( self::$rendered_protection[$post_id] ) ) {
238 + return self::$rendered_protection[$post_id]['form'] ?? $content;
239 + }
240 + }
241 + }
182 242 $activate_protection = get_post_meta( $post_id, 'passster_activate_protection', true );
183 243 // user restriction.
184 244 $user_restriction_type = get_post_meta( $post_id, 'passster_user_restriction_type', true );
185 245 $user_restriction = get_post_meta( $post_id, 'passster_user_restriction', true );
@@ -185,12 +245,13 @@
185 245 $user_restriction = get_post_meta( $post_id, 'passster_user_restriction', true );
186 246 // Redirection.
187 247 $redirection = get_post_meta( $post_id, 'passster_redirect_url', true );
188 248 // texts.
189 - $headline = get_post_meta( $post_id, 'passster_headline', true );
190 - $instruction = get_post_meta( $post_id, 'passster_instruction', true );
191 - $placeholder = get_post_meta( $post_id, 'passster_placeholder', true );
192 - $button = get_post_meta( $post_id, 'passster_button', true );
249 + $overwrite_defaults = get_post_meta( $post_id, 'passster_activate_overwrite_defaults', true );
250 + $headline = ( $overwrite_defaults ? get_post_meta( $post_id, 'passster_headline', true ) : '' );
251 + $instruction = ( $overwrite_defaults ? get_post_meta( $post_id, 'passster_instruction', true ) : '' );
252 + $placeholder = ( $overwrite_defaults ? get_post_meta( $post_id, 'passster_placeholder', true ) : '' );
253 + $button = ( $overwrite_defaults ? get_post_meta( $post_id, 'passster_button', true ) : '' );
193 254 $id = get_post_meta( $post_id, 'passster_id', true );
194 255 if ( !$activate_protection ) {
195 256 return $content;
196 257 }
@@ -199,24 +260,24 @@
199 260 $shortcode = '';
200 261 $password = get_post_meta( $post_id, 'passster_password', true );
201 262 $atts['password'] = $password;
202 263 $shortcode = '[passster password="' . $password . '" protection="full" ';
203 - if ( !empty($redirection) ) {
264 + if ( !empty( $redirection ) ) {
204 265 $shortcode .= 'redirect="' . $redirection . '" ';
205 266 }
206 - if ( !empty($headline) ) {
267 + if ( !empty( $headline ) ) {
207 268 $shortcode .= 'headline="' . $headline . '" ';
208 269 }
209 - if ( !empty($instruction) ) {
210 - $shortcode .= 'instruction="' . $instruction . '" ';
270 + if ( !empty( $instruction ) ) {
271 + $shortcode .= 'instruction="' . base64_encode( $instruction ) . '" ';
211 272 }
212 - if ( !empty($placeholder) ) {
273 + if ( !empty( $placeholder ) ) {
213 274 $shortcode .= 'placeholder="' . $placeholder . '" ';
214 275 }
215 - if ( !empty($button) ) {
276 + if ( !empty( $button ) ) {
216 277 $shortcode .= 'button="' . $button . '" ';
217 278 }
218 - if ( !empty($id) ) {
279 + if ( !empty( $id ) ) {
219 280 $shortcode .= 'id="' . $id . '" ';
220 281 }
221 282 $shortcode .= ']{content}[/passster]';
222 283 // check if valid before restrict anything.
@@ -225,73 +286,37 @@
225 286 return $content;
226 287 }
227 288 // replace placeholder with content.
228 289 $shortcode = str_replace( '{content}', $content, $shortcode );
229 - return do_shortcode( $shortcode );
290 + // Generate the form
291 + $rendered_form = do_shortcode( $shortcode );
292 + // Store reference to prevent duplicate rendering (Avada, Elementor, etc.)
293 + self::$rendered_protection[$post_id] = array(
294 + 'form' => $rendered_form,
295 + );
296 + return $rendered_form;
230 297 }
231 -
298 +
232 299 /**
233 - * Adding compatibility modifications before ajax output.
234 - *
235 - * @param string $content current content.
236 - *
237 - * @return string
238 - */
239 - public function add_compatibilities( string $content, $post_id = null ) : string
240 - {
241 - if ( is_null( $post_id ) ) {
242 - $post_id = get_the_id();
243 - }
244 - // use meta field instead.
245 - $use_meta = apply_filters( 'passster_use_meta_field', false );
246 -
247 - if ( $use_meta ) {
248 - $meta_key = apply_filters( 'passster_meta_key', 'field_name' );
249 - $content = get_post_meta( $post_id, $meta_key, true );
250 - }
251 -
252 - // use meta field instead.
253 - $use_acf = apply_filters( 'passster_use_acf_field', false );
254 -
255 - if ( $use_acf ) {
256 - $meta_key = apply_filters( 'passster_acf_key', 'field_name' );
257 - $content = get_field( $meta_key, $post_id );
258 - }
259 -
260 - // Tablepress.
261 -
262 - if ( class_exists( 'TablePress' ) ) {
263 - \TablePress::$controller = \TablePress::load_controller( 'frontend' );
264 - \TablePress::$controller->init_shortcodes();
265 - }
266 -
267 - // prepare for Visual Composer.
268 - if ( class_exists( 'WPBMap' ) ) {
269 - \WPBMap::addAllMappedShortcodes();
270 - }
271 - // Skip shortcodes.
272 - remove_filter( 'the_content', 'do_shortcode', 11 );
273 - $content = apply_filters( 'the_content', $content );
274 - add_filter( 'the_content', 'do_shortcode', 11 );
275 - return $content;
276 - }
277 -
278 - /**
279 300 * Redirect if global protection is activated and no password is set.
280 301 *
281 302 * @return void
282 303 * @throws Exception
283 304 */
284 - public function check_global_proctection()
285 - {
305 + public function check_global_proctection() {
286 306 $options = get_option( 'passster' );
287 - // Allow Elementor editing the page.
288 - if ( isset( $_GET['elementor-preview'] ) ) {
307 + $post_id = get_queried_object_id();
308 + if ( !$post_id ) {
289 309 return;
290 310 }
311 + // Allow Elementor editing the page.
312 + $elementor_preview = filter_input( INPUT_GET, 'elementor-preview', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
291 313 // Allow Live Canvas Editor.
292 - if ( isset( $_GET['lc_action_launch_editing'] ) ) {
293 - return;
314 + $live_canvas_preview = filter_input( INPUT_GET, 'lc_action_launch_editing', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
315 + if ( is_preview() || $elementor_preview || $live_canvas_preview ) {
316 + if ( is_user_logged_in() && current_user_can( 'edit_post', $post_id ) ) {
317 + return;
318 + }
294 319 }
295 320 if ( !isset( $options['global_protection_id'] ) ) {
296 321 return;
297 322 }
@@ -298,15 +323,14 @@
298 323 if ( !isset( $options['activate_global_protection'] ) ) {
299 324 return;
300 325 }
301 326 // Build $atts array based on protection settings.
302 - $post_id = $options['global_protection_id'];
303 - $is_active = $options['activate_global_protection'];
327 + $post_id = esc_html( $options['global_protection_id'] );
328 + $is_active = esc_html( $options['activate_global_protection'] );
304 329 $atts = array();
305 330 $password = get_post_meta( $post_id, 'passster_password', true );
306 - $atts['password'] = esc_html( $password );
307 - if ( !empty($post_id) ) {
308 -
331 + $atts['password'] = $password;
332 + if ( !empty( $post_id ) ) {
309 333 if ( $is_active ) {
310 334 if ( is_page( $post_id ) || is_single( $post_id ) ) {
311 335 return;
312 336 }
@@ -318,17 +342,104 @@
318 342 }
319 343 }
320 344 }
321 345 // Check if cookie is set.
322 -
323 - if ( empty($_COOKIE['passster']) || !PS_Conditional::is_valid( $atts ) ) {
346 + $cookie = esc_html( $_COOKIE['passster'] );
347 + if ( !PS_Conditional::is_valid( $atts ) ) {
324 348 $global_protection_url = get_permalink( $post_id );
349 + $pass_param = filter_input( INPUT_GET, 'pass', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
350 + if ( !empty( $pass_param ) ) {
351 + $global_protection_url = add_query_arg( 'pass', $pass_param, $global_protection_url );
352 + }
325 353 wp_redirect( esc_url_raw( $global_protection_url ) );
326 354 exit;
327 355 }
328 -
329 356 }
330 -
331 357 }
332 358 }
333 359
334 -}
360 + /**
361 + * Enqueue scripts for shortcode
362 + *
363 + * @return void
364 + */
365 + public function add_public_scripts() {
366 + $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min' );
367 + $options = get_option( 'passster' );
368 + // Only load CSS if not disabled (allows themes to style the form)
369 + if ( empty( $options['disable_css'] ) ) {
370 + wp_enqueue_style(
371 + 'passster-public',
372 + PASSSTER_URL . '/assets/public/passster-public' . $suffix . '.css',
373 + array(),
374 + PASSSTER_VERSION,
375 + 'all'
376 + );
377 + }
378 + wp_enqueue_script(
379 + 'passster-cookie',
380 + PASSSTER_URL . '/assets/public/cookie.js',
381 + array('jquery', 'wp-api-fetch'),
382 + PASSSTER_VERSION,
383 + false
384 + );
385 + wp_enqueue_script(
386 + 'passster-public',
387 + PASSSTER_URL . '/assets/public/passster-public' . $suffix . '.js',
388 + array('jquery', 'passster-cookie'),
389 + PASSSTER_VERSION,
390 + false
391 + );
392 + $shortcodes = array();
393 + if ( isset( $options['third_party_shortcodes'] ) && !empty( $options['third_party_shortcodes'] ) ) {
394 + $shortcodes_in_options = explode( ',', $options['third_party_shortcodes'] );
395 + if ( is_array( $shortcodes_in_options ) ) {
396 + foreach ( $shortcodes_in_options as $shortcode ) {
397 + $shortcodes[$shortcode] = do_shortcode( str_replace( '{post-id}', get_the_id(), $shortcode ) );
398 + }
399 + }
400 + }
401 + // Archive/taxonomy pages have no singular post, so get_permalink() can't be used
402 + // to build the "reload after unlock" URL for links generated by area/CPT-level protection.
403 + $current_post_id = get_the_id();
404 + $reload_url = ( $current_post_id ? get_permalink( $current_post_id ) : esc_url_raw( remove_query_arg( 'pass' ) ) );
405 + $args = array(
406 + 'ajax_url' => admin_url() . 'admin-ajax.php',
407 + 'rest_url' => get_rest_url(),
408 + 'nonce' => wp_create_nonce( 'ps-password-nonce' ),
409 + 'hash_nonce' => wp_create_nonce( 'ps-hash-nonce' ),
410 + 'logout_nonce' => wp_create_nonce( 'ps-logout-nonce' ),
411 + 'post_id' => $current_post_id,
412 + 'shortcodes' => $shortcodes,
413 + 'permalink' => $reload_url,
414 + );
415 + if ( isset( $options['cookie_duration_unit'] ) ) {
416 + $args['cookie_duration_unit'] = esc_html( $options['cookie_duration_unit'] );
417 + } else {
418 + $args['cookie_duration_unit'] = 'days';
419 + }
420 + if ( isset( $options['cookie_duration'] ) ) {
421 + $args['cookie_duration'] = esc_html( $options['cookie_duration'] );
422 + } else {
423 + $args['cookie_duration'] = 1;
424 + }
425 + if ( isset( $options['disable_cookie'] ) ) {
426 + $args['disable_cookie'] = esc_html( $options['disable_cookie'] );
427 + } else {
428 + $args['disable_cookie'] = false;
429 + }
430 + $args['unlock_mode'] = !empty( $options['unlock_mode'] );
431 + wp_localize_script( 'passster-public', 'ps_ajax', $args );
432 + // if password type hint used.
433 + $password_typing = $options['show_password'];
434 + if ( $password_typing ) {
435 + wp_enqueue_script(
436 + 'password-typing',
437 + PASSSTER_URL . '/assets/public/password-typing.js',
438 + array('jquery'),
439 + PASSSTER_VERSION,
440 + false
441 + );
442 + }
443 + }
444 +
445 +}