Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions includes/Core/Util/Reset.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
namespace Google\Site_Kit\Core\Util;

use Google\Site_Kit\Context;
use Google\Site_Kit\Core\Email_Reporting\Email_Log;
use Google\Site_Kit\Core\Authentication\Authentication;
use Google\Site_Kit\Core\Permissions\Permissions;
use Google\Site_Kit\Core\REST_API\REST_Route;
Expand Down Expand Up @@ -113,12 +114,14 @@ public function all() {
$this->delete_user_options( 'site' );
$this->delete_post_meta( 'site' );
$this->delete_term_meta( 'site' );
$this->delete_posts( 'site' );

if ( $this->context->is_network_mode() ) {
$this->delete_options( 'network' );
$this->delete_user_options( 'network' );
$this->delete_post_meta( 'network' );
$this->delete_term_meta( 'network' );
$this->delete_posts( 'network' );
}

wp_cache_flush();
Expand Down Expand Up @@ -256,6 +259,67 @@ private function delete_term_meta( $scope ) {
}
}

/**
* Deletes all Site Kit custom post type posts.
*
* @since n.e.x.t
*
* @param string $scope Scope of the deletion ('site' or 'network').
*/
private function delete_posts( $scope ) {
$sites = array();
if ( 'network' === $scope ) {
$sites = get_sites(
array(
'fields' => 'ids',
'number' => 9999999,
)
);
} elseif ( 'site' === $scope ) {
$sites[] = get_current_blog_id();
} else {
return;
}

foreach ( $sites as $site_id ) {
$switched = false;

if ( get_current_blog_id() !== (int) $site_id ) {
// phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.switch_to_blog_switch_to_blog
switch_to_blog( $site_id );
$switched = true;
}

$posts_per_batch = 100;
do {
// phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.get_posts_get_posts
$post_ids = get_posts(
array(
'post_type' => Email_Log::POST_TYPE,
'post_status' => array(
Email_Log::STATUS_SENT,
Email_Log::STATUS_FAILED,
Email_Log::STATUS_SCHEDULED,
),
'fields' => 'ids',
'posts_per_page' => $posts_per_batch,
'no_found_rows' => true,
'orderby' => 'ID',
'order' => 'ASC',
)
);

foreach ( $post_ids as $post_id ) {
wp_delete_post( $post_id, true );
}
} while ( ! empty( $post_ids ) );

if ( $switched ) {
restore_current_blog();
}
}
}

/**
* Gets related REST routes.
*
Expand Down
146 changes: 146 additions & 0 deletions tests/phpunit/integration/Core/Util/ResetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
namespace Google\Site_Kit\Tests\Core\Util;

use Google\Site_Kit\Context;
use Google\Site_Kit\Core\Email_Reporting\Email_Log;
use Google\Site_Kit\Core\Permissions\Permissions;
use Google\Site_Kit\Core\Util\Reset;
use Google\Site_Kit\Tests\Exception\RedirectException;
Expand All @@ -36,6 +37,13 @@ class ResetTest extends TestCase {
*/
protected $context_with_mutable_input;

/**
* Indicates whether the email log post type and metadata were registered.
*
* @var bool
*/
protected $email_log_registered = false;

public function set_up() {
parent::set_up();

Expand All @@ -46,6 +54,15 @@ public function set_up() {
$this->context_with_mutable_input = new Context( GOOGLESITEKIT_PLUGIN_MAIN_FILE, new MutableInput() );
}

public function tear_down() {
if ( $this->email_log_registered ) {
$this->unregister_email_log_dependencies();
$this->email_log_registered = false;
}

parent::tear_down();
}

public function test_all() {
$context = new Context( GOOGLESITEKIT_PLUGIN_MAIN_FILE );
$this->assertFalse( $context->is_network_mode(), 'Context should not be in network mode by default.' );
Expand Down Expand Up @@ -79,6 +96,35 @@ public function test_all() {
$this->assertEquals( '', get_term_meta( $term_id, 'googlesitekit_keep', true ), 'Term meta with underscore should be deleted.' );
}

public function test_all_deletes_email_log_posts() {
$this->register_email_log_dependencies();

$context = new Context( GOOGLESITEKIT_PLUGIN_MAIN_FILE );

$first_log = $this->factory()->post->create(
array(
'post_type' => Email_Log::POST_TYPE,
'post_status' => Email_Log::STATUS_SCHEDULED,
)
);
add_post_meta( $first_log, Email_Log::META_BATCH_ID, 'batch-a' );

$second_log = $this->factory()->post->create(
array(
'post_type' => Email_Log::POST_TYPE,
'post_status' => Email_Log::STATUS_FAILED,
)
);
add_post_meta( $second_log, Email_Log::META_SEND_ATTEMPTS, 2 );

$this->run_reset( $context );

$this->assertNull( get_post( $first_log ), 'Email log posts should be deleted after reset.' );
$this->assertNull( get_post( $second_log ), 'Email log posts should be deleted after reset.' );
$this->assertFalse( metadata_exists( 'post', $first_log, Email_Log::META_BATCH_ID ), 'Email log post meta should be deleted after reset.' );
$this->assertFalse( metadata_exists( 'post', $second_log, Email_Log::META_SEND_ATTEMPTS ), 'Email log post meta should be deleted after reset.' );
}

/**
* @group ms-required
*/
Expand All @@ -94,6 +140,67 @@ public function test_network_mode_all() {
$this->run_reset( $context );
}

/**
* @group ms-required
*/
public function test_network_mode_all_deletes_email_log_posts() {
$this->network_activate_site_kit();
add_filter( 'googlesitekit_is_network_mode', '__return_true' );

$this->register_email_log_dependencies();

$context = new Context( GOOGLESITEKIT_PLUGIN_MAIN_FILE );
$this->assertTrue( $context->is_network_mode(), 'Context should be in network mode when filter is enabled.' );

$blog_ids = array(
get_current_blog_id(),
$this->factory()->blog->create(),
);

$email_logs = array();
foreach ( $blog_ids as $blog_id ) {
$switched = false;

if ( get_current_blog_id() !== (int) $blog_id ) {
// phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.switch_to_blog_switch_to_blog
switch_to_blog( $blog_id );
$switched = true;
}

$email_logs[ $blog_id ] = $this->factory()->post->create(
array(
'post_type' => Email_Log::POST_TYPE,
'post_status' => Email_Log::STATUS_FAILED,
)
);
add_post_meta( $email_logs[ $blog_id ], Email_Log::META_BATCH_ID, 'network-batch' );

if ( $switched ) {
restore_current_blog();
}
}

$this->run_reset( $context );

foreach ( $blog_ids as $blog_id ) {
$switched = false;

if ( get_current_blog_id() !== (int) $blog_id ) {
// phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.switch_to_blog_switch_to_blog
switch_to_blog( $blog_id );
$switched = true;
}

$log_id = $email_logs[ $blog_id ];
$this->assertNull( get_post( $log_id ), 'Email log posts in each site should be deleted after reset.' );
$this->assertFalse( metadata_exists( 'post', $log_id, Email_Log::META_BATCH_ID ), 'Email log post meta should be deleted for every site after reset.' );

if ( $switched ) {
restore_current_blog();
}
}
}

public function test_handle_reset_action_with_bad_nonce() {
remove_all_actions( 'admin_action_' . Reset::ACTION );
$reset = new Reset( $this->context_with_mutable_input );
Expand Down Expand Up @@ -206,4 +313,43 @@ protected function run_reset( Context $context ) {
$this->assertUserOptionsDeleted( $user_id, $is_network_mode );
$this->assertTransientsDeleted( $is_network_mode );
}

private function register_email_log_dependencies() {
if ( $this->email_log_registered ) {
return;
}

$email_log = new Email_Log( new Context( GOOGLESITEKIT_PLUGIN_MAIN_FILE ) );
$register_method = new \ReflectionMethod( Email_Log::class, 'register_email_log' );
$register_method->setAccessible( true );
$register_method->invoke( $email_log );

$this->email_log_registered = true;
}

private function unregister_email_log_dependencies() {
if ( function_exists( 'unregister_post_type' ) && post_type_exists( Email_Log::POST_TYPE ) ) {
call_user_func( 'unregister_post_type', Email_Log::POST_TYPE );
}

if ( function_exists( 'unregister_post_status' ) ) {
foreach ( array( Email_Log::STATUS_SENT, Email_Log::STATUS_FAILED, Email_Log::STATUS_SCHEDULED ) as $status ) {
call_user_func( 'unregister_post_status', $status );
}
}

if ( function_exists( 'unregister_meta_key' ) ) {
foreach (
array(
Email_Log::META_REPORT_FREQUENCY,
Email_Log::META_BATCH_ID,
Email_Log::META_SEND_ATTEMPTS,
Email_Log::META_ERROR_DETAILS,
Email_Log::META_REPORT_REFERENCE_DATES,
) as $meta_key
) {
call_user_func( 'unregister_meta_key', 'post', Email_Log::POST_TYPE, $meta_key );
}
}
}
}