Completed
Push — update/simplify-jetpack-build-... ( f269d3...3a2ec1 )
by Bernhard
09:10 queued 58s
created

get_status()   B

Complexity

Conditions 10
Paths 16

Size

Total Lines 36

Duplication

Lines 6
Ratio 16.67 %

Importance

Changes 0
Metric Value
cc 10
nc 16
nop 0
dl 6
loc 36
rs 7.6666
c 0
b 0
f 0

How to fix   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 // phpcs:disable WordPress.Files.FileName.InvalidClassFileName
2
/**
3
 * Memberships: API to communicate with "product" database.
4
 *
5
 * @package    Jetpack
6
 * @since      7.3.0
7
 */
8
9
/**
10
 * Class WPCOM_REST_API_V2_Endpoint_Memberships
11
 * This introduces V2 endpoints.
12
 */
13
class WPCOM_REST_API_V2_Endpoint_Memberships extends WP_REST_Controller {
14
15
	/**
16
	 * WPCOM_REST_API_V2_Endpoint_Memberships constructor.
17
	 */
18 View Code Duplication
	public function __construct() {
19
		$this->namespace                       = 'wpcom/v2';
20
		$this->rest_base                       = 'memberships';
21
		$this->wpcom_is_wpcom_only_endpoint    = true;
22
		$this->wpcom_is_site_specific_endpoint = true;
23
		add_action( 'rest_api_init', array( $this, 'register_routes' ) );
24
	}
25
26
	/**
27
	 * Called automatically on `rest_api_init()`.
28
	 */
29
	public function register_routes() {
30
		register_rest_route(
31
			$this->namespace,
32
			$this->rest_base . '/status',
33
			array(
34
				array(
35
					'methods'             => WP_REST_Server::READABLE,
36
					'callback'            => array( $this, 'get_status' ),
37
					'permission_callback' => array( $this, 'get_status_permission_check' ),
38
				),
39
			)
40
		);
41
		register_rest_route(
42
			$this->namespace,
43
			$this->rest_base . '/product',
44
			array(
45
				array(
46
					'methods'             => WP_REST_Server::CREATABLE,
47
					'callback'            => array( $this, 'create_product' ),
48
					'permission_callback' => array( $this, 'get_status_permission_check' ),
49
					'args'                => array(
50
						'title'    => array(
51
							'type'     => 'string',
52
							'required' => true,
53
						),
54
						'price'    => array(
55
							'type'     => 'float',
56
							'required' => true,
57
						),
58
						'currency' => array(
59
							'type'     => 'string',
60
							'required' => true,
61
						),
62
						'interval' => array(
63
							'type'     => 'string',
64
							'required' => true,
65
						),
66
					),
67
				),
68
			)
69
		);
70
	}
71
72
	/**
73
	 * Ensure the user has proper permissions
74
	 *
75
	 * @return boolean
76
	 */
77
	public function get_status_permission_check() {
78
		return current_user_can( 'edit_posts' );
79
	}
80
81
	/**
82
	 * Do create a product based on data, or pass request to wpcom.
83
	 *
84
	 * @param object $request - request passed from WP.
85
	 *
86
	 * @return array|WP_Error
87
	 */
88
	public function create_product( $request ) {
89
		if ( ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ) {
90
			require_lib( 'memberships' );
91
			$connected_destination_account_id = Jetpack_Memberships::get_connected_account_id();
92
			if ( ! $connected_destination_account_id ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $connected_destination_account_id of type integer|null is loosely compared to false; this is ambiguous if the integer can be zero. 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 integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
93
				return new WP_Error( 'no-destination-account', __( 'Please set up a Stripe account for this site first', 'jetpack' ) );
94
			}
95
			$product = Memberships_Product::create(
96
				get_current_blog_id(),
97
				array(
98
					'title'                            => $request['title'],
99
					'price'                            => $request['price'],
100
					'currency'                         => $request['currency'],
101
					'interval'                         => $request['interval'],
102
					'connected_destination_account_id' => $connected_destination_account_id,
103
				)
104
			);
105
			if ( is_wp_error( $product ) ) {
106
				return new WP_Error( $product->get_error_code(), __( 'Creating product has failed.', 'jetpack' ) );
107
			}
108
			return $product->to_array();
109
		} else {
110
			$blog_id  = Jetpack_Options::get_option( 'id' );
111
			$response = Jetpack_Client::wpcom_json_api_request_as_user(
112
				"/sites/$blog_id/{$this->rest_base}/product",
113
				'v2',
114
				array(
115
					'method' => 'POST',
116
				),
117
				array(
0 ignored issues
show
Documentation introduced by
array('title' => $reques...> $request['interval']) is of type array<string,?,{"title":...y":"?","interval":"?"}>, but the function expects a string|null.

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...
118
					'title'    => $request['title'],
119
					'price'    => $request['price'],
120
					'currency' => $request['currency'],
121
					'interval' => $request['interval'],
122
				)
123
			);
124 View Code Duplication
			if ( is_wp_error( $response ) ) {
125
				if ( $response->get_error_code() === 'missing_token' ) {
126
					return new WP_Error( 'missing_token', __( 'Please connect your user account to WordPress.com', 'jetpack' ), 404 );
127
				}
128
				return new WP_Error( 'wpcom_connection_error', __( 'Could not connect to WordPress.com', 'jetpack' ), 404 );
129
			}
130
			$data = isset( $response['body'] ) ? json_decode( $response['body'], true ) : null;
131
			// If endpoint returned error, we have to detect it.
132
			if ( 200 !== $response['response']['code'] && $data['code'] && $data['message'] ) {
133
				return new WP_Error( $data['code'], $data['message'], 401 );
134
			}
135
			return $data;
136
		}
137
138
		return $request;
0 ignored issues
show
Unused Code introduced by
return $request; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
139
	}
140
141
	/**
142
	 * Get a status of connection for the site. If this is Jetpack, pass the request to wpcom.
143
	 *
144
	 * @return array|WP_Error
145
	 */
146
	public function get_status() {
147
		$connected_account_id = Jetpack_Memberships::get_connected_account_id();
148
		$connect_url          = '';
149
		if ( ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ) {
150
			require_lib( 'memberships' );
151
			$blog_id = get_current_blog_id();
152
			if ( ! $connected_account_id ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $connected_account_id of type integer|null is loosely compared to false; this is ambiguous if the integer can be zero. 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 integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
153
				$connect_url = get_memberships_connected_account_redirect( get_current_user_id(), $blog_id );
154
			}
155
			$products = get_memberships_plans( $blog_id );
156
		} else {
157
			$blog_id  = Jetpack_Options::get_option( 'id' );
158
			$response = Jetpack_Client::wpcom_json_api_request_as_user(
159
				"/sites/$blog_id/{$this->rest_base}/status",
160
				'v2',
161
				array(),
162
				null
163
			);
164 View Code Duplication
			if ( is_wp_error( $response ) ) {
165
				if ( $response->get_error_code() === 'missing_token' ) {
166
					return new WP_Error( 'missing_token', __( 'Please connect your user account to WordPress.com', 'jetpack' ), 404 );
167
				}
168
				return new WP_Error( 'wpcom_connection_error', __( 'Could not connect to WordPress.com', 'jetpack' ), 404 );
169
			}
170
			$data = isset( $response['body'] ) ? json_decode( $response['body'], true ) : null;
171
			if ( ! $connected_account_id ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $connected_account_id of type integer|null is loosely compared to false; this is ambiguous if the integer can be zero. 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 integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
172
				$connect_url = empty( $data['connect_url'] ) ? '' : $data['connect_url'];
173
			}
174
			$products = empty( $data['products'] ) ? array() : $data['products'];
175
		}
176
		return array(
177
			'connected_account_id' => $connected_account_id,
178
			'connect_url'          => $connect_url,
179
			'products'             => $products,
180
		);
181
	}
182
}
183
184
if ( ( defined( 'IS_WPCOM' ) && IS_WPCOM ) || Jetpack::is_active() ) {
185
	wpcom_rest_api_v2_load_plugin( 'WPCOM_REST_API_V2_Endpoint_Memberships' );
186
}
187
188