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-signup.php (9 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
/** Sets up the WordPress Environment. */
4
require( dirname(__FILE__) . '/wp-load.php' );
5
6
add_action( 'wp_head', 'wp_no_robots' );
7
8
require( dirname( __FILE__ ) . '/wp-blog-header.php' );
9
10
if ( is_array( get_site_option( 'illegal_names' )) && isset( $_GET[ 'new' ] ) && in_array( $_GET[ 'new' ], get_site_option( 'illegal_names' ) ) ) {
11
	wp_redirect( network_home_url() );
12
	die();
13
}
14
15
/**
16
 * Prints signup_header via wp_head
17
 *
18
 * @since MU
19
 */
20
function do_signup_header() {
21
	/**
22
	 * Fires within the head section of the site sign-up screen.
23
	 *
24
	 * @since 3.0.0
25
	 */
26
	do_action( 'signup_header' );
27
}
28
add_action( 'wp_head', 'do_signup_header' );
29
30
if ( !is_multisite() ) {
31
	wp_redirect( wp_registration_url() );
32
	die();
33
}
34
35
if ( !is_main_site() ) {
36
	wp_redirect( network_site_url( 'wp-signup.php' ) );
37
	die();
38
}
39
40
// Fix for page title
41
$wp_query->is_404 = false;
42
43
/**
44
 * Fires before the Site Signup page is loaded.
45
 *
46
 * @since 4.4.0
47
 */
48
do_action( 'before_signup_header' );
49
50
/**
51
 * Prints styles for front-end Multisite signup pages
52
 *
53
 * @since MU
54
 */
55
function wpmu_signup_stylesheet() {
56
	?>
57
	<style type="text/css">
58
		.mu_register { width: 90%; margin:0 auto; }
59
		.mu_register form { margin-top: 2em; }
60
		.mu_register .error { font-weight:700; padding:10px; color:#333333; background:#FFEBE8; border:1px solid #CC0000; }
61
		.mu_register input[type="submit"],
62
			.mu_register #blog_title,
63
			.mu_register #user_email,
64
			.mu_register #blogname,
65
			.mu_register #user_name { width:100%; font-size: 24px; margin:5px 0; }
66
		.mu_register #site-language { display: block; }
67
		.mu_register .prefix_address,
68
			.mu_register .suffix_address {font-size: 18px;display:inline; }
69
		.mu_register label { font-weight:700; font-size:15px; display:block; margin:10px 0; }
70
		.mu_register label.checkbox { display:inline; }
71
		.mu_register .mu_alert { font-weight:700; padding:10px; color:#333333; background:#ffffe0; border:1px solid #e6db55; }
72
	</style>
73
	<?php
74
}
75
76
add_action( 'wp_head', 'wpmu_signup_stylesheet' );
77
get_header( 'wp-signup' );
78
79
/**
80
 * Fires before the site sign-up form.
81
 *
82
 * @since 3.0.0
83
 */
84
do_action( 'before_signup_form' );
85
?>
86
<div id="signup-content" class="widecolumn">
87
<div class="mu_register wp-signup-container">
88
<?php
89
/**
90
 * Generates and displays the Signup and Create Site forms
91
 *
92
 * @since MU
93
 *
94
 * @param string          $blogname   The new site name.
95
 * @param string          $blog_title The new site title.
96
 * @param WP_Error|string $errors     A WP_Error object containing existing errors. Defaults to empty string.
97
 */
98
function show_blog_form( $blogname = '', $blog_title = '', $errors = '' ) {
99
	if ( ! is_wp_error( $errors ) ) {
100
		$errors = new WP_Error();
101
	}
102
103
	$current_network = get_network();
104
	// Blog name
105
	if ( !is_subdomain_install() )
106
		echo '<label for="blogname">' . __('Site Name:') . '</label>';
107
	else
108
		echo '<label for="blogname">' . __('Site Domain:') . '</label>';
109
110
	if ( $errmsg = $errors->get_error_message('blogname') ) { ?>
0 ignored issues
show
It seems like $errors is not always an object, but can also be of type string. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
111
		<p class="error"><?php echo $errmsg ?></p>
112
	<?php }
113
114
	if ( !is_subdomain_install() )
115
		echo '<span class="prefix_address">' . $current_network->domain . $current_network->path . '</span><input name="blogname" type="text" id="blogname" value="'. esc_attr($blogname) .'" maxlength="60" /><br />';
116
	else
117
		echo '<input name="blogname" type="text" id="blogname" value="'.esc_attr($blogname).'" maxlength="60" /><span class="suffix_address">.' . ( $site_domain = preg_replace( '|^www\.|', '', $current_network->domain ) ) . '</span><br />';
118
119
	if ( ! is_user_logged_in() ) {
120
		if ( ! is_subdomain_install() ) {
121
			$site = $current_network->domain . $current_network->path . __( 'sitename' );
122
		} else {
123
			$site = __( 'domain' ) . '.' . $site_domain . $current_network->path;
0 ignored issues
show
The variable $site_domain does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
124
		}
125
126
		/* translators: %s: site address */
127
		echo '<p>(<strong>' . sprintf( __( 'Your address will be %s.' ), $site ) . '</strong>) ' . __( 'Must be at least 4 characters, letters and numbers only. It cannot be changed, so choose carefully!' ) . '</p>';
128
	}
129
130
	// Blog Title
131
	?>
132
	<label for="blog_title"><?php _e('Site Title:') ?></label>
133
	<?php if ( $errmsg = $errors->get_error_message('blog_title') ) { ?>
134
		<p class="error"><?php echo $errmsg ?></p>
135
	<?php }
136
	echo '<input name="blog_title" type="text" id="blog_title" value="'.esc_attr($blog_title).'" />';
137
	?>
138
139
	<?php
140
	// Site Language.
141
	$languages = signup_get_available_languages();
142
143
	if ( ! empty( $languages ) ) :
144
		?>
145
		<p>
146
			<label for="site-language"><?php _e( 'Site Language:' ); ?></label>
147
			<?php
148
			// Network default.
149
			$lang = get_site_option( 'WPLANG' );
150
151
			if ( isset( $_POST['WPLANG'] ) ) {
152
				$lang = $_POST['WPLANG'];
153
			}
154
155
			// Use US English if the default isn't available.
156
			if ( ! in_array( $lang, $languages ) ) {
157
				$lang = '';
158
			}
159
160
			wp_dropdown_languages( array(
161
				'name'                        => 'WPLANG',
162
				'id'                          => 'site-language',
163
				'selected'                    => $lang,
164
				'languages'                   => $languages,
165
				'show_available_translations' => false,
166
			) );
167
			?>
168
		</p>
169
	<?php endif; // Languages. ?>
170
171
	<div id="privacy">
172
        <p class="privacy-intro">
173
            <label for="blog_public_on"><?php _e('Privacy:') ?></label>
174
            <?php _e( 'Allow search engines to index this site.' ); ?>
175
            <br style="clear:both" />
176
            <label class="checkbox" for="blog_public_on">
177
                <input type="radio" id="blog_public_on" name="blog_public" value="1" <?php if ( !isset( $_POST['blog_public'] ) || $_POST['blog_public'] == '1' ) { ?>checked="checked"<?php } ?> />
178
                <strong><?php _e( 'Yes' ); ?></strong>
179
            </label>
180
            <label class="checkbox" for="blog_public_off">
181
                <input type="radio" id="blog_public_off" name="blog_public" value="0" <?php if ( isset( $_POST['blog_public'] ) && $_POST['blog_public'] == '0' ) { ?>checked="checked"<?php } ?> />
182
                <strong><?php _e( 'No' ); ?></strong>
183
            </label>
184
        </p>
185
	</div>
186
187
	<?php
188
	/**
189
	 * Fires after the site sign-up form.
190
	 *
191
	 * @since 3.0.0
192
	 *
193
	 * @param WP_Error $errors A WP_Error object possibly containing 'blogname' or 'blog_title' errors.
194
	 */
195
	do_action( 'signup_blogform', $errors );
196
}
197
198
/**
199
 * Validate the new site signup
200
 *
201
 * @since MU
202
 *
203
 * @return array Contains the new site data and error messages.
204
 */
205
function validate_blog_form() {
206
	$user = '';
207
	if ( is_user_logged_in() )
208
		$user = wp_get_current_user();
209
210
	return wpmu_validate_blog_signup($_POST['blogname'], $_POST['blog_title'], $user);
211
}
212
213
/**
214
 * Display user registration form
215
 *
216
 * @since MU
217
 *
218
 * @param string          $user_name  The entered username.
219
 * @param string          $user_email The entered email address.
220
 * @param WP_Error|string $errors     A WP_Error object containing existing errors. Defaults to empty string.
221
 */
222
function show_user_form($user_name = '', $user_email = '', $errors = '') {
223
	if ( ! is_wp_error( $errors ) ) {
224
		$errors = new WP_Error();
225
	}
226
227
	// User name
228
	echo '<label for="user_name">' . __('Username:') . '</label>';
229
	if ( $errmsg = $errors->get_error_message('user_name') ) {
0 ignored issues
show
It seems like $errors is not always an object, but can also be of type string. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
230
		echo '<p class="error">'.$errmsg.'</p>';
231
	}
232
	echo '<input name="user_name" type="text" id="user_name" value="'. esc_attr( $user_name ) .'" autocapitalize="none" autocorrect="off" maxlength="60" /><br />';
233
	_e( '(Must be at least 4 characters, letters and numbers only.)' );
234
	?>
235
236
	<label for="user_email"><?php _e( 'Email&nbsp;Address:' ) ?></label>
237
	<?php if ( $errmsg = $errors->get_error_message('user_email') ) { ?>
238
		<p class="error"><?php echo $errmsg ?></p>
239
	<?php } ?>
240
	<input name="user_email" type="email" id="user_email" value="<?php  echo esc_attr($user_email) ?>" maxlength="200" /><br /><?php _e('We send your registration email to this address. (Double-check your email address before continuing.)') ?>
241
	<?php
242
	if ( $errmsg = $errors->get_error_message('generic') ) {
243
		echo '<p class="error">' . $errmsg . '</p>';
244
	}
245
	/**
246
	 * Fires at the end of the user registration form on the site sign-up form.
247
	 *
248
	 * @since 3.0.0
249
	 *
250
	 * @param WP_Error $errors A WP_Error object containing containing 'user_name' or 'user_email' errors.
251
	 */
252
	do_action( 'signup_extra_fields', $errors );
253
}
254
255
/**
256
 * Validate user signup name and email
257
 *
258
 * @since MU
259
 *
260
 * @return array Contains username, email, and error messages.
261
 */
262
function validate_user_form() {
263
	return wpmu_validate_user_signup($_POST['user_name'], $_POST['user_email']);
264
}
265
266
/**
267
 * Allow returning users to sign up for another site
268
 *
269
 * @since MU
270
 *
271
 * @param string          $blogname   The new site name
272
 * @param string          $blog_title The new site title.
273
 * @param WP_Error|string $errors     A WP_Error object containing existing errors. Defaults to empty string.
274
 */
275
function signup_another_blog( $blogname = '', $blog_title = '', $errors = '' ) {
276
	$current_user = wp_get_current_user();
277
278
	if ( ! is_wp_error($errors) ) {
279
		$errors = new WP_Error();
280
	}
281
282
	$signup_defaults = array(
283
		'blogname'   => $blogname,
284
		'blog_title' => $blog_title,
285
		'errors'     => $errors
286
	);
287
288
	/**
289
	 * Filters the default site sign-up variables.
290
	 *
291
	 * @since 3.0.0
292
	 *
293
	 * @param array $signup_defaults {
294
	 *     An array of default site sign-up variables.
295
	 *
296
	 *     @type string   $blogname   The site blogname.
297
	 *     @type string   $blog_title The site title.
298
	 *     @type WP_Error $errors     A WP_Error object possibly containing 'blogname' or 'blog_title' errors.
299
	 * }
300
	 */
301
	$filtered_results = apply_filters( 'signup_another_blog_init', $signup_defaults );
302
303
	$blogname = $filtered_results['blogname'];
304
	$blog_title = $filtered_results['blog_title'];
305
	$errors = $filtered_results['errors'];
306
307
	echo '<h2>' . sprintf( __( 'Get <em>another</em> %s site in seconds' ), get_network()->site_name ) . '</h2>';
308
309
	if ( $errors->get_error_code() ) {
310
		echo '<p>' . __( 'There was a problem, please correct the form below and try again.' ) . '</p>';
311
	}
312
	?>
313
	<p><?php printf( __( 'Welcome back, %s. By filling out the form below, you can <strong>add another site to your account</strong>. There is no limit to the number of sites you can have, so create to your heart&#8217;s content, but write responsibly!' ), $current_user->display_name ) ?></p>
314
315
	<?php
316
	$blogs = get_blogs_of_user($current_user->ID);
317
	if ( !empty($blogs) ) { ?>
318
319
			<p><?php _e( 'Sites you are already a member of:' ) ?></p>
320
			<ul>
321
				<?php foreach ( $blogs as $blog ) {
322
					$home_url = get_home_url( $blog->userblog_id );
323
					echo '<li><a href="' . esc_url( $home_url ) . '">' . $home_url . '</a></li>';
324
				} ?>
325
			</ul>
326
	<?php } ?>
327
328
	<p><?php _e( 'If you&#8217;re not going to use a great site domain, leave it for a new user. Now have at it!' ) ?></p>
329
	<form id="setupform" method="post" action="wp-signup.php">
330
		<input type="hidden" name="stage" value="gimmeanotherblog" />
331
		<?php
332
		/**
333
		 * Hidden sign-up form fields output when creating another site or user.
334
		 *
335
		 * @since MU
336
		 *
337
		 * @param string $context A string describing the steps of the sign-up process. The value can be
338
		 *                        'create-another-site', 'validate-user', or 'validate-site'.
339
		 */
340
		do_action( 'signup_hidden_fields', 'create-another-site' );
341
		?>
342
		<?php show_blog_form($blogname, $blog_title, $errors); ?>
343
		<p class="submit"><input type="submit" name="submit" class="submit" value="<?php esc_attr_e( 'Create Site' ) ?>" /></p>
344
	</form>
345
	<?php
346
}
347
348
/**
349
 * Validate a new site signup.
350
 *
351
 * @since MU
352
 *
353
 * @return null|bool True if site signup was validated, false if error.
354
 *                   The function halts all execution if the user is not logged in.
355
 */
356
function validate_another_blog_signup() {
357
	global $wpdb, $blogname, $blog_title, $errors, $domain, $path;
358
	$current_user = wp_get_current_user();
359
	if ( ! is_user_logged_in() ) {
360
		die();
0 ignored issues
show
Coding Style Compatibility introduced by
The function validate_another_blog_signup() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
361
	}
362
363
	$result = validate_blog_form();
364
365
	// Extracted values set/overwrite globals.
366
	$domain = $result['domain'];
367
	$path = $result['path'];
368
	$blogname = $result['blogname'];
369
	$blog_title = $result['blog_title'];
370
	$errors = $result['errors'];
371
372
	if ( $errors->get_error_code() ) {
373
		signup_another_blog($blogname, $blog_title, $errors);
374
		return false;
375
	}
376
377
	$public = (int) $_POST['blog_public'];
378
379
	$blog_meta_defaults = array(
380
		'lang_id' => 1,
381
		'public'  => $public
382
	);
383
384
	// Handle the language setting for the new site.
385 View Code Duplication
	if ( ! empty( $_POST['WPLANG'] ) ) {
386
387
		$languages = signup_get_available_languages();
388
389
		if ( in_array( $_POST['WPLANG'], $languages ) ) {
390
			$language = wp_unslash( sanitize_text_field( $_POST['WPLANG'] ) );
391
392
			if ( $language ) {
393
				$blog_meta_defaults['WPLANG'] = $language;
394
			}
395
		}
396
397
	}
398
399
	/**
400
	 * Filters the new site meta variables.
401
	 *
402
	 * Use the {@see 'add_signup_meta'} filter instead.
403
	 *
404
	 * @since MU
405
	 * @deprecated 3.0.0 Use the {@see 'add_signup_meta'} filter instead.
406
	 *
407
	 * @param array $blog_meta_defaults An array of default blog meta variables.
408
	 */
409
	$meta_defaults = apply_filters( 'signup_create_blog_meta', $blog_meta_defaults );
410
411
	/**
412
	 * Filters the new default site meta variables.
413
	 *
414
	 * @since 3.0.0
415
	 *
416
	 * @param array $meta {
417
	 *     An array of default site meta variables.
418
	 *
419
	 *     @type int $lang_id     The language ID.
420
	 *     @type int $blog_public Whether search engines should be discouraged from indexing the site. 1 for true, 0 for false.
421
	 * }
422
	 */
423
	$meta = apply_filters( 'add_signup_meta', $meta_defaults );
424
425
	$blog_id = wpmu_create_blog( $domain, $path, $blog_title, $current_user->ID, $meta, $wpdb->siteid );
426
427
	if ( is_wp_error( $blog_id ) ) {
428
		return false;
429
	}
430
431
	confirm_another_blog_signup( $domain, $path, $blog_title, $current_user->user_login, $current_user->user_email, $meta, $blog_id );
432
	return true;
433
}
434
435
/**
436
 * Confirm a new site signup.
437
 *
438
 * @since MU
439
 * @since 4.4.0 Added the `$blog_id` parameter.
440
 *
441
 * @param string $domain     The domain URL.
442
 * @param string $path       The site root path.
443
 * @param string $blog_title The site title.
444
 * @param string $user_name  The username.
445
 * @param string $user_email The user's email address.
446
 * @param array  $meta       Any additional meta from the {@see 'add_signup_meta'} filter in validate_blog_signup().
447
 * @param int    $blog_id    The site ID.
448
 */
449
function confirm_another_blog_signup( $domain, $path, $blog_title, $user_name, $user_email = '', $meta = array(), $blog_id = 0 ) {
0 ignored issues
show
The parameter $user_email is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $meta is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
450
451
	if ( $blog_id ) {
452
		switch_to_blog( $blog_id );
453
		$home_url  = home_url( '/' );
454
		$login_url = wp_login_url();
455
		restore_current_blog();
456
	} else {
457
		$home_url  = 'http://' . $domain . $path;
458
		$login_url = 'http://' . $domain . $path . 'wp-login.php';
459
	}
460
461
	$site = sprintf( '<a href="%1$s">%2$s</a>',
462
		esc_url( $home_url ),
463
		$blog_title
464
	);
465
466
	?>
467
	<h2><?php
468
		/* translators: %s: site name */
469
		printf( __( 'The site %s is yours.' ), $site );
470
	?></h2>
471
	<p>
472
		<?php printf(
473
			/* translators: 1: home URL, 2: site address, 3: login URL, 4: username */
474
			__( '<a href="%1$s">%2$s</a> is your new site. <a href="%3$s">Log in</a> as &#8220;%4$s&#8221; using your existing password.' ),
475
			esc_url( $home_url ),
476
			untrailingslashit( $domain . $path ),
477
			esc_url( $login_url ),
478
			$user_name
479
		); ?>
480
	</p>
481
	<?php
482
	/**
483
	 * Fires when the site or user sign-up process is complete.
484
	 *
485
	 * @since 3.0.0
486
	 */
487
	do_action( 'signup_finished' );
488
}
489
490
/**
491
 * Setup the new user signup process
492
 *
493
 * @since MU
494
 *
495
 * @param string          $user_name  The username.
496
 * @param string          $user_email The user's email.
497
 * @param WP_Error|string $errors     A WP_Error object containing existing errors. Defaults to empty string.
498
 */
499
function signup_user( $user_name = '', $user_email = '', $errors = '' ) {
500
	global $active_signup;
501
502
	if ( !is_wp_error($errors) )
503
		$errors = new WP_Error();
504
505
	$signup_for = isset( $_POST[ 'signup_for' ] ) ? esc_html( $_POST[ 'signup_for' ] ) : 'blog';
506
507
	$signup_user_defaults = array(
508
		'user_name'  => $user_name,
509
		'user_email' => $user_email,
510
		'errors'     => $errors,
511
	);
512
513
	/**
514
	 * Filters the default user variables used on the user sign-up form.
515
	 *
516
	 * @since 3.0.0
517
	 *
518
	 * @param array $signup_user_defaults {
519
	 *     An array of default user variables.
520
	 *
521
	 *     @type string   $user_name  The user username.
522
	 *     @type string   $user_email The user email address.
523
	 *     @type WP_Error $errors     A WP_Error object with possible errors relevant to the sign-up user.
524
	 * }
525
	 */
526
	$filtered_results = apply_filters( 'signup_user_init', $signup_user_defaults );
527
	$user_name = $filtered_results['user_name'];
528
	$user_email = $filtered_results['user_email'];
529
	$errors = $filtered_results['errors'];
530
531
	?>
532
533
	<h2><?php
534
		/* translators: %s: name of the network */
535
		printf( __( 'Get your own %s account in seconds' ), get_network()->site_name );
536
	?></h2>
537
	<form id="setupform" method="post" action="wp-signup.php" novalidate="novalidate">
538
		<input type="hidden" name="stage" value="validate-user-signup" />
539
		<?php
540
		/** This action is documented in wp-signup.php */
541
		do_action( 'signup_hidden_fields', 'validate-user' );
542
		?>
543
		<?php show_user_form($user_name, $user_email, $errors); ?>
544
545
		<p>
546
		<?php if ( $active_signup == 'blog' ) { ?>
547
			<input id="signupblog" type="hidden" name="signup_for" value="blog" />
548
		<?php } elseif ( $active_signup == 'user' ) { ?>
549
			<input id="signupblog" type="hidden" name="signup_for" value="user" />
550
		<?php } else { ?>
551
			<input id="signupblog" type="radio" name="signup_for" value="blog" <?php checked( $signup_for, 'blog' ); ?> />
552
			<label class="checkbox" for="signupblog"><?php _e('Gimme a site!') ?></label>
553
			<br />
554
			<input id="signupuser" type="radio" name="signup_for" value="user" <?php checked( $signup_for, 'user' ); ?> />
555
			<label class="checkbox" for="signupuser"><?php _e('Just a username, please.') ?></label>
556
		<?php } ?>
557
		</p>
558
559
		<p class="submit"><input type="submit" name="submit" class="submit" value="<?php esc_attr_e('Next') ?>" /></p>
560
	</form>
561
	<?php
562
}
563
564
/**
565
 * Validate the new user signup
566
 *
567
 * @since MU
568
 *
569
 * @return bool True if new user signup was validated, false if error
570
 */
571
function validate_user_signup() {
572
	$result = validate_user_form();
573
	$user_name = $result['user_name'];
574
	$user_email = $result['user_email'];
575
	$errors = $result['errors'];
576
577
	if ( $errors->get_error_code() ) {
578
		signup_user($user_name, $user_email, $errors);
579
		return false;
580
	}
581
582
	if ( 'blog' == $_POST['signup_for'] ) {
583
		signup_blog($user_name, $user_email);
584
		return false;
585
	}
586
587
	/** This filter is documented in wp-signup.php */
588
	wpmu_signup_user( $user_name, $user_email, apply_filters( 'add_signup_meta', array() ) );
589
590
	confirm_user_signup($user_name, $user_email);
591
	return true;
592
}
593
594
/**
595
 * New user signup confirmation
596
 *
597
 * @since MU
598
 *
599
 * @param string $user_name The username
600
 * @param string $user_email The user's email address
601
 */
602
function confirm_user_signup($user_name, $user_email) {
603
	?>
604
	<h2><?php /* translators: %s: username */
605
	printf( __( '%s is your new username' ), $user_name) ?></h2>
606
	<p><?php _e( 'But, before you can start using your new username, <strong>you must activate it</strong>.' ) ?></p>
607
	<p><?php /* translators: %s: email address */
608
	printf( __( 'Check your inbox at %s and click the link given.' ), '<strong>' . $user_email . '</strong>' ); ?></p>
609
	<p><?php _e( 'If you do not activate your username within two days, you will have to sign up again.' ); ?></p>
610
	<?php
611
	/** This action is documented in wp-signup.php */
612
	do_action( 'signup_finished' );
613
}
614
615
/**
616
 * Setup the new site signup
617
 *
618
 * @since MU
619
 *
620
 * @param string          $user_name  The username.
621
 * @param string          $user_email The user's email address.
622
 * @param string          $blogname   The site name.
623
 * @param string          $blog_title The site title.
624
 * @param WP_Error|string $errors     A WP_Error object containing existing errors. Defaults to empty string.
625
 */
626
function signup_blog($user_name = '', $user_email = '', $blogname = '', $blog_title = '', $errors = '') {
627
	if ( !is_wp_error($errors) )
628
		$errors = new WP_Error();
629
630
	$signup_blog_defaults = array(
631
		'user_name'  => $user_name,
632
		'user_email' => $user_email,
633
		'blogname'   => $blogname,
634
		'blog_title' => $blog_title,
635
		'errors'     => $errors
636
	);
637
638
	/**
639
	 * Filters the default site creation variables for the site sign-up form.
640
	 *
641
	 * @since 3.0.0
642
	 *
643
	 * @param array $signup_blog_defaults {
644
	 *     An array of default site creation variables.
645
	 *
646
	 *     @type string   $user_name  The user username.
647
	 *     @type string   $user_email The user email address.
648
	 *     @type string   $blogname   The blogname.
649
	 *     @type string   $blog_title The title of the site.
650
	 *     @type WP_Error $errors     A WP_Error object with possible errors relevant to new site creation variables.
651
	 * }
652
	 */
653
	$filtered_results = apply_filters( 'signup_blog_init', $signup_blog_defaults );
654
655
	$user_name = $filtered_results['user_name'];
656
	$user_email = $filtered_results['user_email'];
657
	$blogname = $filtered_results['blogname'];
658
	$blog_title = $filtered_results['blog_title'];
659
	$errors = $filtered_results['errors'];
660
661
	if ( empty($blogname) )
662
		$blogname = $user_name;
663
	?>
664
	<form id="setupform" method="post" action="wp-signup.php">
665
		<input type="hidden" name="stage" value="validate-blog-signup" />
666
		<input type="hidden" name="user_name" value="<?php echo esc_attr($user_name) ?>" />
667
		<input type="hidden" name="user_email" value="<?php echo esc_attr($user_email) ?>" />
668
		<?php
669
		/** This action is documented in wp-signup.php */
670
		do_action( 'signup_hidden_fields', 'validate-site' );
671
		?>
672
		<?php show_blog_form($blogname, $blog_title, $errors); ?>
673
		<p class="submit"><input type="submit" name="submit" class="submit" value="<?php esc_attr_e('Signup') ?>" /></p>
674
	</form>
675
	<?php
676
}
677
678
/**
679
 * Validate new site signup
680
 *
681
 * @since MU
682
 *
683
 * @return bool True if the site signup was validated, false if error
684
 */
685
function validate_blog_signup() {
686
	// Re-validate user info.
687
	$user_result = wpmu_validate_user_signup( $_POST['user_name'], $_POST['user_email'] );
688
	$user_name = $user_result['user_name'];
689
	$user_email = $user_result['user_email'];
690
	$user_errors = $user_result['errors'];
691
692
	if ( $user_errors->get_error_code() ) {
693
		signup_user( $user_name, $user_email, $user_errors );
694
		return false;
695
	}
696
697
	$result = wpmu_validate_blog_signup( $_POST['blogname'], $_POST['blog_title'] );
698
	$domain = $result['domain'];
699
	$path = $result['path'];
700
	$blogname = $result['blogname'];
701
	$blog_title = $result['blog_title'];
702
	$errors = $result['errors'];
703
704
	if ( $errors->get_error_code() ) {
705
		signup_blog($user_name, $user_email, $blogname, $blog_title, $errors);
706
		return false;
707
	}
708
709
	$public = (int) $_POST['blog_public'];
710
	$signup_meta = array ('lang_id' => 1, 'public' => $public);
711
712
	// Handle the language setting for the new site.
713 View Code Duplication
	if ( ! empty( $_POST['WPLANG'] ) ) {
714
715
		$languages = signup_get_available_languages();
716
717
		if ( in_array( $_POST['WPLANG'], $languages ) ) {
718
			$language = wp_unslash( sanitize_text_field( $_POST['WPLANG'] ) );
719
720
			if ( $language ) {
721
				$signup_meta['WPLANG'] = $language;
722
			}
723
		}
724
725
	}
726
727
	/** This filter is documented in wp-signup.php */
728
	$meta = apply_filters( 'add_signup_meta', $signup_meta );
729
730
	wpmu_signup_blog($domain, $path, $blog_title, $user_name, $user_email, $meta);
731
	confirm_blog_signup($domain, $path, $blog_title, $user_name, $user_email, $meta);
732
	return true;
733
}
734
735
/**
736
 * New site signup confirmation
737
 *
738
 * @since MU
739
 *
740
 * @param string $domain The domain URL
741
 * @param string $path The site root path
742
 * @param string $blog_title The new site title
743
 * @param string $user_name The user's username
744
 * @param string $user_email The user's email address
745
 * @param array $meta Any additional meta from the {@see 'add_signup_meta'} filter in validate_blog_signup()
746
 */
747
function confirm_blog_signup( $domain, $path, $blog_title, $user_name = '', $user_email = '', $meta = array() ) {
0 ignored issues
show
The parameter $user_name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $meta is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
748
	?>
749
	<h2><?php /* translators: %s: site address */
750
	printf( __( 'Congratulations! Your new site, %s, is almost ready.' ), "<a href='http://{$domain}{$path}'>{$blog_title}</a>" ) ?></h2>
751
752
	<p><?php _e( 'But, before you can start using your site, <strong>you must activate it</strong>.' ) ?></p>
753
	<p><?php /* translators: %s: email address */
754
	printf( __( 'Check your inbox at %s and click the link given.' ), '<strong>' . $user_email . '</strong>' ); ?></p>
755
	<p><?php _e( 'If you do not activate your site within two days, you will have to sign up again.' ); ?></p>
756
	<h2><?php _e( 'Still waiting for your email?' ); ?></h2>
757
	<p>
758
		<?php _e( 'If you haven&#8217;t received your email yet, there are a number of things you can do:' ) ?>
759
		<ul id="noemail-tips">
760
			<li><p><strong><?php _e( 'Wait a little longer. Sometimes delivery of email can be delayed by processes outside of our control.' ) ?></strong></p></li>
761
			<li><p><?php _e( 'Check the junk or spam folder of your email client. Sometime emails wind up there by mistake.' ) ?></p></li>
762
			<li><?php
763
				/* translators: %s: email address */
764
				printf( __( 'Have you entered your email correctly? You have entered %s, if it&#8217;s incorrect, you will not receive your email.' ), $user_email );
765
			?></li>
766
		</ul>
767
	</p>
768
	<?php
769
	/** This action is documented in wp-signup.php */
770
	do_action( 'signup_finished' );
771
}
772
773
/**
774
 * Retrieves languages available during the site/user signup process.
775
 *
776
 * @since 4.4.0
777
 *
778
 * @see get_available_languages()
779
 *
780
 * @return array List of available languages.
781
 */
782
function signup_get_available_languages() {
783
	/**
784
	 * Filters the list of available languages for front-end site signups.
785
	 *
786
	 * Passing an empty array to this hook will disable output of the setting on the
787
	 * signup form, and the default language will be used when creating the site.
788
	 *
789
	 * Languages not already installed will be stripped.
790
	 *
791
	 * @since 4.4.0
792
	 *
793
	 * @param array $available_languages Available languages.
794
	 */
795
	$languages = (array) apply_filters( 'signup_get_available_languages', get_available_languages() );
796
797
	/*
798
	 * Strip any non-installed languages and return.
799
	 *
800
	 * Re-call get_available_languages() here in case a language pack was installed
801
	 * in a callback hooked to the 'signup_get_available_languages' filter before this point.
802
	 */
803
	return array_intersect_assoc( $languages, get_available_languages() );
804
}
805
806
// Main
807
$active_signup = get_site_option( 'registration', 'none' );
808
809
/**
810
 * Filters the type of site sign-up.
811
 *
812
 * @since 3.0.0
813
 *
814
 * @param string $active_signup String that returns registration type. The value can be
815
 *                              'all', 'none', 'blog', or 'user'.
816
 */
817
$active_signup = apply_filters( 'wpmu_active_signup', $active_signup );
818
819
if ( current_user_can( 'manage_network' ) ) {
820
	echo '<div class="mu_alert">';
821
	_e( 'Greetings Network Administrator!' );
822
	echo ' ';
823
824
	switch ( $active_signup ) {
825
		case 'none':
826
			_e( 'The network currently disallows registrations.' );
827
			break;
828
		case 'blog':
829
			_e( 'The network currently allows site registrations.' );
830
			break;
831
		case 'user':
832
			_e( 'The network currently allows user registrations.' );
833
			break;
834
		default:
835
			_e( 'The network currently allows both site and user registrations.' );
836
			break;
837
	}
838
839
	echo ' ';
840
841
	/* translators: %s: network settings URL */
842
	printf( __( 'To change or disable registration go to your <a href="%s">Options page</a>.' ), esc_url( network_admin_url( 'settings.php' ) ) );
843
	echo '</div>';
844
}
845
846
$newblogname = isset($_GET['new']) ? strtolower(preg_replace('/^-|-$|[^-a-zA-Z0-9]/', '', $_GET['new'])) : null;
847
848
$current_user = wp_get_current_user();
849
if ( $active_signup == 'none' ) {
850
	_e( 'Registration has been disabled.' );
851
} elseif ( $active_signup == 'blog' && !is_user_logged_in() ) {
852
	$login_url = wp_login_url( network_site_url( 'wp-signup.php' ) );
853
	/* translators: %s: login URL */
854
	printf( __( 'You must first <a href="%s">log in</a>, and then you can create a new site.' ), $login_url );
855
} else {
856
	$stage = isset( $_POST['stage'] ) ?  $_POST['stage'] : 'default';
857
	switch ( $stage ) {
858
		case 'validate-user-signup' :
859
			if ( $active_signup == 'all' || $_POST[ 'signup_for' ] == 'blog' && $active_signup == 'blog' || $_POST[ 'signup_for' ] == 'user' && $active_signup == 'user' )
860
				validate_user_signup();
861
			else
862
				_e( 'User registration has been disabled.' );
863
		break;
864
		case 'validate-blog-signup':
865
			if ( $active_signup == 'all' || $active_signup == 'blog' )
866
				validate_blog_signup();
867
			else
868
				_e( 'Site registration has been disabled.' );
869
			break;
870
		case 'gimmeanotherblog':
871
			validate_another_blog_signup();
872
			break;
873
		case 'default':
874
		default :
875
			$user_email = isset( $_POST[ 'user_email' ] ) ? $_POST[ 'user_email' ] : '';
876
			/**
877
			 * Fires when the site sign-up form is sent.
878
			 *
879
			 * @since 3.0.0
880
			 */
881
			do_action( 'preprocess_signup_form' );
882
			if ( is_user_logged_in() && ( $active_signup == 'all' || $active_signup == 'blog' ) )
883
				signup_another_blog($newblogname);
884
			elseif ( ! is_user_logged_in() && ( $active_signup == 'all' || $active_signup == 'user' ) )
885
				signup_user( $newblogname, $user_email );
886
			elseif ( ! is_user_logged_in() && ( $active_signup == 'blog' ) )
887
				_e( 'Sorry, new registrations are not allowed at this time.' );
888
			else
889
				_e( 'You are logged in already. No need to register again!' );
890
891
			if ( $newblogname ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $newblogname of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
892
				$newblog = get_blogaddress_by_name( $newblogname );
893
894
				if ( $active_signup == 'blog' || $active_signup == 'all' )
895
					/* translators: %s: site address */
896
					printf( '<p><em>' . __( 'The site you were looking for, %s, does not exist, but you can create it now!' ) . '</em></p>',
897
						'<strong>' . $newblog . '</strong>'
898
					);
899
				else
900
					/* translators: %s: site address */
901
					printf( '<p><em>' . __( 'The site you were looking for, %s, does not exist.' ) . '</em></p>',
902
						'<strong>' . $newblog . '</strong>'
903
					);
904
			}
905
			break;
906
	}
907
}
908
?>
909
</div>
910
</div>
911
<?php
912
/**
913
 * Fires after the sign-up forms, before wp_footer.
914
 *
915
 * @since 3.0.0
916
 */
917
do_action( 'after_signup_form' ); ?>
918
919
<?php get_footer( 'wp-signup' );
920