diff --git a/tests/integration/tests/test-add-network-existing-site.php b/tests/integration/tests/test-add-network-existing-site.php new file mode 100644 index 0000000..ed9c13b --- /dev/null +++ b/tests/integration/tests/test-add-network-existing-site.php @@ -0,0 +1,177 @@ +factory->user->create( + array( + 'role' => 'administrator', + ) + ); + grant_super_admin( $user_id ); + + // Create a site to use as the existing root site. + $site_id = $this->factory->blog->create( + array( + 'domain' => 'existing-site.example.com', + 'path' => '/', + ) + ); + + // Create a network using the existing site. + $network_id = add_network( + array( + 'domain' => 'existing-site.example.com', + 'path' => '/', + 'site_name' => 'Existing Site', + 'network_name' => 'Test Network', + 'user_id' => $user_id, + 'network_admin_id' => $user_id, + 'existing_blog_id' => $site_id, + ) + ); + + // Verify network was created successfully. + $this->assertNotWPError( $network_id, 'Network should be created successfully' ); + $this->assertIsInt( $network_id, 'Network ID should be an integer' ); + + // Verify the site was moved to the new network. + $site = get_site( $site_id ); + $this->assertEquals( $network_id, (int) $site->network_id, 'Site should be in the new network' ); + + // Verify the site is the main site of the new network. + $main_site_id = get_network_option( $network_id, 'main_site' ); + $this->assertEquals( $site_id, (int) $main_site_id, 'Site should be the main site of the new network' ); + } + + /** + * Test adding a network with a nonexistent site returns an error. + * + * @since NEXT + */ + public function test_add_network_with_nonexistent_site() { + + // Create a test user. + $user_id = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + grant_super_admin( $user_id ); + + // Attempt to create a network with a nonexistent site ID. + $result = add_network( + array( + 'domain' => 'nonexistent.example.com', + 'path' => '/', + 'site_name' => 'Test Site', + 'network_name' => 'Test Network', + 'user_id' => $user_id, + 'network_admin_id' => $user_id, + 'existing_blog_id' => 999999, + ) + ); + + $this->assertWPError( $result, 'Should return WP_Error for nonexistent site' ); + $this->assertEquals( 'blog_not_exist', $result->get_error_code(), 'Error code should be blog_not_exist' ); + } + + /** + * Test adding a network with a main site of another network returns an error. + * + * @since NEXT + */ + public function test_add_network_with_main_site() { + + // Create a test user. + $user_id = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + grant_super_admin( $user_id ); + + // Create a network with add_network() so it has a real main site. + $first_network_id = add_network( + array( + 'domain' => 'first-network.example.com', + 'path' => '/', + 'site_name' => 'First Network Site', + 'network_name' => 'First Network', + 'user_id' => $user_id, + 'network_admin_id' => $user_id, + ) + ); + + // Get the main site of the first network. + $main_site_id = get_main_site_id( $first_network_id ); + + // Attempt to create a second network using the main site. + $result = add_network( + array( + 'domain' => 'second-network.example.com', + 'path' => '/', + 'site_name' => 'Test Site', + 'network_name' => 'Second Network', + 'user_id' => $user_id, + 'network_admin_id' => $user_id, + 'existing_blog_id' => $main_site_id, + ) + ); + + $this->assertWPError( $result, 'Should return WP_Error when using a main site' ); + $this->assertEquals( 'blog_is_main_site', $result->get_error_code(), 'Error code should be blog_is_main_site' ); + } + + /** + * Test adding a network without existing_blog_id creates a new site. + * + * @since NEXT + */ + public function test_add_network_without_existing_site() { + + // Create a test user. + $user_id = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + grant_super_admin( $user_id ); + + // Create a network without existing_blog_id. + $network_id = add_network( + array( + 'domain' => 'site-test.example.com', + 'path' => '/', + 'site_name' => 'Test Site', + 'network_name' => 'Test Network', + 'user_id' => $user_id, + 'network_admin_id' => $user_id, + ) + ); + + // Verify network was created successfully. + $this->assertNotWPError( $network_id, 'Network should be created successfully' ); + $this->assertIsInt( $network_id, 'Network ID should be an integer' ); + + // Verify a new site was created as the main site. + $main_site_id = get_network_option( $network_id, 'main_site' ); + $this->assertNotEmpty( $main_site_id, 'A main site should have been created' ); + + $main_site = get_site( $main_site_id ); + $this->assertNotNull( $main_site, 'Main site should exist' ); + $this->assertEquals( 'site-test.example.com', $main_site->domain, 'Main site should have the network domain' ); + } +} diff --git a/wp-multi-network/assets/css/wp-multi-network-rtl.css b/wp-multi-network/assets/css/wp-multi-network-rtl.css index 110ecab..99c7a3a 100644 --- a/wp-multi-network/assets/css/wp-multi-network-rtl.css +++ b/wp-multi-network/assets/css/wp-multi-network-rtl.css @@ -1,12 +1,15 @@ th.column-title { width: 35%; } + th.column-path { width: 15%; } + th.column-blogs { width: 10%; } + td.column-domain { white-space: nowrap; overflow: hidden; @@ -123,6 +126,7 @@ table.assign-sites td.column-available { table.assign-sites td.column-assigned { padding-right: 0; } + table.assign-sites td.column-available, table.assign-sites td.column-assigned { width: 42%; @@ -135,8 +139,8 @@ table.assign-sites td.column-assigned { div.network-delete { background: #fff; border-right: 4px solid #dc3232; - -webkit-box-shadow: 0 1px 1px 0 rgba( 0, 0, 0, 0.1 ); - box-shadow: 0 1px 1px 0 rgba( 0, 0, 0, 0.1 ); + -webkit-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); margin: 5px 0 2px; padding: 1px 12px; } @@ -154,3 +158,15 @@ ul.delete-sites { ul.delete-sites li { margin: 0; } + +#root-site-toggle { + margin-top: 12px; +} + +#root-site-toggle label { + margin-left: 16px; +} + +.root-site-existing { + display: none; +} diff --git a/wp-multi-network/assets/css/wp-multi-network-rtl.min.css b/wp-multi-network/assets/css/wp-multi-network-rtl.min.css index b0b73d2..fb846b1 100644 --- a/wp-multi-network/assets/css/wp-multi-network-rtl.min.css +++ b/wp-multi-network/assets/css/wp-multi-network-rtl.min.css @@ -1 +1 @@ -th.column-title{width:35%}th.column-path{width:15%}th.column-blogs{width:10%}td.column-domain{overflow:hidden;white-space:nowrap}.edit-network label span.scheme{display:inline-block}.edit-network .form-field label input[type=text]{display:inline-block;width:50%}#poststuff #wpmn-edit-network-assign-sites .inside{margin:0;padding:0}#wpmn-edit-network-publish .submitbox,#wpmn-move-site-publish .submitbox{margin:10px -12px -12px}#wpmn-edit-network-publish #major-publishing-actions,#wpmn-move-site-publish #major-publishing-actions{margin-top:10px}#misc-publishing-actions #network:before,#misc-publishing-actions #sites:before{font:normal 20px/1 dashicons;speak:none;display:inline-block;right:-1px;padding:0 0 0 2px;position:relative;top:0;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}#misc-publishing-actions #network:before{content:"\f319"}#misc-publishing-actions #sites:before{content:"\f325"}table.widefat.assign-sites,table.widefat.move-site{border:none;box-shadow:none}table.assign-sites thead th,table.move-site thead th{background:#f4f4f4;font-size:13px;font-weight:600;text-align:center}.networks tbody td,.networks tbody th{box-shadow:inset 0 -1px 0 rgba(0,0,0,.1);padding:10px 9px}.networks .current th.check-column{border-right:4px solid #00a0d2}.networks .current td,.networks .current th{background-color:#f7fcfe;padding:10px 9px}table.assign-sites select[multiple]{height:80px!important;margin:0;width:100%}table.assign-sites .button{height:80px;margin:0 5px;width:35%}table.assign-sites td.column-actions{padding:8px 0;width:16%}table.assign-sites td.column-actions .assign{content:"\f341";float:right}table.assign-sites td.column-actions .unassign{float:left}table.assign-sites td.column-available{padding-left:0}table.assign-sites td.column-assigned{padding-right:0}table.assign-sites td.column-assigned,table.assign-sites td.column-available{width:42%}table.assign-sites td.column-assigned{text-align:left}div.network-delete{background:#fff;border-right:4px solid #dc3232;box-shadow:0 1px 1px 0 rgba(0,0,0,.1);margin:5px 0 2px;padding:1px 12px}div.network-delete p{margin:.5em 0;padding:2px}ul.delete-sites{list-style:square;margin:10px 20px}ul.delete-sites li{margin:0} +th.column-title{width:35%}th.column-path{width:15%}th.column-blogs{width:10%}td.column-domain{overflow:hidden;white-space:nowrap}.edit-network label span.scheme{display:inline-block}.edit-network .form-field label input[type=text]{display:inline-block;width:50%}#poststuff #wpmn-edit-network-assign-sites .inside{margin:0;padding:0}#wpmn-edit-network-publish .submitbox,#wpmn-move-site-publish .submitbox{margin:10px -12px -12px}#wpmn-edit-network-publish #major-publishing-actions,#wpmn-move-site-publish #major-publishing-actions{margin-top:10px}#misc-publishing-actions #network:before,#misc-publishing-actions #sites:before{font:normal 20px/1 dashicons;speak:none;display:inline-block;right:-1px;padding:0 0 0 2px;position:relative;top:0;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}#misc-publishing-actions #network:before{content:"\f319"}#misc-publishing-actions #sites:before{content:"\f325"}table.widefat.assign-sites,table.widefat.move-site{border:none;box-shadow:none}table.assign-sites thead th,table.move-site thead th{background:#f4f4f4;font-size:13px;font-weight:600;text-align:center}.networks tbody td,.networks tbody th{box-shadow:inset 0 -1px 0 rgba(0,0,0,.1);padding:10px 9px}.networks .current th.check-column{border-right:4px solid #00a0d2}.networks .current td,.networks .current th{background-color:#f7fcfe;padding:10px 9px}table.assign-sites select[multiple]{height:80px!important;margin:0;width:100%}table.assign-sites .button{height:80px;margin:0 5px;width:35%}table.assign-sites td.column-actions{padding:8px 0;width:16%}table.assign-sites td.column-actions .assign{content:"\f341";float:right}table.assign-sites td.column-actions .unassign{float:left}table.assign-sites td.column-available{padding-left:0}table.assign-sites td.column-assigned{padding-right:0}table.assign-sites td.column-assigned,table.assign-sites td.column-available{width:42%}table.assign-sites td.column-assigned{text-align:left}div.network-delete{background:#fff;border-right:4px solid #dc3232;box-shadow:0 1px 1px 0 rgba(0,0,0,.1);margin:5px 0 2px;padding:1px 12px}div.network-delete p{margin:.5em 0;padding:2px}ul.delete-sites{list-style:square;margin:10px 20px}ul.delete-sites li{margin:0}#root-site-toggle{margin-top:12px}#root-site-toggle label{margin-left:16px}.root-site-existing{display:none} diff --git a/wp-multi-network/assets/css/wp-multi-network.css b/wp-multi-network/assets/css/wp-multi-network.css index 4738b4f..1db0aba 100644 --- a/wp-multi-network/assets/css/wp-multi-network.css +++ b/wp-multi-network/assets/css/wp-multi-network.css @@ -1,12 +1,15 @@ th.column-title { width: 35%; } + th.column-path { width: 15%; } + th.column-blogs { width: 10%; } + td.column-domain { white-space: nowrap; overflow: hidden; @@ -123,6 +126,7 @@ table.assign-sites td.column-available { table.assign-sites td.column-assigned { padding-left: 0; } + table.assign-sites td.column-available, table.assign-sites td.column-assigned { width: 42%; @@ -135,8 +139,8 @@ table.assign-sites td.column-assigned { div.network-delete { background: #fff; border-left: 4px solid #dc3232; - -webkit-box-shadow: 0 1px 1px 0 rgba( 0, 0, 0, 0.1 ); - box-shadow: 0 1px 1px 0 rgba( 0, 0, 0, 0.1 ); + -webkit-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); margin: 5px 0 2px; padding: 1px 12px; } @@ -154,3 +158,15 @@ ul.delete-sites { ul.delete-sites li { margin: 0; } + +#root-site-toggle { + margin-top: 12px; +} + +#root-site-toggle label { + margin-right: 16px; +} + +.root-site-existing { + display: none; +} diff --git a/wp-multi-network/assets/css/wp-multi-network.min.css b/wp-multi-network/assets/css/wp-multi-network.min.css index 175a66d..23ae7de 100644 --- a/wp-multi-network/assets/css/wp-multi-network.min.css +++ b/wp-multi-network/assets/css/wp-multi-network.min.css @@ -1 +1 @@ -th.column-title{width:35%}th.column-path{width:15%}th.column-blogs{width:10%}td.column-domain{overflow:hidden;white-space:nowrap}.edit-network label span.scheme{display:inline-block}.edit-network .form-field label input[type=text]{display:inline-block;width:50%}#poststuff #wpmn-edit-network-assign-sites .inside{margin:0;padding:0}#wpmn-edit-network-publish .submitbox,#wpmn-move-site-publish .submitbox{margin:10px -12px -12px}#wpmn-edit-network-publish #major-publishing-actions,#wpmn-move-site-publish #major-publishing-actions{margin-top:10px}#misc-publishing-actions #network:before,#misc-publishing-actions #sites:before{font:normal 20px/1 dashicons;speak:none;display:inline-block;left:-1px;padding:0 2px 0 0;position:relative;top:0;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}#misc-publishing-actions #network:before{content:"\f319"}#misc-publishing-actions #sites:before{content:"\f325"}table.widefat.assign-sites,table.widefat.move-site{border:none;box-shadow:none}table.assign-sites thead th,table.move-site thead th{background:#f4f4f4;font-size:13px;font-weight:600;text-align:center}.networks tbody td,.networks tbody th{box-shadow:inset 0 -1px 0 rgba(0,0,0,.1);padding:10px 9px}.networks .current th.check-column{border-left:4px solid #00a0d2}.networks .current td,.networks .current th{background-color:#f7fcfe;padding:10px 9px}table.assign-sites select[multiple]{height:80px!important;margin:0;width:100%}table.assign-sites .button{height:80px;margin:0 5px;width:35%}table.assign-sites td.column-actions{padding:8px 0;width:16%}table.assign-sites td.column-actions .assign{content:"\f341";float:left}table.assign-sites td.column-actions .unassign{float:right}table.assign-sites td.column-available{padding-right:0}table.assign-sites td.column-assigned{padding-left:0}table.assign-sites td.column-assigned,table.assign-sites td.column-available{width:42%}table.assign-sites td.column-assigned{text-align:right}div.network-delete{background:#fff;border-left:4px solid #dc3232;box-shadow:0 1px 1px 0 rgba(0,0,0,.1);margin:5px 0 2px;padding:1px 12px}div.network-delete p{margin:.5em 0;padding:2px}ul.delete-sites{list-style:square;margin:10px 20px}ul.delete-sites li{margin:0} +th.column-title{width:35%}th.column-path{width:15%}th.column-blogs{width:10%}td.column-domain{overflow:hidden;white-space:nowrap}.edit-network label span.scheme{display:inline-block}.edit-network .form-field label input[type=text]{display:inline-block;width:50%}#poststuff #wpmn-edit-network-assign-sites .inside{margin:0;padding:0}#wpmn-edit-network-publish .submitbox,#wpmn-move-site-publish .submitbox{margin:10px -12px -12px}#wpmn-edit-network-publish #major-publishing-actions,#wpmn-move-site-publish #major-publishing-actions{margin-top:10px}#misc-publishing-actions #network:before,#misc-publishing-actions #sites:before{font:normal 20px/1 dashicons;speak:none;display:inline-block;left:-1px;padding:0 2px 0 0;position:relative;top:0;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}#misc-publishing-actions #network:before{content:"\f319"}#misc-publishing-actions #sites:before{content:"\f325"}table.widefat.assign-sites,table.widefat.move-site{border:none;box-shadow:none}table.assign-sites thead th,table.move-site thead th{background:#f4f4f4;font-size:13px;font-weight:600;text-align:center}.networks tbody td,.networks tbody th{box-shadow:inset 0 -1px 0 rgba(0,0,0,.1);padding:10px 9px}.networks .current th.check-column{border-left:4px solid #00a0d2}.networks .current td,.networks .current th{background-color:#f7fcfe;padding:10px 9px}table.assign-sites select[multiple]{height:80px!important;margin:0;width:100%}table.assign-sites .button{height:80px;margin:0 5px;width:35%}table.assign-sites td.column-actions{padding:8px 0;width:16%}table.assign-sites td.column-actions .assign{content:"\f341";float:left}table.assign-sites td.column-actions .unassign{float:right}table.assign-sites td.column-available{padding-right:0}table.assign-sites td.column-assigned{padding-left:0}table.assign-sites td.column-assigned,table.assign-sites td.column-available{width:42%}table.assign-sites td.column-assigned{text-align:right}div.network-delete{background:#fff;border-left:4px solid #dc3232;box-shadow:0 1px 1px 0 rgba(0,0,0,.1);margin:5px 0 2px;padding:1px 12px}div.network-delete p{margin:.5em 0;padding:2px}ul.delete-sites{list-style:square;margin:10px 20px}ul.delete-sites li{margin:0}#root-site-toggle{margin-top:12px}#root-site-toggle label{margin-right:16px}.root-site-existing{display:none} diff --git a/wp-multi-network/assets/js/wp-multi-network.js b/wp-multi-network/assets/js/wp-multi-network.js index a4794fa..e17b3cc 100644 --- a/wp-multi-network/assets/js/wp-multi-network.js +++ b/wp-multi-network/assets/js/wp-multi-network.js @@ -25,6 +25,19 @@ jQuery( document ).ready( function ( $ ) { move( 'to', 'from' ); } ); + /* Toggle root site option between new and existing */ + $( 'input[name=root_site_option]' ).on( 'change', function () { + if ( $( this ).val() === 'existing' ) { + $( '.root-site-new' ).hide(); + $( '.root-site-existing' ).show(); + $( '#wpmn-edit-network-details' ).hide(); + } else { + $( '.root-site-new' ).show(); + $( '.root-site-existing' ).hide(); + $( '#wpmn-edit-network-details' ).show(); + } + } ); + /* Select all sites in "selected" box when submitting */ $( '#edit-network-form' ).submit( function () { $( '#to' ).children( 'option:enabled' ).attr( 'selected', true ); diff --git a/wp-multi-network/assets/js/wp-multi-network.min.js b/wp-multi-network/assets/js/wp-multi-network.min.js index c004779..5885d25 100644 --- a/wp-multi-network/assets/js/wp-multi-network.min.js +++ b/wp-multi-network/assets/js/wp-multi-network.min.js @@ -1 +1 @@ -(()=>{var e={822:()=>{jQuery(document).ready(function(e){function t(e,t){jQuery("#"+e).children("option:selected").each(function(){jQuery("#"+t).append(jQuery(this).clone()),jQuery(this).remove()})}e(".if-js-closed").removeClass("if-js-closed").addClass("closed"),e(".postbox").children("h3").click(function(){e(this.parentNode).hasClass("closed")?e(this.parentNode).removeClass("closed"):e(this.parentNode).addClass("closed")}),e("input[name=assign]").click(function(){t("from","to")}),e("input[name=unassign]").click(function(){t("to","from")}),e("#edit-network-form").submit(function(){e("#to").children("option:enabled").attr("selected",!0),e("#from").children("option:enabled").attr("selected",!0)})})}},t={};function o(n){var r=t[n];if(void 0!==r)return r.exports;var s=t[n]={exports:{}};return e[n](s,s.exports,o),s.exports}o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var n in t)o.o(t,n)&&!o.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{"use strict";o(822)})()})(); \ No newline at end of file +jQuery(document).ready(function(e){function t(e,t){jQuery("#"+e).children("option:selected").each(function(){jQuery("#"+t).append(jQuery(this).clone()),jQuery(this).remove()})}e(".if-js-closed").removeClass("if-js-closed").addClass("closed"),e(".postbox").children("h3").click(function(){e(this.parentNode).hasClass("closed")?e(this.parentNode).removeClass("closed"):e(this.parentNode).addClass("closed")}),e("input[name=assign]").click(function(){t("from","to")}),e("input[name=unassign]").click(function(){t("to","from")}),e("input[name=root_site_option]").on("change",function(){"existing"===e(this).val()?(e(".root-site-new").hide(),e(".root-site-existing").show(),e("#wpmn-edit-network-details").hide()):(e(".root-site-new").show(),e(".root-site-existing").hide(),e("#wpmn-edit-network-details").show())}),e("#edit-network-form").submit(function(){e("#to").children("option:enabled").attr("selected",!0),e("#from").children("option:enabled").attr("selected",!0)})}); \ No newline at end of file diff --git a/wp-multi-network/includes/classes/class-wp-ms-networks-admin.php b/wp-multi-network/includes/classes/class-wp-ms-networks-admin.php index 883a1aa..48b4d8e 100644 --- a/wp-multi-network/includes/classes/class-wp-ms-networks-admin.php +++ b/wp-multi-network/includes/classes/class-wp-ms-networks-admin.php @@ -472,6 +472,21 @@ public function page_edit_network() { + + +
| @@ -83,6 +96,27 @@ function wpmn_edit_network_new_site_metabox() { | |
|---|---|
| + + | ++ + + + + + + | +