: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Contains instance or null
private static $instance = null ;
* Constructor for PS_Public
public function __construct()
add_action( 'wp_enqueue_scripts', array( $this, 'add_public_scripts' ) );
add_action( 'wp_ajax_validate_input', array( $this, 'validate_input' ) );
add_action( 'wp_ajax_nopriv_validate_input', array( $this, 'validate_input' ) );
add_action( 'wp_ajax_hash_password', array( $this, 'hash_password' ) );
add_action( 'wp_ajax_nopriv_hash_password', array( $this, 'hash_password' ) );
* Returns instance of PS_Public.
public static function get_instance()
if ( null === self::$instance ) {
self::$instance = new self();
* Validate ajax given input.
public function validate_input()
$options = get_option( 'passster' );
if ( !wp_verify_nonce( $_POST['nonce'], 'ps-password-nonce' ) ) {
'error' => 'Security check failed.',
print wp_json_encode( $response );
'error' => $options['error'],
// Check if input exists.
if ( !empty($_POST['input']) ) {
$input = sanitize_text_field( $_POST['input'] );
$remove_spaces = apply_filters( 'passster_remove_spaces_from_list', true );
$type = sanitize_text_field( $_POST['type'] );
$post_id = sanitize_text_field( $_POST['post_id'] );
$protection = sanitize_text_field( $_POST['protection'] );
if ( empty($protection) ) {
$post = get_post( $post_id );
$content = apply_filters( 'passster_compatibility_actions', $post->post_content, $post_id );
if ( !empty($_POST['acf']) ) {
$acf = esc_html( $_POST['acf'] );
$content = \get_field( $acf, $post_id );
if ( !empty($_POST['redirect']) ) {
$redirect = esc_url( $_POST['redirect'] );
$password = get_post_meta( $post_id, 'passster_password', true );
// Check protection type.
if ( !empty($password) && $input === $password ) {
$validation = $this->validate_full_protection(
if ( false !== $validation ) {
$area_id = esc_html( $_POST['area'] );
$password = get_post_meta( $area_id, 'passster_password', true );
if ( !empty($area_id) && !empty($password) && $input === $password ) {
$area = get_post( $area_id );
$validation = $this->validate_area_protection( $input, $area, $redirect );
if ( false !== $validation ) {
$content = apply_filters( 'passster_compatibility_actions', PS_Helper::get_shortcode_content( $content, $input ) );
$validation = $this->validate_shortcode_protection(
if ( false !== $validation ) {
print wp_json_encode( $response );
print wp_json_encode( $response );
* @param $input string given input password.
* @param $post object current post object.
* @param $content string given content.
* @param $redirect bool redirect or not.
public function validate_full_protection(
// Check that its published.
if ( 'publish' !== $post->post_status ) {
do_action( 'passster_validation_success', $input );
* @param $input string given password.
* @param $area object given area.
* @param $redirect bool redirect or not.
public function validate_area_protection( string $input, object $area, bool $redirect )
// Check that it is an area.
if ( 'protected_areas' !== $area->post_type ) {
// Check that its published.
if ( 'publish' !== $area->post_status ) {
$content = apply_filters( 'passster_compatibility_actions', $area->post_content, $area->ID );
do_action( 'passster_validation_success', $input );
* @param $input string given password.
* @param $content string current content.
* @param $redirect bool redirect or not.
* @param $options array given options.
* @return array|bool[]|false
public function validate_shortcode_protection(
if ( !empty($content) ) {
do_action( 'passster_validation_success', $input );
} elseif ( 'on' === $options['toggle_ajax'] ) {
do_action( 'passster_validation_success', $input );
* Hashing the password to store in a cookie.
public function hash_password()
if ( !wp_verify_nonce( $_POST['hash_nonce'], 'ps-hash-nonce' ) ) {
print wp_json_encode( array(
'error' => 'Security check failed.',
// Check if input exists.
if ( empty($_POST['password']) ) {
print wp_json_encode( array(
'error' => 'No password provided.',
'password' => hash_hmac( 'sha256', esc_html( $_POST['password'] ), get_option( 'passster_secure_key' ) ),
print wp_json_encode( $response );
* Enqueue scripts for shortcode
public function add_public_scripts()
$suffix = ( defined( SCRIPT_DEBUG ) && SCRIPT_DEBUG ? '' : '.min' );
$options = get_option( 'passster' );
PASSSTER_URL . '/assets/public/passster-public' . $suffix . '.css',
PASSSTER_URL . '/assets/public/cookie.js',
PASSSTER_URL . '/assets/public/passster-public' . $suffix . '.js',
array( 'jquery', 'passster-cookie' ),
if ( isset( $options['third_party_shortcodes'] ) && !empty($options['third_party_shortcodes']) ) {
$shortcodes_in_options = explode( ',', $options['third_party_shortcodes'] );
if ( is_array( $shortcodes_in_options ) ) {
foreach ( $shortcodes_in_options as $shortcode ) {
$shortcodes[$shortcode] = do_shortcode( str_replace( '{post-id}', get_the_id(), $shortcode ) );
'ajax_url' => admin_url() . 'admin-ajax.php',
'nonce' => wp_create_nonce( 'ps-password-nonce' ),
'hash_nonce' => wp_create_nonce( 'ps-hash-nonce' ),
'logout_nonce' => wp_create_nonce( 'ps-logout-nonce' ),
'post_id' => get_the_id(),
'shortcodes' => $shortcodes,
'permalink' => get_permalink( get_the_id() ),
if ( isset( $options['cookie_duration_unit'] ) ) {
$args['cookie_duration_unit'] = esc_html( $options['cookie_duration_unit'] );
$args['cookie_duration_unit'] = 'days';
if ( isset( $options['cookie_duration'] ) ) {
$args['cookie_duration'] = esc_html( $options['cookie_duration'] );
$args['cookie_duration'] = 1;
if ( isset( $options['disable_cookie'] ) ) {
$args['disable_cookie'] = esc_html( $options['disable_cookie'] );
$args['disable_cookie'] = false;
if ( isset( $options['unlock_mode'] ) ) {
$args['unlock_mode'] = esc_html( $options['unlock_mode'] );
$args['unlock_mode'] = false;
wp_localize_script( 'passster-public', 'ps_ajax', $args );
// if password type hint used.
$password_typing = $options['show_password'];
if ( $password_typing ) {
PASSSTER_URL . '/assets/public/password-typing.js',