PluginProbe
Passster – Password Protect Pages and Content / 3.5.4
Passster – Password Protect Pages and Content v3.5.4
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 4.2.16 All 47 releases
content-protector / src / class-ps-public.php

class-ps-public.php in Passster – Password Protect Pages and Content 3.5.4, at src/class-ps-public.php

625 lines 24.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace passster;
4
5 class PS_Public
6 {
7 /**
8 * Contains instance or null
9 *
10 * @var object|null
11 */
12 private static $instance = null ;
13 /**
14 * Constructor for PS_Public
15 */
16 public function __construct()
17 {
18 add_shortcode( 'content_protector', array( $this, 'render_shortcode' ) );
19 add_shortcode( 'passster', array( $this, 'render_shortcode' ) );
20 add_action( 'wp_enqueue_scripts', array( $this, 'add_public_scripts' ) );
21 add_action( 'wp_ajax_validate_input', array( $this, 'validate_input' ) );
22 add_action( 'wp_ajax_nopriv_validate_input', array( $this, 'validate_input' ) );
23 add_filter( 'the_content', array( $this, 'filter_the_content' ) );
24 add_filter( 'acf_the_content', array( $this, 'filter_the_content' ) );
25 add_filter( 'get_the_excerpt', array( $this, 'filter_the_content' ) );
26 add_filter(
27 'passster_compatibility_actions',
28 array( $this, 'add_compatibilities' ),
29 10,
30 2
31 );
32 add_filter( 'et_builder_load_actions', array( $this, 'add_divi_support' ) );
33 add_action( 'template_redirect', array( $this, 'check_global_proctection' ) );
34 add_action( 'woocommerce_before_single_product_summary', array( $this, 'protect_product' ) );
35 }
36
37 /**
38 * Returns instance of PS_Public.
39 *
40 * @return object
41 */
42 public static function get_instance()
43 {
44 if ( null === self::$instance ) {
45 self::$instance = new self();
46 }
47 return self::$instance;
48 }
49
50 /**
51 * Validate ajax given input.
52 *
53 * @return void
54 */
55 public function validate_input()
56 {
57 // check nonce.
58
59 if ( !wp_verify_nonce( $_POST['nonce'], 'ps-password-nonce' ) ) {
60 $response = array(
61 'error' => 'Security check failed.',
62 );
63 print wp_json_encode( $response );
64 exit;
65 }
66
67 // Get general options.
68 $options = get_option( 'passster_general_settings' );
69 // prepare validation.
70 $type = sanitize_text_field( $_POST['type'] );
71 $post_id = sanitize_text_field( $_POST['post_id'] );
72 $protection = sanitize_text_field( $_POST['protection'] );
73 // check protection.
74 if ( !isset( $protection ) || empty($protection) ) {
75 $protection = false;
76 }
77 // prepare content.
78 $post = get_post( $post_id );
79 $content = apply_filters( 'passster_compatibility_actions', $post->post_content, $post_id );
80 // if it's an ACF Field.
81
82 if ( !empty($_POST['acf']) ) {
83 $acf = esc_html( $_POST['acf'] );
84 $content = \get_field( $acf, $post_id );
85 }
86
87 // Default response.
88 $response = array(
89 'error' => get_theme_mod( 'passster_form_error_text', __( 'Invalid password.', 'content-protector' ) ),
90 'content' => '',
91 );
92 switch ( $type ) {
93 case 'password':
94 // Check if input exists.
95
96 if ( empty($_POST['input']) ) {
97 print wp_json_encode( $response );
98 exit;
99 }
100
101 $input = sanitize_text_field( $_POST['input'] );
102 // Check protection type.
103 switch ( $protection ) {
104 case 'full':
105 $password = get_post_meta( $post_id, 'passster_password', true );
106
107 if ( !empty($password) && $input === $password ) {
108 $response = array(
109 'success' => true,
110 'content' => $content,
111 );
112 do_action( 'passster_validation_success', $input );
113 }
114
115 break;
116 case 'area':
117 $area_id = esc_html( $_POST['area'] );
118 $password = get_post_meta( $area_id, 'passster_password', true );
119
120 if ( !empty($area_id) && !empty($password) && $input === $password ) {
121 $area = get_post( $area_id );
122 $content = apply_filters( 'passster_compatibility_actions', $area->post_content, $area_id );
123 $response = array(
124 'success' => true,
125 'content' => $content,
126 );
127 do_action( 'passster_validation_success', $input );
128 }
129
130 break;
131 default:
132 $content = apply_filters( 'passster_compatibility_actions', PS_Helper::get_shortcode_content( $content, $input ) );
133
134 if ( !empty($content) ) {
135 $response = array(
136 'success' => true,
137 'content' => $content,
138 );
139 do_action( 'passster_validation_success', $input );
140 } elseif ( 'on' === $options['toggle_ajax'] ) {
141 $response = array(
142 'success' => true,
143 );
144 do_action( 'passster_validation_success', $input );
145 }
146
147 }
148 print wp_json_encode( $response );
149 exit;
150 break;
151 case 'captcha':
152 $captcha = sanitize_text_field( $_POST['captcha'] );
153
154 if ( isset( $captcha ) && !empty($captcha) ) {
155 if ( 'full' !== $protection ) {
156
157 if ( 'area' === $protection ) {
158 $area_id = esc_html( $_POST['area'] );
159
160 if ( isset( $area_id ) && !empty($area_id) ) {
161 $area = get_post( $area_id );
162 $content = apply_filters( 'passster_compatibility_actions', $area->post_content, $area_id );
163 }
164
165 } else {
166 $content = apply_filters( 'passster_compatibility_actions', PS_Helper::get_shortcode_content( $content, 'captcha' ) );
167 }
168
169 }
170 $response = array(
171 'success' => true,
172 'content' => $content,
173 );
174 print wp_json_encode( $response );
175 exit;
176 }
177
178 break;
179 }
180 print wp_json_encode( $response );
181 exit;
182 }
183
184 /**
185 * Render the passster shortcode
186 *
187 * @param array $atts array of attributes.
188 * @param string $content the current content.
189 * @return string
190 */
191 public function render_shortcode( $atts, $content = null )
192 {
193 // check if valid before restrict anything.
194 $valid = PS_Conditional::is_valid( $atts );
195 if ( $valid ) {
196
197 if ( isset( $atts['area'] ) && !empty($atts['area']) ) {
198 $area = get_post( $atts['area'] );
199 $content = apply_filters( 'passster_compatibility_actions', $area->post_content, $atts['area'] );
200 return apply_filters( 'the_content', str_replace( '{post-id}', get_the_id(), $content ) );
201 } else {
202 $content = apply_filters( 'the_content', $content );
203 return apply_filters( 'passster_content', $content );
204 }
205
206 }
207 // do nothing if no atts.
208 if ( !isset( $atts ) || empty($atts) ) {
209 return;
210 }
211 // Password.
212
213 if ( isset( $atts['password'] ) ) {
214 $form = PS_Form::get_password_form();
215 $form = str_replace( '[PASSSTER_TYPE]', 'password', $form );
216 }
217
218 // Captcha.
219 if ( isset( $atts['captcha'] ) ) {
220 $form = PS_Form::get_captcha_form();
221 }
222 // Area.
223 if ( isset( $atts['area'] ) ) {
224 $form = str_replace( '[PASSSTER_AREA]', $atts['area'], $form );
225 }
226 // Page.
227
228 if ( isset( $atts['protection'] ) ) {
229 $form = str_replace( '[PASSSTER_PROTECTION]', 'full', $form );
230 } else {
231 if ( isset( $atts['area'] ) ) {
232 $form = str_replace( '[PASSSTER_PROTECTION]', 'area', $form );
233 }
234 }
235
236 // headline.
237
238 if ( isset( $atts['headline'] ) ) {
239 $form = str_replace( '[PASSSTER_FORM_HEADLINE]', $atts['headline'], $form );
240 } else {
241 $form = str_replace( '[PASSSTER_FORM_HEADLINE]', get_theme_mod( 'passster_form_instructions_headline', __( 'Protected Area', 'content-protector' ) ), $form );
242 }
243
244 // instruction.
245
246 if ( isset( $atts['instruction'] ) ) {
247 $form = str_replace( '[PASSSTER_FORM_INSTRUCTIONS]', $atts['instruction'], $form );
248 } else {
249 $form = str_replace( '[PASSSTER_FORM_INSTRUCTIONS]', get_theme_mod( 'passster_form_instructions_text', __( 'This content is password-protected. Please verify with a password to unlock the content.', 'content-protector' ) ), $form );
250 }
251
252 // placeholder.
253
254 if ( isset( $atts['placeholder'] ) ) {
255 $form = str_replace( '[PASSSTER_PLACEHOLDER]', $atts['placeholder'], $form );
256 } else {
257 $form = str_replace( '[PASSSTER_PLACEHOLDER]', get_theme_mod( 'passster_form_instructions_placeholder', __( 'Enter your password..', 'content-protector' ) ), $form );
258 }
259
260 // button.
261
262 if ( isset( $atts['button'] ) ) {
263 $form = str_replace( '[PASSSTER_BUTTON_LABEL]', $atts['button'], $form );
264 } else {
265 $form = str_replace( '[PASSSTER_BUTTON_LABEL]', get_theme_mod( 'passster_form_button_label', __( 'Submit', 'content-protector' ) ), $form );
266 }
267
268 // modify id.
269
270 if ( isset( $atts['id'] ) ) {
271 $form = str_replace( '[PASSSTER_ID]', 'ps-' . $atts['id'], $form );
272 } else {
273 $form = str_replace( '[PASSSTER_ID]', 'ps-' . wp_rand( 10, 1000 ), $form );
274 }
275
276 // hide or not.
277
278 if ( isset( $atts['hide'] ) && true == $atts['hide'] ) {
279 $form = str_replace( '[PASSSTER_HIDE]', ' passster-hide', $form );
280 } else {
281 $form = str_replace( '[PASSSTER_HIDE]', '', $form );
282 }
283
284 // ACF field.
285
286 if ( isset( $atts['acf'] ) && true == $atts['acf'] ) {
287 $form = str_replace( '[PASSSTER_ACF]', ' data-acf="' . $atts['acf'] . '"', $form );
288 } else {
289 $form = str_replace( '[PASSSTER_ACF]', '', $form );
290 }
291
292 // set AMP header.
293 if ( isset( $atts['amp'] ) ) {
294 PS_Helper::set_amp_headers( $atts['amp'], $atts['password'] );
295 }
296 return $form;
297 }
298
299 /**
300 * Filters the_content with Passster.
301 *
302 * @param string $content given content.
303 * @return string
304 */
305 public function filter_the_content( $content )
306 {
307 $post_id = get_the_id();
308 $activate_protection = get_post_meta( $post_id, 'passster_activate_protection', true );
309 // user restriction.
310 $user_restriction_type = get_post_meta( $post_id, 'passster_user_restriction_type', true );
311 $user_restriction = get_post_meta( $post_id, 'passster_user_restriction', true );
312 // texts.
313 $headline = get_post_meta( $post_id, 'passster_headline', true );
314 $instruction = get_post_meta( $post_id, 'passster_instruction', true );
315 $placeholder = get_post_meta( $post_id, 'passster_placeholder', true );
316 $button = get_post_meta( $post_id, 'passster_button', true );
317 $id = get_post_meta( $post_id, 'passster_id', true );
318 if ( !$activate_protection ) {
319 return $content;
320 }
321 // build atts array to validate.
322 $atts = array();
323 $protection_type = get_post_meta( $post_id, 'passster_protection_type', true );
324 switch ( $protection_type ) {
325 case 'password':
326 $password = get_post_meta( $post_id, 'passster_password', true );
327 $atts['password'] = $password;
328 $shortcode = '[passster password="' . $password . '" protection="full" ';
329 break;
330 case 'captcha':
331 $atts['captcha'] = true;
332 $shortcode = '[passster captcha="true" protection="full" ';
333 break;
334 }
335 $shortcode .= ']{content}[/passster]';
336 // check if valid before restrict anything.
337 $valid = PS_Conditional::is_valid( $atts );
338 if ( $valid ) {
339 return $content;
340 }
341 // replace placeholder with content.
342 $shortcode = str_replace( '{content}', $content, $shortcode );
343 return do_shortcode( $shortcode );
344 }
345
346 /**
347 * Enqueue scripts for shortcode
348 *
349 * @return void
350 */
351 public function add_public_scripts()
352 {
353 $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min' );
354 $advanced_options = wp_parse_args( get_option( 'passster_advanced_settings' ), PS_ADMIN::get_defaults( 'passster_advanced_settings' ) );
355 $general_options = wp_parse_args( get_option( 'passster_general_settings' ), PS_ADMIN::get_defaults( 'passster_general_settings' ) );
356 wp_enqueue_style(
357 'passster-public',
358 PASSSTER_URL . '/assets/public/passster-public' . $suffix . '.css',
359 '3.3.8',
360 'all'
361 );
362 wp_enqueue_script(
363 'passster-cookie',
364 PASSSTER_URL . '/assets/public/cookie.js',
365 array( 'jquery' ),
366 '3.3.8',
367 false
368 );
369 wp_enqueue_script(
370 'passster-captcha',
371 PASSSTER_URL . '/assets/public/captcha.js',
372 array(),
373 '3.3.8',
374 false
375 );
376 wp_enqueue_script(
377 'passster-public',
378 PASSSTER_URL . '/assets/public/passster-public' . $suffix . '.js',
379 array( 'jquery', 'passster-cookie', 'passster-captcha' ),
380 '3.3.8.8',
381 false
382 );
383 // pre-render shortcodes if options set.
384 $shortcodes = array();
385
386 if ( isset( $general_options['third_party_shortcodes'] ) && !empty($general_options['third_party_shortcodes']) ) {
387 $shortcodes_in_options = explode( ',', $general_options['third_party_shortcodes'] );
388 if ( is_array( $shortcodes_in_options ) ) {
389 foreach ( $shortcodes_in_options as $shortcode ) {
390 $shortcodes[$shortcode] = do_shortcode( str_replace( '{post-id}', get_the_id(), $shortcode ) );
391 }
392 }
393 }
394
395 wp_localize_script( 'passster-public', 'ps_ajax', array(
396 'ajax_url' => admin_url() . 'admin-ajax.php',
397 'days' => $general_options['passster_cookie_duration'],
398 'use_cookie' => $general_options['toggle_cookie'],
399 'no_ajax' => $general_options['toggle_ajax'],
400 'nonce' => wp_create_nonce( 'ps-password-nonce' ),
401 'post_id' => get_the_id(),
402 'captcha_error' => get_theme_mod( 'passster_form_error_text', __( 'Sorry, your captcha solution was wrong.', 'content-protector' ) ),
403 'recaptcha_key' => '',
404 'shortcodes' => $shortcodes,
405 ) );
406 // if amp used.
407 if ( isset( $general_options['toggle_amp'] ) && 'on' == $general_options['toggle_amp'] ) {
408 wp_enqueue_script(
409 'passster-amp',
410 'https://cdn.ampproject.org/v0/amp-form-0.1.js',
411 array( 'jquery' ),
412 '3.2',
413 false
414 );
415 }
416 // if password type hint used.
417 $password_typing = get_theme_mod( 'passster_form_instructions_password_typing' );
418 if ( isset( $password_typing ) && true === $password_typing ) {
419 wp_enqueue_script(
420 'password-typing',
421 PASSSTER_URL . '/assets/public/password-typing.js',
422 array( 'jquery' ),
423 '3.2',
424 false
425 );
426 }
427 }
428
429 /**
430 * Adding compatibility modifications before ajax output.
431 *
432 * @param string $content current content.
433 * @return string
434 */
435 public function add_compatibilities( $content, $post_id = null )
436 {
437 if ( is_null( $post_id ) ) {
438 $post_id = get_the_id();
439 }
440 // use meta field instead.
441 $use_meta = apply_filters( 'passster_use_meta_field', false );
442
443 if ( $use_meta ) {
444 $meta_key = apply_filters( 'passster_meta_key', 'field_name' );
445 $content = get_post_meta( $post_id, $meta_key, true );
446 }
447
448 // use meta field instead.
449 $use_acf = apply_filters( 'passster_use_acf_field', false );
450
451 if ( $use_acf ) {
452 $meta_key = apply_filters( 'passster_acf_key', 'field_name' );
453 $content = get_field( $meta_key, $post_id );
454 }
455
456 // Tablepress.
457
458 if ( class_exists( 'TablePress' ) ) {
459 \TablePress::$controller = \TablePress::load_controller( 'frontend' );
460 \TablePress::$controller->init_shortcodes();
461 }
462
463 // prepare for Visual Composer.
464 if ( class_exists( 'WPBMap' ) ) {
465 \WPBMap::addAllMappedShortcodes();
466 }
467 // prepare for Elementor.
468 if ( class_exists( '\\Elementor\\Plugin' ) ) {
469 if ( \Elementor\Plugin::$instance->db->is_built_with_elementor( $post_id ) ) {
470 $content = \Elementor\Plugin::$instance->frontend->get_builder_content( $post_id, true );
471 }
472 }
473 // Skip shortcodes.
474 remove_filter( 'the_content', 'do_shortcode', 11 );
475 $content = apply_filters( 'the_content', $content );
476 add_filter( 'the_content', 'do_shortcode', 11 );
477 return $content;
478 }
479
480 /**
481 * Add ajax support for Divi builder.
482 *
483 * @param array $actions array of allowed actions.
484 * @return array
485 */
486 public function add_divi_support( $actions )
487 {
488 $actions[] = 'validate_input';
489 return $actions;
490 }
491
492 /**
493 * Redirect if global protection is activated and no password is set.
494 *
495 * @return void
496 */
497 public function check_global_proctection()
498 {
499 $post_id = get_option( 'passster_global_id' );
500 $atts = array();
501 // Build $atts array based on protection settings.
502 $protection_type = get_post_meta( $post_id, 'passster_protection_type', true );
503 switch ( $protection_type ) {
504 case 'password':
505 $password = get_post_meta( $post_id, 'passster_password', true );
506 $atts['password'] = $password;
507 break;
508 case 'captcha':
509 $atts['captcha'] = true;
510 break;
511 }
512
513 if ( !empty($post_id) ) {
514 $global_protection_active = get_post_meta( $post_id, 'passster_activate_global_protection', true );
515
516 if ( true == $global_protection_active ) {
517 if ( is_page( $post_id ) || is_single( $post_id ) ) {
518 return;
519 }
520 // Check if cookie is set.
521
522 if ( empty($_COOKIE['passster']) || !PS_Conditional::is_valid( $atts ) ) {
523 $global_protection_url = get_permalink( $post_id );
524 wp_redirect( esc_url_raw( $global_protection_url ) );
525 exit;
526 }
527
528 }
529
530 }
531
532 }
533
534 /**
535 * Protect a WooCommerce product.
536 *
537 * @return void
538 */
539 public function protect_product()
540 {
541 $post_id = get_the_id();
542 $activate_protection = get_post_meta( $post_id, 'passster_activate_protection', true );
543 // user restriction.
544 $user_restriction_type = get_post_meta( $post_id, 'passster_user_restriction_type', true );
545 $user_restriction = get_post_meta( $post_id, 'passster_user_restriction', true );
546 // texts.
547 $headline = get_post_meta( $post_id, 'passster_headline', true );
548 $instruction = get_post_meta( $post_id, 'passster_instruction', true );
549 $placeholder = get_post_meta( $post_id, 'passster_placeholder', true );
550 $button = get_post_meta( $post_id, 'passster_button', true );
551 $id = get_post_meta( $post_id, 'passster_id', true );
552 if ( !$activate_protection ) {
553 return;
554 }
555 // build atts array to validate.
556 $atts = array();
557 $protection_type = get_post_meta( $post_id, 'passster_protection_type', true );
558 switch ( $protection_type ) {
559 case 'password':
560 $password = get_post_meta( $post_id, 'passster_password', true );
561 $atts['password'] = $password;
562 $shortcode = '[passster password="' . $password . '" protection="full" ';
563 break;
564 case 'captcha':
565 $atts['captcha'] = true;
566 $shortcode = '[passster captcha="true" protection="full" ';
567 break;
568 }
569 $shortcode .= ']{content}[/passster]';
570 // check if valid before restrict anything.
571 $valid = PS_Conditional::is_valid( $atts );
572
573 if ( !$valid ) {
574 // replace placeholder with content.
575 $shortcode = str_replace( '{content}', $content, $shortcode );
576 echo do_shortcode( $shortcode ) ;
577 add_filter( 'woocommerce_is_purchasable', '__return_false' );
578 // unhook allwoocommerce_before_single_product_summary.
579 remove_action( 'woocommerce_before_single_product_summary', 'woocommerce_show_product_sale_flash', 10 );
580 remove_action( 'woocommerce_before_single_product_summary', 'woocommerce_show_product_images', 20 );
581 // unhook woocommerce_single_product_summary.
582 remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_title', 5 );
583 remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_rating', 10 );
584 remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );
585 remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_excerpt', 20 );
586 remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
587 remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_meta', 40 );
588 remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_sharing', 50 );
589 // unhook woocommerce_after_single_product_summary.
590 remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_product_data_tabs', 10 );
591 remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_upsell_display', 15 );
592 remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20 );
593 // Unhook German Market strings.
594 add_filter(
595 'wgm_product_summary_parts_after',
596 function ( $output_parts, $product, $hook ) {
597 unset( $output_parts['shipping'] );
598 unset( $output_parts['tax'] );
599 unset( $output_parts['ppu'] );
600 return $output_parts;
601 },
602 50,
603 3
604 );
605 // Unhook Germanized strings.
606 add_filter( 'pre_option_woocommerce_gzd_display_product_detail_tax_info', function () {
607 return 'no';
608 } );
609 add_filter( 'pre_option_woocommerce_gzd_display_single_product_unit_price', function () {
610 return 'no';
611 } );
612 add_filter( 'pre_option_woocommerce_gzd_display_product_detail_shipping_costs_info', function () {
613 return 'no';
614 } );
615 add_filter( 'pre_option_woocommerce_gzd_display_single_product_delivery_time', function () {
616 return 'no';
617 } );
618 add_filter( 'pre_option_woocommerce_gzd_display_single_product_units', function () {
619 return 'no';
620 } );
621 }
622
623 }
624
625 }