Skip to content

Commit

Permalink
Add uninstall.php which deletes all URL Metrics posts
Browse files Browse the repository at this point in the history
  • Loading branch information
westonruter committed Mar 18, 2024
1 parent 21a5cec commit a52e0ce
Show file tree
Hide file tree
Showing 4 changed files with 212 additions and 18 deletions.
38 changes: 38 additions & 0 deletions plugins/optimization-detective/class-od-url-metrics-post-type.php
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,42 @@ static function ( OD_URL_Metric $url_metric ): array {

return $result;
}

/**
* Deletes all URL Metrics posts.
*
* This is used during uninstallation.
*
* @since 0.1.0
* @access private
*/
public static function delete_all_posts() {
global $wpdb;

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching

// Delete all related post meta for URL Metrics posts.
$wpdb->query(
$wpdb->prepare(
"
DELETE meta
FROM $wpdb->postmeta AS meta
INNER JOIN $wpdb->posts AS posts
ON posts.ID = meta.post_id
WHERE posts.post_type = %s;
",
self::SLUG
)
);

// Delete all URL Metrics posts.
$wpdb->delete(
$wpdb->posts,
array(
'post_type' => self::SLUG,
)
);

// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
}
}
45 changes: 45 additions & 0 deletions plugins/optimization-detective/uninstall.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
/**
* Plugin uninstaller logic.
*
* @package optimization-detective
* @since 0.1.0
*/

// If uninstall.php is not called by WordPress, bail.
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
exit;
}

require_once __DIR__ . '/class-od-url-metrics-post-type.php';

// Delete all URL Metrics posts for the current site.
OD_URL_Metrics_Post_Type::delete_all_posts();

/*
* For a multisite, delete the URL Metrics for all other sites (however limited to 100 sites to avoid memory limit or
* timeout problems in large scale networks).
*/
if ( is_multisite() ) {
$site_ids = get_sites(
array(
'fields' => 'ids',
'number' => 100,
'update_site_cache' => false,
'update_site_meta_cache' => false,
)
);

// Skip iterating over self.
$site_ids = array_diff(
$site_ids,
array( get_current_blog_id() )
);

// Delete all other blogs' URL Metrics posts.
foreach ( $site_ids as $site_id ) {
switch_to_blog( $site_id );
OD_URL_Metrics_Post_Type::delete_all_posts();
restore_current_blog();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,24 +132,7 @@ static function ( OD_URL_Metric $url_metric ): array {
public function test_store_url_metric() {
$slug = od_get_url_metrics_slug( array( 'p' => 1 ) );

$validated_url_metric = new OD_URL_Metric(
array(
'url' => home_url( '/' ),
'viewport' => array(
'width' => 480,
'height' => 640,
),
'timestamp' => microtime( true ),
'elements' => array(
array(
'isLCP' => true,
'isLCPCandidate' => true,
'xpath' => '/*[0][self::HTML]/*[1][self::BODY]/*[0][self::DIV]/*[1][self::MAIN]/*[0][self::DIV]/*[0][self::FIGURE]/*[0][self::IMG]',
'intersectionRatio' => 1,
),
),
)
);
$validated_url_metric = $this->get_sample_url_metric( home_url( '/' ) );

$post_id = OD_URL_Metrics_Post_Type::store_url_metric( $slug, $validated_url_metric );
$this->assertIsInt( $post_id );
Expand All @@ -167,4 +150,103 @@ public function test_store_url_metric() {
$url_metrics = OD_URL_Metrics_Post_Type::parse_post_content( $post );
$this->assertCount( 2, $url_metrics );
}

/**
* Test delete_all_posts()
*
* @covers ::delete_all_posts
*/
public function test_delete_all_posts() {
global $wpdb;

$other_post_meta_key = 'foo';
$other_post_meta_value = 'bar';
$url_metrics_post_meta_key = 'baz';

// Create sample posts of all post types other than URL Metrics.
$other_post_ids = array();
foreach ( array_diff( get_post_types(), array( OD_URL_Metrics_Post_Type::SLUG ) ) as $post_type ) {
$other_post_ids = array_merge(
$other_post_ids,
self::factory()->post->create_many( 10, compact( 'post_type' ) )
);
}
foreach ( $other_post_ids as $post_id ) {
update_post_meta( $post_id, $other_post_meta_key, $other_post_meta_value );
}

// Now create sample URL Metrics posts.
for ( $i = 1; $i <= 101; $i++ ) {
$slug = od_get_url_metrics_slug( array( 'p' => $i ) );
$post_id = OD_URL_Metrics_Post_Type::store_url_metric( $slug, $this->get_sample_url_metric( home_url( "/?p=$i" ) ) );
update_post_meta( $post_id, $url_metrics_post_meta_key, '' );
}

$get_post_type_counts = static function (): array {
$post_type_counts = array();
foreach ( get_post_types() as $post_type ) {
$post_type_counts[ $post_type ] = (array) wp_count_posts( $post_type );
}
return $post_type_counts;
};

// Capture the initial post type counts.
$initial_post_counts = $get_post_type_counts();
$this->assertEquals( 10, $initial_post_counts['post']['publish'] );
$this->assertEquals( 10, $initial_post_counts['page']['publish'] );
$this->assertEquals( 101, $initial_post_counts[ OD_URL_Metrics_Post_Type::SLUG ]['publish'] );
$other_post_meta_count = $wpdb->get_var( $wpdb->prepare( "SELECT count(*) FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s", $other_post_meta_key, $other_post_meta_value ) );
$this->assertGreaterThan( 0, $other_post_meta_count );
$this->assertEquals( 101, $wpdb->get_var( $wpdb->prepare( "SELECT count(*) FROM $wpdb->postmeta WHERE meta_key = %s", $url_metrics_post_meta_key ) ) );

// Delete the URL Metrics posts.
OD_URL_Metrics_Post_Type::delete_all_posts();

wp_cache_flush();

// Make sure that the counts are as expected.
$final_post_counts = $get_post_type_counts();
$this->assertEquals( 10, $final_post_counts['post']['publish'] );
$this->assertEquals( 10, $final_post_counts['page']['publish'] );
$this->assertEquals( 0, $final_post_counts[ OD_URL_Metrics_Post_Type::SLUG ]['publish'] );
$initial_post_counts[ OD_URL_Metrics_Post_Type::SLUG ]['publish'] = 0;
$this->assertEquals( $initial_post_counts, $final_post_counts );

// Make sure post meta is intact.
foreach ( $other_post_ids as $post_id ) {
$this->assertInstanceOf( WP_Post::class, get_post( $post_id ) );
$this->assertSame( $other_post_meta_value, get_post_meta( $post_id, $other_post_meta_key, true ) );
}
$this->assertEquals( 0, $wpdb->get_var( $wpdb->prepare( "SELECT count(*) FROM $wpdb->postmeta WHERE meta_key = %s", $url_metrics_post_meta_key ) ) );
$this->assertEquals( $other_post_meta_count, $wpdb->get_var( $wpdb->prepare( "SELECT count(*) FROM $wpdb->postmeta WHERE meta_key = %s and meta_value = %s", $other_post_meta_key, $other_post_meta_value ) ) );
}

/**
* Gets a sample URL Metric.
*
* @param string $url URL.
*
* @return OD_URL_Metric
* @throws OD_Data_Validation_Exception When invalid data (but there won't be).
*/
private function get_sample_url_metric( string $url ): OD_URL_Metric {
return new OD_URL_Metric(
array(
'url' => $url,
'viewport' => array(
'width' => 480,
'height' => 640,
),
'timestamp' => microtime( true ),
'elements' => array(
array(
'isLCP' => true,
'isLCPCandidate' => true,
'xpath' => '/*[0][self::HTML]/*[1][self::BODY]/*[0][self::DIV]/*[1][self::MAIN]/*[0][self::DIV]/*[0][self::FIGURE]/*[0][self::IMG]',
'intersectionRatio' => 1,
),
),
)
);
}
}
29 changes: 29 additions & 0 deletions tests/plugins/optimization-detective/uninstall-tests.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
/**
* Tests for optimization-detective module uninstall.php.
*
* @runInSeparateProcess
* @package optimization-detective
*/

class OD_Uninstall_Tests extends WP_UnitTestCase {

/**
* Make sure post deletion is happening.
*/
public function test_post_deletion() {
// Mock uninstall const.
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
define( 'WP_UNINSTALL_PLUGIN', 'Yes' );
}

$post_id = self::factory()->post->create();
$url_metrics_post_id = self::factory()->post->create( array( 'post_type' => OD_URL_Metrics_Post_Type::SLUG ) );

require __DIR__ . '/../../../plugins/optimization-detective/uninstall.php';
wp_cache_flush();

$this->assertInstanceOf( WP_Post::class, get_post( $post_id ) );
$this->assertNull( get_post( $url_metrics_post_id ) );
}
}

0 comments on commit a52e0ce

Please sign in to comment.