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 -105 4.1.4 → 4.3.17 View file →
@@ -1,44 +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_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 );
25 33 }
26 -
34 +
27 35 /**
28 36 * Returns instance of PS_Public.
29 37 *
30 38 * @return object
31 39 */
32 - public static function get_instance()
33 - {
40 + public static function get_instance() {
34 41 if ( null === self::$instance ) {
35 42 self::$instance = new self();
36 43 }
37 44 return self::$instance;
38 45 }
39 -
46 +
40 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 + /**
41 66 * Render the Passster shortcode.
42 67 *
43 68 * @param array $atts array of attributes.
44 69 * @param string|null $content the current content.
@@ -44,125 +69,153 @@
44 69 * @param string|null $content the current content.
45 70 *
46 71 * @return string
47 72 */
48 - public function render_shortcode( array $atts, string $content = null ) : string
49 - {
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 + }
50 98 // check if valid before restrict anything.
51 99 $valid = PS_Conditional::is_valid( $atts );
52 100 $options = get_option( 'passster' );
53 101 if ( $valid ) {
54 -
55 - if ( !empty($atts['area']) ) {
102 + if ( !empty( $atts['area'] ) ) {
56 103 $area_id = esc_html( $atts['area'] );
57 104 $area = get_post( $area_id );
58 - $content = $area->post_content;
59 - do_action( 'passster_content_unlocked' );
60 - 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 + }
61 110 } else {
62 - $content = apply_filters( 'the_content', $content );
111 + $content = $this->render_unlocked_content( $content );
63 112 do_action( 'passster_content_unlocked' );
64 113 return apply_filters( 'passster_content', $content );
65 114 }
66 -
67 115 }
68 116 // do nothing if no atts.
69 - if ( empty($atts) ) {
117 + if ( empty( $atts ) ) {
70 118 return $content;
71 119 }
72 120 // Set default form.
73 121 $form = PS_Form::get_password_form();
74 122 // Password.
75 -
76 - if ( !empty($atts['password']) ) {
123 + if ( !empty( $atts['password'] ) ) {
77 124 $form = PS_Form::get_password_form();
78 125 $form = str_replace( '[PASSSTER_TYPE]', 'password', $form );
79 126 }
80 -
81 127 // Area.
82 -
83 - if ( !empty($atts['area']) ) {
84 - $area_id = esc_html( $atts['area'] );
128 + if ( !empty( $atts['area'] ) ) {
129 + $area_id = absint( $atts['area'] );
85 130 $form = str_replace( '[PASSSTER_AREA]', $area_id, $form );
86 131 }
87 -
88 132 // Page.
89 -
90 - if ( !empty($atts['protection']) ) {
133 + if ( !empty( $atts['protection'] ) ) {
91 134 $form = str_replace( '[PASSSTER_PROTECTION]', 'full', $form );
92 - } else {
93 - if ( !empty($atts['area']) ) {
94 - $form = str_replace( '[PASSSTER_PROTECTION]', 'area', $form );
95 - }
135 + } elseif ( !empty( $atts['area'] ) ) {
136 + $form = str_replace( '[PASSSTER_PROTECTION]', 'area', $form );
96 137 }
97 -
98 138 // Redirect.
99 -
100 - if ( !empty($atts['redirect']) ) {
101 - $form = str_replace( '[PASSSTER_REDIRECT]', $atts['redirect'], $form );
139 + if ( !empty( $atts['redirect'] ) ) {
140 + $form = str_replace( '[PASSSTER_REDIRECT]', esc_url( $atts['redirect'] ), $form );
102 141 } else {
103 142 $form = str_replace( '[PASSSTER_REDIRECT]', '', $form );
104 143 }
105 -
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 );
106 158 // headline.
107 -
108 - if ( !empty($atts['headline']) ) {
159 + if ( !empty( $options['hide_headline'] ) ) {
160 + $form = str_replace( '[PASSSTER_FORM_HEADLINE]', '', $form );
161 + } elseif ( !empty( $atts['headline'] ) ) {
109 162 $form = str_replace( '[PASSSTER_FORM_HEADLINE]', esc_html( $atts['headline'] ), $form );
110 163 } else {
111 - $form = str_replace( '[PASSSTER_FORM_HEADLINE]', $options['headline'], $form );
164 + $form = str_replace( '[PASSSTER_FORM_HEADLINE]', esc_html( $options['headline'] ), $form );
112 165 }
113 -
114 166 // instruction.
115 -
116 - if ( !empty($atts['instruction']) ) {
117 - $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 );
118 172 } else {
119 - $form = str_replace( '[PASSSTER_FORM_INSTRUCTIONS]', $options['instruction'], $form );
173 + $form = str_replace( '[PASSSTER_FORM_INSTRUCTIONS]', wp_kses_post( $options['instruction'] ), $form );
120 174 }
121 -
122 175 // placeholder.
123 -
124 - if ( !empty($atts['placeholder']) ) {
125 - $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 );
126 178 } else {
127 - $form = str_replace( '[PASSSTER_PLACEHOLDER]', $options['placeholder'], $form );
179 + $form = str_replace( '[PASSSTER_PLACEHOLDER]', esc_attr( $options['placeholder'] ), $form );
128 180 }
129 -
181 + // label.
182 + $form = str_replace( '[PASSSTER_LABEL]', esc_html__( 'Enter your password', 'content-protector' ), $form );
130 183 // button.
131 -
132 - if ( !empty($atts['button']) ) {
184 + if ( !empty( $atts['button'] ) ) {
133 185 $form = str_replace( '[PASSSTER_BUTTON_LABEL]', esc_html( $atts['button'] ), $form );
134 186 } else {
135 - $form = str_replace( '[PASSSTER_BUTTON_LABEL]', $options['button_label'], $form );
187 + $form = str_replace( '[PASSSTER_BUTTON_LABEL]', esc_html( $options['button_label'] ), $form );
136 188 }
137 -
138 189 // modify id.
139 -
140 - if ( !empty($atts['id']) ) {
141 - $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 );
142 192 } else {
143 193 $form = str_replace( '[PASSSTER_ID]', 'ps-' . wp_rand( 10, 1000 ), $form );
144 194 }
145 -
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 );
146 203 // hide or not.
147 -
148 - if ( !empty($atts['hide']) ) {
204 + if ( !empty( $atts['hide'] ) ) {
149 205 $form = str_replace( '[PASSSTER_HIDE]', ' passster-hide', $form );
150 206 } else {
151 207 $form = str_replace( '[PASSSTER_HIDE]', '', $form );
152 208 }
153 -
154 209 // ACF field.
155 -
156 - if ( !empty($atts['acf']) ) {
157 - $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 );
158 212 } else {
159 213 $form = str_replace( '[PASSSTER_ACF]', '', $form );
160 214 }
161 -
162 215 return $form;
163 216 }
164 -
217 +
165 218 /**
166 219 * Filters the_content with Passster.
167 220 *
168 221 * @param string $content given content.
@@ -169,11 +222,28 @@
169 222 *
170 223 * @return string
171 224 * @throws Exception
172 225 */
173 - public function filter_the_content( string $content ) : string
174 - {
226 + public function filter_the_content( string $content ) : string {
175 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 + }
176 246 $activate_protection = get_post_meta( $post_id, 'passster_activate_protection', true );
177 247 // user restriction.
178 248 $user_restriction_type = get_post_meta( $post_id, 'passster_user_restriction_type', true );
179 249 $user_restriction = get_post_meta( $post_id, 'passster_user_restriction', true );
@@ -179,12 +249,13 @@
179 249 $user_restriction = get_post_meta( $post_id, 'passster_user_restriction', true );
180 250 // Redirection.
181 251 $redirection = get_post_meta( $post_id, 'passster_redirect_url', true );
182 252 // texts.
183 - $headline = get_post_meta( $post_id, 'passster_headline', true );
184 - $instruction = get_post_meta( $post_id, 'passster_instruction', true );
185 - $placeholder = get_post_meta( $post_id, 'passster_placeholder', true );
186 - $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 ) : '' );
187 258 $id = get_post_meta( $post_id, 'passster_id', true );
188 259 if ( !$activate_protection ) {
189 260 return $content;
190 261 }
@@ -193,24 +264,24 @@
193 264 $shortcode = '';
194 265 $password = get_post_meta( $post_id, 'passster_password', true );
195 266 $atts['password'] = $password;
196 267 $shortcode = '[passster password="' . $password . '" protection="full" ';
197 - if ( !empty($redirection) ) {
268 + if ( !empty( $redirection ) ) {
198 269 $shortcode .= 'redirect="' . $redirection . '" ';
199 270 }
200 - if ( !empty($headline) ) {
271 + if ( !empty( $headline ) ) {
201 272 $shortcode .= 'headline="' . $headline . '" ';
202 273 }
203 - if ( !empty($instruction) ) {
204 - $shortcode .= 'instruction="' . $instruction . '" ';
274 + if ( !empty( $instruction ) ) {
275 + $shortcode .= 'instruction="' . base64_encode( $instruction ) . '" ';
205 276 }
206 - if ( !empty($placeholder) ) {
277 + if ( !empty( $placeholder ) ) {
207 278 $shortcode .= 'placeholder="' . $placeholder . '" ';
208 279 }
209 - if ( !empty($button) ) {
280 + if ( !empty( $button ) ) {
210 281 $shortcode .= 'button="' . $button . '" ';
211 282 }
212 - if ( !empty($id) ) {
283 + if ( !empty( $id ) ) {
213 284 $shortcode .= 'id="' . $id . '" ';
214 285 }
215 286 $shortcode .= ']{content}[/passster]';
216 287 // check if valid before restrict anything.
@@ -219,11 +290,17 @@
219 290 return $content;
220 291 }
221 292 // replace placeholder with content.
222 293 $shortcode = str_replace( '{content}', $content, $shortcode );
223 - 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;
224 301 }
225 -
302 +
226 303 /**
227 304 * Redirect if global protection is activated and no password is set.
228 305 *
229 306 * @return void
@@ -228,18 +305,22 @@
228 305 *
229 306 * @return void
230 307 * @throws Exception
231 308 */
232 - public function check_global_proctection()
233 - {
309 + public function check_global_proctection() {
234 310 $options = get_option( 'passster' );
235 - // Allow Elementor editing the page.
236 - if ( isset( $_GET['elementor-preview'] ) ) {
311 + $post_id = get_queried_object_id();
312 + if ( !$post_id ) {
237 313 return;
238 314 }
315 + // Allow Elementor editing the page.
316 + $elementor_preview = filter_input( INPUT_GET, 'elementor-preview', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
239 317 // Allow Live Canvas Editor.
240 - if ( isset( $_GET['lc_action_launch_editing'] ) ) {
241 - 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 + }
242 323 }
243 324 if ( !isset( $options['global_protection_id'] ) ) {
244 325 return;
245 326 }
@@ -246,15 +327,14 @@
246 327 if ( !isset( $options['activate_global_protection'] ) ) {
247 328 return;
248 329 }
249 330 // Build $atts array based on protection settings.
250 - $post_id = $options['global_protection_id'];
251 - $is_active = $options['activate_global_protection'];
331 + $post_id = esc_html( $options['global_protection_id'] );
332 + $is_active = esc_html( $options['activate_global_protection'] );
252 333 $atts = array();
253 334 $password = get_post_meta( $post_id, 'passster_password', true );
254 - $atts['password'] = esc_html( $password );
255 - if ( !empty($post_id) ) {
256 -
335 + $atts['password'] = $password;
336 + if ( !empty( $post_id ) ) {
257 337 if ( $is_active ) {
258 338 if ( is_page( $post_id ) || is_single( $post_id ) ) {
259 339 return;
260 340 }
@@ -266,17 +346,104 @@
266 346 }
267 347 }
268 348 }
269 349 // Check if cookie is set.
270 -
271 - if ( empty($_COOKIE['passster']) || !PS_Conditional::is_valid( $atts ) ) {
350 + $cookie = esc_html( $_COOKIE['passster'] );
351 + if ( !PS_Conditional::is_valid( $atts ) ) {
272 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 + }
273 357 wp_redirect( esc_url_raw( $global_protection_url ) );
274 358 exit;
275 359 }
276 -
277 360 }
278 -
279 361 }
280 362 }
281 363
282 -}
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 +}