Changeset 60148 for trunk/tests/phpunit/tests/multisite/site.php
- Timestamp:
- 04/09/2025 01:29:39 PM (6 weeks ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tests/phpunit/tests/multisite/site.php
r58235 r60148 1 1 <?php 2 2 3 if ( is_multisite() ) : 4 5 /** 6 * Tests specific to sites in multisite. 7 * 8 * @group ms-site 9 * @group multisite 10 */ 11 class Tests_Multisite_Site extends WP_UnitTestCase { 12 protected $suppress = false; 13 protected $site_status_hooks = array(); 14 protected $wp_initialize_site_args = array(); 15 protected $wp_initialize_site_meta = array(); 16 protected static $network_ids; 17 protected static $site_ids; 18 protected static $uninitialized_site_id; 19 20 public function set_up() { 21 global $wpdb; 22 parent::set_up(); 23 $this->suppress = $wpdb->suppress_errors(); 3 /** 4 * Tests specific to sites in multisite. 5 * 6 * @group ms-required 7 * @group ms-site 8 * @group multisite 9 */ 10 class Tests_Multisite_Site extends WP_UnitTestCase { 11 protected $suppress = false; 12 protected $site_status_hooks = array(); 13 protected $wp_initialize_site_args = array(); 14 protected $wp_initialize_site_meta = array(); 15 protected static $network_ids; 16 protected static $site_ids; 17 protected static $uninitialized_site_id; 18 19 public function set_up() { 20 global $wpdb; 21 parent::set_up(); 22 $this->suppress = $wpdb->suppress_errors(); 23 } 24 25 public function tear_down() { 26 global $wpdb; 27 $wpdb->suppress_errors( $this->suppress ); 28 parent::tear_down(); 29 } 30 31 public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) { 32 self::$network_ids = array( 33 'make.wordpress.org/' => array( 34 'domain' => 'make.wordpress.org', 35 'path' => '/', 36 ), 37 ); 38 39 foreach ( self::$network_ids as &$id ) { 40 $id = $factory->network->create( $id ); 24 41 } 25 26 public function tear_down() { 27 global $wpdb; 28 $wpdb->suppress_errors( $this->suppress ); 29 parent::tear_down(); 42 unset( $id ); 43 44 self::$site_ids = array( 45 'make.wordpress.org/' => array( 46 'domain' => 'make.wordpress.org', 47 'path' => '/', 48 'network_id' => self::$network_ids['make.wordpress.org/'], 49 ), 50 'make.wordpress.org/foo/' => array( 51 'domain' => 'make.wordpress.org', 52 'path' => '/foo/', 53 'network_id' => self::$network_ids['make.wordpress.org/'], 54 ), 55 ); 56 57 foreach ( self::$site_ids as &$id ) { 58 $id = $factory->blog->create( $id ); 30 59 } 31 32 public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) { 33 self::$network_ids = array( 34 'make.wordpress.org/' => array( 35 'domain' => 'make.wordpress.org', 36 'path' => '/', 37 ), 38 ); 39 40 foreach ( self::$network_ids as &$id ) { 41 $id = $factory->network->create( $id ); 42 } 43 unset( $id ); 44 45 self::$site_ids = array( 46 'make.wordpress.org/' => array( 47 'domain' => 'make.wordpress.org', 48 'path' => '/', 49 'network_id' => self::$network_ids['make.wordpress.org/'], 50 ), 51 'make.wordpress.org/foo/' => array( 52 'domain' => 'make.wordpress.org', 53 'path' => '/foo/', 54 'network_id' => self::$network_ids['make.wordpress.org/'], 55 ), 56 ); 57 58 foreach ( self::$site_ids as &$id ) { 59 $id = $factory->blog->create( $id ); 60 } 61 unset( $id ); 62 63 remove_action( 'wp_initialize_site', 'wp_initialize_site', 10 ); 64 self::$uninitialized_site_id = wp_insert_site( 65 array( 66 'domain' => 'uninitialized.org', 67 'path' => '/', 68 'network_id' => self::$network_ids['make.wordpress.org/'], 69 ) 70 ); 71 add_action( 'wp_initialize_site', 'wp_initialize_site', 10, 2 ); 60 unset( $id ); 61 62 remove_action( 'wp_initialize_site', 'wp_initialize_site', 10 ); 63 self::$uninitialized_site_id = wp_insert_site( 64 array( 65 'domain' => 'uninitialized.org', 66 'path' => '/', 67 'network_id' => self::$network_ids['make.wordpress.org/'], 68 ) 69 ); 70 add_action( 'wp_initialize_site', 'wp_initialize_site', 10, 2 ); 71 } 72 73 public static function wpTearDownAfterClass() { 74 global $wpdb; 75 76 remove_action( 'wp_uninitialize_site', 'wp_uninitialize_site', 10 ); 77 wp_delete_site( self::$uninitialized_site_id ); 78 add_action( 'wp_uninitialize_site', 'wp_uninitialize_site', 10, 1 ); 79 80 foreach ( self::$site_ids as $id ) { 81 wp_delete_site( $id ); 72 82 } 73 83 74 public static function wpTearDownAfterClass() { 75 global $wpdb; 76 77 remove_action( 'wp_uninitialize_site', 'wp_uninitialize_site', 10 ); 78 wp_delete_site( self::$uninitialized_site_id ); 79 add_action( 'wp_uninitialize_site', 'wp_uninitialize_site', 10, 1 ); 80 81 foreach ( self::$site_ids as $id ) { 82 wp_delete_site( $id ); 83 } 84 85 foreach ( self::$network_ids as $id ) { 86 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->sitemeta} WHERE site_id = %d", $id ) ); 87 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->site} WHERE id= %d", $id ) ); 84 foreach ( self::$network_ids as $id ) { 85 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->sitemeta} WHERE site_id = %d", $id ) ); 86 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->site} WHERE id= %d", $id ) ); 87 } 88 } 89 90 public function test_switch_restore_blog() { 91 global $_wp_switched_stack, $wpdb; 92 93 $this->assertSame( array(), $_wp_switched_stack ); 94 $this->assertFalse( ms_is_switched() ); 95 $current_blog_id = get_current_blog_id(); 96 $this->assertIsInt( $current_blog_id ); 97 98 wp_cache_set( 'switch-test', $current_blog_id, 'switch-test' ); 99 $this->assertSame( $current_blog_id, wp_cache_get( 'switch-test', 'switch-test' ) ); 100 101 $blog_id = self::factory()->blog->create(); 102 103 $cap_key = wp_get_current_user()->cap_key; 104 switch_to_blog( $blog_id ); 105 $this->assertNotEquals( $cap_key, wp_get_current_user()->cap_key ); 106 $this->assertSame( array( $current_blog_id ), $_wp_switched_stack ); 107 $this->assertTrue( ms_is_switched() ); 108 $this->assertSame( $blog_id, $wpdb->blogid ); 109 $this->assertFalse( wp_cache_get( 'switch-test', 'switch-test' ) ); 110 wp_cache_set( 'switch-test', $blog_id, 'switch-test' ); 111 $this->assertSame( $blog_id, wp_cache_get( 'switch-test', 'switch-test' ) ); 112 113 switch_to_blog( $blog_id ); 114 $this->assertSame( array( $current_blog_id, $blog_id ), $_wp_switched_stack ); 115 $this->assertTrue( ms_is_switched() ); 116 $this->assertSame( $blog_id, $wpdb->blogid ); 117 $this->assertSame( $blog_id, wp_cache_get( 'switch-test', 'switch-test' ) ); 118 119 restore_current_blog(); 120 $this->assertSame( array( $current_blog_id ), $_wp_switched_stack ); 121 $this->assertTrue( ms_is_switched() ); 122 $this->assertSame( $blog_id, $wpdb->blogid ); 123 $this->assertSame( $blog_id, wp_cache_get( 'switch-test', 'switch-test' ) ); 124 125 restore_current_blog(); 126 $this->assertSame( $cap_key, wp_get_current_user()->cap_key ); 127 $this->assertSame( $current_blog_id, get_current_blog_id() ); 128 $this->assertSame( array(), $_wp_switched_stack ); 129 $this->assertFalse( ms_is_switched() ); 130 $this->assertSame( $current_blog_id, wp_cache_get( 'switch-test', 'switch-test' ) ); 131 132 $this->assertFalse( restore_current_blog() ); 133 } 134 135 /** 136 * Test the cache keys and database tables setup through the creation of a site. 137 */ 138 public function test_created_site_details() { 139 global $wpdb; 140 141 $blog_id = self::factory()->blog->create(); 142 143 $this->assertIsInt( $blog_id ); 144 $prefix = $wpdb->get_blog_prefix( $blog_id ); 145 146 // $get_all = false, only retrieve details from the blogs table. 147 $details = get_blog_details( $blog_id, false ); 148 149 // Combine domain and path for a site specific cache key. 150 $key = md5( $details->domain . $details->path ); 151 152 $this->assertEquals( $details, wp_cache_get( $blog_id . 'short', 'blog-details' ) ); 153 154 // get_blogaddress_by_name(). 155 $this->assertSame( 'http://' . $details->domain . $details->path, get_blogaddress_by_name( trim( $details->path, '/' ) ) ); 156 157 // These are empty until get_blog_details() is called with $get_all = true. 158 $this->assertFalse( wp_cache_get( $blog_id, 'blog-details' ) ); 159 $this->assertFalse( wp_cache_get( $key, 'blog-lookup' ) ); 160 161 // $get_all = true, populate the full blog-details cache and the blog slug lookup cache. 162 $details = get_blog_details( $blog_id, true ); 163 $this->assertEquals( $details, wp_cache_get( $blog_id, 'blog-details' ) ); 164 $this->assertEquals( $details, wp_cache_get( $key, 'blog-lookup' ) ); 165 166 // Check existence of each database table for the created site. 167 foreach ( $wpdb->tables( 'blog', false ) as $table ) { 168 $suppress = $wpdb->suppress_errors(); 169 170 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 171 $table_fields = $wpdb->get_results( "DESCRIBE $prefix$table;" ); 172 173 $wpdb->suppress_errors( $suppress ); 174 175 // The table should exist. 176 $this->assertNotEmpty( $table_fields ); 177 178 // And the table should not be empty, unless commentmeta, termmeta, or links. 179 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 180 $result = $wpdb->get_results( "SELECT * FROM $prefix$table LIMIT 1" ); 181 182 if ( 'commentmeta' === $table || 'termmeta' === $table || 'links' === $table ) { 183 $this->assertEmpty( $result ); 184 } else { 185 $this->assertNotEmpty( $result ); 88 186 } 89 187 } 90 188 91 public function test_switch_restore_blog() { 92 global $_wp_switched_stack, $wpdb; 93 94 $this->assertSame( array(), $_wp_switched_stack ); 95 $this->assertFalse( ms_is_switched() ); 96 $current_blog_id = get_current_blog_id(); 97 $this->assertIsInt( $current_blog_id ); 98 99 wp_cache_set( 'switch-test', $current_blog_id, 'switch-test' ); 100 $this->assertSame( $current_blog_id, wp_cache_get( 'switch-test', 'switch-test' ) ); 101 102 $blog_id = self::factory()->blog->create(); 103 104 $cap_key = wp_get_current_user()->cap_key; 105 switch_to_blog( $blog_id ); 106 $this->assertNotEquals( $cap_key, wp_get_current_user()->cap_key ); 107 $this->assertSame( array( $current_blog_id ), $_wp_switched_stack ); 108 $this->assertTrue( ms_is_switched() ); 109 $this->assertSame( $blog_id, $wpdb->blogid ); 110 $this->assertFalse( wp_cache_get( 'switch-test', 'switch-test' ) ); 111 wp_cache_set( 'switch-test', $blog_id, 'switch-test' ); 112 $this->assertSame( $blog_id, wp_cache_get( 'switch-test', 'switch-test' ) ); 113 114 switch_to_blog( $blog_id ); 115 $this->assertSame( array( $current_blog_id, $blog_id ), $_wp_switched_stack ); 116 $this->assertTrue( ms_is_switched() ); 117 $this->assertSame( $blog_id, $wpdb->blogid ); 118 $this->assertSame( $blog_id, wp_cache_get( 'switch-test', 'switch-test' ) ); 119 120 restore_current_blog(); 121 $this->assertSame( array( $current_blog_id ), $_wp_switched_stack ); 122 $this->assertTrue( ms_is_switched() ); 123 $this->assertSame( $blog_id, $wpdb->blogid ); 124 $this->assertSame( $blog_id, wp_cache_get( 'switch-test', 'switch-test' ) ); 125 126 restore_current_blog(); 127 $this->assertSame( $cap_key, wp_get_current_user()->cap_key ); 128 $this->assertSame( $current_blog_id, get_current_blog_id() ); 129 $this->assertSame( array(), $_wp_switched_stack ); 130 $this->assertFalse( ms_is_switched() ); 131 $this->assertSame( $current_blog_id, wp_cache_get( 'switch-test', 'switch-test' ) ); 132 133 $this->assertFalse( restore_current_blog() ); 189 // Update the blog count cache to use get_blog_count(). 190 wp_update_network_counts(); 191 $this->assertSame( 2, (int) get_blog_count() ); 192 } 193 194 public function test_site_caches_should_invalidate_when_invalidation_is_not_suspended() { 195 $site_id = self::factory()->blog->create(); 196 197 $details = get_site( $site_id ); 198 199 $suspend = wp_suspend_cache_invalidation( false ); 200 update_blog_details( $site_id, array( 'path' => '/a-non-random-test-path/' ) ); 201 $new_details = get_site( $site_id ); 202 wp_suspend_cache_invalidation( $suspend ); 203 204 $this->assertNotEquals( $details->path, $new_details->path ); 205 } 206 207 public function test_site_caches_should_not_invalidate_when_invalidation_is_suspended() { 208 $site_id = self::factory()->blog->create(); 209 210 $details = get_site( $site_id ); 211 212 $suspend = wp_suspend_cache_invalidation(); 213 update_blog_details( $site_id, array( 'path' => '/a-non-random-test-path/' ) ); 214 $new_details = get_site( $site_id ); 215 wp_suspend_cache_invalidation( $suspend ); 216 217 $this->assertSame( $details->path, $new_details->path ); 218 } 219 220 /** 221 * When a site is flagged as 'deleted', its data should be cleared from cache. 222 */ 223 public function test_data_in_cache_after_wpmu_delete_blog_drop_false() { 224 $blog_id = self::factory()->blog->create(); 225 226 $details = get_blog_details( $blog_id, false ); 227 $key = md5( $details->domain . $details->path ); 228 229 // Delete the site without forcing a table drop. 230 wpmu_delete_blog( $blog_id, false ); 231 232 $this->assertFalse( wp_cache_get( $blog_id, 'blog-details' ) ); 233 $this->assertFalse( wp_cache_get( $blog_id . 'short', 'blog-details' ) ); 234 $this->assertFalse( wp_cache_get( $key, 'blog-lookup' ) ); 235 $this->assertFalse( wp_cache_get( $key, 'blog-id-cache' ) ); 236 } 237 238 /** 239 * When a site is flagged as 'deleted', its data should remain in the database. 240 */ 241 public function test_data_in_tables_after_wpmu_delete_blog_drop_false() { 242 global $wpdb; 243 244 $blog_id = self::factory()->blog->create(); 245 246 // Delete the site without forcing a table drop. 247 wpmu_delete_blog( $blog_id, false ); 248 249 $prefix = $wpdb->get_blog_prefix( $blog_id ); 250 foreach ( $wpdb->tables( 'blog', false ) as $table ) { 251 $suppress = $wpdb->suppress_errors(); 252 253 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 254 $table_fields = $wpdb->get_results( "DESCRIBE $prefix$table;" ); 255 256 $wpdb->suppress_errors( $suppress ); 257 $this->assertNotEmpty( $table_fields, $prefix . $table ); 134 258 } 135 136 /** 137 * Test the cache keys and database tables setup through the creation of a site. 138 */ 139 public function test_created_site_details() { 140 global $wpdb; 141 142 $blog_id = self::factory()->blog->create(); 143 144 $this->assertIsInt( $blog_id ); 145 $prefix = $wpdb->get_blog_prefix( $blog_id ); 146 147 // $get_all = false, only retrieve details from the blogs table. 148 $details = get_blog_details( $blog_id, false ); 149 150 // Combine domain and path for a site specific cache key. 151 $key = md5( $details->domain . $details->path ); 152 153 $this->assertEquals( $details, wp_cache_get( $blog_id . 'short', 'blog-details' ) ); 154 155 // get_blogaddress_by_name(). 156 $this->assertSame( 'http://' . $details->domain . $details->path, get_blogaddress_by_name( trim( $details->path, '/' ) ) ); 157 158 // These are empty until get_blog_details() is called with $get_all = true. 159 $this->assertFalse( wp_cache_get( $blog_id, 'blog-details' ) ); 160 $this->assertFalse( wp_cache_get( $key, 'blog-lookup' ) ); 161 162 // $get_all = true, populate the full blog-details cache and the blog slug lookup cache. 163 $details = get_blog_details( $blog_id, true ); 164 $this->assertEquals( $details, wp_cache_get( $blog_id, 'blog-details' ) ); 165 $this->assertEquals( $details, wp_cache_get( $key, 'blog-lookup' ) ); 166 167 // Check existence of each database table for the created site. 168 foreach ( $wpdb->tables( 'blog', false ) as $table ) { 169 $suppress = $wpdb->suppress_errors(); 170 171 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 172 $table_fields = $wpdb->get_results( "DESCRIBE $prefix$table;" ); 173 174 $wpdb->suppress_errors( $suppress ); 175 176 // The table should exist. 177 $this->assertNotEmpty( $table_fields ); 178 179 // And the table should not be empty, unless commentmeta, termmeta, or links. 180 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 181 $result = $wpdb->get_results( "SELECT * FROM $prefix$table LIMIT 1" ); 182 183 if ( 'commentmeta' === $table || 'termmeta' === $table || 'links' === $table ) { 184 $this->assertEmpty( $result ); 185 } else { 186 $this->assertNotEmpty( $result ); 187 } 188 } 189 190 // Update the blog count cache to use get_blog_count(). 191 wp_update_network_counts(); 192 $this->assertSame( 2, (int) get_blog_count() ); 259 } 260 261 /** 262 * When a site is fully deleted, its data should be cleared from cache. 263 */ 264 public function test_data_in_cache_after_wpmu_delete_blog_drop_true() { 265 $blog_id = self::factory()->blog->create(); 266 267 $details = get_blog_details( $blog_id, false ); 268 $key = md5( $details->domain . $details->path ); 269 270 // Delete the site and force a table drop. 271 wpmu_delete_blog( $blog_id, true ); 272 273 $this->assertFalse( wp_cache_get( $blog_id, 'blog-details' ) ); 274 $this->assertFalse( wp_cache_get( $blog_id . 'short', 'blog-details' ) ); 275 $this->assertFalse( wp_cache_get( $key, 'blog-lookup' ) ); 276 $this->assertFalse( wp_cache_get( $key, 'blog-id-cache' ) ); 277 } 278 279 /** 280 * When a site is fully deleted, its data should be removed from the database. 281 */ 282 public function test_data_in_tables_after_wpmu_delete_blog_drop_true() { 283 global $wpdb; 284 285 $blog_id = self::factory()->blog->create(); 286 287 // Delete the site and force a table drop. 288 wpmu_delete_blog( $blog_id, true ); 289 290 $prefix = $wpdb->get_blog_prefix( $blog_id ); 291 foreach ( $wpdb->tables( 'blog', false ) as $table ) { 292 $suppress = $wpdb->suppress_errors(); 293 294 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 295 $table_fields = $wpdb->get_results( "DESCRIBE $prefix$table;" ); 296 297 $wpdb->suppress_errors( $suppress ); 298 $this->assertEmpty( $table_fields ); 193 299 } 194 195 public function test_site_caches_should_invalidate_when_invalidation_is_not_suspended() { 196 $site_id = self::factory()->blog->create(); 197 198 $details = get_site( $site_id ); 199 200 $suspend = wp_suspend_cache_invalidation( false ); 201 update_blog_details( $site_id, array( 'path' => '/a-non-random-test-path/' ) ); 202 $new_details = get_site( $site_id ); 203 wp_suspend_cache_invalidation( $suspend ); 204 205 $this->assertNotEquals( $details->path, $new_details->path ); 300 } 301 302 /** 303 * When the main site of a network is fully deleted, its data should be cleared from cache. 304 */ 305 public function test_data_in_cache_after_wpmu_delete_blog_main_site_drop_true() { 306 $blog_id = 1; // The main site in our test suite has an ID of 1. 307 308 $details = get_blog_details( $blog_id, false ); 309 $key = md5( $details->domain . $details->path ); 310 311 // Delete the site and force a table drop. 312 wpmu_delete_blog( $blog_id, true ); 313 314 $this->assertFalse( wp_cache_get( $blog_id, 'blog-details' ) ); 315 $this->assertFalse( wp_cache_get( $blog_id . 'short', 'blog-details' ) ); 316 $this->assertFalse( wp_cache_get( $key, 'blog-lookup' ) ); 317 $this->assertFalse( wp_cache_get( $key, 'blog-id-cache' ) ); 318 } 319 320 /** 321 * When the main site of a network is fully deleted, its data should remain in the database. 322 */ 323 public function test_data_in_tables_after_wpmu_delete_blog_main_site_drop_true() { 324 global $wpdb; 325 326 $blog_id = 1; // The main site in our test suite has an ID of 1. 327 328 // Delete the site and force a table drop. 329 wpmu_delete_blog( $blog_id, true ); 330 331 $prefix = $wpdb->get_blog_prefix( $blog_id ); 332 foreach ( $wpdb->tables( 'blog', false ) as $table ) { 333 $suppress = $wpdb->suppress_errors(); 334 335 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 336 $table_fields = $wpdb->get_results( "DESCRIBE $prefix$table;" ); 337 338 $wpdb->suppress_errors( $suppress ); 339 $this->assertNotEmpty( $table_fields, $prefix . $table ); 206 340 } 207 208 public function test_site_caches_should_not_invalidate_when_invalidation_is_suspended() { 209 $site_id = self::factory()->blog->create(); 210 211 $details = get_site( $site_id ); 212 213 $suspend = wp_suspend_cache_invalidation(); 214 update_blog_details( $site_id, array( 'path' => '/a-non-random-test-path/' ) ); 215 $new_details = get_site( $site_id ); 216 wp_suspend_cache_invalidation( $suspend ); 217 218 $this->assertSame( $details->path, $new_details->path ); 341 } 342 343 /** 344 * The site count of a network should change when a site is flagged as 'deleted'. 345 */ 346 public function test_network_count_after_wpmu_delete_blog_drop_false() { 347 $blog_id = self::factory()->blog->create(); 348 349 // Delete the site without forcing a table drop. 350 wpmu_delete_blog( $blog_id, false ); 351 352 // Update the blog count cache to use get_blog_count(). 353 wp_update_network_counts(); 354 $this->assertSame( 1, get_blog_count() ); 355 } 356 357 /** 358 * The site count of a network should change when a site is fully deleted. 359 */ 360 public function test_blog_count_after_wpmu_delete_blog_drop_true() { 361 $blog_id = self::factory()->blog->create(); 362 363 // Delete the site and force a table drop. 364 wpmu_delete_blog( $blog_id, true ); 365 366 // Update the blog count cache to use get_blog_count(). 367 wp_update_network_counts(); 368 $this->assertSame( 1, get_blog_count() ); 369 } 370 371 /** 372 * When a site is deleted with wpmu_delete_blog(), only the files associated with 373 * that site should be removed. When wpmu_delete_blog() is run a second time, nothing 374 * should change with upload directories. 375 */ 376 public function test_upload_directories_after_multiple_wpmu_delete_blog() { 377 $filename = __FUNCTION__ . '.jpg'; 378 $contents = __FUNCTION__ . '_contents'; 379 380 // Upload a file to the main site on the network. 381 $file1 = wp_upload_bits( $filename, null, $contents ); 382 383 $blog_id = self::factory()->blog->create(); 384 385 switch_to_blog( $blog_id ); 386 $file2 = wp_upload_bits( $filename, null, $contents ); 387 restore_current_blog(); 388 389 wpmu_delete_blog( $blog_id, true ); 390 391 // The file on the main site should still exist. The file on the deleted site should not. 392 $this->assertFileExists( $file1['file'] ); 393 $this->assertFileDoesNotExist( $file2['file'] ); 394 395 wpmu_delete_blog( $blog_id, true ); 396 397 // The file on the main site should still exist. The file on the deleted site should not. 398 $this->assertFileExists( $file1['file'] ); 399 $this->assertFileDoesNotExist( $file2['file'] ); 400 401 unlink( $file1['file'] ); 402 } 403 404 public function test_wpmu_update_blogs_date() { 405 global $wpdb; 406 407 wpmu_update_blogs_date(); 408 409 $blog = get_site( get_current_blog_id() ); 410 $current_time = time(); 411 412 // Compare the update time with the current time, allow delta < 2. 413 $this->assertEqualsWithDelta( $current_time, strtotime( $blog->last_updated ), 2, 'The dates should be equal' ); 414 } 415 416 /** 417 * Test cached data for a site that does not exist and then again after it exists. 418 * 419 * @ticket 23405 420 */ 421 public function test_get_blog_details_when_site_does_not_exist() { 422 // Create an unused site so that we can then assume an invalid site ID. 423 $blog_id = self::factory()->blog->create(); 424 ++$blog_id; 425 426 // Prime the cache for an invalid site. 427 get_blog_details( $blog_id ); 428 429 // When the cache is primed with an invalid site, the value is set to -1. 430 $this->assertSame( -1, wp_cache_get( $blog_id, 'blog-details' ) ); 431 432 // Create a site in the invalid site's place. 433 self::factory()->blog->create(); 434 435 // When a new site is created, its cache is cleared through refresh_blog_details. 436 $this->assertFalse( wp_cache_get( $blog_id, 'blog-details' ) ); 437 438 $blog = get_blog_details( $blog_id ); 439 440 // When the cache is refreshed, it should now equal the site data. 441 $this->assertEquals( $blog, wp_cache_get( $blog_id, 'blog-details' ) ); 442 } 443 444 /** 445 * @ticket 26410 446 */ 447 public function test_blog_details_cache_invalidation() { 448 update_option( 'blogname', 'foo' ); 449 $details = get_site( get_current_blog_id() ); 450 $this->assertSame( 'foo', $details->blogname ); 451 452 update_option( 'blogname', 'bar' ); 453 $details = get_site( get_current_blog_id() ); 454 $this->assertSame( 'bar', $details->blogname ); 455 } 456 457 /** 458 * Test the original and cached responses for a created and then deleted site when 459 * the blog ID is requested through get_blog_id_from_url(). 460 */ 461 public function test_get_blog_id_from_url() { 462 $blog_id = self::factory()->blog->create(); 463 $details = get_site( $blog_id ); 464 $key = md5( $details->domain . $details->path ); 465 466 // Test the original response and cached response for the newly created site. 467 $this->assertSame( $blog_id, get_blog_id_from_url( $details->domain, $details->path ) ); 468 $this->assertSame( $blog_id, wp_cache_get( $key, 'blog-id-cache' ) ); 469 } 470 471 /** 472 * Test the case insensitivity of the site lookup. 473 */ 474 public function test_get_blog_id_from_url_is_case_insensitive() { 475 $blog_id = self::factory()->blog->create( 476 array( 477 'domain' => 'example.com', 478 'path' => '/xyz', 479 ) 480 ); 481 $details = get_site( $blog_id ); 482 483 $this->assertSame( $blog_id, get_blog_id_from_url( strtoupper( $details->domain ), strtoupper( $details->path ) ) ); 484 } 485 486 /** 487 * Test the first and cached responses for a site that does not exist. 488 */ 489 public function test_get_blog_id_from_url_that_does_not_exist() { 490 $blog_id = self::factory()->blog->create( array( 'path' => '/xyz' ) ); 491 $details = get_site( $blog_id ); 492 493 $this->assertSame( 0, get_blog_id_from_url( $details->domain, 'foo' ) ); 494 $this->assertSame( -1, wp_cache_get( md5( $details->domain . 'foo' ), 'blog-id-cache' ) ); 495 } 496 497 /** 498 * A blog ID is still available if only the `deleted` flag is set for a site. The same 499 * behavior would be expected if passing `false` explicitly to `wpmu_delete_blog()`. 500 */ 501 public function test_get_blog_id_from_url_with_deleted_flag() { 502 $blog_id = self::factory()->blog->create(); 503 $details = get_site( $blog_id ); 504 $key = md5( $details->domain . $details->path ); 505 wpmu_delete_blog( $blog_id ); 506 507 $this->assertSame( $blog_id, get_blog_id_from_url( $details->domain, $details->path ) ); 508 $this->assertSame( $blog_id, wp_cache_get( $key, 'blog-id-cache' ) ); 509 } 510 511 /** 512 * When deleted with the drop parameter as true, the cache will first be false, then set to 513 * -1 after an attempt at `get_blog_id_from_url()` is made. 514 */ 515 public function test_get_blog_id_from_url_after_dropped() { 516 $blog_id = self::factory()->blog->create(); 517 $details = get_site( $blog_id ); 518 $key = md5( $details->domain . $details->path ); 519 wpmu_delete_blog( $blog_id, true ); 520 521 $this->assertFalse( wp_cache_get( $key, 'blog-id-cache' ) ); 522 $this->assertSame( 0, get_blog_id_from_url( $details->domain, $details->path ) ); 523 $this->assertSame( -1, wp_cache_get( $key, 'blog-id-cache' ) ); 524 } 525 526 /** 527 * Test with default parameter of site_id as null. 528 */ 529 public function test_is_main_site() { 530 $this->assertTrue( is_main_site() ); 531 } 532 533 /** 534 * Test with a site id of get_current_blog_id(), which should be the same as the 535 * default parameter tested above. 536 */ 537 public function test_current_blog_id_is_main_site() { 538 $this->assertTrue( is_main_site( get_current_blog_id() ) ); 539 } 540 541 /** 542 * Test with a site ID other than the main site to ensure a false response. 543 */ 544 public function test_is_main_site_is_false_with_other_blog_id() { 545 $blog_id = self::factory()->blog->create(); 546 547 $this->assertFalse( is_main_site( $blog_id ) ); 548 } 549 550 /** 551 * Test with no passed ID after switching to another site ID. 552 */ 553 public function test_is_main_site_is_false_after_switch_to_blog() { 554 $blog_id = self::factory()->blog->create(); 555 switch_to_blog( $blog_id ); 556 557 $this->assertFalse( is_main_site() ); 558 559 restore_current_blog(); 560 } 561 562 public function test_switch_upload_dir() { 563 $this->assertTrue( is_main_site() ); 564 565 $site = get_current_site(); 566 $date = date_format( date_create( 'now' ), 'Y/m' ); 567 568 $info = wp_upload_dir(); 569 $this->assertSame( 'http://' . $site->domain . '/wp-content/uploads/' . $date, $info['url'] ); 570 $this->assertSame( ABSPATH . 'wp-content/uploads/' . $date, $info['path'] ); 571 $this->assertSame( '/' . $date, $info['subdir'] ); 572 $this->assertFalse( $info['error'] ); 573 574 $blog_id = self::factory()->blog->create(); 575 576 switch_to_blog( $blog_id ); 577 $info = wp_upload_dir(); 578 $this->assertSame( 'http://' . $site->domain . '/wp-content/uploads/sites/' . get_current_blog_id() . '/' . $date, $info['url'] ); 579 $this->assertSame( ABSPATH . 'wp-content/uploads/sites/' . get_current_blog_id() . '/' . $date, $info['path'] ); 580 $this->assertSame( '/' . $date, $info['subdir'] ); 581 $this->assertFalse( $info['error'] ); 582 restore_current_blog(); 583 584 $info = wp_upload_dir(); 585 $this->assertSame( 'http://' . $site->domain . '/wp-content/uploads/' . $date, $info['url'] ); 586 $this->assertSame( ABSPATH . 'wp-content/uploads/' . $date, $info['path'] ); 587 $this->assertSame( '/' . $date, $info['subdir'] ); 588 $this->assertFalse( $info['error'] ); 589 } 590 591 /** 592 * Test the primary purpose of get_blog_post(), to retrieve a post from 593 * another site on the network. 594 */ 595 public function test_get_blog_post_from_another_site_on_network() { 596 $blog_id = self::factory()->blog->create(); 597 $post_id = self::factory()->post->create(); // Create a post on the primary site, ID 1. 598 $post = get_post( $post_id ); 599 switch_to_blog( $blog_id ); 600 601 // The post created and retrieved on the main site should match the one retrieved "remotely". 602 $this->assertEquals( $post, get_blog_post( 1, $post_id ) ); 603 604 restore_current_blog(); 605 } 606 607 /** 608 * If get_blog_post() is used on the same site, it should still work. 609 */ 610 public function test_get_blog_post_from_same_site() { 611 $post_id = self::factory()->post->create(); 612 613 $this->assertEquals( get_blog_post( 1, $post_id ), get_post( $post_id ) ); 614 } 615 616 /** 617 * A null response should be returned if an invalid post is requested. 618 */ 619 public function test_get_blog_post_invalid_returns_null() { 620 $this->assertNull( get_blog_post( 1, 999999 ) ); 621 } 622 623 /** 624 * Added as a callback to the domain_exists filter to provide manual results for 625 * the testing of the filter and for a test which does not need the database. 626 */ 627 public function domain_exists_cb( $exists, $domain, $path, $site_id ) { 628 if ( 'foo' === $domain && 'bar/' === $path ) { 629 return 1234; 630 } else { 631 return null; 219 632 } 220 221 /** 222 * When a site is flagged as 'deleted', its data should be cleared from cache. 223 */ 224 public function test_data_in_cache_after_wpmu_delete_blog_drop_false() { 225 $blog_id = self::factory()->blog->create(); 226 227 $details = get_blog_details( $blog_id, false ); 228 $key = md5( $details->domain . $details->path ); 229 230 // Delete the site without forcing a table drop. 231 wpmu_delete_blog( $blog_id, false ); 232 233 $this->assertFalse( wp_cache_get( $blog_id, 'blog-details' ) ); 234 $this->assertFalse( wp_cache_get( $blog_id . 'short', 'blog-details' ) ); 235 $this->assertFalse( wp_cache_get( $key, 'blog-lookup' ) ); 236 $this->assertFalse( wp_cache_get( $key, 'blog-id-cache' ) ); 633 } 634 635 public function test_domain_exists_with_default_site_id() { 636 $details = get_site( 1 ); 637 638 $this->assertSame( 1, domain_exists( $details->domain, $details->path ) ); 639 } 640 641 public function test_domain_exists_with_specified_site_id() { 642 $details = get_site( 1 ); 643 644 $this->assertSame( 1, domain_exists( $details->domain, $details->path, $details->site_id ) ); 645 } 646 647 /** 648 * When the domain is valid, but the resulting site does not belong to the specified network, 649 * it is marked as not existing. 650 */ 651 public function test_domain_does_not_exist_with_invalid_site_id() { 652 $details = get_site( 1 ); 653 654 $this->assertNull( domain_exists( $details->domain, $details->path, 999 ) ); 655 } 656 657 public function test_invalid_domain_does_not_exist_with_default_site_id() { 658 $this->assertNull( domain_exists( 'foo', 'bar' ) ); 659 } 660 661 public function test_domain_filtered_to_exist() { 662 add_filter( 'domain_exists', array( $this, 'domain_exists_cb' ), 10, 4 ); 663 $exists = domain_exists( 'foo', 'bar' ); 664 remove_filter( 'domain_exists', array( $this, 'domain_exists_cb' ), 10, 4 ); 665 $this->assertSame( 1234, $exists ); 666 } 667 668 /** 669 * When a path is passed to domain_exists, it is immediately trailing slashed. A path 670 * value with or without the slash should result in the same return value. 671 */ 672 public function test_slashed_path_in_domain_exists() { 673 add_filter( 'domain_exists', array( $this, 'domain_exists_cb' ), 10, 4 ); 674 $exists1 = domain_exists( 'foo', 'bar' ); 675 $exists2 = domain_exists( 'foo', 'bar/' ); 676 remove_filter( 'domain_exists', array( $this, 'domain_exists_cb' ), 10, 4 ); 677 678 // Make sure the same result is returned with or without a trailing slash. 679 $this->assertSame( $exists1, $exists2 ); 680 } 681 682 /** 683 * Tests returning an address for a given valid ID. 684 */ 685 public function test_get_blogaddress_by_id_with_valid_id() { 686 $blogaddress = get_blogaddress_by_id( 1 ); 687 $this->assertSame( 'http://' . WP_TESTS_DOMAIN . '/', $blogaddress ); 688 } 689 690 /** 691 * Tests returning an empty string for a non-existing ID. 692 */ 693 public function test_get_blogaddress_by_id_with_invalid_id() { 694 $blogaddress = get_blogaddress_by_id( PHP_INT_MAX ); 695 $this->assertSame( '', $blogaddress ); 696 } 697 698 /** 699 * @ticket 14867 700 */ 701 public function test_get_blogaddress_by_id_scheme_reflects_blog_scheme() { 702 $blog = self::factory()->blog->create(); 703 704 $this->assertSame( 'http', parse_url( get_blogaddress_by_id( $blog ), PHP_URL_SCHEME ) ); 705 706 update_blog_option( $blog, 'home', set_url_scheme( get_blog_option( $blog, 'home' ), 'https' ) ); 707 708 $this->assertSame( 'https', parse_url( get_blogaddress_by_id( $blog ), PHP_URL_SCHEME ) ); 709 } 710 711 /** 712 * @ticket 14867 713 */ 714 public function test_get_blogaddress_by_id_scheme_is_unaffected_by_request() { 715 $blog = self::factory()->blog->create(); 716 717 $this->assertFalse( is_ssl() ); 718 $this->assertSame( 'http', parse_url( get_blogaddress_by_id( $blog ), PHP_URL_SCHEME ) ); 719 720 $_SERVER['HTTPS'] = 'on'; 721 722 $is_ssl = is_ssl(); 723 $address = parse_url( get_blogaddress_by_id( $blog ), PHP_URL_SCHEME ); 724 725 $this->assertTrue( $is_ssl ); 726 $this->assertSame( 'http', $address ); 727 } 728 729 /** 730 * @ticket 33620 731 * @dataProvider data_new_blog_url_schemes 732 */ 733 public function test_new_blog_url_schemes( $home_scheme, $siteurl_scheme, $force_ssl_admin ) { 734 $current_site = get_current_site(); 735 736 $home = get_option( 'home' ); 737 $siteurl = get_site_option( 'siteurl' ); 738 $admin = force_ssl_admin(); 739 740 // Setup: 741 update_option( 'home', set_url_scheme( $home, $home_scheme ) ); 742 update_site_option( 'siteurl', set_url_scheme( $siteurl, $siteurl_scheme ) ); 743 force_ssl_admin( $force_ssl_admin ); 744 745 // Install: 746 $new = wpmu_create_blog( $current_site->domain, '/new-blog/', 'New Blog', get_current_user_id() ); 747 748 // Reset: 749 update_option( 'home', $home ); 750 update_site_option( 'siteurl', $siteurl ); 751 force_ssl_admin( $admin ); 752 753 // Assert: 754 $this->assertNotWPError( $new ); 755 $this->assertSame( $home_scheme, parse_url( get_blog_option( $new, 'home' ), PHP_URL_SCHEME ) ); 756 $this->assertSame( $siteurl_scheme, parse_url( get_blog_option( $new, 'siteurl' ), PHP_URL_SCHEME ) ); 757 } 758 759 public function data_new_blog_url_schemes() { 760 return array( 761 array( 762 'https', 763 'https', 764 false, 765 ), 766 array( 767 'http', 768 'https', 769 false, 770 ), 771 array( 772 'https', 773 'http', 774 false, 775 ), 776 array( 777 'http', 778 'http', 779 false, 780 ), 781 array( 782 'http', 783 'http', 784 true, 785 ), 786 ); 787 } 788 789 /** 790 * @ticket 36918 791 */ 792 public function test_new_blog_locale() { 793 $current_site = get_current_site(); 794 795 add_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10, 3 ); 796 update_site_option( 'WPLANG', 'de_DE' ); 797 remove_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10 ); 798 799 // No locale, use default locale. 800 add_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10, 3 ); 801 $blog_id = wpmu_create_blog( $current_site->domain, '/de-de/', 'New Blog', get_current_user_id() ); 802 remove_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10 ); 803 804 $this->assertNotWPError( $blog_id ); 805 $this->assertSame( 'de_DE', get_blog_option( $blog_id, 'WPLANG' ) ); 806 807 // Custom locale. 808 add_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10, 3 ); 809 $blog_id = wpmu_create_blog( $current_site->domain, '/es-es/', 'New Blog', get_current_user_id(), array( 'WPLANG' => 'es_ES' ) ); 810 remove_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10 ); 811 812 $this->assertNotWPError( $blog_id ); 813 $this->assertSame( 'es_ES', get_blog_option( $blog_id, 'WPLANG' ) ); 814 815 // en_US locale. 816 add_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10, 3 ); 817 $blog_id = wpmu_create_blog( $current_site->domain, '/en-us/', 'New Blog', get_current_user_id(), array( 'WPLANG' => '' ) ); 818 remove_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10 ); 819 820 $this->assertNotWPError( $blog_id ); 821 $this->assertSame( '', get_blog_option( $blog_id, 'WPLANG' ) ); 822 } 823 824 /** 825 * @ticket 40503 826 */ 827 public function test_different_network_language() { 828 $network = get_network( self::$network_ids['make.wordpress.org/'] ); 829 830 add_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10, 3 ); 831 832 update_network_option( self::$network_ids['make.wordpress.org/'], 'WPLANG', 'wibble' ); 833 $blog_id = wpmu_create_blog( $network->domain, '/de-de/', 'New Blog', get_current_user_id(), array(), $network->id ); 834 835 remove_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10 ); 836 837 $this->assertSame( get_network_option( self::$network_ids['make.wordpress.org/'], 'WPLANG' ), get_blog_option( $blog_id, 'WPLANG' ) ); 838 } 839 840 /** 841 * Allows to set the WPLANG option to any language. 842 * 843 * @param string $value The sanitized option value. 844 * @param string $option The option name. 845 * @param string $original_value The original value passed to the function. 846 * @return string The original value. 847 */ 848 public function filter_allow_unavailable_languages( $value, $option, $original_value ) { 849 return $original_value; 850 } 851 852 /** 853 * @ticket 29684 854 */ 855 public function test_is_main_site_different_network() { 856 $this->assertTrue( is_main_site( self::$site_ids['make.wordpress.org/'], self::$network_ids['make.wordpress.org/'] ) ); 857 } 858 859 /** 860 * @ticket 29684 861 */ 862 public function test_is_main_site_different_network_random_site() { 863 $this->assertFalse( is_main_site( self::$site_ids['make.wordpress.org/foo/'], self::$network_ids['make.wordpress.org/'] ) ); 864 } 865 866 /** 867 * @ticket 40201 868 * @dataProvider data_get_site_caches 869 */ 870 public function test_clean_blog_cache( $key, $group ) { 871 $site = get_site( self::$site_ids['make.wordpress.org/'] ); 872 873 $replacements = array( 874 '%blog_id%' => $site->blog_id, 875 '%domain%' => $site->domain, 876 '%path%' => $site->path, 877 '%domain_path_key%' => md5( $site->domain . $site->path ), 878 ); 879 880 $key = str_replace( array_keys( $replacements ), array_values( $replacements ), $key ); 881 882 if ( 'sites' === $group ) { // This needs to be actual data for get_site() lookups. 883 wp_cache_set( $key, (object) $site->to_array(), $group ); 884 } else { 885 wp_cache_set( $key, 'something', $group ); 237 886 } 238 887 239 /** 240 * When a site is flagged as 'deleted', its data should remain in the database. 241 */ 242 public function test_data_in_tables_after_wpmu_delete_blog_drop_false() { 243 global $wpdb; 244 245 $blog_id = self::factory()->blog->create(); 246 247 // Delete the site without forcing a table drop. 248 wpmu_delete_blog( $blog_id, false ); 249 250 $prefix = $wpdb->get_blog_prefix( $blog_id ); 251 foreach ( $wpdb->tables( 'blog', false ) as $table ) { 252 $suppress = $wpdb->suppress_errors(); 253 254 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 255 $table_fields = $wpdb->get_results( "DESCRIBE $prefix$table;" ); 256 257 $wpdb->suppress_errors( $suppress ); 258 $this->assertNotEmpty( $table_fields, $prefix . $table ); 888 clean_blog_cache( $site ); 889 $this->assertFalse( wp_cache_get( $key, $group ) ); 890 } 891 892 /** 893 * @ticket 40201 894 * @dataProvider data_get_site_caches 895 */ 896 public function test_clean_blog_cache_with_id( $key, $group ) { 897 $site = get_site( self::$site_ids['make.wordpress.org/'] ); 898 899 $replacements = array( 900 '%blog_id%' => $site->blog_id, 901 '%domain%' => $site->domain, 902 '%path%' => $site->path, 903 '%domain_path_key%' => md5( $site->domain . $site->path ), 904 ); 905 906 $key = str_replace( array_keys( $replacements ), array_values( $replacements ), $key ); 907 908 if ( 'sites' === $group ) { // This needs to be actual data for get_site() lookups. 909 wp_cache_set( $key, (object) $site->to_array(), $group ); 910 } else { 911 wp_cache_set( $key, 'something', $group ); 912 } 913 914 clean_blog_cache( $site->blog_id ); 915 $this->assertFalse( wp_cache_get( $key, $group ) ); 916 } 917 918 /** 919 * @ticket 40201 920 */ 921 public function test_clean_blog_cache_resets_last_changed() { 922 $site = get_site( self::$site_ids['make.wordpress.org/'] ); 923 924 wp_cache_delete( 'last_changed', 'sites' ); 925 926 clean_blog_cache( $site ); 927 $this->assertNotFalse( wp_cache_get( 'last_changed', 'sites' ) ); 928 } 929 930 /** 931 * @ticket 40201 932 */ 933 public function test_clean_blog_cache_fires_action() { 934 $site = get_site( self::$site_ids['make.wordpress.org/'] ); 935 936 $old_count = did_action( 'clean_site_cache' ); 937 938 clean_blog_cache( $site ); 939 $this->assertSame( $old_count + 1, did_action( 'clean_site_cache' ) ); 940 } 941 942 /** 943 * @ticket 40201 944 */ 945 public function test_clean_blog_cache_bails_on_suspend_cache_invalidation() { 946 $site = get_site( self::$site_ids['make.wordpress.org/'] ); 947 948 $old_count = did_action( 'clean_site_cache' ); 949 950 $suspend = wp_suspend_cache_invalidation(); 951 clean_blog_cache( $site ); 952 wp_suspend_cache_invalidation( $suspend ); 953 $this->assertSame( $old_count, did_action( 'clean_site_cache' ) ); 954 } 955 956 /** 957 * @ticket 40201 958 */ 959 public function test_clean_blog_cache_bails_on_empty_input() { 960 $old_count = did_action( 'clean_site_cache' ); 961 962 clean_blog_cache( null ); 963 $this->assertSame( $old_count, did_action( 'clean_site_cache' ) ); 964 } 965 966 /** 967 * @ticket 40201 968 */ 969 public function test_clean_blog_cache_bails_on_non_numeric_input() { 970 $old_count = did_action( 'clean_site_cache' ); 971 972 clean_blog_cache( 'something' ); 973 $this->assertSame( $old_count, did_action( 'clean_site_cache' ) ); 974 } 975 976 /** 977 * @ticket 40201 978 */ 979 public function test_clean_blog_cache_works_with_deleted_site() { 980 $site_id = 12345; 981 982 wp_cache_set( $site_id, 'something', 'site-details' ); 983 984 clean_blog_cache( $site_id ); 985 $this->assertFalse( wp_cache_get( $site_id, 'site-details' ) ); 986 } 987 988 /** 989 * @ticket 40201 990 * @dataProvider data_get_site_caches 991 */ 992 public function test_refresh_blog_details( $key, $group ) { 993 $site = get_site( self::$site_ids['make.wordpress.org/'] ); 994 995 $replacements = array( 996 '%blog_id%' => $site->blog_id, 997 '%domain%' => $site->domain, 998 '%path%' => $site->path, 999 '%domain_path_key%' => md5( $site->domain . $site->path ), 1000 ); 1001 1002 $key = str_replace( array_keys( $replacements ), array_values( $replacements ), $key ); 1003 1004 if ( 'sites' === $group ) { // This needs to be actual data for get_site() lookups. 1005 wp_cache_set( $key, (object) $site->to_array(), $group ); 1006 } else { 1007 wp_cache_set( $key, 'something', $group ); 1008 } 1009 1010 refresh_blog_details( $site->blog_id ); 1011 $this->assertFalse( wp_cache_get( $key, $group ) ); 1012 } 1013 1014 /** 1015 * @ticket 40201 1016 */ 1017 public function test_refresh_blog_details_works_with_deleted_site() { 1018 $site_id = 12345; 1019 1020 wp_cache_set( $site_id, 'something', 'site-details' ); 1021 1022 refresh_blog_details( $site_id ); 1023 $this->assertFalse( wp_cache_get( $site_id, 'site-details' ) ); 1024 } 1025 1026 /** 1027 * @ticket 40201 1028 */ 1029 public function test_refresh_blog_details_uses_current_site_as_default() { 1030 $site_id = get_current_blog_id(); 1031 1032 wp_cache_set( $site_id, 'something', 'site-details' ); 1033 1034 refresh_blog_details(); 1035 $this->assertFalse( wp_cache_get( $site_id, 'site-details' ) ); 1036 } 1037 1038 public function data_get_site_caches() { 1039 return array( 1040 array( '%blog_id%', 'sites' ), 1041 array( '%blog_id%', 'site-details' ), 1042 array( '%blog_id%', 'blog-details' ), 1043 array( '%blog_id%' . 'short', 'blog-details' ), 1044 array( '%domain_path_key%', 'blog-lookup' ), 1045 array( '%domain_path_key%', 'blog-id-cache' ), 1046 ); 1047 } 1048 1049 /** 1050 * @ticket 40364 1051 * @dataProvider data_wp_insert_site 1052 */ 1053 public function test_wp_insert_site( $site_data, $expected_data ) { 1054 remove_action( 'wp_initialize_site', 'wp_initialize_site', 10 ); 1055 $site_id = wp_insert_site( $site_data ); 1056 1057 $this->assertIsInt( $site_id ); 1058 1059 $site = get_site( $site_id ); 1060 foreach ( $expected_data as $key => $value ) { 1061 $this->assertEquals( $value, $site->$key ); 1062 } 1063 } 1064 1065 public function data_wp_insert_site() { 1066 return array( 1067 array( 1068 array( 1069 'domain' => 'example.com', 1070 ), 1071 array( 1072 'domain' => 'example.com', 1073 'path' => '/', 1074 'network_id' => 1, 1075 'public' => 1, 1076 'archived' => 0, 1077 'mature' => 0, 1078 'spam' => 0, 1079 'deleted' => 0, 1080 'lang_id' => 0, 1081 ), 1082 ), 1083 array( 1084 array( 1085 'domain' => 'example.com', 1086 'path' => '/foo', 1087 'network_id' => 2, 1088 ), 1089 array( 1090 'domain' => 'example.com', 1091 'path' => '/foo/', 1092 'network_id' => 2, 1093 ), 1094 ), 1095 array( 1096 array( 1097 'domain' => 'example.com', 1098 'path' => '/bar/', 1099 'site_id' => 2, 1100 ), 1101 array( 1102 'domain' => 'example.com', 1103 'path' => '/bar/', 1104 'network_id' => 2, 1105 ), 1106 ), 1107 array( 1108 array( 1109 'domain' => 'example.com', 1110 'path' => '/bar/', 1111 'site_id' => 2, 1112 'network_id' => 3, 1113 ), 1114 array( 1115 'domain' => 'example.com', 1116 'path' => '/bar/', 1117 'network_id' => 3, 1118 ), 1119 ), 1120 array( 1121 array( 1122 'domain' => 'example.com', 1123 'path' => 'foobar', 1124 'public' => 0, 1125 'archived' => 1, 1126 'mature' => 1, 1127 'spam' => 1, 1128 'deleted' => 1, 1129 'lang_id' => 1, 1130 ), 1131 array( 1132 'domain' => 'example.com', 1133 'path' => '/foobar/', 1134 'public' => 0, 1135 'archived' => 1, 1136 'mature' => 1, 1137 'spam' => 1, 1138 'deleted' => 1, 1139 'lang_id' => 1, 1140 ), 1141 ), 1142 array( 1143 array( 1144 'domain' => 'example.com:8888', 1145 ), 1146 array( 1147 'domain' => 'example.com:8888', 1148 'path' => '/', 1149 'network_id' => 1, 1150 'public' => 1, 1151 'archived' => 0, 1152 'mature' => 0, 1153 'spam' => 0, 1154 'deleted' => 0, 1155 'lang_id' => 0, 1156 ), 1157 ), 1158 ); 1159 } 1160 1161 /** 1162 * @ticket 50324 1163 */ 1164 public function test_wp_insert_site_with_clean_site_cache() { 1165 remove_action( 'wp_initialize_site', 'wp_initialize_site', 10 ); 1166 1167 add_action( 'clean_site_cache', array( $this, 'action_database_insert_on_clean_site_cache' ) ); 1168 1169 $site_id = wp_insert_site( 1170 array( 1171 'domain' => 'valid-domain.com', 1172 'path' => '/valid-path/', 1173 'network_id' => 1, 1174 ) 1175 ); 1176 1177 remove_action( 'clean_site_cache', array( $this, 'action_database_insert_on_clean_site_cache' ) ); 1178 1179 $this->assertIsInt( $site_id ); 1180 } 1181 1182 public function action_database_insert_on_clean_site_cache() { 1183 update_site_option( 'database_write_test.' . time(), true ); 1184 } 1185 1186 /** 1187 * @ticket 40364 1188 */ 1189 public function test_wp_insert_site_empty_domain() { 1190 remove_action( 'wp_initialize_site', 'wp_initialize_site', 10 ); 1191 $site_id = wp_insert_site( array( 'public' => 0 ) ); 1192 1193 $this->assertWPError( $site_id ); 1194 $this->assertSame( 'site_empty_domain', $site_id->get_error_code() ); 1195 } 1196 1197 /** 1198 * @ticket 40364 1199 * @dataProvider data_wp_update_site 1200 */ 1201 public function test_wp_update_site( $site_data, $expected_data ) { 1202 $site_id = self::factory()->blog->create(); 1203 1204 $old_site = get_site( $site_id ); 1205 1206 $result = wp_update_site( $site_id, $site_data ); 1207 1208 $this->assertSame( $site_id, $result ); 1209 1210 $new_site = get_site( $site_id ); 1211 foreach ( $new_site->to_array() as $key => $value ) { 1212 if ( isset( $expected_data[ $key ] ) ) { 1213 $this->assertEquals( $expected_data[ $key ], $value ); 1214 } elseif ( 'last_updated' === $key ) { 1215 $this->assertLessThanOrEqual( $value, $old_site->last_updated ); 1216 } else { 1217 $this->assertSame( $old_site->$key, $value ); 259 1218 } 260 1219 } 261 262 /** 263 * When a site is fully deleted, its data should be cleared from cache. 264 */ 265 public function test_data_in_cache_after_wpmu_delete_blog_drop_true() { 266 $blog_id = self::factory()->blog->create(); 267 268 $details = get_blog_details( $blog_id, false ); 269 $key = md5( $details->domain . $details->path ); 270 271 // Delete the site and force a table drop. 272 wpmu_delete_blog( $blog_id, true ); 273 274 $this->assertFalse( wp_cache_get( $blog_id, 'blog-details' ) ); 275 $this->assertFalse( wp_cache_get( $blog_id . 'short', 'blog-details' ) ); 276 $this->assertFalse( wp_cache_get( $key, 'blog-lookup' ) ); 277 $this->assertFalse( wp_cache_get( $key, 'blog-id-cache' ) ); 1220 } 1221 1222 public function data_wp_update_site() { 1223 return array( 1224 array( 1225 array( 1226 'domain' => 'example.com', 1227 'network_id' => 2, 1228 ), 1229 array( 1230 'domain' => 'example.com', 1231 'site_id' => 2, 1232 ), 1233 ), 1234 array( 1235 array( 1236 'path' => 'foo', 1237 ), 1238 array( 1239 'path' => '/foo/', 1240 ), 1241 ), 1242 array( 1243 array( 1244 'public' => 0, 1245 'archived' => 1, 1246 'mature' => 1, 1247 'spam' => 1, 1248 'deleted' => 1, 1249 'lang_id' => 1, 1250 ), 1251 array( 1252 'public' => 0, 1253 'archived' => 1, 1254 'mature' => 1, 1255 'spam' => 1, 1256 'deleted' => 1, 1257 'lang_id' => 1, 1258 ), 1259 ), 1260 array( 1261 array( 1262 'domain' => 'example.com:8888', 1263 'network_id' => 2, 1264 ), 1265 array( 1266 'domain' => 'example.com:8888', 1267 'site_id' => 2, 1268 ), 1269 ), 1270 ); 1271 } 1272 1273 /** 1274 * @ticket 40364 1275 */ 1276 public function test_wp_update_site_empty_domain() { 1277 $site_id = self::factory()->blog->create(); 1278 1279 $result = wp_update_site( $site_id, array( 'domain' => '' ) ); 1280 1281 $this->assertWPError( $result ); 1282 $this->assertSame( 'site_empty_domain', $result->get_error_code() ); 1283 } 1284 1285 /** 1286 * @ticket 40364 1287 */ 1288 public function test_wp_update_site_invalid_id() { 1289 $result = wp_update_site( 444444, array( 'domain' => 'example.com' ) ); 1290 1291 $this->assertWPError( $result ); 1292 $this->assertSame( 'site_not_exist', $result->get_error_code() ); 1293 } 1294 1295 /** 1296 * @ticket 40364 1297 */ 1298 public function test_wp_update_site_cleans_cache() { 1299 $site_id = self::factory()->blog->create(); 1300 $site1 = get_site( $site_id ); 1301 1302 $result = wp_update_site( $site_id, array( 'public' => 0 ) ); 1303 $site2 = get_site( $site_id ); 1304 1305 $result = wp_update_site( $site_id, array( 'public' => 1 ) ); 1306 $site3 = get_site( $site_id ); 1307 1308 $this->assertSame( '1', $site1->public ); 1309 $this->assertSame( '0', $site2->public ); 1310 $this->assertSame( '1', $site3->public ); 1311 } 1312 1313 /** 1314 * @ticket 40364 1315 */ 1316 public function test_wp_delete_site() { 1317 $site_id = self::factory()->blog->create(); 1318 1319 $site = get_site( $site_id ); 1320 1321 $result = wp_delete_site( $site_id ); 1322 1323 $this->assertInstanceOf( 'WP_Site', $result ); 1324 $this->assertSame( $result->to_array(), $site->to_array() ); 1325 } 1326 1327 /** 1328 * @ticket 40364 1329 */ 1330 public function test_wp_delete_site_invalid_id() { 1331 $result = wp_delete_site( 444444 ); 1332 1333 $this->assertWPError( $result ); 1334 $this->assertSame( 'site_not_exist', $result->get_error_code() ); 1335 } 1336 1337 /** 1338 * @ticket 41333 1339 */ 1340 public function test_wp_delete_site_validate_site_deletion_action() { 1341 add_action( 'wp_validate_site_deletion', array( $this, 'action_wp_validate_site_deletion_prevent_deletion' ) ); 1342 $result = wp_delete_site( self::$site_ids['make.wordpress.org/'] ); 1343 $this->assertWPError( $result ); 1344 $this->assertSame( 'action_does_not_like_deletion', $result->get_error_code() ); 1345 } 1346 1347 public function action_wp_validate_site_deletion_prevent_deletion( $errors ) { 1348 $errors->add( 'action_does_not_like_deletion', 'You cannot delete this site because the action does not like it.' ); 1349 } 1350 1351 /** 1352 * @ticket 40364 1353 * @dataProvider data_wp_normalize_site_data 1354 */ 1355 public function test_wp_normalize_site_data( $data, $expected ) { 1356 $result = wp_normalize_site_data( $data ); 1357 1358 $this->assertSameSetsWithIndex( $expected, $result ); 1359 } 1360 1361 public function data_wp_normalize_site_data() { 1362 return array( 1363 array( 1364 array( 1365 'network_id' => '4', 1366 ), 1367 array( 1368 'network_id' => 4, 1369 ), 1370 ), 1371 array( 1372 array( 1373 'domain' => 'invalid domain .com', 1374 'path' => 'foo', 1375 ), 1376 array( 1377 'domain' => 'invaliddomain.com', 1378 'path' => '/foo/', 1379 ), 1380 ), 1381 array( 1382 array( 1383 'domain' => '<yet>/another-invalid-domain.com', 1384 ), 1385 array( 1386 'domain' => 'yetanother-invalid-domain.com', 1387 ), 1388 ), 1389 array( 1390 array( 1391 'domain' => 'with-port.com:8888', 1392 ), 1393 array( 1394 'domain' => 'with-port.com:8888', 1395 ), 1396 ), 1397 array( 1398 array( 1399 'domain' => 'subdomain.with-port.com:8888', 1400 ), 1401 array( 1402 'domain' => 'subdomain.with-port.com:8888', 1403 ), 1404 ), 1405 array( 1406 array( 1407 'path' => '', 1408 ), 1409 array( 1410 'path' => '/', 1411 ), 1412 ), 1413 array( 1414 array( 1415 'public' => '0', 1416 'archived' => '1', 1417 'mature' => '1', 1418 'spam' => true, 1419 'deleted' => true, 1420 ), 1421 array( 1422 'public' => 0, 1423 'archived' => 1, 1424 'mature' => 1, 1425 'spam' => 1, 1426 'deleted' => 1, 1427 ), 1428 ), 1429 array( 1430 array( 1431 'registered' => '', 1432 'last_updated' => '', 1433 ), 1434 array(), 1435 ), 1436 array( 1437 array( 1438 'registered' => '0000-00-00 00:00:00', 1439 'last_updated' => '0000-00-00 00:00:00', 1440 ), 1441 array(), 1442 ), 1443 ); 1444 } 1445 1446 /** 1447 * @ticket 40364 1448 * @dataProvider data_wp_validate_site_data 1449 */ 1450 public function test_wp_validate_site_data( $data, $expected_errors ) { 1451 $result = new WP_Error(); 1452 wp_validate_site_data( $result, $data ); 1453 1454 if ( empty( $expected_errors ) ) { 1455 $this->assertEmpty( $result->errors ); 1456 } else { 1457 $this->assertSameSets( $expected_errors, array_keys( $result->errors ) ); 278 1458 } 279 280 /** 281 * When a site is fully deleted, its data should be removed from the database. 282 */ 283 public function test_data_in_tables_after_wpmu_delete_blog_drop_true() { 284 global $wpdb; 285 286 $blog_id = self::factory()->blog->create(); 287 288 // Delete the site and force a table drop. 289 wpmu_delete_blog( $blog_id, true ); 290 291 $prefix = $wpdb->get_blog_prefix( $blog_id ); 292 foreach ( $wpdb->tables( 'blog', false ) as $table ) { 293 $suppress = $wpdb->suppress_errors(); 294 295 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 296 $table_fields = $wpdb->get_results( "DESCRIBE $prefix$table;" ); 297 298 $wpdb->suppress_errors( $suppress ); 299 $this->assertEmpty( $table_fields ); 300 } 1459 } 1460 1461 public function data_wp_validate_site_data() { 1462 $date = current_time( 'mysql', true ); 1463 1464 return array( 1465 array( 1466 array( 1467 'domain' => 'example-site.com', 1468 'path' => '/', 1469 'network_id' => 1, 1470 'registered' => $date, 1471 'last_updated' => $date, 1472 ), 1473 array(), 1474 ), 1475 array( 1476 array( 1477 'path' => '/', 1478 'network_id' => 1, 1479 'registered' => $date, 1480 'last_updated' => $date, 1481 ), 1482 array( 'site_empty_domain' ), 1483 ), 1484 array( 1485 array( 1486 'domain' => 'example-site.com', 1487 'network_id' => 1, 1488 'registered' => $date, 1489 'last_updated' => $date, 1490 ), 1491 array( 'site_empty_path' ), 1492 ), 1493 array( 1494 array( 1495 'domain' => 'example-site.com', 1496 'path' => '/', 1497 'registered' => $date, 1498 'last_updated' => $date, 1499 ), 1500 array( 'site_empty_network_id' ), 1501 ), 1502 array( 1503 array( 1504 'domain' => get_site()->domain, 1505 'path' => get_site()->path, 1506 'network_id' => get_site()->network_id, 1507 'registered' => $date, 1508 'last_updated' => $date, 1509 ), 1510 array( 'site_taken' ), 1511 ), 1512 array( 1513 array( 1514 'domain' => 'valid-domain.com', 1515 'path' => '/valid-path/', 1516 'network_id' => 1, 1517 'registered' => '', 1518 'last_updated' => $date, 1519 ), 1520 array( 'site_empty_registered' ), 1521 ), 1522 array( 1523 array( 1524 'domain' => 'valid-domain.com', 1525 'path' => '/valid-path/', 1526 'network_id' => 1, 1527 'registered' => $date, 1528 'last_updated' => '', 1529 ), 1530 array( 'site_empty_last_updated' ), 1531 ), 1532 array( 1533 array( 1534 'domain' => 'valid-domain.com', 1535 'path' => '/valid-path/', 1536 'network_id' => 1, 1537 'registered' => '2000-13-32 25:25:61', 1538 'last_updated' => $date, 1539 ), 1540 array( 'site_invalid_registered' ), 1541 ), 1542 array( 1543 array( 1544 'domain' => 'valid-domain.com', 1545 'path' => '/valid-path/', 1546 'network_id' => 1, 1547 'registered' => $date, 1548 'last_updated' => '2000-13-32 25:25:61', 1549 ), 1550 array( 'site_invalid_last_updated' ), 1551 ), 1552 array( 1553 array( 1554 'domain' => 'valid-domain.com', 1555 'path' => '/valid-path/', 1556 'network_id' => 1, 1557 'registered' => '0000-00-00 00:00:00', 1558 'last_updated' => $date, 1559 ), 1560 array(), 1561 ), 1562 array( 1563 array( 1564 'domain' => 'valid-domain.com', 1565 'path' => '/valid-path/', 1566 'network_id' => 1, 1567 'registered' => $date, 1568 'last_updated' => '0000-00-00 00:00:00', 1569 ), 1570 array(), 1571 ), 1572 ); 1573 } 1574 1575 /** 1576 * @ticket 40364 1577 */ 1578 public function test_site_dates_are_gmt() { 1579 $first_date = current_time( 'mysql', true ); 1580 1581 remove_action( 'wp_initialize_site', 'wp_initialize_site', 10 ); 1582 $site_id = wp_insert_site( 1583 array( 1584 'domain' => 'valid-domain.com', 1585 'path' => '/valid-path/', 1586 'network_id' => 1, 1587 ) 1588 ); 1589 $this->assertIsInt( $site_id ); 1590 1591 $site = get_site( $site_id ); 1592 $this->assertEqualsWithDelta( strtotime( $first_date ), strtotime( $site->registered ), 2, 'The dates should be equal' ); 1593 $this->assertEqualsWithDelta( strtotime( $first_date ), strtotime( $site->last_updated ), 2, 'The dates should be equal' ); 1594 1595 $second_date = current_time( 'mysql', true ); 1596 $site_id = wp_update_site( $site_id, array() ); 1597 $this->assertIsInt( $site_id ); 1598 1599 $site = get_site( $site_id ); 1600 $this->assertEqualsWithDelta( strtotime( $first_date ), strtotime( $site->registered ), 2, 'The dates should be equal' ); 1601 $this->assertEqualsWithDelta( strtotime( $second_date ), strtotime( $site->last_updated ), 2, 'The dates should be equal' ); 1602 } 1603 1604 /** 1605 * @ticket 40364 1606 */ 1607 public function test_wp_delete_site_cleans_cache() { 1608 $site_id = self::factory()->blog->create(); 1609 1610 get_site( $site_id ); 1611 1612 wp_delete_site( $site_id ); 1613 1614 $this->assertNull( get_site( $site_id ) ); 1615 } 1616 1617 /** 1618 * @ticket 40364 1619 */ 1620 public function test_wp_update_site_cleans_old_cache_on_domain_change() { 1621 $old_domain = 'old.wordpress.org'; 1622 $new_domain = 'new.wordpress.org'; 1623 1624 $site = self::factory()->blog->create_and_get( 1625 array( 1626 'domain' => $old_domain, 1627 'path' => '/', 1628 ) 1629 ); 1630 1631 // Populate the caches. 1632 get_blog_details( 1633 array( 1634 'domain' => $old_domain, 1635 'path' => '/', 1636 ) 1637 ); 1638 get_blog_id_from_url( $old_domain, '/' ); 1639 get_blog_details( 1640 array( 1641 'domain' => $new_domain, 1642 'path' => '/', 1643 ) 1644 ); 1645 get_blog_id_from_url( $new_domain, '/' ); 1646 1647 wp_update_site( 1648 $site->id, 1649 array( 1650 'domain' => $new_domain, 1651 ) 1652 ); 1653 1654 $domain_path_key_old = md5( $old_domain . '/' ); 1655 $domain_path_key_new = md5( $new_domain . '/' ); 1656 1657 // Ensure all respective cache values are empty. 1658 $result = array( 1659 wp_cache_get( $domain_path_key_old, 'blog-lookup' ), 1660 wp_cache_get( $domain_path_key_old, 'blog-id-cache' ), 1661 wp_cache_get( 'current_blog_' . $old_domain, 'site-options' ), 1662 wp_cache_get( 'current_blog_' . $old_domain . '/', 'site-options' ), 1663 wp_cache_get( $domain_path_key_new, 'blog-lookup' ), 1664 wp_cache_get( $domain_path_key_new, 'blog-id-cache' ), 1665 wp_cache_get( 'current_blog_' . $new_domain, 'site-options' ), 1666 wp_cache_get( 'current_blog_' . $new_domain . '/', 'site-options' ), 1667 ); 1668 1669 $this->assertEmpty( array_filter( $result ) ); 1670 } 1671 1672 /** 1673 * @ticket 40364 1674 */ 1675 public function test_wp_update_site_cleans_old_cache_on_path_change() { 1676 $old_path = '/foo/'; 1677 $new_path = '/bar/'; 1678 1679 $site = self::factory()->blog->create_and_get( 1680 array( 1681 'domain' => 'test.wordpress.org', 1682 'path' => $old_path, 1683 ) 1684 ); 1685 1686 // Populate the caches. 1687 get_blog_details( 1688 array( 1689 'domain' => 'test.wordpress.org', 1690 'path' => $old_path, 1691 ) 1692 ); 1693 get_blog_id_from_url( 'test.wordpress.org', $old_path ); 1694 get_blog_details( 1695 array( 1696 'domain' => 'test.wordpress.org', 1697 'path' => $new_path, 1698 ) 1699 ); 1700 get_blog_id_from_url( 'test.wordpress.org', $new_path ); 1701 1702 wp_update_site( 1703 $site->id, 1704 array( 1705 'path' => $new_path, 1706 ) 1707 ); 1708 1709 $domain_path_key_old = md5( 'test.wordpress.org' . $old_path ); 1710 $domain_path_key_new = md5( 'test.wordpress.org' . $new_path ); 1711 1712 // Ensure all respective cache values are empty. 1713 $result = array( 1714 wp_cache_get( $domain_path_key_old, 'blog-lookup' ), 1715 wp_cache_get( $domain_path_key_old, 'blog-id-cache' ), 1716 wp_cache_get( 'current_blog_test.wordpress.org' . $old_path, 'site-options' ), 1717 wp_cache_get( $domain_path_key_new, 'blog-lookup' ), 1718 wp_cache_get( $domain_path_key_new, 'blog-id-cache' ), 1719 wp_cache_get( 'current_blog_test.wordpress.org' . $new_path, 'site-options' ), 1720 ); 1721 1722 $this->assertEmpty( array_filter( $result ) ); 1723 } 1724 1725 /** 1726 * @ticket 40364 1727 * @dataProvider data_site_status_hook_triggers 1728 */ 1729 public function test_site_status_hook_triggers( $insert_site_data, $expected_insert_hooks, $update_site_data, $expected_update_hooks ) { 1730 // First: Insert a site. 1731 $this->listen_to_site_status_hooks(); 1732 1733 $site_data = array_merge( 1734 array( 1735 'domain' => 'example-site.com', 1736 'path' => '/', 1737 ), 1738 $insert_site_data 1739 ); 1740 1741 $site_id = wp_insert_site( $site_data ); 1742 1743 $insert_expected = array_fill_keys( $expected_insert_hooks, $site_id ); 1744 $insert_result = $this->get_listen_to_site_status_hooks_result(); 1745 1746 // Second: Update that site. 1747 $this->listen_to_site_status_hooks(); 1748 1749 wp_update_site( $site_id, $update_site_data ); 1750 1751 $update_expected = array_fill_keys( $expected_update_hooks, $site_id ); 1752 $update_result = $this->get_listen_to_site_status_hooks_result(); 1753 1754 // Check both insert and update results. 1755 $this->assertSameSetsWithIndex( $insert_expected, $insert_result ); 1756 $this->assertSameSetsWithIndex( $update_expected, $update_result ); 1757 } 1758 1759 public function data_site_status_hook_triggers() { 1760 return array( 1761 array( 1762 array( 1763 'public' => 1, 1764 'archived' => 1, 1765 'mature' => 1, 1766 'spam' => 1, 1767 'deleted' => 1, 1768 ), 1769 array( 1770 'archive_blog', 1771 'mature_blog', 1772 'make_spam_blog', 1773 'make_delete_blog', 1774 ), 1775 array( 1776 'public' => 0, 1777 'archived' => 0, 1778 'mature' => 0, 1779 'spam' => 0, 1780 'deleted' => 0, 1781 ), 1782 array( 1783 'update_blog_public', 1784 'unarchive_blog', 1785 'unmature_blog', 1786 'make_ham_blog', 1787 'make_undelete_blog', 1788 ), 1789 ), 1790 array( 1791 array( 1792 'public' => 0, 1793 'archived' => 0, 1794 'mature' => 0, 1795 'spam' => 0, 1796 'deleted' => 0, 1797 ), 1798 array( 1799 'update_blog_public', 1800 ), 1801 array( 1802 'public' => 1, 1803 'archived' => 1, 1804 'mature' => 1, 1805 'spam' => 1, 1806 'deleted' => 1, 1807 ), 1808 array( 1809 'update_blog_public', 1810 'archive_blog', 1811 'mature_blog', 1812 'make_spam_blog', 1813 'make_delete_blog', 1814 ), 1815 ), 1816 array( 1817 array( 1818 'public' => 0, 1819 'archived' => 0, 1820 'mature' => 1, 1821 'spam' => 1, 1822 'deleted' => 1, 1823 ), 1824 array( 1825 'update_blog_public', 1826 'mature_blog', 1827 'make_spam_blog', 1828 'make_delete_blog', 1829 ), 1830 array( 1831 'public' => 0, 1832 'archived' => 1, 1833 'mature' => 1, 1834 'spam' => 1, 1835 'deleted' => 0, 1836 ), 1837 array( 1838 'archive_blog', 1839 'make_undelete_blog', 1840 ), 1841 ), 1842 ); 1843 } 1844 1845 private function listen_to_site_status_hooks() { 1846 $this->site_status_hooks = array(); 1847 1848 $hooknames = array( 1849 'make_spam_blog', 1850 'make_ham_blog', 1851 'mature_blog', 1852 'unmature_blog', 1853 'archive_blog', 1854 'unarchive_blog', 1855 'make_delete_blog', 1856 'make_undelete_blog', 1857 'update_blog_public', 1858 ); 1859 1860 foreach ( $hooknames as $hookname ) { 1861 add_action( $hookname, array( $this, 'action_site_status_hook' ), 10, 1 ); 301 1862 } 302 303 /** 304 * When the main site of a network is fully deleted, its data should be cleared from cache.305 */306 public function test_data_in_cache_after_wpmu_delete_blog_main_site_drop_true() {307 $blog_id = 1; // The main site in our test suite has an ID of 1.308 309 $details = get_blog_details( $blog_id, false );310 $key = md5( $details->domain . $details->path );311 312 // Delete the site and force a table drop.313 wpmu_delete_blog( $blog_id, true );314 315 $this->assertFalse( wp_cache_get( $blog_id, 'blog-details' ));316 $this->assertFalse( wp_cache_get( $blog_id . 'short', 'blog-details' ) ); 317 $this->assertFalse( wp_cache_get( $key, 'blog-lookup' ) );318 $this->assertFalse( wp_cache_get( $key, 'blog-id-cache' ));1863 } 1864 1865 private function get_listen_to_site_status_hooks_result() { 1866 $hooknames = array( 1867 'make_spam_blog', 1868 'make_ham_blog', 1869 'mature_blog', 1870 'unmature_blog', 1871 'archive_blog', 1872 'unarchive_blog', 1873 'make_delete_blog', 1874 'make_undelete_blog', 1875 'update_blog_public', 1876 ); 1877 1878 foreach ( $hooknames as $hookname ) { 1879 remove_action( $hookname, array( $this, 'action_site_status_hook' ), 10 ); 319 1880 } 320 1881 321 /** 322 * When the main site of a network is fully deleted, its data should remain in the database. 323 */ 324 public function test_data_in_tables_after_wpmu_delete_blog_main_site_drop_true() { 325 global $wpdb; 326 327 $blog_id = 1; // The main site in our test suite has an ID of 1. 328 329 // Delete the site and force a table drop. 330 wpmu_delete_blog( $blog_id, true ); 331 332 $prefix = $wpdb->get_blog_prefix( $blog_id ); 333 foreach ( $wpdb->tables( 'blog', false ) as $table ) { 334 $suppress = $wpdb->suppress_errors(); 335 336 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 337 $table_fields = $wpdb->get_results( "DESCRIBE $prefix$table;" ); 338 339 $wpdb->suppress_errors( $suppress ); 340 $this->assertNotEmpty( $table_fields, $prefix . $table ); 341 } 1882 return $this->site_status_hooks; 1883 } 1884 1885 public function action_site_status_hook( $site_id ) { 1886 $this->site_status_hooks[ current_action() ] = $site_id; 1887 } 1888 1889 /** 1890 * @ticket 41333 1891 * @dataProvider data_wp_initialize_site 1892 */ 1893 public function test_wp_initialize_site( $args, $expected_options, $expected_meta ) { 1894 $result = wp_initialize_site( self::$uninitialized_site_id, $args ); 1895 1896 switch_to_blog( self::$uninitialized_site_id ); 1897 1898 $options = array(); 1899 foreach ( $expected_options as $option => $value ) { 1900 $options[ $option ] = get_option( $option ); 342 1901 } 343 1902 344 /** 345 * The site count of a network should change when a site is flagged as 'deleted'. 346 */ 347 public function test_network_count_after_wpmu_delete_blog_drop_false() { 348 $blog_id = self::factory()->blog->create(); 349 350 // Delete the site without forcing a table drop. 351 wpmu_delete_blog( $blog_id, false ); 352 353 // Update the blog count cache to use get_blog_count(). 354 wp_update_network_counts(); 355 $this->assertSame( 1, get_blog_count() ); 1903 $meta = array(); 1904 foreach ( $expected_meta as $meta_key => $value ) { 1905 $meta[ $meta_key ] = get_site_meta( self::$uninitialized_site_id, $meta_key, true ); 356 1906 } 357 1907 358 /** 359 * The site count of a network should change when a site is fully deleted. 360 */ 361 public function test_blog_count_after_wpmu_delete_blog_drop_true() { 362 $blog_id = self::factory()->blog->create(); 363 364 // Delete the site and force a table drop. 365 wpmu_delete_blog( $blog_id, true ); 366 367 // Update the blog count cache to use get_blog_count(). 368 wp_update_network_counts(); 369 $this->assertSame( 1, get_blog_count() ); 370 } 371 372 /** 373 * When a site is deleted with wpmu_delete_blog(), only the files associated with 374 * that site should be removed. When wpmu_delete_blog() is run a second time, nothing 375 * should change with upload directories. 376 */ 377 public function test_upload_directories_after_multiple_wpmu_delete_blog() { 378 $filename = __FUNCTION__ . '.jpg'; 379 $contents = __FUNCTION__ . '_contents'; 380 381 // Upload a file to the main site on the network. 382 $file1 = wp_upload_bits( $filename, null, $contents ); 383 384 $blog_id = self::factory()->blog->create(); 385 386 switch_to_blog( $blog_id ); 387 $file2 = wp_upload_bits( $filename, null, $contents ); 388 restore_current_blog(); 389 390 wpmu_delete_blog( $blog_id, true ); 391 392 // The file on the main site should still exist. The file on the deleted site should not. 393 $this->assertFileExists( $file1['file'] ); 394 $this->assertFileDoesNotExist( $file2['file'] ); 395 396 wpmu_delete_blog( $blog_id, true ); 397 398 // The file on the main site should still exist. The file on the deleted site should not. 399 $this->assertFileExists( $file1['file'] ); 400 $this->assertFileDoesNotExist( $file2['file'] ); 401 402 unlink( $file1['file'] ); 403 } 404 405 public function test_wpmu_update_blogs_date() { 406 global $wpdb; 407 408 wpmu_update_blogs_date(); 409 410 $blog = get_site( get_current_blog_id() ); 411 $current_time = time(); 412 413 // Compare the update time with the current time, allow delta < 2. 414 $this->assertEqualsWithDelta( $current_time, strtotime( $blog->last_updated ), 2, 'The dates should be equal' ); 415 } 416 417 /** 418 * Test cached data for a site that does not exist and then again after it exists. 419 * 420 * @ticket 23405 421 */ 422 public function test_get_blog_details_when_site_does_not_exist() { 423 // Create an unused site so that we can then assume an invalid site ID. 424 $blog_id = self::factory()->blog->create(); 425 ++$blog_id; 426 427 // Prime the cache for an invalid site. 428 get_blog_details( $blog_id ); 429 430 // When the cache is primed with an invalid site, the value is set to -1. 431 $this->assertSame( -1, wp_cache_get( $blog_id, 'blog-details' ) ); 432 433 // Create a site in the invalid site's place. 434 self::factory()->blog->create(); 435 436 // When a new site is created, its cache is cleared through refresh_blog_details. 437 $this->assertFalse( wp_cache_get( $blog_id, 'blog-details' ) ); 438 439 $blog = get_blog_details( $blog_id ); 440 441 // When the cache is refreshed, it should now equal the site data. 442 $this->assertEquals( $blog, wp_cache_get( $blog_id, 'blog-details' ) ); 443 } 444 445 /** 446 * @ticket 26410 447 */ 448 public function test_blog_details_cache_invalidation() { 449 update_option( 'blogname', 'foo' ); 450 $details = get_site( get_current_blog_id() ); 451 $this->assertSame( 'foo', $details->blogname ); 452 453 update_option( 'blogname', 'bar' ); 454 $details = get_site( get_current_blog_id() ); 455 $this->assertSame( 'bar', $details->blogname ); 456 } 457 458 /** 459 * Test the original and cached responses for a created and then deleted site when 460 * the blog ID is requested through get_blog_id_from_url(). 461 */ 462 public function test_get_blog_id_from_url() { 463 $blog_id = self::factory()->blog->create(); 464 $details = get_site( $blog_id ); 465 $key = md5( $details->domain . $details->path ); 466 467 // Test the original response and cached response for the newly created site. 468 $this->assertSame( $blog_id, get_blog_id_from_url( $details->domain, $details->path ) ); 469 $this->assertSame( $blog_id, wp_cache_get( $key, 'blog-id-cache' ) ); 470 } 471 472 /** 473 * Test the case insensitivity of the site lookup. 474 */ 475 public function test_get_blog_id_from_url_is_case_insensitive() { 476 $blog_id = self::factory()->blog->create( 477 array( 478 'domain' => 'example.com', 479 'path' => '/xyz', 480 ) 481 ); 482 $details = get_site( $blog_id ); 483 484 $this->assertSame( $blog_id, get_blog_id_from_url( strtoupper( $details->domain ), strtoupper( $details->path ) ) ); 485 } 486 487 /** 488 * Test the first and cached responses for a site that does not exist. 489 */ 490 public function test_get_blog_id_from_url_that_does_not_exist() { 491 $blog_id = self::factory()->blog->create( array( 'path' => '/xyz' ) ); 492 $details = get_site( $blog_id ); 493 494 $this->assertSame( 0, get_blog_id_from_url( $details->domain, 'foo' ) ); 495 $this->assertSame( -1, wp_cache_get( md5( $details->domain . 'foo' ), 'blog-id-cache' ) ); 496 } 497 498 /** 499 * A blog ID is still available if only the `deleted` flag is set for a site. The same 500 * behavior would be expected if passing `false` explicitly to `wpmu_delete_blog()`. 501 */ 502 public function test_get_blog_id_from_url_with_deleted_flag() { 503 $blog_id = self::factory()->blog->create(); 504 $details = get_site( $blog_id ); 505 $key = md5( $details->domain . $details->path ); 506 wpmu_delete_blog( $blog_id ); 507 508 $this->assertSame( $blog_id, get_blog_id_from_url( $details->domain, $details->path ) ); 509 $this->assertSame( $blog_id, wp_cache_get( $key, 'blog-id-cache' ) ); 510 } 511 512 /** 513 * When deleted with the drop parameter as true, the cache will first be false, then set to 514 * -1 after an attempt at `get_blog_id_from_url()` is made. 515 */ 516 public function test_get_blog_id_from_url_after_dropped() { 517 $blog_id = self::factory()->blog->create(); 518 $details = get_site( $blog_id ); 519 $key = md5( $details->domain . $details->path ); 520 wpmu_delete_blog( $blog_id, true ); 521 522 $this->assertFalse( wp_cache_get( $key, 'blog-id-cache' ) ); 523 $this->assertSame( 0, get_blog_id_from_url( $details->domain, $details->path ) ); 524 $this->assertSame( -1, wp_cache_get( $key, 'blog-id-cache' ) ); 525 } 526 527 /** 528 * Test with default parameter of site_id as null. 529 */ 530 public function test_is_main_site() { 531 $this->assertTrue( is_main_site() ); 532 } 533 534 /** 535 * Test with a site id of get_current_blog_id(), which should be the same as the 536 * default parameter tested above. 537 */ 538 public function test_current_blog_id_is_main_site() { 539 $this->assertTrue( is_main_site( get_current_blog_id() ) ); 540 } 541 542 /** 543 * Test with a site ID other than the main site to ensure a false response. 544 */ 545 public function test_is_main_site_is_false_with_other_blog_id() { 546 $blog_id = self::factory()->blog->create(); 547 548 $this->assertFalse( is_main_site( $blog_id ) ); 549 } 550 551 /** 552 * Test with no passed ID after switching to another site ID. 553 */ 554 public function test_is_main_site_is_false_after_switch_to_blog() { 555 $blog_id = self::factory()->blog->create(); 556 switch_to_blog( $blog_id ); 557 558 $this->assertFalse( is_main_site() ); 559 560 restore_current_blog(); 561 } 562 563 public function test_switch_upload_dir() { 564 $this->assertTrue( is_main_site() ); 565 566 $site = get_current_site(); 567 $date = date_format( date_create( 'now' ), 'Y/m' ); 568 569 $info = wp_upload_dir(); 570 $this->assertSame( 'http://' . $site->domain . '/wp-content/uploads/' . $date, $info['url'] ); 571 $this->assertSame( ABSPATH . 'wp-content/uploads/' . $date, $info['path'] ); 572 $this->assertSame( '/' . $date, $info['subdir'] ); 573 $this->assertFalse( $info['error'] ); 574 575 $blog_id = self::factory()->blog->create(); 576 577 switch_to_blog( $blog_id ); 578 $info = wp_upload_dir(); 579 $this->assertSame( 'http://' . $site->domain . '/wp-content/uploads/sites/' . get_current_blog_id() . '/' . $date, $info['url'] ); 580 $this->assertSame( ABSPATH . 'wp-content/uploads/sites/' . get_current_blog_id() . '/' . $date, $info['path'] ); 581 $this->assertSame( '/' . $date, $info['subdir'] ); 582 $this->assertFalse( $info['error'] ); 583 restore_current_blog(); 584 585 $info = wp_upload_dir(); 586 $this->assertSame( 'http://' . $site->domain . '/wp-content/uploads/' . $date, $info['url'] ); 587 $this->assertSame( ABSPATH . 'wp-content/uploads/' . $date, $info['path'] ); 588 $this->assertSame( '/' . $date, $info['subdir'] ); 589 $this->assertFalse( $info['error'] ); 590 } 591 592 /** 593 * Test the primary purpose of get_blog_post(), to retrieve a post from 594 * another site on the network. 595 */ 596 public function test_get_blog_post_from_another_site_on_network() { 597 $blog_id = self::factory()->blog->create(); 598 $post_id = self::factory()->post->create(); // Create a post on the primary site, ID 1. 599 $post = get_post( $post_id ); 600 switch_to_blog( $blog_id ); 601 602 // The post created and retrieved on the main site should match the one retrieved "remotely". 603 $this->assertEquals( $post, get_blog_post( 1, $post_id ) ); 604 605 restore_current_blog(); 606 } 607 608 /** 609 * If get_blog_post() is used on the same site, it should still work. 610 */ 611 public function test_get_blog_post_from_same_site() { 612 $post_id = self::factory()->post->create(); 613 614 $this->assertEquals( get_blog_post( 1, $post_id ), get_post( $post_id ) ); 615 } 616 617 /** 618 * A null response should be returned if an invalid post is requested. 619 */ 620 public function test_get_blog_post_invalid_returns_null() { 621 $this->assertNull( get_blog_post( 1, 999999 ) ); 622 } 623 624 /** 625 * Added as a callback to the domain_exists filter to provide manual results for 626 * the testing of the filter and for a test which does not need the database. 627 */ 628 public function domain_exists_cb( $exists, $domain, $path, $site_id ) { 629 if ( 'foo' === $domain && 'bar/' === $path ) { 630 return 1234; 631 } else { 632 return null; 633 } 634 } 635 636 public function test_domain_exists_with_default_site_id() { 637 $details = get_site( 1 ); 638 639 $this->assertSame( 1, domain_exists( $details->domain, $details->path ) ); 640 } 641 642 public function test_domain_exists_with_specified_site_id() { 643 $details = get_site( 1 ); 644 645 $this->assertSame( 1, domain_exists( $details->domain, $details->path, $details->site_id ) ); 646 } 647 648 /** 649 * When the domain is valid, but the resulting site does not belong to the specified network, 650 * it is marked as not existing. 651 */ 652 public function test_domain_does_not_exist_with_invalid_site_id() { 653 $details = get_site( 1 ); 654 655 $this->assertNull( domain_exists( $details->domain, $details->path, 999 ) ); 656 } 657 658 public function test_invalid_domain_does_not_exist_with_default_site_id() { 659 $this->assertNull( domain_exists( 'foo', 'bar' ) ); 660 } 661 662 public function test_domain_filtered_to_exist() { 663 add_filter( 'domain_exists', array( $this, 'domain_exists_cb' ), 10, 4 ); 664 $exists = domain_exists( 'foo', 'bar' ); 665 remove_filter( 'domain_exists', array( $this, 'domain_exists_cb' ), 10, 4 ); 666 $this->assertSame( 1234, $exists ); 667 } 668 669 /** 670 * When a path is passed to domain_exists, it is immediately trailing slashed. A path 671 * value with or without the slash should result in the same return value. 672 */ 673 public function test_slashed_path_in_domain_exists() { 674 add_filter( 'domain_exists', array( $this, 'domain_exists_cb' ), 10, 4 ); 675 $exists1 = domain_exists( 'foo', 'bar' ); 676 $exists2 = domain_exists( 'foo', 'bar/' ); 677 remove_filter( 'domain_exists', array( $this, 'domain_exists_cb' ), 10, 4 ); 678 679 // Make sure the same result is returned with or without a trailing slash. 680 $this->assertSame( $exists1, $exists2 ); 681 } 682 683 /** 684 * Tests returning an address for a given valid ID. 685 */ 686 public function test_get_blogaddress_by_id_with_valid_id() { 687 $blogaddress = get_blogaddress_by_id( 1 ); 688 $this->assertSame( 'http://' . WP_TESTS_DOMAIN . '/', $blogaddress ); 689 } 690 691 /** 692 * Tests returning an empty string for a non-existing ID. 693 */ 694 public function test_get_blogaddress_by_id_with_invalid_id() { 695 $blogaddress = get_blogaddress_by_id( PHP_INT_MAX ); 696 $this->assertSame( '', $blogaddress ); 697 } 698 699 /** 700 * @ticket 14867 701 */ 702 public function test_get_blogaddress_by_id_scheme_reflects_blog_scheme() { 703 $blog = self::factory()->blog->create(); 704 705 $this->assertSame( 'http', parse_url( get_blogaddress_by_id( $blog ), PHP_URL_SCHEME ) ); 706 707 update_blog_option( $blog, 'home', set_url_scheme( get_blog_option( $blog, 'home' ), 'https' ) ); 708 709 $this->assertSame( 'https', parse_url( get_blogaddress_by_id( $blog ), PHP_URL_SCHEME ) ); 710 } 711 712 /** 713 * @ticket 14867 714 */ 715 public function test_get_blogaddress_by_id_scheme_is_unaffected_by_request() { 716 $blog = self::factory()->blog->create(); 717 718 $this->assertFalse( is_ssl() ); 719 $this->assertSame( 'http', parse_url( get_blogaddress_by_id( $blog ), PHP_URL_SCHEME ) ); 720 721 $_SERVER['HTTPS'] = 'on'; 722 723 $is_ssl = is_ssl(); 724 $address = parse_url( get_blogaddress_by_id( $blog ), PHP_URL_SCHEME ); 725 726 $this->assertTrue( $is_ssl ); 727 $this->assertSame( 'http', $address ); 728 } 729 730 /** 731 * @ticket 33620 732 * @dataProvider data_new_blog_url_schemes 733 */ 734 public function test_new_blog_url_schemes( $home_scheme, $siteurl_scheme, $force_ssl_admin ) { 735 $current_site = get_current_site(); 736 737 $home = get_option( 'home' ); 738 $siteurl = get_site_option( 'siteurl' ); 739 $admin = force_ssl_admin(); 740 741 // Setup: 742 update_option( 'home', set_url_scheme( $home, $home_scheme ) ); 743 update_site_option( 'siteurl', set_url_scheme( $siteurl, $siteurl_scheme ) ); 744 force_ssl_admin( $force_ssl_admin ); 745 746 // Install: 747 $new = wpmu_create_blog( $current_site->domain, '/new-blog/', 'New Blog', get_current_user_id() ); 748 749 // Reset: 750 update_option( 'home', $home ); 751 update_site_option( 'siteurl', $siteurl ); 752 force_ssl_admin( $admin ); 753 754 // Assert: 755 $this->assertNotWPError( $new ); 756 $this->assertSame( $home_scheme, parse_url( get_blog_option( $new, 'home' ), PHP_URL_SCHEME ) ); 757 $this->assertSame( $siteurl_scheme, parse_url( get_blog_option( $new, 'siteurl' ), PHP_URL_SCHEME ) ); 758 } 759 760 public function data_new_blog_url_schemes() { 761 return array( 762 array( 763 'https', 764 'https', 765 false, 766 ), 767 array( 768 'http', 769 'https', 770 false, 771 ), 772 array( 773 'https', 774 'http', 775 false, 776 ), 777 array( 778 'http', 779 'http', 780 false, 781 ), 782 array( 783 'http', 784 'http', 785 true, 786 ), 787 ); 788 } 789 790 /** 791 * @ticket 36918 792 */ 793 public function test_new_blog_locale() { 794 $current_site = get_current_site(); 795 796 add_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10, 3 ); 797 update_site_option( 'WPLANG', 'de_DE' ); 798 remove_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10 ); 799 800 // No locale, use default locale. 801 add_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10, 3 ); 802 $blog_id = wpmu_create_blog( $current_site->domain, '/de-de/', 'New Blog', get_current_user_id() ); 803 remove_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10 ); 804 805 $this->assertNotWPError( $blog_id ); 806 $this->assertSame( 'de_DE', get_blog_option( $blog_id, 'WPLANG' ) ); 807 808 // Custom locale. 809 add_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10, 3 ); 810 $blog_id = wpmu_create_blog( $current_site->domain, '/es-es/', 'New Blog', get_current_user_id(), array( 'WPLANG' => 'es_ES' ) ); 811 remove_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10 ); 812 813 $this->assertNotWPError( $blog_id ); 814 $this->assertSame( 'es_ES', get_blog_option( $blog_id, 'WPLANG' ) ); 815 816 // en_US locale. 817 add_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10, 3 ); 818 $blog_id = wpmu_create_blog( $current_site->domain, '/en-us/', 'New Blog', get_current_user_id(), array( 'WPLANG' => '' ) ); 819 remove_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10 ); 820 821 $this->assertNotWPError( $blog_id ); 822 $this->assertSame( '', get_blog_option( $blog_id, 'WPLANG' ) ); 823 } 824 825 /** 826 * @ticket 40503 827 */ 828 public function test_different_network_language() { 829 $network = get_network( self::$network_ids['make.wordpress.org/'] ); 830 831 add_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10, 3 ); 832 833 update_network_option( self::$network_ids['make.wordpress.org/'], 'WPLANG', 'wibble' ); 834 $blog_id = wpmu_create_blog( $network->domain, '/de-de/', 'New Blog', get_current_user_id(), array(), $network->id ); 835 836 remove_filter( 'sanitize_option_WPLANG', array( $this, 'filter_allow_unavailable_languages' ), 10 ); 837 838 $this->assertSame( get_network_option( self::$network_ids['make.wordpress.org/'], 'WPLANG' ), get_blog_option( $blog_id, 'WPLANG' ) ); 839 } 840 841 /** 842 * Allows to set the WPLANG option to any language. 843 * 844 * @param string $value The sanitized option value. 845 * @param string $option The option name. 846 * @param string $original_value The original value passed to the function. 847 * @return string The original value. 848 */ 849 public function filter_allow_unavailable_languages( $value, $option, $original_value ) { 850 return $original_value; 851 } 852 853 /** 854 * @ticket 29684 855 */ 856 public function test_is_main_site_different_network() { 857 $this->assertTrue( is_main_site( self::$site_ids['make.wordpress.org/'], self::$network_ids['make.wordpress.org/'] ) ); 858 } 859 860 /** 861 * @ticket 29684 862 */ 863 public function test_is_main_site_different_network_random_site() { 864 $this->assertFalse( is_main_site( self::$site_ids['make.wordpress.org/foo/'], self::$network_ids['make.wordpress.org/'] ) ); 865 } 866 867 /** 868 * @ticket 40201 869 * @dataProvider data_get_site_caches 870 */ 871 public function test_clean_blog_cache( $key, $group ) { 872 $site = get_site( self::$site_ids['make.wordpress.org/'] ); 873 874 $replacements = array( 875 '%blog_id%' => $site->blog_id, 876 '%domain%' => $site->domain, 877 '%path%' => $site->path, 878 '%domain_path_key%' => md5( $site->domain . $site->path ), 879 ); 880 881 $key = str_replace( array_keys( $replacements ), array_values( $replacements ), $key ); 882 883 if ( 'sites' === $group ) { // This needs to be actual data for get_site() lookups. 884 wp_cache_set( $key, (object) $site->to_array(), $group ); 885 } else { 886 wp_cache_set( $key, 'something', $group ); 887 } 888 889 clean_blog_cache( $site ); 890 $this->assertFalse( wp_cache_get( $key, $group ) ); 891 } 892 893 /** 894 * @ticket 40201 895 * @dataProvider data_get_site_caches 896 */ 897 public function test_clean_blog_cache_with_id( $key, $group ) { 898 $site = get_site( self::$site_ids['make.wordpress.org/'] ); 899 900 $replacements = array( 901 '%blog_id%' => $site->blog_id, 902 '%domain%' => $site->domain, 903 '%path%' => $site->path, 904 '%domain_path_key%' => md5( $site->domain . $site->path ), 905 ); 906 907 $key = str_replace( array_keys( $replacements ), array_values( $replacements ), $key ); 908 909 if ( 'sites' === $group ) { // This needs to be actual data for get_site() lookups. 910 wp_cache_set( $key, (object) $site->to_array(), $group ); 911 } else { 912 wp_cache_set( $key, 'something', $group ); 913 } 914 915 clean_blog_cache( $site->blog_id ); 916 $this->assertFalse( wp_cache_get( $key, $group ) ); 917 } 918 919 /** 920 * @ticket 40201 921 */ 922 public function test_clean_blog_cache_resets_last_changed() { 923 $site = get_site( self::$site_ids['make.wordpress.org/'] ); 924 925 wp_cache_delete( 'last_changed', 'sites' ); 926 927 clean_blog_cache( $site ); 928 $this->assertNotFalse( wp_cache_get( 'last_changed', 'sites' ) ); 929 } 930 931 /** 932 * @ticket 40201 933 */ 934 public function test_clean_blog_cache_fires_action() { 935 $site = get_site( self::$site_ids['make.wordpress.org/'] ); 936 937 $old_count = did_action( 'clean_site_cache' ); 938 939 clean_blog_cache( $site ); 940 $this->assertSame( $old_count + 1, did_action( 'clean_site_cache' ) ); 941 } 942 943 /** 944 * @ticket 40201 945 */ 946 public function test_clean_blog_cache_bails_on_suspend_cache_invalidation() { 947 $site = get_site( self::$site_ids['make.wordpress.org/'] ); 948 949 $old_count = did_action( 'clean_site_cache' ); 950 951 $suspend = wp_suspend_cache_invalidation(); 952 clean_blog_cache( $site ); 953 wp_suspend_cache_invalidation( $suspend ); 954 $this->assertSame( $old_count, did_action( 'clean_site_cache' ) ); 955 } 956 957 /** 958 * @ticket 40201 959 */ 960 public function test_clean_blog_cache_bails_on_empty_input() { 961 $old_count = did_action( 'clean_site_cache' ); 962 963 clean_blog_cache( null ); 964 $this->assertSame( $old_count, did_action( 'clean_site_cache' ) ); 965 } 966 967 /** 968 * @ticket 40201 969 */ 970 public function test_clean_blog_cache_bails_on_non_numeric_input() { 971 $old_count = did_action( 'clean_site_cache' ); 972 973 clean_blog_cache( 'something' ); 974 $this->assertSame( $old_count, did_action( 'clean_site_cache' ) ); 975 } 976 977 /** 978 * @ticket 40201 979 */ 980 public function test_clean_blog_cache_works_with_deleted_site() { 981 $site_id = 12345; 982 983 wp_cache_set( $site_id, 'something', 'site-details' ); 984 985 clean_blog_cache( $site_id ); 986 $this->assertFalse( wp_cache_get( $site_id, 'site-details' ) ); 987 } 988 989 /** 990 * @ticket 40201 991 * @dataProvider data_get_site_caches 992 */ 993 public function test_refresh_blog_details( $key, $group ) { 994 $site = get_site( self::$site_ids['make.wordpress.org/'] ); 995 996 $replacements = array( 997 '%blog_id%' => $site->blog_id, 998 '%domain%' => $site->domain, 999 '%path%' => $site->path, 1000 '%domain_path_key%' => md5( $site->domain . $site->path ), 1001 ); 1002 1003 $key = str_replace( array_keys( $replacements ), array_values( $replacements ), $key ); 1004 1005 if ( 'sites' === $group ) { // This needs to be actual data for get_site() lookups. 1006 wp_cache_set( $key, (object) $site->to_array(), $group ); 1007 } else { 1008 wp_cache_set( $key, 'something', $group ); 1009 } 1010 1011 refresh_blog_details( $site->blog_id ); 1012 $this->assertFalse( wp_cache_get( $key, $group ) ); 1013 } 1014 1015 /** 1016 * @ticket 40201 1017 */ 1018 public function test_refresh_blog_details_works_with_deleted_site() { 1019 $site_id = 12345; 1020 1021 wp_cache_set( $site_id, 'something', 'site-details' ); 1022 1023 refresh_blog_details( $site_id ); 1024 $this->assertFalse( wp_cache_get( $site_id, 'site-details' ) ); 1025 } 1026 1027 /** 1028 * @ticket 40201 1029 */ 1030 public function test_refresh_blog_details_uses_current_site_as_default() { 1031 $site_id = get_current_blog_id(); 1032 1033 wp_cache_set( $site_id, 'something', 'site-details' ); 1034 1035 refresh_blog_details(); 1036 $this->assertFalse( wp_cache_get( $site_id, 'site-details' ) ); 1037 } 1038 1039 public function data_get_site_caches() { 1040 return array( 1041 array( '%blog_id%', 'sites' ), 1042 array( '%blog_id%', 'site-details' ), 1043 array( '%blog_id%', 'blog-details' ), 1044 array( '%blog_id%' . 'short', 'blog-details' ), 1045 array( '%domain_path_key%', 'blog-lookup' ), 1046 array( '%domain_path_key%', 'blog-id-cache' ), 1047 ); 1048 } 1049 1050 /** 1051 * @ticket 40364 1052 * @dataProvider data_wp_insert_site 1053 */ 1054 public function test_wp_insert_site( $site_data, $expected_data ) { 1055 remove_action( 'wp_initialize_site', 'wp_initialize_site', 10 ); 1056 $site_id = wp_insert_site( $site_data ); 1057 1058 $this->assertIsInt( $site_id ); 1059 1060 $site = get_site( $site_id ); 1061 foreach ( $expected_data as $key => $value ) { 1062 $this->assertEquals( $value, $site->$key ); 1063 } 1064 } 1065 1066 public function data_wp_insert_site() { 1067 return array( 1068 array( 1069 array( 1070 'domain' => 'example.com', 1071 ), 1072 array( 1073 'domain' => 'example.com', 1074 'path' => '/', 1075 'network_id' => 1, 1076 'public' => 1, 1077 'archived' => 0, 1078 'mature' => 0, 1079 'spam' => 0, 1080 'deleted' => 0, 1081 'lang_id' => 0, 1082 ), 1083 ), 1084 array( 1085 array( 1086 'domain' => 'example.com', 1087 'path' => '/foo', 1088 'network_id' => 2, 1089 ), 1090 array( 1091 'domain' => 'example.com', 1092 'path' => '/foo/', 1093 'network_id' => 2, 1094 ), 1095 ), 1096 array( 1097 array( 1098 'domain' => 'example.com', 1099 'path' => '/bar/', 1100 'site_id' => 2, 1101 ), 1102 array( 1103 'domain' => 'example.com', 1104 'path' => '/bar/', 1105 'network_id' => 2, 1106 ), 1107 ), 1108 array( 1109 array( 1110 'domain' => 'example.com', 1111 'path' => '/bar/', 1112 'site_id' => 2, 1113 'network_id' => 3, 1114 ), 1115 array( 1116 'domain' => 'example.com', 1117 'path' => '/bar/', 1118 'network_id' => 3, 1119 ), 1120 ), 1121 array( 1122 array( 1123 'domain' => 'example.com', 1124 'path' => 'foobar', 1125 'public' => 0, 1126 'archived' => 1, 1127 'mature' => 1, 1128 'spam' => 1, 1129 'deleted' => 1, 1130 'lang_id' => 1, 1131 ), 1132 array( 1133 'domain' => 'example.com', 1134 'path' => '/foobar/', 1135 'public' => 0, 1136 'archived' => 1, 1137 'mature' => 1, 1138 'spam' => 1, 1139 'deleted' => 1, 1140 'lang_id' => 1, 1141 ), 1142 ), 1143 array( 1144 array( 1145 'domain' => 'example.com:8888', 1146 ), 1147 array( 1148 'domain' => 'example.com:8888', 1149 'path' => '/', 1150 'network_id' => 1, 1151 'public' => 1, 1152 'archived' => 0, 1153 'mature' => 0, 1154 'spam' => 0, 1155 'deleted' => 0, 1156 'lang_id' => 0, 1157 ), 1158 ), 1159 ); 1160 } 1161 1162 /** 1163 * @ticket 50324 1164 */ 1165 public function test_wp_insert_site_with_clean_site_cache() { 1166 remove_action( 'wp_initialize_site', 'wp_initialize_site', 10 ); 1167 1168 add_action( 'clean_site_cache', array( $this, 'action_database_insert_on_clean_site_cache' ) ); 1169 1170 $site_id = wp_insert_site( 1171 array( 1172 'domain' => 'valid-domain.com', 1173 'path' => '/valid-path/', 1174 'network_id' => 1, 1175 ) 1176 ); 1177 1178 remove_action( 'clean_site_cache', array( $this, 'action_database_insert_on_clean_site_cache' ) ); 1179 1180 $this->assertIsInt( $site_id ); 1181 } 1182 1183 public function action_database_insert_on_clean_site_cache() { 1184 update_site_option( 'database_write_test.' . time(), true ); 1185 } 1186 1187 /** 1188 * @ticket 40364 1189 */ 1190 public function test_wp_insert_site_empty_domain() { 1191 remove_action( 'wp_initialize_site', 'wp_initialize_site', 10 ); 1192 $site_id = wp_insert_site( array( 'public' => 0 ) ); 1193 1194 $this->assertWPError( $site_id ); 1195 $this->assertSame( 'site_empty_domain', $site_id->get_error_code() ); 1196 } 1197 1198 /** 1199 * @ticket 40364 1200 * @dataProvider data_wp_update_site 1201 */ 1202 public function test_wp_update_site( $site_data, $expected_data ) { 1203 $site_id = self::factory()->blog->create(); 1204 1205 $old_site = get_site( $site_id ); 1206 1207 $result = wp_update_site( $site_id, $site_data ); 1208 1209 $this->assertSame( $site_id, $result ); 1210 1211 $new_site = get_site( $site_id ); 1212 foreach ( $new_site->to_array() as $key => $value ) { 1213 if ( isset( $expected_data[ $key ] ) ) { 1214 $this->assertEquals( $expected_data[ $key ], $value ); 1215 } elseif ( 'last_updated' === $key ) { 1216 $this->assertLessThanOrEqual( $value, $old_site->last_updated ); 1217 } else { 1218 $this->assertSame( $old_site->$key, $value ); 1219 } 1220 } 1221 } 1222 1223 public function data_wp_update_site() { 1224 return array( 1225 array( 1226 array( 1227 'domain' => 'example.com', 1228 'network_id' => 2, 1229 ), 1230 array( 1231 'domain' => 'example.com', 1232 'site_id' => 2, 1233 ), 1234 ), 1235 array( 1236 array( 1237 'path' => 'foo', 1238 ), 1239 array( 1240 'path' => '/foo/', 1241 ), 1242 ), 1243 array( 1244 array( 1245 'public' => 0, 1246 'archived' => 1, 1247 'mature' => 1, 1248 'spam' => 1, 1249 'deleted' => 1, 1250 'lang_id' => 1, 1251 ), 1252 array( 1253 'public' => 0, 1254 'archived' => 1, 1255 'mature' => 1, 1256 'spam' => 1, 1257 'deleted' => 1, 1258 'lang_id' => 1, 1259 ), 1260 ), 1261 array( 1262 array( 1263 'domain' => 'example.com:8888', 1264 'network_id' => 2, 1265 ), 1266 array( 1267 'domain' => 'example.com:8888', 1268 'site_id' => 2, 1269 ), 1270 ), 1271 ); 1272 } 1273 1274 /** 1275 * @ticket 40364 1276 */ 1277 public function test_wp_update_site_empty_domain() { 1278 $site_id = self::factory()->blog->create(); 1279 1280 $result = wp_update_site( $site_id, array( 'domain' => '' ) ); 1281 1282 $this->assertWPError( $result ); 1283 $this->assertSame( 'site_empty_domain', $result->get_error_code() ); 1284 } 1285 1286 /** 1287 * @ticket 40364 1288 */ 1289 public function test_wp_update_site_invalid_id() { 1290 $result = wp_update_site( 444444, array( 'domain' => 'example.com' ) ); 1291 1292 $this->assertWPError( $result ); 1293 $this->assertSame( 'site_not_exist', $result->get_error_code() ); 1294 } 1295 1296 /** 1297 * @ticket 40364 1298 */ 1299 public function test_wp_update_site_cleans_cache() { 1300 $site_id = self::factory()->blog->create(); 1301 $site1 = get_site( $site_id ); 1302 1303 $result = wp_update_site( $site_id, array( 'public' => 0 ) ); 1304 $site2 = get_site( $site_id ); 1305 1306 $result = wp_update_site( $site_id, array( 'public' => 1 ) ); 1307 $site3 = get_site( $site_id ); 1308 1309 $this->assertSame( '1', $site1->public ); 1310 $this->assertSame( '0', $site2->public ); 1311 $this->assertSame( '1', $site3->public ); 1312 } 1313 1314 /** 1315 * @ticket 40364 1316 */ 1317 public function test_wp_delete_site() { 1318 $site_id = self::factory()->blog->create(); 1319 1320 $site = get_site( $site_id ); 1321 1322 $result = wp_delete_site( $site_id ); 1323 1324 $this->assertInstanceOf( 'WP_Site', $result ); 1325 $this->assertSame( $result->to_array(), $site->to_array() ); 1326 } 1327 1328 /** 1329 * @ticket 40364 1330 */ 1331 public function test_wp_delete_site_invalid_id() { 1332 $result = wp_delete_site( 444444 ); 1333 1334 $this->assertWPError( $result ); 1335 $this->assertSame( 'site_not_exist', $result->get_error_code() ); 1336 } 1337 1338 /** 1339 * @ticket 41333 1340 */ 1341 public function test_wp_delete_site_validate_site_deletion_action() { 1342 add_action( 'wp_validate_site_deletion', array( $this, 'action_wp_validate_site_deletion_prevent_deletion' ) ); 1343 $result = wp_delete_site( self::$site_ids['make.wordpress.org/'] ); 1344 $this->assertWPError( $result ); 1345 $this->assertSame( 'action_does_not_like_deletion', $result->get_error_code() ); 1346 } 1347 1348 public function action_wp_validate_site_deletion_prevent_deletion( $errors ) { 1349 $errors->add( 'action_does_not_like_deletion', 'You cannot delete this site because the action does not like it.' ); 1350 } 1351 1352 /** 1353 * @ticket 40364 1354 * @dataProvider data_wp_normalize_site_data 1355 */ 1356 public function test_wp_normalize_site_data( $data, $expected ) { 1357 $result = wp_normalize_site_data( $data ); 1358 1359 $this->assertSameSetsWithIndex( $expected, $result ); 1360 } 1361 1362 public function data_wp_normalize_site_data() { 1363 return array( 1364 array( 1365 array( 1366 'network_id' => '4', 1367 ), 1368 array( 1369 'network_id' => 4, 1370 ), 1371 ), 1372 array( 1373 array( 1374 'domain' => 'invalid domain .com', 1375 'path' => 'foo', 1376 ), 1377 array( 1378 'domain' => 'invaliddomain.com', 1379 'path' => '/foo/', 1380 ), 1381 ), 1382 array( 1383 array( 1384 'domain' => '<yet>/another-invalid-domain.com', 1385 ), 1386 array( 1387 'domain' => 'yetanother-invalid-domain.com', 1388 ), 1389 ), 1390 array( 1391 array( 1392 'domain' => 'with-port.com:8888', 1393 ), 1394 array( 1395 'domain' => 'with-port.com:8888', 1396 ), 1397 ), 1398 array( 1399 array( 1400 'domain' => 'subdomain.with-port.com:8888', 1401 ), 1402 array( 1403 'domain' => 'subdomain.with-port.com:8888', 1404 ), 1405 ), 1406 array( 1407 array( 1408 'path' => '', 1409 ), 1410 array( 1411 'path' => '/', 1412 ), 1413 ), 1414 array( 1415 array( 1416 'public' => '0', 1417 'archived' => '1', 1418 'mature' => '1', 1419 'spam' => true, 1420 'deleted' => true, 1421 ), 1422 array( 1423 'public' => 0, 1424 'archived' => 1, 1425 'mature' => 1, 1426 'spam' => 1, 1427 'deleted' => 1, 1428 ), 1429 ), 1430 array( 1431 array( 1432 'registered' => '', 1433 'last_updated' => '', 1434 ), 1435 array(), 1436 ), 1437 array( 1438 array( 1439 'registered' => '0000-00-00 00:00:00', 1440 'last_updated' => '0000-00-00 00:00:00', 1441 ), 1442 array(), 1443 ), 1444 ); 1445 } 1446 1447 /** 1448 * @ticket 40364 1449 * @dataProvider data_wp_validate_site_data 1450 */ 1451 public function test_wp_validate_site_data( $data, $expected_errors ) { 1452 $result = new WP_Error(); 1453 wp_validate_site_data( $result, $data ); 1454 1455 if ( empty( $expected_errors ) ) { 1456 $this->assertEmpty( $result->errors ); 1457 } else { 1458 $this->assertSameSets( $expected_errors, array_keys( $result->errors ) ); 1459 } 1460 } 1461 1462 public function data_wp_validate_site_data() { 1463 $date = current_time( 'mysql', true ); 1464 1465 return array( 1466 array( 1467 array( 1468 'domain' => 'example-site.com', 1469 'path' => '/', 1470 'network_id' => 1, 1471 'registered' => $date, 1472 'last_updated' => $date, 1473 ), 1474 array(), 1475 ), 1476 array( 1477 array( 1478 'path' => '/', 1479 'network_id' => 1, 1480 'registered' => $date, 1481 'last_updated' => $date, 1482 ), 1483 array( 'site_empty_domain' ), 1484 ), 1485 array( 1486 array( 1487 'domain' => 'example-site.com', 1488 'network_id' => 1, 1489 'registered' => $date, 1490 'last_updated' => $date, 1491 ), 1492 array( 'site_empty_path' ), 1493 ), 1494 array( 1495 array( 1496 'domain' => 'example-site.com', 1497 'path' => '/', 1498 'registered' => $date, 1499 'last_updated' => $date, 1500 ), 1501 array( 'site_empty_network_id' ), 1502 ), 1503 array( 1504 array( 1505 'domain' => get_site()->domain, 1506 'path' => get_site()->path, 1507 'network_id' => get_site()->network_id, 1508 'registered' => $date, 1509 'last_updated' => $date, 1510 ), 1511 array( 'site_taken' ), 1512 ), 1513 array( 1514 array( 1515 'domain' => 'valid-domain.com', 1516 'path' => '/valid-path/', 1517 'network_id' => 1, 1518 'registered' => '', 1519 'last_updated' => $date, 1520 ), 1521 array( 'site_empty_registered' ), 1522 ), 1523 array( 1524 array( 1525 'domain' => 'valid-domain.com', 1526 'path' => '/valid-path/', 1527 'network_id' => 1, 1528 'registered' => $date, 1529 'last_updated' => '', 1530 ), 1531 array( 'site_empty_last_updated' ), 1532 ), 1533 array( 1534 array( 1535 'domain' => 'valid-domain.com', 1536 'path' => '/valid-path/', 1537 'network_id' => 1, 1538 'registered' => '2000-13-32 25:25:61', 1539 'last_updated' => $date, 1540 ), 1541 array( 'site_invalid_registered' ), 1542 ), 1543 array( 1544 array( 1545 'domain' => 'valid-domain.com', 1546 'path' => '/valid-path/', 1547 'network_id' => 1, 1548 'registered' => $date, 1549 'last_updated' => '2000-13-32 25:25:61', 1550 ), 1551 array( 'site_invalid_last_updated' ), 1552 ), 1553 array( 1554 array( 1555 'domain' => 'valid-domain.com', 1556 'path' => '/valid-path/', 1557 'network_id' => 1, 1558 'registered' => '0000-00-00 00:00:00', 1559 'last_updated' => $date, 1560 ), 1561 array(), 1562 ), 1563 array( 1564 array( 1565 'domain' => 'valid-domain.com', 1566 'path' => '/valid-path/', 1567 'network_id' => 1, 1568 'registered' => $date, 1569 'last_updated' => '0000-00-00 00:00:00', 1570 ), 1571 array(), 1572 ), 1573 ); 1574 } 1575 1576 /** 1577 * @ticket 40364 1578 */ 1579 public function test_site_dates_are_gmt() { 1580 $first_date = current_time( 'mysql', true ); 1581 1582 remove_action( 'wp_initialize_site', 'wp_initialize_site', 10 ); 1583 $site_id = wp_insert_site( 1584 array( 1585 'domain' => 'valid-domain.com', 1586 'path' => '/valid-path/', 1587 'network_id' => 1, 1588 ) 1589 ); 1590 $this->assertIsInt( $site_id ); 1591 1592 $site = get_site( $site_id ); 1593 $this->assertEqualsWithDelta( strtotime( $first_date ), strtotime( $site->registered ), 2, 'The dates should be equal' ); 1594 $this->assertEqualsWithDelta( strtotime( $first_date ), strtotime( $site->last_updated ), 2, 'The dates should be equal' ); 1595 1596 $second_date = current_time( 'mysql', true ); 1597 $site_id = wp_update_site( $site_id, array() ); 1598 $this->assertIsInt( $site_id ); 1599 1600 $site = get_site( $site_id ); 1601 $this->assertEqualsWithDelta( strtotime( $first_date ), strtotime( $site->registered ), 2, 'The dates should be equal' ); 1602 $this->assertEqualsWithDelta( strtotime( $second_date ), strtotime( $site->last_updated ), 2, 'The dates should be equal' ); 1603 } 1604 1605 /** 1606 * @ticket 40364 1607 */ 1608 public function test_wp_delete_site_cleans_cache() { 1609 $site_id = self::factory()->blog->create(); 1610 1611 get_site( $site_id ); 1612 1613 wp_delete_site( $site_id ); 1614 1615 $this->assertNull( get_site( $site_id ) ); 1616 } 1617 1618 /** 1619 * @ticket 40364 1620 */ 1621 public function test_wp_update_site_cleans_old_cache_on_domain_change() { 1622 $old_domain = 'old.wordpress.org'; 1623 $new_domain = 'new.wordpress.org'; 1624 1625 $site = self::factory()->blog->create_and_get( 1626 array( 1627 'domain' => $old_domain, 1628 'path' => '/', 1629 ) 1630 ); 1631 1632 // Populate the caches. 1633 get_blog_details( 1634 array( 1635 'domain' => $old_domain, 1636 'path' => '/', 1637 ) 1638 ); 1639 get_blog_id_from_url( $old_domain, '/' ); 1640 get_blog_details( 1641 array( 1642 'domain' => $new_domain, 1643 'path' => '/', 1644 ) 1645 ); 1646 get_blog_id_from_url( $new_domain, '/' ); 1647 1648 wp_update_site( 1649 $site->id, 1650 array( 1651 'domain' => $new_domain, 1652 ) 1653 ); 1654 1655 $domain_path_key_old = md5( $old_domain . '/' ); 1656 $domain_path_key_new = md5( $new_domain . '/' ); 1657 1658 // Ensure all respective cache values are empty. 1659 $result = array( 1660 wp_cache_get( $domain_path_key_old, 'blog-lookup' ), 1661 wp_cache_get( $domain_path_key_old, 'blog-id-cache' ), 1662 wp_cache_get( 'current_blog_' . $old_domain, 'site-options' ), 1663 wp_cache_get( 'current_blog_' . $old_domain . '/', 'site-options' ), 1664 wp_cache_get( $domain_path_key_new, 'blog-lookup' ), 1665 wp_cache_get( $domain_path_key_new, 'blog-id-cache' ), 1666 wp_cache_get( 'current_blog_' . $new_domain, 'site-options' ), 1667 wp_cache_get( 'current_blog_' . $new_domain . '/', 'site-options' ), 1668 ); 1669 1670 $this->assertEmpty( array_filter( $result ) ); 1671 } 1672 1673 /** 1674 * @ticket 40364 1675 */ 1676 public function test_wp_update_site_cleans_old_cache_on_path_change() { 1677 $old_path = '/foo/'; 1678 $new_path = '/bar/'; 1679 1680 $site = self::factory()->blog->create_and_get( 1681 array( 1682 'domain' => 'test.wordpress.org', 1683 'path' => $old_path, 1684 ) 1685 ); 1686 1687 // Populate the caches. 1688 get_blog_details( 1689 array( 1690 'domain' => 'test.wordpress.org', 1691 'path' => $old_path, 1692 ) 1693 ); 1694 get_blog_id_from_url( 'test.wordpress.org', $old_path ); 1695 get_blog_details( 1696 array( 1697 'domain' => 'test.wordpress.org', 1698 'path' => $new_path, 1699 ) 1700 ); 1701 get_blog_id_from_url( 'test.wordpress.org', $new_path ); 1702 1703 wp_update_site( 1704 $site->id, 1705 array( 1706 'path' => $new_path, 1707 ) 1708 ); 1709 1710 $domain_path_key_old = md5( 'test.wordpress.org' . $old_path ); 1711 $domain_path_key_new = md5( 'test.wordpress.org' . $new_path ); 1712 1713 // Ensure all respective cache values are empty. 1714 $result = array( 1715 wp_cache_get( $domain_path_key_old, 'blog-lookup' ), 1716 wp_cache_get( $domain_path_key_old, 'blog-id-cache' ), 1717 wp_cache_get( 'current_blog_test.wordpress.org' . $old_path, 'site-options' ), 1718 wp_cache_get( $domain_path_key_new, 'blog-lookup' ), 1719 wp_cache_get( $domain_path_key_new, 'blog-id-cache' ), 1720 wp_cache_get( 'current_blog_test.wordpress.org' . $new_path, 'site-options' ), 1721 ); 1722 1723 $this->assertEmpty( array_filter( $result ) ); 1724 } 1725 1726 /** 1727 * @ticket 40364 1728 * @dataProvider data_site_status_hook_triggers 1729 */ 1730 public function test_site_status_hook_triggers( $insert_site_data, $expected_insert_hooks, $update_site_data, $expected_update_hooks ) { 1731 // First: Insert a site. 1732 $this->listen_to_site_status_hooks(); 1733 1734 $site_data = array_merge( 1735 array( 1736 'domain' => 'example-site.com', 1737 'path' => '/', 1738 ), 1739 $insert_site_data 1740 ); 1741 1742 $site_id = wp_insert_site( $site_data ); 1743 1744 $insert_expected = array_fill_keys( $expected_insert_hooks, $site_id ); 1745 $insert_result = $this->get_listen_to_site_status_hooks_result(); 1746 1747 // Second: Update that site. 1748 $this->listen_to_site_status_hooks(); 1749 1750 wp_update_site( $site_id, $update_site_data ); 1751 1752 $update_expected = array_fill_keys( $expected_update_hooks, $site_id ); 1753 $update_result = $this->get_listen_to_site_status_hooks_result(); 1754 1755 // Check both insert and update results. 1756 $this->assertSameSetsWithIndex( $insert_expected, $insert_result ); 1757 $this->assertSameSetsWithIndex( $update_expected, $update_result ); 1758 } 1759 1760 public function data_site_status_hook_triggers() { 1761 return array( 1762 array( 1763 array( 1764 'public' => 1, 1765 'archived' => 1, 1766 'mature' => 1, 1767 'spam' => 1, 1768 'deleted' => 1, 1769 ), 1770 array( 1771 'archive_blog', 1772 'mature_blog', 1773 'make_spam_blog', 1774 'make_delete_blog', 1775 ), 1776 array( 1777 'public' => 0, 1778 'archived' => 0, 1779 'mature' => 0, 1780 'spam' => 0, 1781 'deleted' => 0, 1782 ), 1783 array( 1784 'update_blog_public', 1785 'unarchive_blog', 1786 'unmature_blog', 1787 'make_ham_blog', 1788 'make_undelete_blog', 1789 ), 1790 ), 1791 array( 1792 array( 1793 'public' => 0, 1794 'archived' => 0, 1795 'mature' => 0, 1796 'spam' => 0, 1797 'deleted' => 0, 1798 ), 1799 array( 1800 'update_blog_public', 1801 ), 1802 array( 1803 'public' => 1, 1804 'archived' => 1, 1805 'mature' => 1, 1806 'spam' => 1, 1807 'deleted' => 1, 1808 ), 1809 array( 1810 'update_blog_public', 1811 'archive_blog', 1812 'mature_blog', 1813 'make_spam_blog', 1814 'make_delete_blog', 1815 ), 1816 ), 1817 array( 1818 array( 1819 'public' => 0, 1820 'archived' => 0, 1821 'mature' => 1, 1822 'spam' => 1, 1823 'deleted' => 1, 1824 ), 1825 array( 1826 'update_blog_public', 1827 'mature_blog', 1828 'make_spam_blog', 1829 'make_delete_blog', 1830 ), 1831 array( 1832 'public' => 0, 1833 'archived' => 1, 1834 'mature' => 1, 1835 'spam' => 1, 1836 'deleted' => 0, 1837 ), 1838 array( 1839 'archive_blog', 1840 'make_undelete_blog', 1841 ), 1842 ), 1843 ); 1844 } 1845 1846 private function listen_to_site_status_hooks() { 1847 $this->site_status_hooks = array(); 1848 1849 $hooknames = array( 1850 'make_spam_blog', 1851 'make_ham_blog', 1852 'mature_blog', 1853 'unmature_blog', 1854 'archive_blog', 1855 'unarchive_blog', 1856 'make_delete_blog', 1857 'make_undelete_blog', 1858 'update_blog_public', 1859 ); 1860 1861 foreach ( $hooknames as $hookname ) { 1862 add_action( $hookname, array( $this, 'action_site_status_hook' ), 10, 1 ); 1863 } 1864 } 1865 1866 private function get_listen_to_site_status_hooks_result() { 1867 $hooknames = array( 1868 'make_spam_blog', 1869 'make_ham_blog', 1870 'mature_blog', 1871 'unmature_blog', 1872 'archive_blog', 1873 'unarchive_blog', 1874 'make_delete_blog', 1875 'make_undelete_blog', 1876 'update_blog_public', 1877 ); 1878 1879 foreach ( $hooknames as $hookname ) { 1880 remove_action( $hookname, array( $this, 'action_site_status_hook' ), 10 ); 1881 } 1882 1883 return $this->site_status_hooks; 1884 } 1885 1886 public function action_site_status_hook( $site_id ) { 1887 $this->site_status_hooks[ current_action() ] = $site_id; 1888 } 1889 1890 /** 1891 * @ticket 41333 1892 * @dataProvider data_wp_initialize_site 1893 */ 1894 public function test_wp_initialize_site( $args, $expected_options, $expected_meta ) { 1895 $result = wp_initialize_site( self::$uninitialized_site_id, $args ); 1896 1897 switch_to_blog( self::$uninitialized_site_id ); 1898 1899 $options = array(); 1900 foreach ( $expected_options as $option => $value ) { 1901 $options[ $option ] = get_option( $option ); 1902 } 1903 1904 $meta = array(); 1905 foreach ( $expected_meta as $meta_key => $value ) { 1906 $meta[ $meta_key ] = get_site_meta( self::$uninitialized_site_id, $meta_key, true ); 1907 } 1908 1909 restore_current_blog(); 1910 1911 $initialized = wp_is_site_initialized( self::$uninitialized_site_id ); 1912 1913 wp_uninitialize_site( self::$uninitialized_site_id ); 1914 1915 $this->assertTrue( $result ); 1916 $this->assertTrue( $initialized ); 1917 $this->assertSame( $expected_options, $options ); 1918 $this->assertSame( $expected_meta, $meta ); 1919 } 1920 1921 public function data_wp_initialize_site() { 1922 return array( 1923 array( 1924 array(), 1925 array( 1926 'home' => 'http://uninitialized.org', 1927 'siteurl' => 'http://uninitialized.org', 1928 'admin_email' => '', 1929 'blog_public' => '1', 1930 ), 1931 array(), 1932 ), 1933 array( 1934 array( 1935 'options' => array( 1936 'home' => 'https://uninitialized.org', 1937 'siteurl' => 'https://uninitialized.org', 1938 'key' => 'value', 1939 ), 1940 'meta' => array( 1941 'key1' => 'value1', 1942 'key2' => 'value2', 1943 ), 1944 ), 1945 array( 1908 restore_current_blog(); 1909 1910 $initialized = wp_is_site_initialized( self::$uninitialized_site_id ); 1911 1912 wp_uninitialize_site( self::$uninitialized_site_id ); 1913 1914 $this->assertTrue( $result ); 1915 $this->assertTrue( $initialized ); 1916 $this->assertSame( $expected_options, $options ); 1917 $this->assertSame( $expected_meta, $meta ); 1918 } 1919 1920 public function data_wp_initialize_site() { 1921 return array( 1922 array( 1923 array(), 1924 array( 1925 'home' => 'http://uninitialized.org', 1926 'siteurl' => 'http://uninitialized.org', 1927 'admin_email' => '', 1928 'blog_public' => '1', 1929 ), 1930 array(), 1931 ), 1932 array( 1933 array( 1934 'options' => array( 1946 1935 'home' => 'https://uninitialized.org', 1947 1936 'siteurl' => 'https://uninitialized.org', 1948 1937 'key' => 'value', 1949 1938 ), 1950 array(1939 'meta' => array( 1951 1940 'key1' => 'value1', 1952 1941 'key2' => 'value2', 1953 'key3' => '',1954 1942 ), 1955 1943 ), 1956 1944 array( 1957 array( 1958 'title' => 'My New Site', 1959 'options' => array( 1960 'blogdescription' => 'Just My New Site', 1961 ), 1962 ), 1963 array( 1964 'blogname' => 'My New Site', 1945 'home' => 'https://uninitialized.org', 1946 'siteurl' => 'https://uninitialized.org', 1947 'key' => 'value', 1948 ), 1949 array( 1950 'key1' => 'value1', 1951 'key2' => 'value2', 1952 'key3' => '', 1953 ), 1954 ), 1955 array( 1956 array( 1957 'title' => 'My New Site', 1958 'options' => array( 1965 1959 'blogdescription' => 'Just My New Site', 1966 1960 ), 1967 array(), 1968 ), 1969 ); 1970 } 1971 1972 /** 1973 * @ticket 41333 1961 ), 1962 array( 1963 'blogname' => 'My New Site', 1964 'blogdescription' => 'Just My New Site', 1965 ), 1966 array(), 1967 ), 1968 ); 1969 } 1970 1971 /** 1972 * @ticket 41333 1973 */ 1974 public function test_wp_initialize_site_user_roles() { 1975 global $wpdb; 1976 1977 $result = wp_initialize_site( self::$uninitialized_site_id, array() ); 1978 1979 switch_to_blog( self::$uninitialized_site_id ); 1980 $table_prefix = $wpdb->get_blog_prefix( self::$uninitialized_site_id ); 1981 $roles = get_option( $table_prefix . 'user_roles' ); 1982 restore_current_blog(); 1983 1984 wp_uninitialize_site( self::$uninitialized_site_id ); 1985 1986 $this->assertTrue( $result ); 1987 $this->assertSameSets( 1988 array( 1989 'administrator', 1990 'editor', 1991 'author', 1992 'contributor', 1993 'subscriber', 1994 ), 1995 array_keys( $roles ) 1996 ); 1997 } 1998 1999 /** 2000 * @ticket 41333 2001 */ 2002 public function test_wp_initialize_site_user_is_admin() { 2003 $result = wp_initialize_site( self::$uninitialized_site_id, array( 'user_id' => 1 ) ); 2004 2005 switch_to_blog( self::$uninitialized_site_id ); 2006 $user_is_admin = user_can( 1, 'manage_options' ); 2007 $admin_email = get_option( 'admin_email' ); 2008 restore_current_blog(); 2009 2010 wp_uninitialize_site( self::$uninitialized_site_id ); 2011 2012 $this->assertTrue( $result ); 2013 $this->assertTrue( $user_is_admin ); 2014 $this->assertSame( get_userdata( 1 )->user_email, $admin_email ); 2015 } 2016 2017 /** 2018 * @ticket 41333 2019 */ 2020 public function test_wp_initialize_site_args_filter() { 2021 add_filter( 'wp_initialize_site_args', array( $this, 'filter_wp_initialize_site_args' ), 10, 3 ); 2022 $result = wp_initialize_site( self::$uninitialized_site_id, array( 'title' => 'My Site' ) ); 2023 2024 switch_to_blog( self::$uninitialized_site_id ); 2025 $site_title = get_option( 'blogname' ); 2026 restore_current_blog(); 2027 2028 wp_uninitialize_site( self::$uninitialized_site_id ); 2029 2030 $this->assertSame( 2031 sprintf( 'My Site %1$d in Network %2$d', self::$uninitialized_site_id, get_site( self::$uninitialized_site_id )->network_id ), 2032 $site_title 2033 ); 2034 } 2035 2036 public function filter_wp_initialize_site_args( $args, $site, $network ) { 2037 $args['title'] = sprintf( 'My Site %1$d in Network %2$d', $site->id, $network->id ); 2038 2039 return $args; 2040 } 2041 2042 /** 2043 * @ticket 41333 2044 */ 2045 public function test_wp_initialize_site_empty_id() { 2046 $result = wp_initialize_site( 0 ); 2047 $this->assertWPError( $result ); 2048 $this->assertSame( 'site_empty_id', $result->get_error_code() ); 2049 } 2050 2051 /** 2052 * @ticket 41333 2053 */ 2054 public function test_wp_initialize_site_invalid_id() { 2055 $result = wp_initialize_site( 123 ); 2056 $this->assertWPError( $result ); 2057 $this->assertSame( 'site_invalid_id', $result->get_error_code() ); 2058 } 2059 2060 /** 2061 * @ticket 41333 2062 */ 2063 public function test_wp_initialize_site_already_initialized() { 2064 $result = wp_initialize_site( get_current_blog_id() ); 2065 $this->assertWPError( $result ); 2066 $this->assertSame( 'site_already_initialized', $result->get_error_code() ); 2067 } 2068 2069 /** 2070 * @ticket 41333 2071 */ 2072 public function test_wp_uninitialize_site() { 2073 $site_id = self::factory()->blog->create(); 2074 2075 $result = wp_uninitialize_site( $site_id ); 2076 $this->assertTrue( $result ); 2077 $this->assertFalse( wp_is_site_initialized( $site_id ) ); 2078 } 2079 2080 /** 2081 * @ticket 41333 2082 */ 2083 public function test_wp_uninitialize_site_empty_id() { 2084 $result = wp_uninitialize_site( 0 ); 2085 $this->assertWPError( $result ); 2086 $this->assertSame( 'site_empty_id', $result->get_error_code() ); 2087 } 2088 2089 /** 2090 * @ticket 41333 2091 */ 2092 public function test_wp_uninitialize_site_invalid_id() { 2093 $result = wp_uninitialize_site( 123 ); 2094 $this->assertWPError( $result ); 2095 $this->assertSame( 'site_invalid_id', $result->get_error_code() ); 2096 } 2097 2098 /** 2099 * @ticket 41333 2100 */ 2101 public function test_wp_uninitialize_site_already_uninitialized() { 2102 $result = wp_uninitialize_site( self::$uninitialized_site_id ); 2103 $this->assertWPError( $result ); 2104 $this->assertSame( 'site_already_uninitialized', $result->get_error_code() ); 2105 } 2106 2107 /** 2108 * @ticket 41333 2109 */ 2110 public function test_wp_is_site_initialized() { 2111 $this->assertTrue( wp_is_site_initialized( get_current_blog_id() ) ); 2112 $this->assertFalse( wp_is_site_initialized( self::$uninitialized_site_id ) ); 2113 } 2114 2115 /** 2116 * @ticket 41333 2117 */ 2118 public function test_wp_is_site_initialized_prefilter() { 2119 add_filter( 'pre_wp_is_site_initialized', '__return_false' ); 2120 $this->assertFalse( wp_is_site_initialized( get_current_blog_id() ) ); 2121 2122 add_filter( 'pre_wp_is_site_initialized', '__return_true' ); 2123 $this->assertTrue( wp_is_site_initialized( self::$uninitialized_site_id ) ); 2124 } 2125 2126 /** 2127 * @ticket 41333 2128 */ 2129 public function test_wp_insert_site_forwards_args_to_wp_initialize_site() { 2130 $args = array( 2131 'user_id' => 1, 2132 'title' => 'My Site', 2133 'options' => array( 'option1' => 'value1' ), 2134 'meta' => array( 'meta1' => 'value1' ), 2135 ); 2136 2137 add_filter( 'wp_initialize_site_args', array( $this, 'filter_wp_initialize_site_args_catch_args' ) ); 2138 $site_id = wp_insert_site( 2139 array_merge( 2140 array( 2141 'domain' => 'testsite.org', 2142 'path' => '/', 2143 ), 2144 $args 2145 ) 2146 ); 2147 2148 $passed_args = $this->wp_initialize_site_args; 2149 $this->wp_initialize_site_args = null; 2150 2151 $this->assertSameSetsWithIndex( $args, $passed_args ); 2152 } 2153 2154 public function filter_wp_initialize_site_args_catch_args( $args ) { 2155 $this->wp_initialize_site_args = $args; 2156 2157 return $args; 2158 } 2159 2160 /** 2161 * @ticket 46125 2162 */ 2163 public function test_wpmu_create_blog_cache_cleanup_backward_compatible() { 2164 add_action( 'populate_options', array( $this, 'populate_options_callback' ) ); 2165 2166 $blog_id = wpmu_create_blog( 'testsite1.example.org', '/test', 'test', 1, array( 'public' => 1 ), 2 ); 2167 2168 /* 2169 * Should not hit blog_details cache initialized in $this->populate_options_callback triggered during 2170 * populate_options callback's call of get_blog_details. 1974 2171 */ 1975 public function test_wp_initialize_site_user_roles() { 1976 global $wpdb; 1977 1978 $result = wp_initialize_site( self::$uninitialized_site_id, array() ); 1979 1980 switch_to_blog( self::$uninitialized_site_id ); 1981 $table_prefix = $wpdb->get_blog_prefix( self::$uninitialized_site_id ); 1982 $roles = get_option( $table_prefix . 'user_roles' ); 1983 restore_current_blog(); 1984 1985 wp_uninitialize_site( self::$uninitialized_site_id ); 1986 1987 $this->assertTrue( $result ); 1988 $this->assertSameSets( 1989 array( 1990 'administrator', 1991 'editor', 1992 'author', 1993 'contributor', 1994 'subscriber', 1995 ), 1996 array_keys( $roles ) 1997 ); 1998 } 1999 2000 /** 2001 * @ticket 41333 2002 */ 2003 public function test_wp_initialize_site_user_is_admin() { 2004 $result = wp_initialize_site( self::$uninitialized_site_id, array( 'user_id' => 1 ) ); 2005 2006 switch_to_blog( self::$uninitialized_site_id ); 2007 $user_is_admin = user_can( 1, 'manage_options' ); 2008 $admin_email = get_option( 'admin_email' ); 2009 restore_current_blog(); 2010 2011 wp_uninitialize_site( self::$uninitialized_site_id ); 2012 2013 $this->assertTrue( $result ); 2014 $this->assertTrue( $user_is_admin ); 2015 $this->assertSame( get_userdata( 1 )->user_email, $admin_email ); 2016 } 2017 2018 /** 2019 * @ticket 41333 2020 */ 2021 public function test_wp_initialize_site_args_filter() { 2022 add_filter( 'wp_initialize_site_args', array( $this, 'filter_wp_initialize_site_args' ), 10, 3 ); 2023 $result = wp_initialize_site( self::$uninitialized_site_id, array( 'title' => 'My Site' ) ); 2024 2025 switch_to_blog( self::$uninitialized_site_id ); 2026 $site_title = get_option( 'blogname' ); 2027 restore_current_blog(); 2028 2029 wp_uninitialize_site( self::$uninitialized_site_id ); 2030 2031 $this->assertSame( 2032 sprintf( 'My Site %1$d in Network %2$d', self::$uninitialized_site_id, get_site( self::$uninitialized_site_id )->network_id ), 2033 $site_title 2034 ); 2035 } 2036 2037 public function filter_wp_initialize_site_args( $args, $site, $network ) { 2038 $args['title'] = sprintf( 'My Site %1$d in Network %2$d', $site->id, $network->id ); 2039 2040 return $args; 2041 } 2042 2043 /** 2044 * @ticket 41333 2045 */ 2046 public function test_wp_initialize_site_empty_id() { 2047 $result = wp_initialize_site( 0 ); 2048 $this->assertWPError( $result ); 2049 $this->assertSame( 'site_empty_id', $result->get_error_code() ); 2050 } 2051 2052 /** 2053 * @ticket 41333 2054 */ 2055 public function test_wp_initialize_site_invalid_id() { 2056 $result = wp_initialize_site( 123 ); 2057 $this->assertWPError( $result ); 2058 $this->assertSame( 'site_invalid_id', $result->get_error_code() ); 2059 } 2060 2061 /** 2062 * @ticket 41333 2063 */ 2064 public function test_wp_initialize_site_already_initialized() { 2065 $result = wp_initialize_site( get_current_blog_id() ); 2066 $this->assertWPError( $result ); 2067 $this->assertSame( 'site_already_initialized', $result->get_error_code() ); 2068 } 2069 2070 /** 2071 * @ticket 41333 2072 */ 2073 public function test_wp_uninitialize_site() { 2074 $site_id = self::factory()->blog->create(); 2075 2076 $result = wp_uninitialize_site( $site_id ); 2077 $this->assertTrue( $result ); 2078 $this->assertFalse( wp_is_site_initialized( $site_id ) ); 2079 } 2080 2081 /** 2082 * @ticket 41333 2083 */ 2084 public function test_wp_uninitialize_site_empty_id() { 2085 $result = wp_uninitialize_site( 0 ); 2086 $this->assertWPError( $result ); 2087 $this->assertSame( 'site_empty_id', $result->get_error_code() ); 2088 } 2089 2090 /** 2091 * @ticket 41333 2092 */ 2093 public function test_wp_uninitialize_site_invalid_id() { 2094 $result = wp_uninitialize_site( 123 ); 2095 $this->assertWPError( $result ); 2096 $this->assertSame( 'site_invalid_id', $result->get_error_code() ); 2097 } 2098 2099 /** 2100 * @ticket 41333 2101 */ 2102 public function test_wp_uninitialize_site_already_uninitialized() { 2103 $result = wp_uninitialize_site( self::$uninitialized_site_id ); 2104 $this->assertWPError( $result ); 2105 $this->assertSame( 'site_already_uninitialized', $result->get_error_code() ); 2106 } 2107 2108 /** 2109 * @ticket 41333 2110 */ 2111 public function test_wp_is_site_initialized() { 2112 $this->assertTrue( wp_is_site_initialized( get_current_blog_id() ) ); 2113 $this->assertFalse( wp_is_site_initialized( self::$uninitialized_site_id ) ); 2114 } 2115 2116 /** 2117 * @ticket 41333 2118 */ 2119 public function test_wp_is_site_initialized_prefilter() { 2120 add_filter( 'pre_wp_is_site_initialized', '__return_false' ); 2121 $this->assertFalse( wp_is_site_initialized( get_current_blog_id() ) ); 2122 2123 add_filter( 'pre_wp_is_site_initialized', '__return_true' ); 2124 $this->assertTrue( wp_is_site_initialized( self::$uninitialized_site_id ) ); 2125 } 2126 2127 /** 2128 * @ticket 41333 2129 */ 2130 public function test_wp_insert_site_forwards_args_to_wp_initialize_site() { 2131 $args = array( 2132 'user_id' => 1, 2133 'title' => 'My Site', 2134 'options' => array( 'option1' => 'value1' ), 2135 'meta' => array( 'meta1' => 'value1' ), 2136 ); 2137 2138 add_filter( 'wp_initialize_site_args', array( $this, 'filter_wp_initialize_site_args_catch_args' ) ); 2139 $site_id = wp_insert_site( 2140 array_merge( 2141 array( 2142 'domain' => 'testsite.org', 2143 'path' => '/', 2144 ), 2145 $args 2146 ) 2147 ); 2148 2149 $passed_args = $this->wp_initialize_site_args; 2150 $this->wp_initialize_site_args = null; 2151 2152 $this->assertSameSetsWithIndex( $args, $passed_args ); 2153 } 2154 2155 public function filter_wp_initialize_site_args_catch_args( $args ) { 2156 $this->wp_initialize_site_args = $args; 2157 2158 return $args; 2159 } 2160 2161 /** 2162 * @ticket 46125 2163 */ 2164 public function test_wpmu_create_blog_cache_cleanup_backward_compatible() { 2165 add_action( 'populate_options', array( $this, 'populate_options_callback' ) ); 2166 2167 $blog_id = wpmu_create_blog( 'testsite1.example.org', '/test', 'test', 1, array( 'public' => 1 ), 2 ); 2168 2169 /* 2170 * Should not hit blog_details cache initialized in $this->populate_options_callback triggered during 2171 * populate_options callback's call of get_blog_details. 2172 */ 2173 $this->assertSame( 'http://testsite1.example.org/test', get_blog_details( $blog_id )->siteurl ); 2174 $this->assertSame( 'http://testsite1.example.org/test', get_site( $blog_id )->siteurl ); 2175 2176 remove_action( 'populate_options', array( $this, 'populate_options_callback' ) ); 2177 } 2178 2179 /** 2180 * Populate options callback to warm cache for blog-details / site-details cache group 2181 */ 2182 public function populate_options_callback() { 2183 // Cache blog details. 2184 $blog_id = get_current_blog_id(); 2185 get_blog_details( $blog_id ); 2186 get_site( $blog_id )->siteurl; 2187 // Set siteurl. 2188 update_option( 'siteurl', 'http://testsite1.example.org/test' ); 2189 } 2190 2191 /** 2192 * Tests whether all expected meta are provided in deprecated `wpmu_new_blog` action. 2193 * 2194 * @dataProvider data_wpmu_new_blog_action_backward_compatible 2195 * 2196 * @ticket 46351 2197 */ 2198 public function test_wpmu_new_blog_action_backward_compatible( $meta, $expected_meta ) { 2199 // We are testing deprecated hook. Register it to expected deprecated notices. 2200 $this->setExpectedDeprecated( 'wpmu_new_blog' ); 2201 add_action( 'wpmu_new_blog', array( $this, 'wpmu_new_blog_callback' ), 10, 6 ); 2202 2203 wpmu_create_blog( 'testsite1.example.org', '/new-blog/', 'New Blog', get_current_user_id(), $meta, 1 ); 2204 2205 $this->assertSameSetsWithIndex( $expected_meta, $this->wp_initialize_site_meta ); 2206 2207 $this->wp_initialize_site_meta = array(); 2208 } 2209 2210 /** 2211 * @ticket 42251 2212 */ 2213 public function test_get_site_not_found_cache() { 2214 $new_site_id = $this->_get_next_site_id(); 2215 $this->assertNull( get_site( $new_site_id ) ); 2216 2217 $num_queries = get_num_queries(); 2218 $this->assertNull( get_site( $new_site_id ) ); 2219 $this->assertSame( $num_queries, get_num_queries() ); 2220 } 2221 2222 /** 2223 * @ticket 42251 2224 */ 2225 public function test_get_site_not_found_cache_clear() { 2226 $new_site_id = $this->_get_next_site_id(); 2227 $this->assertNull( get_site( $new_site_id ) ); 2228 2229 $new_site = self::factory()->blog->create_and_get(); 2230 2231 // Double-check we got the ID of the new site correct. 2232 $this->assertEquals( $new_site_id, $new_site->blog_id ); 2233 2234 // Verify that if we fetch the site now, it's no longer false. 2235 $fetched_site = get_site( $new_site_id ); 2236 $this->assertInstanceOf( 'WP_Site', $fetched_site ); 2237 $this->assertEquals( $new_site_id, $fetched_site->blog_id ); 2238 } 2239 2240 /** 2241 * Gets the ID of the next site that will get inserted 2242 * @return int 2243 */ 2244 protected function _get_next_site_id() { 2245 global $wpdb; 2246 // Create an entry. 2247 static::factory()->blog->create(); 2248 // Get the ID after it. 2249 return (int) $wpdb->get_var( 'SELECT blog_id FROM ' . $wpdb->blogs . ' ORDER BY blog_ID DESC LIMIT 1' ) + 1; 2250 } 2251 2252 /** 2253 * Capture the $meta value passed to the wpmu_new_blog action and compare it. 2254 */ 2255 public function wpmu_new_blog_callback( $blog_id, $user_id, $domain, $path, $network_id, $meta ) { 2256 $this->wp_initialize_site_meta = $meta; 2257 } 2258 2259 public function data_wpmu_new_blog_action_backward_compatible() { 2260 return array( 2261 'default values' => array( 2262 array(), 2263 array( 2264 'public' => 0, // `public` is one of the default metas in `wpmu_create_blog()' function prior to WordPress 5.1.0. 2265 'WPLANG' => 'en_US', // WPLANG is another default meta in `wpmu_create_blog()` function prior to WordPress 5.1.0. 2266 ), 2267 ), 2268 'public site' => array( 2269 array( 2270 'public' => 1, 2271 ), 2272 array( 2273 'public' => 1, 2274 'WPLANG' => 'en_US', 2275 ), 2276 ), 2277 'allowed_keys' => array( 2278 array( 2279 'public' => -1, 2280 'archived' => 0, 2281 'mature' => 0, 2282 'spam' => 0, 2283 'deleted' => 0, 2284 'lang_id' => 11, 2285 2286 ), 2287 array( 2288 'public' => -1, 2289 'WPLANG' => 'en_US', 2290 'archived' => 0, 2291 'mature' => 0, 2292 'spam' => 0, 2293 'deleted' => 0, 2294 'lang_id' => 11, 2295 ), 2296 ), 2297 'extra meta key' => array( 2298 array( 2299 'foo' => 'bar', 2300 ), 2301 array( 2302 'public' => 0, 2303 'foo' => 'bar', 2304 'WPLANG' => 'en_US', 2305 ), 2306 ), 2307 ); 2308 } 2309 } 2310 2311 endif; 2172 $this->assertSame( 'http://testsite1.example.org/test', get_blog_details( $blog_id )->siteurl ); 2173 $this->assertSame( 'http://testsite1.example.org/test', get_site( $blog_id )->siteurl ); 2174 2175 remove_action( 'populate_options', array( $this, 'populate_options_callback' ) ); 2176 } 2177 2178 /** 2179 * Populate options callback to warm cache for blog-details / site-details cache group 2180 */ 2181 public function populate_options_callback() { 2182 // Cache blog details. 2183 $blog_id = get_current_blog_id(); 2184 get_blog_details( $blog_id ); 2185 get_site( $blog_id )->siteurl; 2186 // Set siteurl. 2187 update_option( 'siteurl', 'http://testsite1.example.org/test' ); 2188 } 2189 2190 /** 2191 * Tests whether all expected meta are provided in deprecated `wpmu_new_blog` action. 2192 * 2193 * @dataProvider data_wpmu_new_blog_action_backward_compatible 2194 * 2195 * @ticket 46351 2196 */ 2197 public function test_wpmu_new_blog_action_backward_compatible( $meta, $expected_meta ) { 2198 // We are testing deprecated hook. Register it to expected deprecated notices. 2199 $this->setExpectedDeprecated( 'wpmu_new_blog' ); 2200 add_action( 'wpmu_new_blog', array( $this, 'wpmu_new_blog_callback' ), 10, 6 ); 2201 2202 wpmu_create_blog( 'testsite1.example.org', '/new-blog/', 'New Blog', get_current_user_id(), $meta, 1 ); 2203 2204 $this->assertSameSetsWithIndex( $expected_meta, $this->wp_initialize_site_meta ); 2205 2206 $this->wp_initialize_site_meta = array(); 2207 } 2208 2209 /** 2210 * @ticket 42251 2211 */ 2212 public function test_get_site_not_found_cache() { 2213 $new_site_id = $this->_get_next_site_id(); 2214 $this->assertNull( get_site( $new_site_id ) ); 2215 2216 $num_queries = get_num_queries(); 2217 $this->assertNull( get_site( $new_site_id ) ); 2218 $this->assertSame( $num_queries, get_num_queries() ); 2219 } 2220 2221 /** 2222 * @ticket 42251 2223 */ 2224 public function test_get_site_not_found_cache_clear() { 2225 $new_site_id = $this->_get_next_site_id(); 2226 $this->assertNull( get_site( $new_site_id ) ); 2227 2228 $new_site = self::factory()->blog->create_and_get(); 2229 2230 // Double-check we got the ID of the new site correct. 2231 $this->assertEquals( $new_site_id, $new_site->blog_id ); 2232 2233 // Verify that if we fetch the site now, it's no longer false. 2234 $fetched_site = get_site( $new_site_id ); 2235 $this->assertInstanceOf( 'WP_Site', $fetched_site ); 2236 $this->assertEquals( $new_site_id, $fetched_site->blog_id ); 2237 } 2238 2239 /** 2240 * Gets the ID of the next site that will get inserted 2241 * @return int 2242 */ 2243 protected function _get_next_site_id() { 2244 global $wpdb; 2245 // Create an entry. 2246 static::factory()->blog->create(); 2247 // Get the ID after it. 2248 return (int) $wpdb->get_var( 'SELECT blog_id FROM ' . $wpdb->blogs . ' ORDER BY blog_ID DESC LIMIT 1' ) + 1; 2249 } 2250 2251 /** 2252 * Capture the $meta value passed to the wpmu_new_blog action and compare it. 2253 */ 2254 public function wpmu_new_blog_callback( $blog_id, $user_id, $domain, $path, $network_id, $meta ) { 2255 $this->wp_initialize_site_meta = $meta; 2256 } 2257 2258 public function data_wpmu_new_blog_action_backward_compatible() { 2259 return array( 2260 'default values' => array( 2261 array(), 2262 array( 2263 'public' => 0, // `public` is one of the default metas in `wpmu_create_blog()' function prior to WordPress 5.1.0. 2264 'WPLANG' => 'en_US', // WPLANG is another default meta in `wpmu_create_blog()` function prior to WordPress 5.1.0. 2265 ), 2266 ), 2267 'public site' => array( 2268 array( 2269 'public' => 1, 2270 ), 2271 array( 2272 'public' => 1, 2273 'WPLANG' => 'en_US', 2274 ), 2275 ), 2276 'allowed_keys' => array( 2277 array( 2278 'public' => -1, 2279 'archived' => 0, 2280 'mature' => 0, 2281 'spam' => 0, 2282 'deleted' => 0, 2283 'lang_id' => 11, 2284 2285 ), 2286 array( 2287 'public' => -1, 2288 'WPLANG' => 'en_US', 2289 'archived' => 0, 2290 'mature' => 0, 2291 'spam' => 0, 2292 'deleted' => 0, 2293 'lang_id' => 11, 2294 ), 2295 ), 2296 'extra meta key' => array( 2297 array( 2298 'foo' => 'bar', 2299 ), 2300 array( 2301 'public' => 0, 2302 'foo' => 'bar', 2303 'WPLANG' => 'en_US', 2304 ), 2305 ), 2306 ); 2307 } 2308 }
Note: See TracChangeset
for help on using the changeset viewer.