Skip to content

Commit f528456

Browse files
Copilotswissspidy
andcommitted
Implement wp site get command with ID and URL support
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
1 parent 67c9c73 commit f528456

3 files changed

Lines changed: 202 additions & 0 deletions

File tree

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
"site deactivate",
150150
"site delete",
151151
"site empty",
152+
"site get",
152153
"site list",
153154
"site mature",
154155
"site meta",

features/site.feature

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,3 +763,76 @@ Feature: Manage sites in a multisite installation
763763
Then STDOUT should be a table containing rows:
764764
| blog_id | public |
765765
| 2 | 1 |
766+
767+
Scenario: Get site by ID
768+
Given a WP multisite install
769+
770+
When I run `wp site create --slug=testsite --porcelain`
771+
Then STDOUT should be a number
772+
And save STDOUT as {SITE_ID}
773+
774+
When I run `wp site get {SITE_ID} --field=blog_id`
775+
Then STDOUT should be:
776+
"""
777+
{SITE_ID}
778+
"""
779+
780+
When I run `wp site get {SITE_ID}`
781+
Then STDOUT should be a table containing rows:
782+
| blog_id |
783+
| {SITE_ID} |
784+
785+
Scenario: Get site by URL
786+
Given a WP multisite install
787+
788+
When I run `wp site create --slug=testsite --porcelain`
789+
Then STDOUT should be a number
790+
And save STDOUT as {SITE_ID}
791+
And I run `wp site list --blog_id={SITE_ID} --field=url`
792+
And save STDOUT as {SITE_URL}
793+
794+
When I run `wp site get {SITE_URL} --field=blog_id`
795+
Then STDOUT should be:
796+
"""
797+
{SITE_ID}
798+
"""
799+
800+
Scenario: Get site by URL with subdirectory
801+
Given a WP multisite subdirectory install
802+
803+
When I run `wp site create --slug=mysubdir --porcelain`
804+
Then STDOUT should be a number
805+
And save STDOUT as {SITE_ID}
806+
807+
When I run `wp site get http://example.com/mysubdir/ --field=blog_id`
808+
Then STDOUT should be:
809+
"""
810+
{SITE_ID}
811+
"""
812+
813+
Scenario: Use site get with site delete
814+
Given a WP multisite install
815+
816+
When I run `wp site create --slug=deleteme --porcelain`
817+
Then STDOUT should be a number
818+
And save STDOUT as {SITE_ID}
819+
820+
When I run `wp site delete $(wp site get http://example.com/deleteme/ --field=blog_id) --yes`
821+
Then STDOUT should contain:
822+
"""
823+
Success: The site at
824+
"""
825+
And STDOUT should contain:
826+
"""
827+
was deleted.
828+
"""
829+
830+
Scenario: Get site with invalid URL should fail
831+
Given a WP multisite install
832+
833+
When I try `wp site get http://example.com/nonexistent/ --field=blog_id`
834+
Then STDERR should contain:
835+
"""
836+
Error: Could not find site with URL: http://example.com/nonexistent/
837+
"""
838+
And the return code should be 1

src/Site_Command.php

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,134 @@ public function delete( $args, $assoc_args ) {
384384
WP_CLI::success( "The site at '{$site_url}' was deleted." );
385385
}
386386

387+
/**
388+
* Gets details about a site in a multisite installation.
389+
*
390+
* ## OPTIONS
391+
*
392+
* <site>
393+
* : Site ID or URL of the site to get. For subdirectory sites, use the full URL (e.g., http://example.com/subdir/).
394+
*
395+
* [--field=<field>]
396+
* : Instead of returning the whole site, returns the value of a single field.
397+
*
398+
* [--fields=<fields>]
399+
* : Limit the output to specific fields. Defaults to all fields.
400+
*
401+
* [--format=<format>]
402+
* : Render output in a particular format.
403+
* ---
404+
* default: table
405+
* options:
406+
* - table
407+
* - csv
408+
* - json
409+
* - yaml
410+
* ---
411+
*
412+
* ## AVAILABLE FIELDS
413+
*
414+
* These fields will be displayed by default for the site:
415+
*
416+
* * blog_id
417+
* * url
418+
* * last_updated
419+
* * registered
420+
*
421+
* These fields are optionally available:
422+
*
423+
* * site_id
424+
* * domain
425+
* * path
426+
* * public
427+
* * archived
428+
* * mature
429+
* * spam
430+
* * deleted
431+
* * lang_id
432+
*
433+
* ## EXAMPLES
434+
*
435+
* # Get site by ID
436+
* $ wp site get 1
437+
* +---------+-------------------------+---------------------+---------------------+
438+
* | blog_id | url | last_updated | registered |
439+
* +---------+-------------------------+---------------------+---------------------+
440+
* | 1 | http://example.com/ | 2025-01-01 12:00:00 | 2025-01-01 12:00:00 |
441+
* +---------+-------------------------+---------------------+---------------------+
442+
*
443+
* # Get site URL by site ID
444+
* $ wp site get 1 --field=url
445+
* http://example.com/
446+
*
447+
* # Get site ID by URL
448+
* $ wp site get http://example.com/subdir/ --field=blog_id
449+
* 2
450+
*/
451+
public function get( $args, $assoc_args ) {
452+
if ( ! is_multisite() ) {
453+
WP_CLI::error( 'This is not a multisite installation.' );
454+
}
455+
456+
$site_arg = $args[0];
457+
$site = null;
458+
459+
// Check if the argument is a URL (contains :// or starts with www.)
460+
if ( false !== strpos( $site_arg, '://' ) || 0 === strpos( $site_arg, 'www.' ) ) {
461+
// Parse the URL to get domain and path
462+
$url_parts = wp_parse_url( $site_arg );
463+
464+
if ( ! isset( $url_parts['host'] ) ) {
465+
WP_CLI::error( "Invalid URL: {$site_arg}" );
466+
}
467+
468+
$domain = $url_parts['host'];
469+
$path = isset( $url_parts['path'] ) ? $url_parts['path'] : '/';
470+
471+
// Ensure path ends with /
472+
if ( '/' !== substr( $path, -1 ) ) {
473+
$path .= '/';
474+
}
475+
476+
// Query the database for the site
477+
global $wpdb;
478+
$site = $wpdb->get_row(
479+
$wpdb->prepare(
480+
"SELECT * FROM {$wpdb->blogs} WHERE domain = %s AND path = %s",
481+
$domain,
482+
$path
483+
)
484+
);
485+
486+
if ( ! $site ) {
487+
WP_CLI::error( "Could not find site with URL: {$site_arg}" );
488+
}
489+
} else {
490+
// Treat as site ID
491+
$site = $this->fetcher->get_check( $site_arg );
492+
}
493+
494+
// Get the site details and add URL
495+
$site_data = get_object_vars( $site );
496+
$site_data['url'] = trailingslashit( get_home_url( $site->blog_id ) );
497+
498+
// Cast numeric fields to int for consistent output
499+
if ( isset( $site_data['blog_id'] ) && is_scalar( $site_data['blog_id'] ) ) {
500+
$site_data['blog_id'] = (int) $site_data['blog_id'];
501+
}
502+
if ( isset( $site_data['site_id'] ) && is_scalar( $site_data['site_id'] ) ) {
503+
$site_data['site_id'] = (int) $site_data['site_id'];
504+
}
505+
506+
// Set default fields if not specified
507+
if ( empty( $assoc_args['fields'] ) ) {
508+
$assoc_args['fields'] = [ 'blog_id', 'url', 'last_updated', 'registered' ];
509+
}
510+
511+
$formatter = $this->get_formatter( $assoc_args );
512+
$formatter->display_item( $site_data );
513+
}
514+
387515
/**
388516
* Creates a site in a multisite installation.
389517
*

0 commit comments

Comments
 (0)