Issues (4967)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/wp-includes/ms-load.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * These functions are needed to load Multisite.
4
 *
5
 * @since 3.0.0
6
 *
7
 * @package WordPress
8
 * @subpackage Multisite
9
 */
10
11
/**
12
 * Whether a subdomain configuration is enabled.
13
 *
14
 * @since 3.0.0
15
 *
16
 * @return bool True if subdomain configuration is enabled, false otherwise.
17
 */
18
function is_subdomain_install() {
19
	if ( defined('SUBDOMAIN_INSTALL') )
20
		return SUBDOMAIN_INSTALL;
21
22
	return ( defined( 'VHOST' ) && VHOST == 'yes' );
23
}
24
25
/**
26
 * Returns array of network plugin files to be included in global scope.
27
 *
28
 * The default directory is wp-content/plugins. To change the default directory
29
 * manually, define `WP_PLUGIN_DIR` and `WP_PLUGIN_URL` in `wp-config.php`.
30
 *
31
 * @access private
32
 * @since 3.1.0
33
 *
34
 * @return array Files to include.
35
 */
36
function wp_get_active_network_plugins() {
37
	$active_plugins = (array) get_site_option( 'active_sitewide_plugins', array() );
38
	if ( empty( $active_plugins ) )
39
		return array();
40
41
	$plugins = array();
42
	$active_plugins = array_keys( $active_plugins );
43
	sort( $active_plugins );
44
45
	foreach ( $active_plugins as $plugin ) {
46
		if ( ! validate_file( $plugin ) // $plugin must validate as file
47
			&& '.php' == substr( $plugin, -4 ) // $plugin must end with '.php'
48
			&& file_exists( WP_PLUGIN_DIR . '/' . $plugin ) // $plugin must exist
49
			)
50
		$plugins[] = WP_PLUGIN_DIR . '/' . $plugin;
51
	}
52
	return $plugins;
53
}
54
55
/**
56
 * Checks status of current blog.
57
 *
58
 * Checks if the blog is deleted, inactive, archived, or spammed.
59
 *
60
 * Dies with a default message if the blog does not pass the check.
61
 *
62
 * To change the default message when a blog does not pass the check,
63
 * use the wp-content/blog-deleted.php, blog-inactive.php and
64
 * blog-suspended.php drop-ins.
65
 *
66
 * @since 3.0.0
67
 *
68
 * @return true|string Returns true on success, or drop-in file to include.
0 ignored issues
show
Should the return type not be boolean|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
69
 */
70
function ms_site_check() {
71
72
	/**
73
	 * Filters checking the status of the current blog.
74
	 *
75
	 * @since 3.0.0
76
	 *
77
	 * @param bool null Whether to skip the blog status check. Default null.
78
	*/
79
	$check = apply_filters( 'ms_site_check', null );
80
	if ( null !== $check )
81
		return true;
82
83
	// Allow super admins to see blocked sites
84
	if ( is_super_admin() )
85
		return true;
86
87
	$blog = get_site();
88
89 View Code Duplication
	if ( '1' == $blog->deleted ) {
90
		if ( file_exists( WP_CONTENT_DIR . '/blog-deleted.php' ) )
91
			return WP_CONTENT_DIR . '/blog-deleted.php';
92
		else
93
			wp_die( __( 'This site is no longer available.' ), '', array( 'response' => 410 ) );
94
	}
95
96
	if ( '2' == $blog->deleted ) {
97
		if ( file_exists( WP_CONTENT_DIR . '/blog-inactive.php' ) ) {
98
			return WP_CONTENT_DIR . '/blog-inactive.php';
99
		} else {
100
			$admin_email = str_replace( '@', ' AT ', get_site_option( 'admin_email', 'support@' . get_network()->domain ) );
101
			wp_die(
102
				/* translators: %s: admin email link */
103
				sprintf( __( 'This site has not been activated yet. If you are having problems activating your site, please contact %s.' ),
104
					sprintf( '<a href="mailto:%s">%s</a>', $admin_email )
105
				)
106
			);
107
		}
108
	}
109
110 View Code Duplication
	if ( $blog->archived == '1' || $blog->spam == '1' ) {
111
		if ( file_exists( WP_CONTENT_DIR . '/blog-suspended.php' ) )
112
			return WP_CONTENT_DIR . '/blog-suspended.php';
113
		else
114
			wp_die( __( 'This site has been archived or suspended.' ), '', array( 'response' => 410 ) );
115
	}
116
117
	return true;
118
}
119
120
/**
121
 * Retrieve the closest matching network for a domain and path.
122
 *
123
 * @since 3.9.0
124
 *
125
 * @internal In 4.4.0, converted to a wrapper for WP_Network::get_by_path()
126
 *
127
 * @param string   $domain   Domain to check.
128
 * @param string   $path     Path to check.
129
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
130
 * @return WP_Network|false Network object if successful. False when no network is found.
0 ignored issues
show
Should the return type not be WP_Network|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
131
 */
132
function get_network_by_path( $domain, $path, $segments = null ) {
133
	return WP_Network::get_by_path( $domain, $path, $segments );
134
}
135
136
/**
137
 * Retrieves the closest matching site object by its domain and path.
138
 * 
139
 * This will not necessarily return an exact match for a domain and path. Instead, it
140
 * breaks the domain and path into pieces that are then used to match the closest
141
 * possibility from a query.
142
 *
143
 * The intent of this method is to match a site object during bootstrap for a
144
 * requested site address
145
 *
146
 * @since 3.9.0
147
 * @since 4.7.0 Updated to always return a `WP_Site` object.
148
 *
149
 * @global wpdb $wpdb WordPress database abstraction object.
150
 *
151
 * @param string   $domain   Domain to check.
152
 * @param string   $path     Path to check.
153
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
154
 * @return WP_Site|false Site object if successful. False when no site is found.
155
 */
156
function get_site_by_path( $domain, $path, $segments = null ) {
157
	$path_segments = array_filter( explode( '/', trim( $path, '/' ) ) );
158
159
	/**
160
	 * Filters the number of path segments to consider when searching for a site.
161
	 *
162
	 * @since 3.9.0
163
	 *
164
	 * @param int|null $segments The number of path segments to consider. WordPress by default looks at
165
	 *                           one path segment following the network path. The function default of
166
	 *                           null only makes sense when you know the requested path should match a site.
167
	 * @param string   $domain   The requested domain.
168
	 * @param string   $path     The requested path, in full.
169
	 */
170
	$segments = apply_filters( 'site_by_path_segments_count', $segments, $domain, $path );
171
172 View Code Duplication
	if ( null !== $segments && count( $path_segments ) > $segments ) {
173
		$path_segments = array_slice( $path_segments, 0, $segments );
174
	}
175
176
	$paths = array();
177
178 View Code Duplication
	while ( count( $path_segments ) ) {
179
		$paths[] = '/' . implode( '/', $path_segments ) . '/';
180
		array_pop( $path_segments );
181
	}
182
183
	$paths[] = '/';
184
185
	/**
186
	 * Determine a site by its domain and path.
187
	 *
188
	 * This allows one to short-circuit the default logic, perhaps by
189
	 * replacing it with a routine that is more optimal for your setup.
190
	 *
191
	 * Return null to avoid the short-circuit. Return false if no site
192
	 * can be found at the requested domain and path. Otherwise, return
193
	 * a site object.
194
	 *
195
	 * @since 3.9.0
196
	 *
197
	 * @param null|bool|WP_Site $site     Site value to return by path.
198
	 * @param string            $domain   The requested domain.
199
	 * @param string            $path     The requested path, in full.
200
	 * @param int|null          $segments The suggested number of paths to consult.
201
	 *                                    Default null, meaning the entire path was to be consulted.
202
	 * @param array             $paths    The paths to search for, based on $path and $segments.
203
	 */
204
	$pre = apply_filters( 'pre_get_site_by_path', null, $domain, $path, $segments, $paths );
205
	if ( null !== $pre ) {
206
		if ( false !== $pre && ! $pre instanceof WP_Site ) {
207
			$pre = new WP_Site( $pre );
208
		}
209
		return $pre;
210
	}
211
212
	/*
213
	 * @todo
214
	 * caching, etc. Consider alternative optimization routes,
215
	 * perhaps as an opt-in for plugins, rather than using the pre_* filter.
216
	 * For example: The segments filter can expand or ignore paths.
217
	 * If persistent caching is enabled, we could query the DB for a path <> '/'
218
	 * then cache whether we can just always ignore paths.
219
	 */
220
221
	// Either www or non-www is supported, not both. If a www domain is requested,
222
	// query for both to provide the proper redirect.
223
	$domains = array( $domain );
224
	if ( 'www.' === substr( $domain, 0, 4 ) ) {
225
		$domains[] = substr( $domain, 4 );
226
	}
227
228
	$args = array(
229
		'domain__in' => $domains,
230
		'path__in' => $paths,
231
		'number' => 1,
232
	);
233
234
	if ( count( $domains ) > 1 ) {
235
		$args['orderby']['domain_length'] = 'DESC';
236
	}
237
238
	if ( count( $paths ) > 1 ) {
239
		$args['orderby']['path_length'] = 'DESC';
240
	}
241
242
	$result = get_sites( $args );
243
	$site = array_shift( $result );
244
245
	if ( $site ) {
246
		return $site;
247
	}
248
249
	return false;
250
}
251
252
/**
253
 * Identifies the network and site of a requested domain and path and populates the
254
 * corresponding network and site global objects as part of the multisite bootstrap process.
255
 *
256
 * Prior to 4.6.0, this was a procedural block in `ms-settings.php`. It was wrapped into
257
 * a function to facilitate unit tests. It should not be used outside of core.
258
 *
259
 * Usually, it's easier to query the site first, which then declares its network.
260
 * In limited situations, we either can or must find the network first.
261
 *
262
 * If a network and site are found, a `true` response will be returned so that the
263
 * request can continue.
264
 *
265
 * If neither a network or site is found, `false` or a URL string will be returned
266
 * so that either an error can be shown or a redirect can occur.
267
 *
268
 * @since 4.6.0
269
 * @access private
270
 *
271
 * @global wpdb       $wpdb         WordPress database abstraction object.
272
 * @global WP_Network $current_site The current network.
273
 * @global WP_Site    $current_blog The current site.
274
 *
275
 * @param string $domain    The requested domain.
276
 * @param string $path      The requested path.
277
 * @param bool   $subdomain Optional. Whether a subdomain (true) or subdirectory (false) configuration.
278
 *                          Default false.
279
 * @return bool|string True if bootstrap successfully populated `$current_blog` and `$current_site`.
280
 *                     False if bootstrap could not be properly completed.
281
 *                     Redirect URL if parts exist, but the request as a whole can not be fulfilled.
282
 */
283
function ms_load_current_site_and_network( $domain, $path, $subdomain = false ) {
284
	global $wpdb, $current_site, $current_blog;
285
286
	// If the network is defined in wp-config.php, we can simply use that.
287
	if ( defined( 'DOMAIN_CURRENT_SITE' ) && defined( 'PATH_CURRENT_SITE' ) ) {
288
		$current_site = new stdClass;
289
		$current_site->id = defined( 'SITE_ID_CURRENT_SITE' ) ? SITE_ID_CURRENT_SITE : 1;
290
		$current_site->domain = DOMAIN_CURRENT_SITE;
291
		$current_site->path = PATH_CURRENT_SITE;
292
		if ( defined( 'BLOG_ID_CURRENT_SITE' ) ) {
293
			$current_site->blog_id = BLOG_ID_CURRENT_SITE;
294
		} elseif ( defined( 'BLOGID_CURRENT_SITE' ) ) { // deprecated.
295
			$current_site->blog_id = BLOGID_CURRENT_SITE;
296
		}
297
298
		if ( 0 === strcasecmp( $current_site->domain, $domain ) && 0 === strcasecmp( $current_site->path, $path ) ) {
299
			$current_blog = get_site_by_path( $domain, $path );
300
		} elseif ( '/' !== $current_site->path && 0 === strcasecmp( $current_site->domain, $domain ) && 0 === stripos( $path, $current_site->path ) ) {
301
			// If the current network has a path and also matches the domain and path of the request,
302
			// we need to look for a site using the first path segment following the network's path.
303
			$current_blog = get_site_by_path( $domain, $path, 1 + count( explode( '/', trim( $current_site->path, '/' ) ) ) );
304
		} else {
305
			// Otherwise, use the first path segment (as usual).
306
			$current_blog = get_site_by_path( $domain, $path, 1 );
307
		}
308
309
	} elseif ( ! $subdomain ) {
310
		/*
311
		 * A "subdomain" install can be re-interpreted to mean "can support any domain".
312
		 * If we're not dealing with one of these installs, then the important part is determining
313
		 * the network first, because we need the network's path to identify any sites.
314
		 */
315
		if ( ! $current_site = wp_cache_get( 'current_network', 'site-options' ) ) {
316
			// Are there even two networks installed?
317
			$one_network = $wpdb->get_row( "SELECT * FROM $wpdb->site LIMIT 2" ); // [sic]
318
			if ( 1 === $wpdb->num_rows ) {
319
				$current_site = new WP_Network( $one_network );
320
				wp_cache_add( 'current_network', $current_site, 'site-options' );
321
			} elseif ( 0 === $wpdb->num_rows ) {
322
				// A network not found hook should fire here.
323
				return false;
324
			}
325
		}
326
327
		if ( empty( $current_site ) ) {
328
			$current_site = WP_Network::get_by_path( $domain, $path, 1 );
329
		}
330
331
		if ( empty( $current_site ) ) {
332
			/**
333
			 * Fires when a network cannot be found based on the requested domain and path.
334
			 *
335
			 * At the time of this action, the only recourse is to redirect somewhere
336
			 * and exit. If you want to declare a particular network, do so earlier.
337
			 *
338
			 * @since 4.4.0
339
			 *
340
			 * @param string $domain       The domain used to search for a network.
341
			 * @param string $path         The path used to search for a path.
342
			 */
343
			do_action( 'ms_network_not_found', $domain, $path );
344
345
			return false;
346
		} elseif ( $path === $current_site->path ) {
347
			$current_blog = get_site_by_path( $domain, $path );
348
		} else {
349
			// Search the network path + one more path segment (on top of the network path).
350
			$current_blog = get_site_by_path( $domain, $path, substr_count( $current_site->path, '/' ) );
351
		}
352
	} else {
353
		// Find the site by the domain and at most the first path segment.
354
		$current_blog = get_site_by_path( $domain, $path, 1 );
355
		if ( $current_blog ) {
356
			$current_site = WP_Network::get_instance( $current_blog->site_id ? $current_blog->site_id : 1 );
357
		} else {
358
			// If you don't have a site with the same domain/path as a network, you're pretty screwed, but:
359
			$current_site = WP_Network::get_by_path( $domain, $path, 1 );
360
		}
361
	}
362
363
	// The network declared by the site trumps any constants.
364
	if ( $current_blog && $current_blog->site_id != $current_site->id ) {
365
		$current_site = WP_Network::get_instance( $current_blog->site_id );
366
	}
367
368
	// No network has been found, bail.
369
	if ( empty( $current_site ) ) {
370
		/** This action is documented in wp-includes/ms-settings.php */
371
		do_action( 'ms_network_not_found', $domain, $path );
372
373
		return false;
374
	}
375
376
	// During activation of a new subdomain, the requested site does not yet exist.
377
	if ( empty( $current_blog ) && wp_installing() ) {
378
		$current_blog = new stdClass;
379
		$current_blog->blog_id = $blog_id = 1;
380
		$current_blog->public = 1;
381
	}
382
383
	// No site has been found, bail.
384
	if ( empty( $current_blog ) ) {
385
		// We're going to redirect to the network URL, with some possible modifications.
386
		$scheme = is_ssl() ? 'https' : 'http';
387
		$destination = "$scheme://{$current_site->domain}{$current_site->path}";
388
389
		/**
390
		 * Fires when a network can be determined but a site cannot.
391
		 *
392
		 * At the time of this action, the only recourse is to redirect somewhere
393
		 * and exit. If you want to declare a particular site, do so earlier.
394
		 *
395
		 * @since 3.9.0
396
		 *
397
		 * @param object $current_site The network that had been determined.
398
		 * @param string $domain       The domain used to search for a site.
399
		 * @param string $path         The path used to search for a site.
400
		 */
401
		do_action( 'ms_site_not_found', $current_site, $domain, $path );
402
403
		if ( $subdomain && ! defined( 'NOBLOGREDIRECT' ) ) {
404
			// For a "subdomain" install, redirect to the signup form specifically.
405
			$destination .= 'wp-signup.php?new=' . str_replace( '.' . $current_site->domain, '', $domain );
406
		} elseif ( $subdomain ) {
407
			// For a "subdomain" install, the NOBLOGREDIRECT constant
408
			// can be used to avoid a redirect to the signup form.
409
			// Using the ms_site_not_found action is preferred to the constant.
410
			if ( '%siteurl%' !== NOBLOGREDIRECT ) {
411
				$destination = NOBLOGREDIRECT;
412
			}
413
		} elseif ( 0 === strcasecmp( $current_site->domain, $domain ) ) {
414
			/*
415
			 * If the domain we were searching for matches the network's domain,
416
			 * it's no use redirecting back to ourselves -- it'll cause a loop.
417
			 * As we couldn't find a site, we're simply not installed.
418
			 */
419
			return false;
420
		}
421
422
		return $destination;
423
	}
424
425
	// Figure out the current network's main site.
426
	if ( empty( $current_site->blog_id ) ) {
427
		if ( $current_blog->domain === $current_site->domain && $current_blog->path === $current_site->path ) {
428
			$current_site->blog_id = $current_blog->blog_id;
429
		} elseif ( ! $current_site->blog_id = wp_cache_get( 'network:' . $current_site->id . ':main_site', 'site-options' ) ) {
430
			$current_site->blog_id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s",
431
				$current_site->domain, $current_site->path ) );
432
			wp_cache_add( 'network:' . $current_site->id . ':main_site', $current_site->blog_id, 'site-options' );
433
		}
434
	}
435
436
	return true;
437
}
438
439
/**
440
 * Displays a failure message.
441
 *
442
 * Used when a blog's tables do not exist. Checks for a missing $wpdb->site table as well.
443
 *
444
 * @access private
445
 * @since 3.0.0
446
 * @since 4.4.0 The `$domain` and `$path` parameters were added.
447
 *
448
 * @global wpdb $wpdb WordPress database abstraction object.
449
 *
450
 * @param string $domain The requested domain for the error to reference.
451
 * @param string $path   The requested path for the error to reference.
452
 */
453
function ms_not_installed( $domain, $path ) {
454
	global $wpdb;
455
456
	if ( ! is_admin() ) {
457
		dead_db();
458
	}
459
460
	wp_load_translations_early();
461
462
	$title = __( 'Error establishing a database connection' );
463
464
	$msg  = '<h1>' . $title . '</h1>';
465
	$msg .= '<p>' . __( 'If your site does not display, please contact the owner of this network.' ) . '';
466
	$msg .= ' ' . __( 'If you are the owner of this network please check that MySQL is running properly and all tables are error free.' ) . '</p>';
467
	$query = $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->esc_like( $wpdb->site ) );
468
	if ( ! $wpdb->get_var( $query ) ) {
469
		$msg .= '<p>' . sprintf(
470
			/* translators: %s: table name */
471
			__( '<strong>Database tables are missing.</strong> This means that MySQL is not running, WordPress was not installed properly, or someone deleted %s. You really should look at your database now.' ),
472
			'<code>' . $wpdb->site . '</code>'
473
		) . '</p>';
474
	} else {
475
		$msg .= '<p>' . sprintf(
476
			/* translators: 1: site url, 2: table name, 3: database name */
477
			__( '<strong>Could not find site %1$s.</strong> Searched for table %2$s in database %3$s. Is that right?' ),
478
			'<code>' . rtrim( $domain . $path, '/' ) . '</code>',
479
			'<code>' . $wpdb->blogs . '</code>',
480
			'<code>' . DB_NAME . '</code>'
481
		) . '</p>';
482
	}
483
	$msg .= '<p><strong>' . __( 'What do I do now?' ) . '</strong> ';
484
	/* translators: %s: Codex URL */
485
	$msg .= sprintf( __( 'Read the <a href="%s" target="_blank">bug report</a> page. Some of the guidelines there may help you figure out what went wrong.' ),
486
		__( 'https://codex.wordpress.org/Debugging_a_WordPress_Network' )
487
	);
488
	$msg .= ' ' . __( 'If you&#8217;re still stuck with this message, then check that your database contains the following tables:' ) . '</p><ul>';
489
	foreach ( $wpdb->tables('global') as $t => $table ) {
490
		if ( 'sitecategories' == $t )
491
			continue;
492
		$msg .= '<li>' . $table . '</li>';
493
	}
494
	$msg .= '</ul>';
495
496
	wp_die( $msg, $title, array( 'response' => 500 ) );
497
}
498
499
/**
500
 * This deprecated function formerly set the site_name property of the $current_site object.
501
 *
502
 * This function simply returns the object, as before.
503
 * The bootstrap takes care of setting site_name.
504
 *
505
 * @access private
506
 * @since 3.0.0
507
 * @deprecated 3.9.0 Use get_current_site() instead.
508
 *
509
 * @param object $current_site
510
 * @return object
511
 */
512
function get_current_site_name( $current_site ) {
513
	_deprecated_function( __FUNCTION__, '3.9.0', 'get_current_site()' );
514
	return $current_site;
515
}
516
517
/**
518
 * This deprecated function managed much of the site and network loading in multisite.
519
 *
520
 * The current bootstrap code is now responsible for parsing the site and network load as
521
 * well as setting the global $current_site object.
522
 *
523
 * @access private
524
 * @since 3.0.0
525
 * @deprecated 3.9.0
526
 *
527
 * @global object $current_site
528
 *
529
 * @return object
530
 */
531
function wpmu_current_site() {
532
	global $current_site;
533
	_deprecated_function( __FUNCTION__, '3.9.0' );
534
	return $current_site;
535
}
536
537
/**
538
 * Retrieve an object containing information about the requested network.
539
 *
540
 * @since 3.9.0
541
 * @deprecated 4.7.0 Use `get_network()`
542
 * @see get_network()
543
 *
544
 * @internal In 4.6.0, converted to use get_network()
545
 *
546
 * @param object|int $network The network's database row or ID.
547
 * @return WP_Network|false Object containing network information if found, false if not.
548
 */
549
function wp_get_network( $network ) {
550
	_deprecated_function( __FUNCTION__, '4.7.0', 'get_network()' );
551
552
	$network = get_network( $network );
0 ignored issues
show
It seems like $network can also be of type object; however, get_network() does only seem to accept object<WP_Network>|integer|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
553
	if ( null === $network ) {
554
		return false;
555
	}
556
557
	return $network;
558
}
559