Completed
Push — try/remote-provision ( 47bd35...40c913 )
by
unknown
09:27
created

Jetpack_Provision::partner_provision()   F

Complexity

Conditions 40
Paths > 20000

Size

Total Lines 176
Code Lines 95

Duplication

Lines 24
Ratio 13.64 %

Importance

Changes 0
Metric Value
cc 40
eloc 95
nc 39321600
nop 2
dl 24
loc 176
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
class Jetpack_Provision {
3
	static function partner_provision( $access_token, $named_args ) {
4
		$url_args = array(
5
			'home_url' => 'WP_HOME',
6
			'site_url' => 'WP_SITEURL',
7
		);
8
9
		foreach ( $url_args as $url_arg => $constant_name ) {
10
			// Anonymous functions were introduced in 5.3.0. So, if we're running on
11
			// >= 5.3.0, use an anonymous function to set the home/siteurl value%s.
12
			//
13
			// Otherwise, fallback to setting the home/siteurl value via the WP_HOME and
14
			// WP_SITEURL constants if the constant hasn't already been defined.
15
			if ( isset( $named_args[ $url_arg ] ) ) {
16
				if ( version_compare( phpversion(), '5.3.0', '>=') ) {
17
					add_filter( $url_arg, function( $url ) use ( $url_arg, $named_args ) {
18
						return $named_args[ $url_arg ];
19
					}, 11 );
20
				} else if ( ! defined( $constant_name ) ) {
21
					define( $constant_name, $named_args[ $url_arg ] );
22
				}
23
			}
24
		}
25
26
		$blog_id    = Jetpack_Options::get_option( 'id' );
27
		$blog_token = Jetpack_Options::get_option( 'blog_token' );
28
29
		if ( ! $blog_id || ! $blog_token || ( isset( $named_args['force_register'] ) && intval( $named_args['force_register'] ) ) ) {
30
			// this code mostly copied from Jetpack::admin_page_load
31
			Jetpack::maybe_set_version_option();
32
			$registered = Jetpack::try_registration();
33
			if ( is_wp_error( $registered ) ) {
34
				self::partner_provision_error( $registered );
35
			} elseif ( ! $registered ) {
36
				self::partner_provision_error( new WP_Error( 'registration_error', __( 'There was an unspecified error registering the site', 'jetpack' ) ) );
37
			}
38
39
			$blog_id    = Jetpack_Options::get_option( 'id' );
40
			$blog_token = Jetpack_Options::get_option( 'blog_token' );
0 ignored issues
show
Unused Code introduced by
$blog_token is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
41
		}
42
43
		// if the user isn't specified, but we have a current master user, then set that to current user
44
		if ( ! get_current_user_id() && $master_user_id = Jetpack_Options::get_option( 'master_user' ) ) {
45
			wp_set_current_user( $master_user_id );
46
		}
47
48
		$site_icon = ( function_exists( 'has_site_icon') && has_site_icon() )
49
			? get_site_icon_url()
50
			: false;
51
52
		$auto_enable_sso = ( ! Jetpack::is_active() || Jetpack::is_module_active( 'sso' ) );
53
54
		/** This filter is documented in class.jetpack-cli.php */
55
		if ( apply_filters( 'jetpack_start_enable_sso', $auto_enable_sso ) ) {
56
			$redirect_uri = add_query_arg(
57
				array( 'action' => 'jetpack-sso', 'redirect_to' => urlencode( admin_url() ) ),
58
				wp_login_url() // TODO: come back to Jetpack dashboard?
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
59
			);
60
		} else {
61
			$redirect_uri = admin_url();
62
		}
63
64
		$request_body = array(
65
			'jp_version'    => JETPACK__VERSION,
66
			'redirect_uri'  => $redirect_uri
67
		);
68
69
		if ( $site_icon ) {
70
			$request_body['site_icon'] = $site_icon;
71
		}
72
73
		if ( get_current_user_id() ) {
74
			$user = wp_get_current_user();
75
76
			// role
77
			$role = Jetpack::translate_current_user_to_role();
78
			$signed_role = Jetpack::sign_role( $role );
79
80
			$secrets = Jetpack::init()->generate_secrets( 'authorize' );
81
82
			// Jetpack auth stuff
83
			$request_body['scope']  = $signed_role;
84
			$request_body['secret'] = $secrets['secret_1'];
85
86
			// User stuff
87
			$request_body['user_id']    = $user->ID;
88
			$request_body['user_email'] = $user->user_email;
89
			$request_body['user_login'] = $user->user_login;
90
		}
91
92
		// optional additional params
93 View Code Duplication
		if ( isset( $named_args['wpcom_user_id'] ) && ! empty( $named_args['wpcom_user_id'] ) ) {
94
			$request_body['wpcom_user_id'] = $named_args['wpcom_user_id'];
95
		}
96
97
		// override email of selected user
98 View Code Duplication
		if ( isset( $named_args['wpcom_user_email'] ) && ! empty( $named_args['wpcom_user_email'] ) ) {
99
			$request_body['user_email'] = $named_args['wpcom_user_email'];
100
		}
101
102 View Code Duplication
		if ( isset( $named_args['plan'] ) && ! empty( $named_args['plan'] ) ) {
103
			$request_body['plan'] = $named_args['plan'];
104
		}
105
106 View Code Duplication
		if ( isset( $named_args['onboarding'] ) && ! empty( $named_args['onboarding'] ) ) {
107
			$request_body['onboarding'] = intval( $named_args['onboarding'] );
108
		}
109
110 View Code Duplication
		if ( isset( $named_args['force_connect'] ) && ! empty( $named_args['force_connect'] ) ) {
111
			$request_body['force_connect'] = intval( $named_args['force_connect'] );
112
		}
113
114
		if ( isset( $request_body['onboarding'] ) && (bool) $request_body['onboarding'] ) {
115
			Jetpack::create_onboarding_token();
116
		}
117
118
		$request = array(
119
			'headers' => array(
120
				'Authorization' => "Bearer " . $access_token,
121
				'Host'          => defined( 'JETPACK__WPCOM_JSON_API_HOST_HEADER' ) ? JETPACK__WPCOM_JSON_API_HOST_HEADER : 'public-api.wordpress.com',
122
			),
123
			'timeout' => 60,
124
			'method'  => 'POST',
125
			'body'    => json_encode( $request_body )
126
		);
127
128
		$url = sprintf( 'https://%s/rest/v1.3/jpphp/%d/partner-provision', self::get_api_host(), $blog_id );
129 View Code Duplication
		if ( ! empty( $named_args['partner-tracking-id'] ) ) {
130
			$url = esc_url_raw( add_query_arg( 'partner_tracking_id', $named_args['partner-tracking-id'], $url ) );
131
		}
132
133
		// add calypso env if set
134
		if ( getenv( 'CALYPSO_ENV' ) ) {
135
			$url = add_query_arg( array( 'calypso_env' => getenv( 'CALYPSO_ENV' ) ), $url );
136
		}
137
138
		$result = Jetpack_Client::_wp_remote_request( $url, $request );
139
140
		if ( is_wp_error( $result ) ) {
141
			self::partner_provision_error( $result );
142
		}
143
144
		$response_code = wp_remote_retrieve_response_code( $result );
145
		$body_json     = json_decode( wp_remote_retrieve_body( $result ) );
146
147
		if( 200 !== $response_code ) {
148
			if ( isset( $body_json->error ) ) {
149
				self::partner_provision_error( new WP_Error( $body_json->error, $body_json->message ) );
150
			} else {
151
				self::partner_provision_error( new WP_Error( 'server_error', sprintf( __( "Request failed with code %s" ), $response_code ) ) );
152
			}
153
		}
154
155
		if ( isset( $body_json->access_token ) ) {
156
			// authorize user and enable SSO
157
			Jetpack::update_user_token( $user->ID, sprintf( '%s.%d', $body_json->access_token, $user->ID ), true );
0 ignored issues
show
Bug introduced by
The variable $user 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...
158
159
			/**
160
			 * Auto-enable SSO module for new Jetpack Start connections
161
			 *
162
			 * @since 5.0.0
163
			 *
164
			 * @param bool $enable_sso Whether to enable the SSO module. Default to true.
165
			 */
166
			$other_modules = apply_filters( 'jetpack_start_enable_sso', true )
167
				? array( 'sso' )
168
				: array();
169
170 View Code Duplication
			if ( $active_modules = Jetpack_Options::get_option( 'active_modules' ) ) {
171
				Jetpack::delete_active_modules();
172
				Jetpack::activate_default_modules( 999, 1, array_merge( $active_modules, $other_modules ), false );
0 ignored issues
show
Documentation introduced by
999 is of type integer, but the function expects a boolean.

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...
173
			} else {
174
				Jetpack::activate_default_modules( false, false, $other_modules, false );
175
			}
176
		}
177
		return $body_json;
178
	}
179
180 View Code Duplication
	private static function partner_provision_error( $error ) {
181
		WP_CLI::log( json_encode( array(
182
			'success'       => false,
183
			'error_code'    => $error->get_error_code(),
184
			'error_message' => $error->get_error_message()
185
		) ) );
186
		exit( 1 );
0 ignored issues
show
Coding Style Compatibility introduced by
The method partner_provision_error() 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...
187
	}
188
189
	private static function get_api_host() {
190
		$env_api_host = getenv( 'JETPACK_START_API_HOST', true );
191
		return $env_api_host ? $env_api_host : JETPACK__WPCOM_JSON_API_HOST;
192
	}
193
}
194