prefix = $wpdb->base_prefix; $s->base_prefix = $wpdb->base_prefix; $s->name = SiteInfo::plain_name((string) get_bloginfo('name')); $s->home_url = home_url(); $s->site_url = site_url(); $s->path = ABSPATH; $uploads = wp_upload_dir(null, false); $s->uploads_dir = rtrim(wp_normalize_path($uploads['basedir']), '/'); $s->uploads_url = rtrim($uploads['baseurl'], '/'); $s->content_url = rtrim(content_url(), '/'); return $s; } /** One subsite of this network; refuses one that doesn't exist or is archived, deleted or spam. */ public static function subsite(int $blog_id): self { global $wpdb; $site = $blog_id > 0 ? get_site($blog_id) : null; if (!is_multisite() || $site === null) { /* translators: %d: subsite id */ throw new RelayError('subsite.not_found', esc_html(sprintf(__('Subsite %d does not exist on this network.', 'siterelay'), $blog_id))); } if ((int) $site->archived || (int) $site->deleted || (int) $site->spam) { throw new RelayError( 'subsite.unavailable', /* translators: %s: subsite address */ esc_html(sprintf(__('The subsite %s is archived, deleted or marked as spam.', 'siterelay'), $site->domain . $site->path)), esc_html__('Activate it again under Network Admin → Sites, or choose another subsite.', 'siterelay') ); } $s = new self(); $s->blog_id = (int) $site->blog_id; $s->prefix = $wpdb->get_blog_prefix($s->blog_id); $s->base_prefix = $wpdb->base_prefix; $s->path = ABSPATH; $network_site_url = untrailingslashit(get_site_url(get_main_site_id())); switch_to_blog($s->blog_id); try { $s->name = SiteInfo::plain_name((string) get_option('blogname')); $s->home_url = untrailingslashit((string) get_option('home')); $s->site_url = untrailingslashit((string) get_option('siteurl')); $uploads = wp_upload_dir(null, false); $s->uploads_dir = rtrim(wp_normalize_path($uploads['basedir']), '/'); $main_uploads_url = rtrim($uploads['baseurl'], '/'); } finally { restore_current_blog(); } // WordPress builds wp-content addresses from the site being viewed: a subsite's own pages use its // address (https://net.test/client1/wp-content/…), the main site's the network's (https://net.test/wp-content/…). $main_content_url = rtrim(content_url(), '/'); $own = static fn (string $url): string => strpos($url, $network_site_url) === 0 ? $s->site_url . substr($url, strlen($network_site_url)) : $url; $s->content_url = $own($main_content_url); $s->uploads_url = $own($main_uploads_url); $s->alt_content_url = $s->content_url !== $main_content_url ? $main_content_url : ''; $s->alt_uploads_url = $s->uploads_url !== $main_uploads_url ? $main_uploads_url : ''; return $s; } /** * The scope of a job's settings: its subsite on a network (required there), this site otherwise. */ public static function for_settings(array $settings): self { if (!is_multisite()) { return self::site(); } $id = (int) ($settings['subsite'] ?? 0); if ($id <= 0) { throw new RelayError('subsite.required', esc_html__('Choose the subsite to work on.', 'siterelay')); } return self::subsite($id); } public function is_subsite(): bool { return $this->blog_id > 0; } public function is_main_site(): bool { return $this->is_subsite() && $this->prefix === $this->base_prefix; } /** What AutoPairs::map() needs about this side. */ public function urls(): array { return array_filter([ 'site_url' => $this->site_url, 'home_url' => $this->home_url, 'path' => $this->path, 'uploads_url' => $this->uploads_url, 'uploads_dir' => $this->uploads_dir, 'content_url' => $this->content_url, 'alt_uploads_url' => $this->alt_uploads_url, 'alt_content_url' => $this->alt_content_url, ], static fn ($v) => $v !== ''); } /** What a job and History keep about it: {id, name, url}. */ public function to_array(): array { return ['id' => $this->blog_id, 'name' => $this->name, 'url' => $this->home_url]; } }