Issues (2010)

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.

wp-includes/ms-blogs.php (16 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
/**
4
 * Site/blog functions that work with the blogs table and related data.
5
 *
6
 * @package WordPress
7
 * @subpackage Multisite
8
 * @since MU
9
 */
10
11
/**
12
 * Update the last_updated field for the current site.
13
 *
14
 * @since MU
15
 *
16
 * @global wpdb $wpdb WordPress database abstraction object.
17
 */
18
function wpmu_update_blogs_date() {
19
	global $wpdb;
20
21
	update_blog_details( $wpdb->blogid, array('last_updated' => current_time('mysql', true)) );
0 ignored issues
show
true is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
22
	/**
23
	 * Fires after the blog details are updated.
24
	 *
25
	 * @since MU
26
	 *
27
	 * @param int $blog_id Site ID.
28
	 */
29
	do_action( 'wpmu_blog_updated', $wpdb->blogid );
30
}
31
32
/**
33
 * Get a full blog URL, given a blog id.
34
 *
35
 * @since MU
36
 *
37
 * @param int $blog_id Blog ID
38
 * @return string Full URL of the blog if found. Empty string if not.
39
 */
40
function get_blogaddress_by_id( $blog_id ) {
41
	$bloginfo = get_blog_details( (int) $blog_id );
42
43
	if ( empty( $bloginfo ) ) {
44
		return '';
45
	}
46
47
	$scheme = parse_url( $bloginfo->home, PHP_URL_SCHEME );
0 ignored issues
show
The property home does not exist on object<WP_Site>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
48
	$scheme = empty( $scheme ) ? 'http' : $scheme;
49
50
	return esc_url( $scheme . '://' . $bloginfo->domain . $bloginfo->path );
51
}
52
53
/**
54
 * Get a full blog URL, given a blog name.
55
 *
56
 * @since MU
57
 *
58
 * @param string $blogname The (subdomain or directory) name
59
 * @return string
60
 */
61
function get_blogaddress_by_name( $blogname ) {
62
	if ( is_subdomain_install() ) {
63
		if ( $blogname == 'main' )
64
			$blogname = 'www';
65
		$url = rtrim( network_home_url(), '/' );
66
		if ( !empty( $blogname ) )
67
			$url = preg_replace( '|^([^\.]+://)|', "\${1}" . $blogname . '.', $url );
68
	} else {
69
		$url = network_home_url( $blogname );
70
	}
71
	return esc_url( $url . '/' );
72
}
73
74
/**
75
 * Given a blog's (subdomain or directory) slug, retrieve its id.
76
 *
77
 * @since MU
78
 *
79
 * @global wpdb $wpdb WordPress database abstraction object.
80
 *
81
 * @param string $slug
82
 * @return int A blog id
83
 */
84
function get_id_from_blogname( $slug ) {
85
	global $wpdb;
86
87
	$current_site = get_current_site();
88
	$slug = trim( $slug, '/' );
89
90
	$blog_id = wp_cache_get( 'get_id_from_blogname_' . $slug, 'blog-details' );
91
	if ( $blog_id )
92
		return $blog_id;
93
94 View Code Duplication
	if ( is_subdomain_install() ) {
95
		$domain = $slug . '.' . $current_site->domain;
96
		$path = $current_site->path;
97
	} else {
98
		$domain = $current_site->domain;
99
		$path = $current_site->path . $slug . '/';
100
	}
101
102
	$blog_id = $wpdb->get_var( $wpdb->prepare("SELECT blog_id FROM {$wpdb->blogs} WHERE domain = %s AND path = %s", $domain, $path) );
103
	wp_cache_set( 'get_id_from_blogname_' . $slug, $blog_id, 'blog-details' );
104
	return $blog_id;
105
}
106
107
/**
108
 * Retrieve the details for a blog from the blogs table and blog options.
109
 *
110
 * @since MU
111
 *
112
 * @global wpdb $wpdb WordPress database abstraction object.
113
 *
114
 * @param int|string|array $fields  Optional. A blog ID, a blog slug, or an array of fields to query against.
115
 *                                  If not specified the current blog ID is used.
116
 * @param bool             $get_all Whether to retrieve all details or only the details in the blogs table.
117
 *                                  Default is true.
118
 * @return WP_Site|false Blog details on success. False on failure.
119
 */
120
function get_blog_details( $fields = null, $get_all = true ) {
121
	global $wpdb;
122
123
	if ( is_array($fields ) ) {
124
		if ( isset($fields['blog_id']) ) {
125
			$blog_id = $fields['blog_id'];
126
		} elseif ( isset($fields['domain']) && isset($fields['path']) ) {
127
			$key = md5( $fields['domain'] . $fields['path'] );
128
			$blog = wp_cache_get($key, 'blog-lookup');
129
			if ( false !== $blog )
130
				return $blog;
131
			if ( substr( $fields['domain'], 0, 4 ) == 'www.' ) {
132
				$nowww = substr( $fields['domain'], 4 );
133
				$blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain IN (%s,%s) AND path = %s ORDER BY CHAR_LENGTH(domain) DESC", $nowww, $fields['domain'], $fields['path'] ) );
134
			} else {
135
				$blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s AND path = %s", $fields['domain'], $fields['path'] ) );
136
			}
137 View Code Duplication
			if ( $blog ) {
138
				wp_cache_set($blog->blog_id . 'short', $blog, 'blog-details');
139
				$blog_id = $blog->blog_id;
140
			} else {
141
				return false;
142
			}
143
		} elseif ( isset($fields['domain']) && is_subdomain_install() ) {
144
			$key = md5( $fields['domain'] );
145
			$blog = wp_cache_get($key, 'blog-lookup');
146
			if ( false !== $blog )
147
				return $blog;
148
			if ( substr( $fields['domain'], 0, 4 ) == 'www.' ) {
149
				$nowww = substr( $fields['domain'], 4 );
150
				$blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain IN (%s,%s) ORDER BY CHAR_LENGTH(domain) DESC", $nowww, $fields['domain'] ) );
151
			} else {
152
				$blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s", $fields['domain'] ) );
153
			}
154 View Code Duplication
			if ( $blog ) {
155
				wp_cache_set($blog->blog_id . 'short', $blog, 'blog-details');
156
				$blog_id = $blog->blog_id;
157
			} else {
158
				return false;
159
			}
160
		} else {
161
			return false;
162
		}
163
	} else {
164
		if ( ! $fields )
165
			$blog_id = get_current_blog_id();
166
		elseif ( ! is_numeric( $fields ) )
167
			$blog_id = get_id_from_blogname( $fields );
168
		else
169
			$blog_id = $fields;
170
	}
171
172
	$blog_id = (int) $blog_id;
173
174
	$all = $get_all == true ? '' : 'short';
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
175
	$details = wp_cache_get( $blog_id . $all, 'blog-details' );
176
177 View Code Duplication
	if ( $details ) {
178
		if ( ! is_object( $details ) ) {
179
			if ( $details == -1 ) {
180
				return false;
181
			} else {
182
				// Clear old pre-serialized objects. Cache clients do better with that.
183
				wp_cache_delete( $blog_id . $all, 'blog-details' );
184
				unset($details);
185
			}
186
		} else {
187
			return $details;
188
		}
189
	}
190
191
	// Try the other cache.
192
	if ( $get_all ) {
193
		$details = wp_cache_get( $blog_id . 'short', 'blog-details' );
194 View Code Duplication
	} else {
195
		$details = wp_cache_get( $blog_id, 'blog-details' );
196
		// If short was requested and full cache is set, we can return.
197
		if ( $details ) {
198
			if ( ! is_object( $details ) ) {
199
				if ( $details == -1 ) {
200
					return false;
201
				} else {
202
					// Clear old pre-serialized objects. Cache clients do better with that.
203
					wp_cache_delete( $blog_id, 'blog-details' );
204
					unset($details);
205
				}
206
			} else {
207
				return $details;
208
			}
209
		}
210
	}
211
212
	if ( empty($details) ) {
213
		$details = WP_Site::get_instance( $blog_id );
214
		if ( ! $details ) {
215
			// Set the full cache.
216
			wp_cache_set( $blog_id, -1, 'blog-details' );
217
			return false;
218
		}
219
	}
220
221
	if ( ! $details instanceof WP_Site ) {
222
		$details = new WP_Site( $details );
223
	}
224
225
	if ( ! $get_all ) {
226
		wp_cache_set( $blog_id . $all, $details, 'blog-details' );
227
		return $details;
228
	}
229
230
	switch_to_blog( $blog_id );
231
	$details->blogname   = get_option( 'blogname' );
0 ignored issues
show
The property blogname does not exist on object<WP_Site>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
232
	$details->siteurl    = get_option( 'siteurl' );
0 ignored issues
show
The property siteurl does not exist on object<WP_Site>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
233
	$details->post_count = get_option( 'post_count' );
0 ignored issues
show
The property post_count does not exist on object<WP_Site>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
234
	$details->home       = get_option( 'home' );
0 ignored issues
show
The property home does not exist on object<WP_Site>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
235
	restore_current_blog();
236
237
	/**
238
	 * Filters a blog's details.
239
	 *
240
	 * @since MU
241
	 *
242
	 * @param object $details The blog details.
243
	 */
244
	$details = apply_filters( 'blog_details', $details );
245
246
	wp_cache_set( $blog_id . $all, $details, 'blog-details' );
247
248
	$key = md5( $details->domain . $details->path );
249
	wp_cache_set( $key, $details, 'blog-lookup' );
250
251
	return $details;
252
}
253
254
/**
255
 * Clear the blog details cache.
256
 *
257
 * @since MU
258
 *
259
 * @param int $blog_id Optional. Blog ID. Defaults to current blog.
260
 */
261
function refresh_blog_details( $blog_id = 0 ) {
262
	$blog_id = (int) $blog_id;
263
	if ( ! $blog_id ) {
264
		$blog_id = get_current_blog_id();
265
	}
266
267
	$details = get_blog_details( $blog_id, false );
268
	if ( ! $details ) {
269
		// Make sure clean_blog_cache() gets the blog ID
270
		// when the blog has been previously cached as
271
		// non-existent.
272
		$details = (object) array(
273
			'blog_id' => $blog_id,
274
			'domain' => null,
275
			'path' => null
276
		);
277
	}
278
279
	clean_blog_cache( $details );
280
281
	/**
282
	 * Fires after the blog details cache is cleared.
283
	 *
284
	 * @since 3.4.0
285
	 *
286
	 * @param int $blog_id Blog ID.
287
	 */
288
	do_action( 'refresh_blog_details', $blog_id );
289
}
290
291
/**
292
 * Update the details for a blog. Updates the blogs table for a given blog id.
293
 *
294
 * @since MU
295
 *
296
 * @global wpdb $wpdb WordPress database abstraction object.
297
 *
298
 * @param int   $blog_id Blog ID
299
 * @param array $details Array of details keyed by blogs table field names.
300
 * @return bool True if update succeeds, false otherwise.
301
 */
302
function update_blog_details( $blog_id, $details = array() ) {
303
	global $wpdb;
304
305
	if ( empty($details) )
306
		return false;
307
308
	if ( is_object($details) )
309
		$details = get_object_vars($details);
310
311
	$current_details = get_blog_details($blog_id, false);
312
	if ( empty($current_details) )
313
		return false;
314
315
	$current_details = get_object_vars($current_details);
316
317
	$details = array_merge($current_details, $details);
318
	$details['last_updated'] = current_time('mysql', true);
0 ignored issues
show
true is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
319
320
	$update_details = array();
321
	$fields = array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id');
322
	foreach ( array_intersect( array_keys( $details ), $fields ) as $field ) {
323
		if ( 'path' === $field ) {
324
			$details[ $field ] = trailingslashit( '/' . trim( $details[ $field ], '/' ) );
325
		}
326
327
		$update_details[ $field ] = $details[ $field ];
328
	}
329
330
	$result = $wpdb->update( $wpdb->blogs, $update_details, array('blog_id' => $blog_id) );
331
332
	if ( false === $result )
333
		return false;
334
335
	// If spam status changed, issue actions.
336 View Code Duplication
	if ( $details['spam'] != $current_details['spam'] ) {
337
		if ( $details['spam'] == 1 ) {
338
			/**
339
			 * Fires when the blog status is changed to 'spam'.
340
			 *
341
			 * @since MU
342
			 *
343
			 * @param int $blog_id Blog ID.
344
			 */
345
			do_action( 'make_spam_blog', $blog_id );
346
		} else {
347
			/**
348
			 * Fires when the blog status is changed to 'ham'.
349
			 *
350
			 * @since MU
351
			 *
352
			 * @param int $blog_id Blog ID.
353
			 */
354
			do_action( 'make_ham_blog', $blog_id );
355
		}
356
	}
357
358
	// If mature status changed, issue actions.
359 View Code Duplication
	if ( $details['mature'] != $current_details['mature'] ) {
360
		if ( $details['mature'] == 1 ) {
361
			/**
362
			 * Fires when the blog status is changed to 'mature'.
363
			 *
364
			 * @since 3.1.0
365
			 *
366
			 * @param int $blog_id Blog ID.
367
			 */
368
			do_action( 'mature_blog', $blog_id );
369
		} else {
370
			/**
371
			 * Fires when the blog status is changed to 'unmature'.
372
			 *
373
			 * @since 3.1.0
374
			 *
375
			 * @param int $blog_id Blog ID.
376
			 */
377
			do_action( 'unmature_blog', $blog_id );
378
		}
379
	}
380
381
	// If archived status changed, issue actions.
382 View Code Duplication
	if ( $details['archived'] != $current_details['archived'] ) {
383
		if ( $details['archived'] == 1 ) {
384
			/**
385
			 * Fires when the blog status is changed to 'archived'.
386
			 *
387
			 * @since MU
388
			 *
389
			 * @param int $blog_id Blog ID.
390
			 */
391
			do_action( 'archive_blog', $blog_id );
392
		} else {
393
			/**
394
			 * Fires when the blog status is changed to 'unarchived'.
395
			 *
396
			 * @since MU
397
			 *
398
			 * @param int $blog_id Blog ID.
399
			 */
400
			do_action( 'unarchive_blog', $blog_id );
401
		}
402
	}
403
404
	// If deleted status changed, issue actions.
405 View Code Duplication
	if ( $details['deleted'] != $current_details['deleted'] ) {
406
		if ( $details['deleted'] == 1 ) {
407
			/**
408
			 * Fires when the blog status is changed to 'deleted'.
409
			 *
410
			 * @since 3.5.0
411
			 *
412
			 * @param int $blog_id Blog ID.
413
			 */
414
			do_action( 'make_delete_blog', $blog_id );
415
		} else {
416
			/**
417
			 * Fires when the blog status is changed to 'undeleted'.
418
			 *
419
			 * @since 3.5.0
420
			 *
421
			 * @param int $blog_id Blog ID.
422
			 */
423
			do_action( 'make_undelete_blog', $blog_id );
424
		}
425
	}
426
427
	if ( isset( $details['public'] ) ) {
428
		switch_to_blog( $blog_id );
429
		update_option( 'blog_public', $details['public'] );
430
		restore_current_blog();
431
	}
432
433
	refresh_blog_details($blog_id);
434
435
	return true;
436
}
437
438
/**
439
 * Clean the blog cache
440
 *
441
 * @since 3.5.0
442
 *
443
 * @param WP_Site $blog The blog details as returned from get_blog_details()
444
 */
445
function clean_blog_cache( $blog ) {
446
	$blog_id = $blog->blog_id;
447
	$domain_path_key = md5( $blog->domain . $blog->path );
448
449
	wp_cache_delete( $blog_id, 'sites' );
450
	wp_cache_delete( $blog_id, 'site-details' );
451
	wp_cache_delete( $blog_id , 'blog-details' );
452
	wp_cache_delete( $blog_id . 'short' , 'blog-details' );
453
	wp_cache_delete(  $domain_path_key, 'blog-lookup' );
454
	wp_cache_delete( 'current_blog_' . $blog->domain, 'site-options' );
455
	wp_cache_delete( 'current_blog_' . $blog->domain . $blog->path, 'site-options' );
456
	wp_cache_delete( 'get_id_from_blogname_' . trim( $blog->path, '/' ), 'blog-details' );
457
	wp_cache_delete( $domain_path_key, 'blog-id-cache' );
458
459
	/**
460
	 * Fires immediately after a site has been removed from the object cache.
461
	 *
462
	 * @since 4.6.0
463
	 *
464
	 * @param int     $id              Blog ID.
465
	 * @param WP_Site $blog            Site object.
466
	 * @param string  $domain_path_key md5 hash of domain and path.
467
	 */
468
	do_action( 'clean_site_cache', $blog_id, $blog, $domain_path_key );
469
470
	wp_cache_set( 'last_changed', microtime(), 'sites' );
471
}
472
473
/**
474
 * Retrieves site data given a site ID or site object.
475
 *
476
 * Site data will be cached and returned after being passed through a filter.
477
 * If the provided site is empty, the current site global will be used.
478
 *
479
 * @since 4.6.0
480
 *
481
 * @param WP_Site|int|null $site Optional. Site to retrieve. Default is the current site.
482
 * @return WP_Site|null The site object or null if not found.
483
 */
484
function get_site( $site = null ) {
485
	if ( empty( $site ) ) {
486
		$site = get_current_blog_id();
487
	}
488
489
	if ( $site instanceof WP_Site ) {
490
		$_site = $site;
491
	} elseif ( is_object( $site ) ) {
492
		$_site = new WP_Site( $site );
493
	} else {
494
		$_site = WP_Site::get_instance( $site );
495
	}
496
497
	if ( ! $_site ) {
498
		return null;
499
	}
500
501
	/**
502
	 * Fires after a site is retrieved.
503
	 *
504
	 * @since 4.6.0
505
	 *
506
	 * @param WP_Site $_site Site data.
507
	 */
508
	$_site = apply_filters( 'get_site', $_site );
509
510
	return $_site;
511
}
512
513
/**
514
 * Adds any sites from the given ids to the cache that do not already exist in cache.
515
 *
516
 * @since 4.6.0
517
 * @access private
518
 *
519
 * @see update_site_cache()
520
 * @global wpdb $wpdb WordPress database abstraction object.
521
 *
522
 * @param array $ids ID list.
523
 */
524 View Code Duplication
function _prime_site_caches( $ids ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
525
	global $wpdb;
526
527
	$non_cached_ids = _get_non_cached_ids( $ids, 'sites' );
528
	if ( ! empty( $non_cached_ids ) ) {
529
		$fresh_sites = $wpdb->get_results( sprintf( "SELECT * FROM $wpdb->blogs WHERE blog_id IN (%s)", join( ",", array_map( 'intval', $non_cached_ids ) ) ) );
530
531
		update_site_cache( $fresh_sites );
532
	}
533
}
534
535
/**
536
 * Updates sites in cache.
537
 *
538
 * @since 4.6.0
539
 *
540
 * @param array $sites Array of site objects.
541
 */
542
function update_site_cache( $sites ) {
543
	if ( ! $sites ) {
544
		return;
545
	}
546
547
	foreach ( $sites as $site ) {
548
		wp_cache_add( $site->blog_id, $site, 'sites' );
549
		wp_cache_add( $site->blog_id . 'short', $site, 'blog-details' );
550
	}
551
}
552
553
/**
554
 * Retrieves a list of sites matching requested arguments.
555
 *
556
 * @since 4.6.0
557
 *
558
 * @see WP_Site_Query::parse_query()
559
 *
560
 * @param string|array $args {
561
 *     Optional. Array or query string of site query parameters. Default empty.
562
 *
563
 *     @type array        $site__in          Array of site IDs to include. Default empty.
564
 *     @type array        $site__not_in      Array of site IDs to exclude. Default empty.
565
 *     @type bool         $count             Whether to return a site count (true) or array of site objects.
566
 *                                           Default false.
567
 *     @type array        $date_query        Date query clauses to limit sites by. See WP_Date_Query.
568
 *                                           Default null.
569
 *     @type string       $fields            Site fields to return. Accepts 'ids' for site IDs only or empty
570
 *                                           for all fields. Default empty.
571
 *     @type int          $ID                A site ID to only return that site. Default empty.
572
 *     @type int          $number            Maximum number of sites to retrieve. Default null (no limit).
573
 *     @type int          $offset            Number of sites to offset the query. Used to build LIMIT clause.
574
 *                                           Default 0.
575
 *     @type bool         $no_found_rows     Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true.
576
 *     @type string|array $orderby           Site status or array of statuses. Accepts 'id', 'domain', 'path',
577
 *                                           'network_id', 'last_updated', 'registered', 'domain_length',
578
 *                                           'path_length', 'site__in' and 'network__in'. Also accepts false,
579
 *                                           an empty array, or 'none' to disable `ORDER BY` clause.
580
 *                                           Default 'id'.
581
 *     @type string       $order             How to order retrieved sites. Accepts 'ASC', 'DESC'. Default 'ASC'.
582
 *     @type int          $network_id        Limit results to those affiliated with a given network ID.
583
 *                                           Default current network ID.
584
 *     @type array        $network__in       Array of network IDs to include affiliated sites for. Default empty.
585
 *     @type array        $network__not_in   Array of network IDs to exclude affiliated sites for. Default empty.
586
 *     @type string       $domain            Limit results to those affiliated with a given domain.
587
 *                                           Default empty.
588
 *     @type array        $domain__in        Array of domains to include affiliated sites for. Default empty.
589
 *     @type array        $domain__not_in    Array of domains to exclude affiliated sites for. Default empty.
590
 *     @type string       $path              Limit results to those affiliated with a given path.
591
 *                                           Default empty.
592
 *     @type array        $path__in          Array of paths to include affiliated sites for. Default empty.
593
 *     @type array        $path__not_in      Array of paths to exclude affiliated sites for. Default empty.
594
 *     @type int          $public            Limit results to public sites. Accepts '1' or '0'. Default empty.
595
 *     @type int          $archived          Limit results to archived sites. Accepts '1' or '0'. Default empty.
596
 *     @type int          $mature            Limit results to mature sites. Accepts '1' or '0'. Default empty.
597
 *     @type int          $spam              Limit results to spam sites. Accepts '1' or '0'. Default empty.
598
 *     @type int          $deleted           Limit results to deleted sites. Accepts '1' or '0'. Default empty.
599
 *     @type string       $search            Search term(s) to retrieve matching sites for. Default empty.
600
 *     @type bool         $update_site_cache Whether to prime the cache for found sites. Default false.
601
 * }
602
 * @return array List of sites.
603
 */
604
function get_sites( $args = array() ) {
605
	$query = new WP_Site_Query();
606
607
	return $query->query( $args );
608
}
609
610
/**
611
 * Retrieve option value for a given blog id based on name of option.
612
 *
613
 * If the option does not exist or does not have a value, then the return value
614
 * will be false. This is useful to check whether you need to install an option
615
 * and is commonly used during installation of plugin options and to test
616
 * whether upgrading is required.
617
 *
618
 * If the option was serialized then it will be unserialized when it is returned.
619
 *
620
 * @since MU
621
 *
622
 * @param int    $id      A blog ID. Can be null to refer to the current blog.
623
 * @param string $option  Name of option to retrieve. Expected to not be SQL-escaped.
624
 * @param mixed  $default Optional. Default value to return if the option does not exist.
625
 * @return mixed Value set for the option.
626
 */
627
function get_blog_option( $id, $option, $default = false ) {
628
	$id = (int) $id;
629
630
	if ( empty( $id ) )
631
		$id = get_current_blog_id();
632
633
	if ( get_current_blog_id() == $id )
634
		return get_option( $option, $default );
635
636
	switch_to_blog( $id );
637
	$value = get_option( $option, $default );
638
	restore_current_blog();
639
640
	/**
641
	 * Filters a blog option value.
642
	 *
643
	 * The dynamic portion of the hook name, `$option`, refers to the blog option name.
644
	 *
645
	 * @since 3.5.0
646
	 *
647
	 * @param string  $value The option value.
648
	 * @param int     $id    Blog ID.
649
	 */
650
	return apply_filters( "blog_option_{$option}", $value, $id );
651
}
652
653
/**
654
 * Add a new option for a given blog id.
655
 *
656
 * You do not need to serialize values. If the value needs to be serialized, then
657
 * it will be serialized before it is inserted into the database. Remember,
658
 * resources can not be serialized or added as an option.
659
 *
660
 * You can create options without values and then update the values later.
661
 * Existing options will not be updated and checks are performed to ensure that you
662
 * aren't adding a protected WordPress option. Care should be taken to not name
663
 * options the same as the ones which are protected.
664
 *
665
 * @since MU
666
 *
667
 * @param int    $id     A blog ID. Can be null to refer to the current blog.
668
 * @param string $option Name of option to add. Expected to not be SQL-escaped.
669
 * @param mixed  $value  Optional. Option value, can be anything. Expected to not be SQL-escaped.
670
 * @return bool False if option was not added and true if option was added.
671
 */
672 View Code Duplication
function add_blog_option( $id, $option, $value ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
673
	$id = (int) $id;
674
675
	if ( empty( $id ) )
676
		$id = get_current_blog_id();
677
678
	if ( get_current_blog_id() == $id )
679
		return add_option( $option, $value );
680
681
	switch_to_blog( $id );
682
	$return = add_option( $option, $value );
683
	restore_current_blog();
684
685
	return $return;
686
}
687
688
/**
689
 * Removes option by name for a given blog id. Prevents removal of protected WordPress options.
690
 *
691
 * @since MU
692
 *
693
 * @param int    $id     A blog ID. Can be null to refer to the current blog.
694
 * @param string $option Name of option to remove. Expected to not be SQL-escaped.
695
 * @return bool True, if option is successfully deleted. False on failure.
696
 */
697 View Code Duplication
function delete_blog_option( $id, $option ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
698
	$id = (int) $id;
699
700
	if ( empty( $id ) )
701
		$id = get_current_blog_id();
702
703
	if ( get_current_blog_id() == $id )
704
		return delete_option( $option );
705
706
	switch_to_blog( $id );
707
	$return = delete_option( $option );
708
	restore_current_blog();
709
710
	return $return;
711
}
712
713
/**
714
 * Update an option for a particular blog.
715
 *
716
 * @since MU
717
 *
718
 * @param int    $id         The blog id.
719
 * @param string $option     The option key.
720
 * @param mixed  $value      The option value.
721
 * @param mixed  $deprecated Not used.
722
 * @return bool True on success, false on failure.
723
 */
724
function update_blog_option( $id, $option, $value, $deprecated = null ) {
725
	$id = (int) $id;
726
727
	if ( null !== $deprecated  )
728
		_deprecated_argument( __FUNCTION__, '3.1.0' );
729
730
	if ( get_current_blog_id() == $id )
731
		return update_option( $option, $value );
732
733
	switch_to_blog( $id );
734
	$return = update_option( $option, $value );
735
	restore_current_blog();
736
737
	refresh_blog_details( $id );
738
739
	return $return;
740
}
741
742
/**
743
 * Switch the current blog.
744
 *
745
 * This function is useful if you need to pull posts, or other information,
746
 * from other blogs. You can switch back afterwards using restore_current_blog().
747
 *
748
 * Things that aren't switched:
749
 *  - autoloaded options. See #14992
750
 *  - plugins. See #14941
751
 *
752
 * @see restore_current_blog()
753
 * @since MU
754
 *
755
 * @global wpdb            $wpdb
756
 * @global int             $blog_id
757
 * @global array           $_wp_switched_stack
758
 * @global bool            $switched
759
 * @global string          $table_prefix
760
 * @global WP_Object_Cache $wp_object_cache
761
 *
762
 * @param int  $new_blog   The id of the blog you want to switch to. Default: current blog
763
 * @param bool $deprecated Deprecated argument
764
 * @return true Always returns True.
765
 */
766
function switch_to_blog( $new_blog, $deprecated = null ) {
767
	global $wpdb;
768
769
	if ( empty( $new_blog ) )
770
		$new_blog = $GLOBALS['blog_id'];
771
772
	$GLOBALS['_wp_switched_stack'][] = $GLOBALS['blog_id'];
773
774
	/*
775
	 * If we're switching to the same blog id that we're on,
776
	 * set the right vars, do the associated actions, but skip
777
	 * the extra unnecessary work
778
	 */
779
	if ( $new_blog == $GLOBALS['blog_id'] ) {
780
		/**
781
		 * Fires when the blog is switched.
782
		 *
783
		 * @since MU
784
		 *
785
		 * @param int $new_blog New blog ID.
786
		 * @param int $new_blog Blog ID.
787
		 */
788
		do_action( 'switch_blog', $new_blog, $new_blog );
789
		$GLOBALS['switched'] = true;
790
		return true;
791
	}
792
793
	$wpdb->set_blog_id( $new_blog );
794
	$GLOBALS['table_prefix'] = $wpdb->get_blog_prefix();
795
	$prev_blog_id = $GLOBALS['blog_id'];
796
	$GLOBALS['blog_id'] = $new_blog;
797
798 View Code Duplication
	if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
799
		wp_cache_switch_to_blog( $new_blog );
800
	} else {
801
		global $wp_object_cache;
802
803
		if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) )
804
			$global_groups = $wp_object_cache->global_groups;
805
		else
806
			$global_groups = false;
807
808
		wp_cache_init();
809
810
		if ( function_exists( 'wp_cache_add_global_groups' ) ) {
811
			if ( is_array( $global_groups ) ) {
812
				wp_cache_add_global_groups( $global_groups );
813
			} else {
814
				wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'site-details' ) );
815
			}
816
			wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) );
817
		}
818
	}
819
820
	if ( did_action( 'init' ) ) {
821
		wp_roles()->reinit();
822
		$current_user = wp_get_current_user();
823
		$current_user->for_blog( $new_blog );
824
	}
825
826
	/** This filter is documented in wp-includes/ms-blogs.php */
827
	do_action( 'switch_blog', $new_blog, $prev_blog_id );
828
	$GLOBALS['switched'] = true;
829
830
	return true;
831
}
832
833
/**
834
 * Restore the current blog, after calling switch_to_blog()
835
 *
836
 * @see switch_to_blog()
837
 * @since MU
838
 *
839
 * @global wpdb            $wpdb
840
 * @global array           $_wp_switched_stack
841
 * @global int             $blog_id
842
 * @global bool            $switched
843
 * @global string          $table_prefix
844
 * @global WP_Object_Cache $wp_object_cache
845
 *
846
 * @return bool True on success, false if we're already on the current blog
847
 */
848
function restore_current_blog() {
849
	global $wpdb;
850
851
	if ( empty( $GLOBALS['_wp_switched_stack'] ) )
852
		return false;
853
854
	$blog = array_pop( $GLOBALS['_wp_switched_stack'] );
855
856
	if ( $GLOBALS['blog_id'] == $blog ) {
857
		/** This filter is documented in wp-includes/ms-blogs.php */
858
		do_action( 'switch_blog', $blog, $blog );
859
		// If we still have items in the switched stack, consider ourselves still 'switched'
860
		$GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );
861
		return true;
862
	}
863
864
	$wpdb->set_blog_id( $blog );
865
	$prev_blog_id = $GLOBALS['blog_id'];
866
	$GLOBALS['blog_id'] = $blog;
867
	$GLOBALS['table_prefix'] = $wpdb->get_blog_prefix();
868
869 View Code Duplication
	if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
870
		wp_cache_switch_to_blog( $blog );
871
	} else {
872
		global $wp_object_cache;
873
874
		if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) )
875
			$global_groups = $wp_object_cache->global_groups;
876
		else
877
			$global_groups = false;
878
879
		wp_cache_init();
880
881
		if ( function_exists( 'wp_cache_add_global_groups' ) ) {
882
			if ( is_array( $global_groups ) ) {
883
				wp_cache_add_global_groups( $global_groups );
884
			} else {
885
				wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'site-details' ) );
886
			}
887
			wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) );
888
		}
889
	}
890
891
	if ( did_action( 'init' ) ) {
892
		wp_roles()->reinit();
893
		$current_user = wp_get_current_user();
894
		$current_user->for_blog( $blog );
895
	}
896
897
	/** This filter is documented in wp-includes/ms-blogs.php */
898
	do_action( 'switch_blog', $blog, $prev_blog_id );
899
900
	// If we still have items in the switched stack, consider ourselves still 'switched'
901
	$GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );
902
903
	return true;
904
}
905
906
/**
907
 * Determines if switch_to_blog() is in effect
908
 *
909
 * @since 3.5.0
910
 *
911
 * @global array $_wp_switched_stack
912
 *
913
 * @return bool True if switched, false otherwise.
914
 */
915
function ms_is_switched() {
916
	return ! empty( $GLOBALS['_wp_switched_stack'] );
917
}
918
919
/**
920
 * Check if a particular blog is archived.
921
 *
922
 * @since MU
923
 *
924
 * @param int $id The blog id
925
 * @return string Whether the blog is archived or not
926
 */
927
function is_archived( $id ) {
928
	return get_blog_status($id, 'archived');
929
}
930
931
/**
932
 * Update the 'archived' status of a particular blog.
933
 *
934
 * @since MU
935
 *
936
 * @param int    $id       The blog id
937
 * @param string $archived The new status
938
 * @return string $archived
939
 */
940
function update_archived( $id, $archived ) {
941
	update_blog_status($id, 'archived', $archived);
942
	return $archived;
943
}
944
945
/**
946
 * Update a blog details field.
947
 *
948
 * @since MU
949
 *
950
 * @global wpdb $wpdb WordPress database abstraction object.
951
 *
952
 * @param int    $blog_id BLog ID
953
 * @param string $pref    A field name
954
 * @param string $value   Value for $pref
955
 * @param null   $deprecated
956
 * @return string|false $value
957
 */
958
function update_blog_status( $blog_id, $pref, $value, $deprecated = null ) {
959
	global $wpdb;
960
961
	if ( null !== $deprecated  )
962
		_deprecated_argument( __FUNCTION__, '3.1.0' );
963
964
	if ( ! in_array( $pref, array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id') ) )
965
		return $value;
966
967
	$result = $wpdb->update( $wpdb->blogs, array($pref => $value, 'last_updated' => current_time('mysql', true)), array('blog_id' => $blog_id) );
0 ignored issues
show
true is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
968
969
	if ( false === $result )
970
		return false;
971
972
	refresh_blog_details( $blog_id );
973
974
	if ( 'spam' == $pref ) {
975
		if ( $value == 1 ) {
976
			/** This filter is documented in wp-includes/ms-blogs.php */
977
			do_action( 'make_spam_blog', $blog_id );
978
		} else {
979
			/** This filter is documented in wp-includes/ms-blogs.php */
980
			do_action( 'make_ham_blog', $blog_id );
981
		}
982
	} elseif ( 'mature' == $pref ) {
983
		if ( $value == 1 ) {
984
			/** This filter is documented in wp-includes/ms-blogs.php */
985
			do_action( 'mature_blog', $blog_id );
986
		} else {
987
			/** This filter is documented in wp-includes/ms-blogs.php */
988
			do_action( 'unmature_blog', $blog_id );
989
		}
990
	} elseif ( 'archived' == $pref ) {
991
		if ( $value == 1 ) {
992
			/** This filter is documented in wp-includes/ms-blogs.php */
993
			do_action( 'archive_blog', $blog_id );
994
		} else {
995
			/** This filter is documented in wp-includes/ms-blogs.php */
996
			do_action( 'unarchive_blog', $blog_id );
997
		}
998
	} elseif ( 'deleted' == $pref ) {
999
		if ( $value == 1 ) {
1000
			/** This filter is documented in wp-includes/ms-blogs.php */
1001
			do_action( 'make_delete_blog', $blog_id );
1002
		} else {
1003
			/** This filter is documented in wp-includes/ms-blogs.php */
1004
			do_action( 'make_undelete_blog', $blog_id );
1005
		}
1006
	} elseif ( 'public' == $pref ) {
1007
		/**
1008
		 * Fires after the current blog's 'public' setting is updated.
1009
		 *
1010
		 * @since MU
1011
		 *
1012
		 * @param int    $blog_id Blog ID.
1013
		 * @param string $value   The value of blog status.
1014
 		 */
1015
		do_action( 'update_blog_public', $blog_id, $value ); // Moved here from update_blog_public().
1016
	}
1017
1018
	return $value;
1019
}
1020
1021
/**
1022
 * Get a blog details field.
1023
 *
1024
 * @since MU
1025
 *
1026
 * @global wpdb $wpdb WordPress database abstraction object.
1027
 *
1028
 * @param int    $id   The blog id
1029
 * @param string $pref A field name
1030
 * @return bool|string|null $value
1031
 */
1032
function get_blog_status( $id, $pref ) {
1033
	global $wpdb;
1034
1035
	$details = get_blog_details( $id, false );
1036
	if ( $details )
1037
		return $details->$pref;
1038
1039
	return $wpdb->get_var( $wpdb->prepare("SELECT %s FROM {$wpdb->blogs} WHERE blog_id = %d", $pref, $id) );
1040
}
1041
1042
/**
1043
 * Get a list of most recently updated blogs.
1044
 *
1045
 * @since MU
1046
 *
1047
 * @global wpdb $wpdb WordPress database abstraction object.
1048
 *
1049
 * @param mixed $deprecated Not used
1050
 * @param int   $start      The offset
1051
 * @param int   $quantity   The maximum number of blogs to retrieve. Default is 40.
1052
 * @return array The list of blogs
1053
 */
1054
function get_last_updated( $deprecated = '', $start = 0, $quantity = 40 ) {
1055
	global $wpdb;
1056
1057
	if ( ! empty( $deprecated ) )
1058
		_deprecated_argument( __FUNCTION__, 'MU' ); // never used
1059
1060
	return $wpdb->get_results( $wpdb->prepare("SELECT blog_id, domain, path FROM $wpdb->blogs WHERE site_id = %d AND public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' AND last_updated != '0000-00-00 00:00:00' ORDER BY last_updated DESC limit %d, %d", $wpdb->siteid, $start, $quantity ) , ARRAY_A );
1061
}
1062
1063
/**
1064
 * Retrieves a list of networks.
1065
 *
1066
 * @since 4.6.0
1067
 *
1068
 * @param string|array $args Optional. Array or string of arguments. See WP_Network_Query::parse_query()
1069
 *                           for information on accepted arguments. Default empty array.
1070
 * @return int|array List of networks or number of found networks if `$count` argument is true.
1071
 */
1072
function get_networks( $args = array() ) {
1073
	$query = new WP_Network_Query();
1074
1075
	return $query->query( $args );
1076
}
1077
1078
/**
1079
 * Retrieves network data given a network ID or network object.
1080
 *
1081
 * Network data will be cached and returned after being passed through a filter.
1082
 * If the provided network is empty, the current network global will be used.
1083
 *
1084
 * @since 4.6.0
1085
 *
1086
 * @global WP_Network $current_site
1087
 *
1088
 * @param WP_Network|int|null $network Optional. Network to retrieve. Default is the current network.
1089
 * @return WP_Network|null The network object or null if not found.
1090
 */
1091
function get_network( $network = null ) {
1092
	global $current_site;
1093
	if ( empty( $network ) && isset( $current_site ) ) {
1094
		$network = $current_site;
1095
	}
1096
1097
	if ( $network instanceof WP_Network ) {
1098
		$_network = $network;
1099
	} elseif ( is_object( $network ) ) {
1100
		$_network = new WP_Network( $network );
1101
	} else {
1102
		$_network = WP_Network::get_instance( $network );
1103
	}
1104
1105
	if ( ! $_network ) {
1106
		return null;
1107
	}
1108
1109
	/**
1110
	 * Fires after a network is retrieved.
1111
	 *
1112
	 * @since 4.6.0
1113
	 *
1114
	 * @param WP_Network $_network Network data.
1115
	 */
1116
	$_network = apply_filters( 'get_network', $_network );
1117
1118
	return $_network;
1119
}
1120
1121
/**
1122
 * Removes a network from the object cache.
1123
 *
1124
 * @since 4.6.0
1125
 *
1126
 * @param int|array $ids Network ID or an array of network IDs to remove from cache.
1127
 */
1128 View Code Duplication
function clean_network_cache( $ids ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1129
	foreach ( (array) $ids as $id ) {
1130
		wp_cache_delete( $id, 'networks' );
1131
1132
		/**
1133
		 * Fires immediately after a network has been removed from the object cache.
1134
		 *
1135
		 * @since 4.6.0
1136
		 *
1137
		 * @param int $id Network ID.
1138
		 */
1139
		do_action( 'clean_network_cache', $id );
1140
	}
1141
1142
	wp_cache_set( 'last_changed', microtime(), 'networks' );
1143
}
1144
1145
/**
1146
 * Updates the network cache of given networks.
1147
 *
1148
 * Will add the networks in $networks to the cache. If network ID already exists
1149
 * in the network cache then it will not be updated. The network is added to the
1150
 * cache using the network group with the key using the ID of the networks.
1151
 *
1152
 * @since 4.6.0
1153
 *
1154
 * @param array $networks Array of network row objects.
1155
 */
1156
function update_network_cache( $networks ) {
1157
	foreach ( (array) $networks as $network ) {
1158
		wp_cache_add( $network->id, $network, 'networks' );
1159
	}
1160
}
1161
1162
/**
1163
 * Adds any networks from the given IDs to the cache that do not already exist in cache.
1164
 *
1165
 * @since 4.6.0
1166
 * @access private
1167
 *
1168
 * @see update_network_cache()
1169
 * @global wpdb $wpdb WordPress database abstraction object.
1170
 *
1171
 * @param array $network_ids Array of network IDs.
1172
 */
1173 View Code Duplication
function _prime_network_caches( $network_ids ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1174
	global $wpdb;
1175
1176
	$non_cached_ids = _get_non_cached_ids( $network_ids, 'networks' );
1177
	if ( !empty( $non_cached_ids ) ) {
1178
		$fresh_networks = $wpdb->get_results( sprintf( "SELECT $wpdb->site.* FROM $wpdb->site WHERE id IN (%s)", join( ",", array_map( 'intval', $non_cached_ids ) ) ) );
1179
1180
		update_network_cache( $fresh_networks );
1181
	}
1182
}
1183
1184
/**
1185
 * Handler for updating the blog date when a post is published or an already published post is changed.
1186
 *
1187
 * @since 3.3.0
1188
 *
1189
 * @param string $new_status The new post status
1190
 * @param string $old_status The old post status
1191
 * @param object $post       Post object
1192
 */
1193 View Code Duplication
function _update_blog_date_on_post_publish( $new_status, $old_status, $post ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1194
	$post_type_obj = get_post_type_object( $post->post_type );
1195
	if ( ! $post_type_obj || ! $post_type_obj->public ) {
1196
		return;
1197
	}
1198
1199
	if ( 'publish' != $new_status && 'publish' != $old_status ) {
1200
		return;
1201
	}
1202
1203
	// Post was freshly published, published post was saved, or published post was unpublished.
1204
1205
	wpmu_update_blogs_date();
1206
}
1207
1208
/**
1209
 * Handler for updating the blog date when a published post is deleted.
1210
 *
1211
 * @since 3.4.0
1212
 *
1213
 * @param int $post_id Post ID
1214
 */
1215 View Code Duplication
function _update_blog_date_on_post_delete( $post_id ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1216
	$post = get_post( $post_id );
1217
1218
	$post_type_obj = get_post_type_object( $post->post_type );
1219
	if ( ! $post_type_obj || ! $post_type_obj->public ) {
1220
		return;
1221
	}
1222
1223
	if ( 'publish' != $post->post_status ) {
1224
		return;
1225
	}
1226
1227
	wpmu_update_blogs_date();
1228
}
1229
1230
/**
1231
 * Handler for updating the blog posts count date when a post is deleted.
1232
 *
1233
 * @since 4.0.0
1234
 *
1235
 * @param int $post_id Post ID.
1236
 */
1237
function _update_posts_count_on_delete( $post_id ) {
1238
	$post = get_post( $post_id );
1239
1240
	if ( ! $post || 'publish' !== $post->post_status ) {
1241
		return;
1242
	}
1243
1244
	update_posts_count();
1245
}
1246
1247
/**
1248
 * Handler for updating the blog posts count date when a post status changes.
1249
 *
1250
 * @since 4.0.0
1251
 *
1252
 * @param string $new_status The status the post is changing to.
1253
 * @param string $old_status The status the post is changing from.
1254
 */
1255
function _update_posts_count_on_transition_post_status( $new_status, $old_status ) {
1256
	if ( $new_status === $old_status ) {
1257
		return;
1258
	}
1259
1260
	if ( 'publish' !== $new_status && 'publish' !== $old_status ) {
1261
		return;
1262
	}
1263
1264
	update_posts_count();
1265
}
1266