#14511 closed enhancement (fixed)
new function - wp_get_sites($args)
Reported by: | transom | Owned by: | |
---|---|---|---|
Milestone: | 3.7 | Priority: | normal |
Severity: | normal | Version: | |
Component: | Multisite | Keywords: | has-patch needs-testing |
Focuses: | Cc: |
Description (last modified by )
With the deprication of get_blog_list (and the dire warnings), we had a need for a function to retrieve a list of blogs. At first blush, it appears that one could use get_blogs_of_user. It seems to assume that the same admin (userid 1) is going to create all sites. If you have multiple network_admins, then a search for a single user's sites won't return a full list.
So I have adapted the code from wp-admin/ms-sites.php and with a nod to wp_list_pages - am submitting wp_get_sites for a future release.
This function accepts an argument list to filter the results, modify the order, and limit the range of results. I wrote it with an eye to provide an interface consistent with other wp functions, as well as potentially replacing the sql query in wp-admin/ms-sites.php.
The initial set of arguments include:
'include_id' , // includes only these sites in the results, comma-delimited 'exclude_id' , // excludes these sites from the results, comma-delimted 'blogname_like' , // domain or path is like this value 'ip_like' , // Match IP address 'reg_date_since' , // sites registered since (accepts pretty much any valid date like tomorrow, today, 5/12/2009, etc.) 'reg_date_before' , // sites registered before 'include_user_id' , // only sites owned by these users, comma-delimited 'exclude_user_id' , // don't include sites owned by these users, comma-delimited 'include_spam' => false, // Include sites marked as "spam" 'include_deleted' => false, // Include deleted sites 'include_archived' => false, // Include archived sites 'include_mature' => false, // Included blogs marked as mature 'public_only' => true, // Include only blogs marked as public 'sort_column' => 'registered',// or registered, last_updated, blogname, site_id 'order' => 'asc', // or desc 'limit_results' , // return this many results 'start' , // return results starting with this item
The usual warning are provided. It works for me but I haven't tested it completely yet. But I am assuming this could be helpful to others and I have no doubt about getting comments back <grin>
Attachments (12)
Change History (59)
#2
@
14 years ago
Found a bug will submit new patch shortly (joining on the registration log causes interesting problems vis-a-vie blogs not created via registration - duh!)
#3
@
14 years ago
Attached is a patch for wp-includes/ms-functions.php (replacing the farked version)
#5
@
14 years ago
This probably generates quite a bit of notices (turn on WP_DEBUG) since most of the variables being extracted don't actually exist in the array. include_id is being considered a value, not the key -- should be include_id => ''
instead.
Lots of LIKEs and such. This query probably isn't very efficient, but it's a start we can work off of.
#6
@
14 years ago
Changing the "isset" to not-empty (after defining defaults for all strings).
I am confused by your comment re: variables being extracted not existing in the array - after the wp_parse_args there should be a value (even if it is the default) for each variable.
Include_id is supposed to be a string of blog_ids to be included in the results.
Will post new diff shortly.
#7
@
14 years ago
Updated diff and attached file for wp_get_sites that can used in functions.php to test functionality
#8
follow-up:
↓ 9
@
14 years ago
Copied wp_get_sites2.php into my themes functions.php and am getting
Undefined property: wpdb::$site_id in /path-to-wp-content/wp-content/themes/delicious/functions.php on line 159
and line 159 is
$query .= "WHERE b.site_id
= '{$wpdb->site_id}' ";
I am running the latest nightly build.
#9
in reply to:
↑ 8
;
follow-up:
↓ 11
@
14 years ago
Replying to kahless:
Copied wp_get_sites2.php into my themes functions.php and am getting
Undefined property: wpdb::$site_id in /path-to-wp-content/wp-content/themes/delicious/functions.php on line 159
and line 159 is
$query .= "WHERE b.
site_id
= '{$wpdb->site_id}' ";
I am running the latest nightly build.
I am running a subdirectory install if that makes any difference.
#10
@
14 years ago
- Keywords 3.2-early added
- Milestone changed from Awaiting Review to Future Release
Will likely need some thought and a new patch.
#11
in reply to:
↑ 9
@
14 years ago
Replying to kahless:
Replying to kahless:
Copied wp_get_sites2.php into my themes functions.php and am getting
Undefined property: wpdb::$site_id in /path-to-wp-content/wp-content/themes/delicious/functions.php on line 159
and line 159 is
$query .= "WHERE b.
site_id
= '{$wpdb->site_id}' ";
I am running the latest nightly build.
I am running a subdirectory install if that makes any difference.
I've the same problem here. Renaming {$wpdb->site_id} to {$wpdb->siteid} seams to resolve the problem.
#18
@
12 years ago
- Cc pbaylies added
- Keywords has-patch needs-testing added; needs-patch removed
I've uploaded a new patch for this, rewritten the original without the join and some of the options, and most of the LIKEs; all data in the query should be known or sanitized as well. So what do we need to do to get a function like this back into core.
#20
@
11 years ago
- Milestone changed from Future Release to 3.7
A wp_get_sites()
would be nice.
IMO, it doesn't necessarily need to duplicate the efforts of get_blog_list()
(deprecated in [15170]). It should provide a straight forward method of accessing information about the sites in a specified network.
I've attached 14511.diff as a starting point. Caching needs to be added and most likely the site query would need to return more than blog_id, domain, path
.
Moving to 3.7 for discussion.
#21
@
11 years ago
14511.diff is simple and definitely an improvement over get_blog_list(), which I've previously ranted about.
I'd argue that $network_id should be a default argument in $args, and that setting it to null, bool, or 'all' should allow all network IDs to be queried; it should probably also take an array of network IDs to query. What about querying regardless of the value of public
or other flags? (As in, you want any sites whether it is public or not.) What about querying by domain and by path? What about wp_is_large_network()? Is it worth looking into a proper WP_Site_Query class?
Not suggesting this should get out of hand, but just tossing out some ideas. I'm fine with 14511.diff, with minor modifications, for 3.7.
#23
@
11 years ago
14511.2.diff does a few things better/differently.
$network_id
defaults tonull
as a default argument in$args
- If
$network_id
is passed as null, bool, or all, sites from all networks are returned - If
$network_id
is passed as a single network ID or an array of network IDs, only those sites are returned - Arguments for public, archived, mature, spam, deleted are accepted. By default they are left out of the query
- All DB fields are returned in the response rather than just blog_id, domain, and path.
Have not hit querying by domain/path yet.
#24
@
11 years ago
14511.3.diff is the above with the realization that there is no reason to reprocess results into a new array.
Also starts to add caching, though invalidation is likely going to be a bit weird. I'm guessing we need a last_updated
key to rely on, but then need to figure out all the places that indicate a refresh is needed.
#27
@
11 years ago
14511.4.diff removes the initial caching attempts, to be addressed at a later time, and adds a default limit argument of 100 for the query.
Also use %d
instead of %s
in the prepare statement as we're dealing with int and enum.
#28
follow-up:
↓ 29
@
11 years ago
14511.4.diff looks good. A few things:
- Some basic unit tests would be stellar.
- If get_results() returns no results, the response will be
array( 0 => null )
— I imagine an empty array was desired. - If wp_is_large_network() is true,
null
is returned — I imagine an empty array was desired. - I would document public, deleted, etc., as "defaults". The trick is to set them to null, which is ! isset().
- Some super basic unit tests would be fantastic. Probably just testing 'public' => null, true, and false; and also the return value for when nothing matches (as in an empty array).
#29
in reply to:
↑ 28
@
11 years ago
14511.5.diff adds basic unit tests and ensures proper return of an empty array if no results return.
Replying to nacin:
- If get_results() returns no results, the response will be
array( 0 => null )
— I imagine an empty array was desired.
I always got an empty array with how it was setup, though the updated patch uses $wpdb->get_results( $query, ARRAY_A )
to make sure an array is returned rather than null
if no results are found.
#30
follow-up:
↓ 37
@
11 years ago
I think wp_get_sites() should only return sites *from that network* by default. You should need to explicitly pass null
to this function to get sites from any network.
This is similar to how WP_User_Query works (only users assigned to a site), and also the network admin (only sites for the network being edited).
I think the roadmap for this function, by the way, should be to replace all direct queries to $wpdb->blogs in WP_MS_Sites_List_Table, and ideally any other non-complex direct queries to $wpdb->blogs elsewhere.
#32
@
11 years ago
There should be one white space before 'intval'
:
$network_ids = array_map('intval', (array) $args['network_id'] );
#34
@
11 years ago
As reported by markoheijnen, archived
remains an ENUM of '0'
and '1'
. These are indexed from 1, so querying for the integer 1
means we're actually querying the ENUM 0. Going to write a test to demonstrate this.
We've worked to eliminate ENUM from the database previously, but all of those former ENUM fields became strings. ([6732].) In this case, it should become a tinyint(2) like the related fields. I am not familiar with what an upgrade routine might look like for this. pento might have some ideas.
#37
in reply to:
↑ 30
@
11 years ago
Replying to nacin:
This is similar to how WP_User_Query works (only users assigned to a site), and also the network admin (only sites for the network being edited).
That makes sense. Random info for another ticket: the WP_MS_Users_List_Table overwrites that user query with blog_id => 0
, so all users are returned on all networks.
I think the roadmap for this function, by the way, should be to replace all direct queries to $wpdb->blogs in WP_MS_Sites_List_Table, and ideally any other non-complex direct queries to $wpdb->blogs elsewhere.
Agreed. There's a bunch that can be cleaned up. To go all the way, we'd also want to handle domain and path searches.
#38
in reply to:
↑ 38
;
follow-up:
↓ 38
@
11 years ago
14511_wp_parse_id_list.diff
uses WordPress' built in wp_parse_id_list()
function to parse the network_id
parameter.
#39
@
11 years ago
Given that we have a limit
parameter, I thought it would be useful to also add a offset
parameter. This allows people to query the first 100 sites, then the second 100 sites if required.
14511_offset.diff
implements this, including unit tests.
#41
follow-up:
↓ 42
@
11 years ago
In 14511_offset.diff, looks like intval( $args['limit'] ) > 0
in line 2057 can be just $args['limit']
. Same for $args['offset']
.
#42
in reply to:
↑ 41
@
11 years ago
Replying to SergeyBiryukov:
In 14511_offset.diff, looks like
intval( $args['limit'] ) > 0
in line 2057 can be just$args['limit']
. Same for$args['offset']
.
Thanks for the feedback SergeyBiryukov.
I've implemented this in 14511_offset2.diff.
#46
@
11 years ago
- Resolution set to fixed
- Status changed from new to closed
I'm going to close this as fixed. New enhancements can be brought up in new tickets.
Source for wp_get_sites