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