Find Site ID From WP_Post

No, post objects do not store this data. You need to store the site ID separately.

Post objects do not store the site they were created on or are currently hosted on. That information doesn’t exist in the posts table, nor does WordPress track it elsewhere. The assumption is always that the post comes from the current site.

The code you’re writing will need to store the source site ID somehow. Some plugins do this via post meta.

If you already have posts that have been migrated though, would have to load up each site, and query for the post with the same ID, then compare them, and if they match, you’ve found it. This assumes no modifications have been made at either end.

Q: How do we know this?

Because there is nowhere in WP_Post that stores the site ID or network ID. Inspecting a variable holding a post object shows this information isn’t available either.

Q: What do other plugins/developers do?

If they need to migrate a post to another site, but also need to trace it back to its source, they store those details in post meta.

For example, the original URL, site ID, and post ID can be stored as post meta. This is useful for UI purposes, telling a user that the post has been migrated or syndicated. This is what the syndicator and distributor plugins do.

Q: Can the GUID be used?

No, GUID’s aren’t always URLs, aren’t always current, and don’t always represent the source.

For example, a GUID will not change if a posts slug or URL changes, the GUID can be a hash not a URL, the GUID may be a remote URL, or it may be a URL from an old permalink structure or an old site URL.

Q: Do we need to get the site ID from a post object?

No! If you have a post object then at some point you were in the context of the site it came from. Pass the site ID as a second parameter.

Ideally, your function should receive a post ID and a site ID, not a post object:

function doSomethingWithPost( int $post_id, int $site_id=0 ) {
    switch_to_blog( $site_id );
    $post = get_post( $post_id );
    // ....
    restore_current_blog();
}

Or, the site should be assumed to be the current site, and switch_to_blog called beforehand, e.g.:

switch_to_blog( $site_id );
doSomethingWithPost($post_id);
restore_current_blog();

I recommend passing the site ID as a function parameter so that good dependency injection can be practiced.