Completed
Push — renovate/webpack-cli-3.x ( 961c1b...02322b )
by
unknown
06:55
created

WPCOM_REST_API_V2_Endpoint_Memberships   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 163
Duplicated Lines 11.66 %

Coupling/Cohesion

Components 0
Dependencies 3

Importance

Changes 0
Metric Value
dl 19
loc 163
rs 10
c 0
b 0
f 0
wmc 20
lcom 0
cbo 3

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 7 7 1
A register_routes() 0 42 1
A get_status_permission_check() 0 3 1
B create_product() 6 45 7
B get_status() 6 36 10

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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
			return $product->to_array();
106
		} else {
107
			$blog_id  = Jetpack_Options::get_option( 'id' );
108
			$response = Jetpack_Client::wpcom_json_api_request_as_user(
109
				"/sites/$blog_id/{$this->rest_base}/product",
110
				'v2',
111
				array(
112
					'method' => 'POST',
113
				),
114
				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...
115
					'title'    => $request['title'],
116
					'price'    => $request['price'],
117
					'currency' => $request['currency'],
118
					'interval' => $request['interval'],
119
				)
120
			);
121 View Code Duplication
			if ( is_wp_error( $response ) ) {
122
				if ( $response->get_error_code() === 'missing_token' ) {
123
					return new WP_Error( 'missing_token', __( 'Please connect your user account to WordPress.com', 'jetpack' ), 404 );
124
				}
125
				return new WP_Error( 'wpcom_connection_error', __( 'Could not connect to WordPress.com', 'jetpack' ), 404 );
126
			}
127
			$data = isset( $response['body'] ) ? json_decode( $response['body'], true ) : null;
128
			return $data;
129
		}
130
131
		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...
132
	}
133
134
	/**
135
	 * Get a status of connection for the site. If this is Jetpack, pass the request to wpcom.
136
	 *
137
	 * @return array|WP_Error
138
	 */
139
	public function get_status() {
140
		$connected_account_id = Jetpack_Memberships::get_connected_account_id();
141
		$connect_url          = '';
142
		if ( ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ) {
143
			require_lib( 'memberships' );
144
			$blog_id = get_current_blog_id();
145
			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...
146
				$connect_url = get_memberships_connected_account_redirect( get_current_user_id(), $blog_id );
147
			}
148
			$products = get_memberships_plans( $blog_id );
149
		} else {
150
			$blog_id  = Jetpack_Options::get_option( 'id' );
151
			$response = Jetpack_Client::wpcom_json_api_request_as_user(
152
				"/sites/$blog_id/{$this->rest_base}/status",
153
				'v2',
154
				array(),
155
				null
156
			);
157 View Code Duplication
			if ( is_wp_error( $response ) ) {
158
				if ( $response->get_error_code() === 'missing_token' ) {
159
					return new WP_Error( 'missing_token', __( 'Please connect your user account to WordPress.com', 'jetpack' ), 404 );
160
				}
161
				return new WP_Error( 'wpcom_connection_error', __( 'Could not connect to WordPress.com', 'jetpack' ), 404 );
162
			}
163
			$data = isset( $response['body'] ) ? json_decode( $response['body'], true ) : null;
164
			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...
165
				$connect_url = empty( $data['connect_url'] ) ? '' : $data['connect_url'];
166
			}
167
			$products = empty( $data['products'] ) ? array() : $data['products'];
168
		}
169
		return array(
170
			'connected_account_id' => $connected_account_id,
171
			'connect_url'          => $connect_url,
172
			'products'             => $products,
173
		);
174
	}
175
}
176
177
if ( ( defined( 'IS_WPCOM' ) && IS_WPCOM ) || Jetpack::is_active() ) {
178
	wpcom_rest_api_v2_load_plugin( 'WPCOM_REST_API_V2_Endpoint_Memberships' );
179
}
180
181