| @@ -44,8 +44,22 @@ | ||
| 44 | 44 | return self::$instance; |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | 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 | + /** | |
| 48 | 62 | * Render the Passster shortcode. |
| 49 | 63 | * |
| 50 | 64 | * @param array $atts array of attributes. |
| 51 | 65 | * @param string|null $content the current content. |
| @@ -70,9 +84,9 @@ | ||
| 70 | 84 | } |
| 71 | 85 | if ( !$in_schedule ) { |
| 72 | 86 | $area = get_post( $area_id ); |
| 73 | 87 | if ( $area && ('publish' === $area->post_status || current_user_can( 'edit_post', $area_id )) ) { |
| 74 | - return apply_filters( 'the_content', str_replace( '{post-id}', get_the_id(), $area->post_content ) ); | |
| 88 | + return $this->render_unlocked_content( str_replace( '{post-id}', get_the_id(), $area->post_content ) ); | |
| 75 | 89 | } |
| 76 | 90 | return $content ?? ''; |
| 77 | 91 | } |
| 78 | 92 | } |
| @@ -86,12 +100,12 @@ | ||
| 86 | 100 | $area = get_post( $area_id ); |
| 87 | 101 | if ( 'publish' === $area->post_status || current_user_can( 'edit_post', $area_id ) ) { |
| 88 | 102 | $content = $area->post_content; |
| 89 | 103 | do_action( 'passster_content_unlocked' ); |
| 90 | - return apply_filters( 'the_content', str_replace( '{post-id}', get_the_id(), $content ) ); | |
| 104 | + return $this->render_unlocked_content( str_replace( '{post-id}', get_the_id(), $content ) ); | |
| 91 | 105 | } |
| 92 | 106 | } else { |
| 93 | - $content = apply_filters( 'the_content', $content ); | |
| 107 | + $content = $this->render_unlocked_content( $content ); | |
| 94 | 108 | do_action( 'passster_content_unlocked' ); |
| 95 | 109 | return apply_filters( 'passster_content', $content ); |
| 96 | 110 | } |
| 97 | 111 | } |
| @@ -178,8 +192,11 @@ | ||
| 178 | 192 | $form = str_replace( '[PASSSTER_POST_ID]', absint( get_the_ID() ), $form ); |
| 179 | 193 | // term id (for category archive protection — passed to REST API so it can validate against term meta). |
| 180 | 194 | $term_id_val = ( !empty( $atts['term_id'] ) ? absint( $atts['term_id'] ) : 0 ); |
| 181 | 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 ); | |
| 182 | 199 | // hide or not. |
| 183 | 200 | if ( !empty( $atts['hide'] ) ) { |
| 184 | 201 | $form = str_replace( '[PASSSTER_HIDE]', ' passster-hide', $form ); |
| 185 | 202 | } else { |
| @@ -380,8 +397,12 @@ | ||
| 380 | 397 | $shortcodes[$shortcode] = do_shortcode( str_replace( '{post-id}', get_the_id(), $shortcode ) ); |
| 381 | 398 | } |
| 382 | 399 | } |
| 383 | 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' ) ) ); | |
| 384 | 405 | $args = array( |
| 385 | 406 | 'ajax_url' => admin_url() . 'admin-ajax.php', |
| 386 | 407 | 'rest_url' => get_rest_url(), |
| 387 | 408 | 'nonce' => wp_create_nonce( 'ps-password-nonce' ), |
| @@ -386,11 +407,11 @@ | ||
| 386 | 407 | 'rest_url' => get_rest_url(), |
| 387 | 408 | 'nonce' => wp_create_nonce( 'ps-password-nonce' ), |
| 388 | 409 | 'hash_nonce' => wp_create_nonce( 'ps-hash-nonce' ), |
| 389 | 410 | 'logout_nonce' => wp_create_nonce( 'ps-logout-nonce' ), |
| 390 | - 'post_id' => get_the_id(), | |
| 411 | + 'post_id' => $current_post_id, | |
| 391 | 412 | 'shortcodes' => $shortcodes, |
| 392 | - 'permalink' => get_permalink( get_the_id() ), | |
| 413 | + 'permalink' => $reload_url, | |
| 393 | 414 | ); |
| 394 | 415 | if ( isset( $options['cookie_duration_unit'] ) ) { |
| 395 | 416 | $args['cookie_duration_unit'] = esc_html( $options['cookie_duration_unit'] ); |
| 396 | 417 | } else { |