Skip to content

Commit

Permalink
Merge pull request #2408 from rebeccahum/rebecca/feature_password-pro…
Browse files Browse the repository at this point in the history
…tected-posts

Account for password protected posts via protected_content feature
  • Loading branch information
felipeelia authored Dec 3, 2021
2 parents 12e0036 + 8e30ded commit 3608190
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 3 deletions.
89 changes: 86 additions & 3 deletions includes/classes/Feature/ProtectedContent/ProtectedContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
class ProtectedContent extends Feature {

/**
* Initialize feature setting it's config
* Initialize feature setting its config
*
* @since 3.0
*/
Expand All @@ -45,8 +45,16 @@ public function __construct() {
public function setup() {
add_filter( 'ep_indexable_post_status', [ $this, 'get_statuses' ] );
add_filter( 'ep_indexable_post_types', [ $this, 'post_types' ], 10, 1 );
add_filter( 'ep_admin_wp_query_integration', '__return_true' );
add_action( 'pre_get_posts', [ $this, 'integrate' ] );
add_filter( 'ep_post_formatted_args', [ $this, 'exclude_protected_posts' ], 10, 2 );
add_filter( 'ep_index_posts_args', [ $this, 'query_password_protected_posts' ] );
add_filter( 'ep_post_sync_args', [ $this, 'include_post_password' ], 10, 2 );
add_filter( 'ep_search_post_return_args', [ $this, 'return_post_password' ] );

if ( is_admin() ) {
add_filter( 'ep_admin_wp_query_integration', '__return_true' );
add_action( 'pre_get_posts', [ $this, 'integrate' ] );
add_filter( 'ep_post_query_db_args', [ $this, 'query_password_protected_posts' ] );
}

if ( Features::factory()->get_registered_feature( 'comments' )->is_active() ) {
add_filter( 'ep_indexable_comment_status', [ $this, 'get_comment_statuses' ] );
Expand Down Expand Up @@ -180,6 +188,81 @@ public function integrate( $query ) {
remove_filter( 'ep_formatted_args', [ $search_feature, 'weight_recent' ], 10 );
}

/**
* Query all posts with and without password for indexing.
*
* @since 4.0.0
*
* @param array $args Database arguments
* @return array
*/
public function query_password_protected_posts( $args ) {
$args['has_password'] = null;

return $args;
}

/**
* Include post password when indexing.
*
* @since 4.0.0
*
* @param array $post_args Post arguments
* @param int $post_id Post ID
* @return array
*/
public function include_post_password( $post_args, $post_id ) {
$post = get_post( $post_id );

// Assign null value so we can use the EXISTS filter.
$post_args['post_password'] = ! empty( $post->post_password ) ? $post->post_password : null;

return $post_args;
}

/**
* Exclude proctected post from the frontend queries.
*
* @since 4.0.0
*
* @param array $formatted_args Formatted Elasticsearch query
* @param array $args Query variables
* @return array
*/
public function exclude_protected_posts( $formatted_args, $args ) {
if ( empty( $args['has_password'] ) ) {
/**
* Filter to exclude protected posts from search.
*
* @hook ep_exclude_password_protected_from_search
* @param {bool} $exclude Exclude post from search.
* @return {bool}
*/
if ( ! is_user_logged_in() && apply_filters( 'ep_exclude_password_protected_from_search', true ) ) {
$formatted_args['post_filter']['bool']['must_not'][] = array(
'exists' => array(
'field' => 'post_password',
),
);
}
}

return $formatted_args;
}

/**
* Add post_password to post object properties set after query
*
* @since 4.0.0
*
* @param array $properties Post properties
* @return array
*/
public function return_post_password( $properties ) {
$properties[] = 'post_password';
return $properties;
}

/**
* Integrate EP into comment queries
*
Expand Down
1 change: 1 addition & 0 deletions includes/classes/Indexable/Post/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public function query_db( $args ) {
'order' => 'desc',
'no_found_rows' => false,
'ep_indexing_advanced_pagination' => true,
'has_password' => false,
];

if ( isset( $args['per_page'] ) ) {
Expand Down
3 changes: 3 additions & 0 deletions includes/mappings/post/5-2.php
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,9 @@
'post_excerpt' => array(
'type' => 'text',
),
'post_password' => array(
'type' => 'text',
),
'post_content' => array(
'type' => 'text',
),
Expand Down
3 changes: 3 additions & 0 deletions includes/mappings/post/7-0.php
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@
'post_excerpt' => array(
'type' => 'text',
),
'post_password' => array(
'type' => 'text',
),
'post_content' => array(
'type' => 'text',
),
Expand Down
151 changes: 151 additions & 0 deletions tests/php/features/TestProtectedContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -229,4 +229,155 @@ public function testAdminCategories() {
$this->assertEquals( 2, $query->post_count );
$this->assertEquals( 2, $query->found_posts );
}

/**
* Check if passwords on posts are synced when feature not active
*
* @since 4.0.0
* @group protected-content
*/
public function testNoSyncPasswordedPost() {
add_filter( 'ep_post_sync_args', array( $this, 'filter_post_sync_args' ), 10, 1 );

$post_id = Functions\create_and_sync_post( array( 'post_password' => 'test' ) );

ElasticPress\Elasticsearch::factory()->refresh_indices();

// Check if ES post sync filter has been triggered
$this->assertNotEmpty( $this->applied_filters['ep_post_sync_args'] );

// Check if password was synced
$post = ElasticPress\Indexables::factory()->get( 'post' )->get( $post_id );

$this->assertArrayNotHasKey( 'post_password', $post );
}

/**
* Check if passwords on posts are synced when feature active
*
* @since 4.0.0
* @group protected-content
*/
public function testSyncPasswordedPost() {
ElasticPress\Features::factory()->activate_feature( 'protected_content' );
ElasticPress\Features::factory()->setup_features();

add_filter( 'ep_post_sync_args', array( $this, 'filter_post_sync_args' ), 10, 1 );

$post_id = Functions\create_and_sync_post( array( 'post_password' => 'test' ) );

ElasticPress\Elasticsearch::factory()->refresh_indices();

// Check if ES post sync filter has been triggered
$this->assertNotEmpty( $this->applied_filters['ep_post_sync_args'] );

// Check if password was synced
$post = ElasticPress\Indexables::factory()->get( 'post' )->get( $post_id );
$this->assertEquals( 'test', $post['post_password'] );

// Remove password from post
wp_update_post(
array(
'ID' => $post_id,
'post_password' => '',
) );

ElasticPress\Indexables::factory()->get( 'post' )->index( $post_id, true );
ElasticPress\Elasticsearch::factory()->refresh_indices();

$post = ElasticPress\Indexables::factory()->get( 'post' )->get( $post_id );

// Check if password was removed on sync
$this->assertEmpty( $post['post_password'] );

// Add back password on post
wp_update_post(
array(
'ID' => $post_id,
'post_password' => 'test',
) );

ElasticPress\Indexables::factory()->get( 'post' )->index( $post_id, true );
ElasticPress\Elasticsearch::factory()->refresh_indices();

$post = ElasticPress\Indexables::factory()->get( 'post' )->get( $post_id );

// Check if password was added back on sync
$this->assertEquals( 'test', $post['post_password'] );
}

/**
* Check if password protected post shows up in admin
*
* @since 4.0.0
* @group protected-content
*/
public function testAdminPasswordedPost() {
set_current_screen( 'edit.php' );

ElasticPress\Features::factory()->activate_feature( 'protected_content' );
ElasticPress\Features::factory()->setup_features();

Functions\create_and_sync_post(
array(
'post_content' => 'findme 123',
'post_password' => 'test'
)
);

ElasticPress\Elasticsearch::factory()->refresh_indices();

$query = new \WP_Query();

global $wp_the_query;

$wp_the_query = $query;

$args = array(
's' => 'findme',
);

$query->query( $args );

$this->assertTrue( $query->elasticsearch_success );
$this->assertEquals( 1, $query->post_count );
$this->assertEquals( 1, $query->found_posts );
}

/**
* Check password protected post in front-end
*
* @since 4.0.0
* @group protected-content
*/
public function testFrontEndSearchPasswordedPost() {
set_current_screen( 'front' );

ElasticPress\Features::factory()->activate_feature( 'protected_content' );
ElasticPress\Features::factory()->activate_feature( 'search' );
ElasticPress\Features::factory()->setup_features();

// Need to call this since it's hooked to init
ElasticPress\Features::factory()->get_registered_feature( 'search' )->search_setup();

Functions\create_and_sync_post(
array(
'post_content' => 'findme 123',
'post_password' => 'test',
)
);
ElasticPress\Elasticsearch::factory()->refresh_indices();

$query = new \WP_Query(
array(
's' => 'findme',
)
);

$this->assertTrue( $query->elasticsearch_success );

// Password post is expected to return as we are logged in.
$this->assertEquals( 1, $query->post_count );
$this->assertEquals( 1, $query->found_posts );
}
}

0 comments on commit 3608190

Please sign in to comment.