Completed
Push — renovate/wordpress-monorepo ( 8cdadc...6203b6 )
by
unknown
552:54 queued 542:45
created

Jetpack_XMLRPC_Methods::json_api()   F

Complexity

Conditions 17
Paths 292

Size

Total Lines 91

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
nc 292
nop 1
dl 0
loc 91
rs 2.783
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
/**
3
 * Jetpack XMLRPC Methods.
4
 *
5
 * Registers the Jetpack specific XMLRPC methods
6
 *
7
 * @package jetpack
8
 */
9
10
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
11
use Automattic\Jetpack\Connection\Tokens;
12
13
/**
14
 * XMLRPC Methods registration and callbacks
15
 */
16
class Jetpack_XMLRPC_Methods {
17
18
	/**
19
	 * Initialize the main hooks.
20
	 */
21
	public static function init() {
22
		add_filter( 'jetpack_xmlrpc_unauthenticated_methods', array( __CLASS__, 'xmlrpc_methods' ) );
23
		add_filter( 'jetpack_xmlrpc_test_connection_response', array( __CLASS__, 'test_connection' ) );
24
	}
25
26
	/**
27
	 * Adds Jetpack specific methods to the methods added by the Connection package.
28
	 *
29
	 * @param array $methods Methods added by the Connection package.
30
	 */
31
	public static function xmlrpc_methods( $methods ) {
32
33
		$methods['jetpack.featuresAvailable'] = array( __CLASS__, 'features_available' );
34
		$methods['jetpack.featuresEnabled']   = array( __CLASS__, 'features_enabled' );
35
		$methods['jetpack.disconnectBlog']    = array( __CLASS__, 'disconnect_blog' );
36
		$methods['jetpack.jsonAPI']           = array( __CLASS__, 'json_api' );
37
38
		return $methods;
39
	}
40
41
	/**
42
	 * Returns what features are available. Uses the slug of the module files.
43
	 *
44
	 * @return array
45
	 */
46 View Code Duplication
	public static function features_available() {
47
		$raw_modules = Jetpack::get_available_modules();
48
		$modules     = array();
49
		foreach ( $raw_modules as $module ) {
50
			$modules[] = Jetpack::get_module_slug( $module );
51
		}
52
53
		return $modules;
54
	}
55
56
	/**
57
	 * Returns what features are enabled. Uses the slug of the modules files.
58
	 *
59
	 * @return array
60
	 */
61 View Code Duplication
	public static function features_enabled() {
62
		$raw_modules = Jetpack::get_active_modules();
63
		$modules     = array();
64
		foreach ( $raw_modules as $module ) {
65
			$modules[] = Jetpack::get_module_slug( $module );
66
		}
67
68
		return $modules;
69
	}
70
71
	/**
72
	 * Filters the result of test_connection XMLRPC method
73
	 *
74
	 * @return string The current Jetpack version number
75
	 */
76
	public static function test_connection() {
77
		return JETPACK__VERSION;
78
	}
79
80
	/**
81
	 * Disconnect this blog from the connected wordpress.com account
82
	 *
83
	 * @return boolean
84
	 */
85
	public static function disconnect_blog() {
86
87
		/**
88
		 * Fired when we want to log an event to the Jetpack event log.
89
		 *
90
		 * @since 7.7.0
91
		 *
92
		 * @param string $code Unique name for the event.
93
		 * @param string $data Optional data about the event.
94
		 */
95
		do_action( 'jetpack_event_log', 'disconnect' );
96
		Jetpack::disconnect();
97
98
		return true;
99
	}
100
101
	/**
102
	 * Serve a JSON API request.
103
	 *
104
	 * @param array $args request arguments.
105
	 */
106
	public static function json_api( $args = array() ) {
107
		$json_api_args        = $args[0];
108
		$verify_api_user_args = $args[1];
109
110
		$method       = (string) $json_api_args[0];
111
		$url          = (string) $json_api_args[1];
112
		$post_body    = is_null( $json_api_args[2] ) ? null : (string) $json_api_args[2];
113
		$user_details = (array) $json_api_args[4];
114
		$locale       = (string) $json_api_args[5];
115
116
		if ( ! $verify_api_user_args ) {
117
			$user_id = 0;
118
		} elseif ( 'internal' === $verify_api_user_args[0] ) {
119
			$user_id = (int) $verify_api_user_args[1];
120
			if ( $user_id ) {
121
				$user = get_user_by( 'id', $user_id );
122
				if ( ! $user || is_wp_error( $user ) ) {
123
					return false;
124
				}
125
			}
126
		} else {
127
			$user_id = call_user_func( array( new Jetpack_XMLRPC_Server(), 'test_api_user_code' ), $verify_api_user_args );
128
			if ( ! $user_id ) {
129
				return false;
130
			}
131
		}
132
133
		if ( 'en' !== $locale ) {
134
			// .org mo files are named slightly different from .com, and all we have is this the locale -- try to guess them.
135
			$new_locale = $locale;
136
			if ( strpos( $locale, '-' ) !== false ) {
137
				$locale_pieces = explode( '-', $locale );
138
				$new_locale    = $locale_pieces[0];
139
				$new_locale   .= ( ! empty( $locale_pieces[1] ) ) ? '_' . strtoupper( $locale_pieces[1] ) : '';
140
			} else {
141
				// .com might pass 'fr' because thats what our language files are named as, where core seems
142
				// to do fr_FR - so try that if we don't think we can load the file.
143
				if ( ! file_exists( WP_LANG_DIR . '/' . $locale . '.mo' ) ) {
144
					$new_locale = $locale . '_' . strtoupper( $locale );
145
				}
146
			}
147
148
			if ( file_exists( WP_LANG_DIR . '/' . $new_locale . '.mo' ) ) {
149
				unload_textdomain( 'default' );
150
				load_textdomain( 'default', WP_LANG_DIR . '/' . $new_locale . '.mo' );
151
			}
152
		}
153
154
		$old_user = wp_get_current_user();
155
		wp_set_current_user( $user_id );
156
157
		if ( $user_id ) {
158
			$token_key = false;
159
		} else {
160
			$verified  = ( new Connection_Manager() )->verify_xml_rpc_signature();
161
			$token_key = $verified['token_key'];
162
		}
163
164
		$token = ( new Tokens() )->get_access_token( $user_id, $token_key );
165
		if ( ! $token || is_wp_error( $token ) ) {
166
			return false;
167
		}
168
169
		define( 'REST_API_REQUEST', true );
170
		define( 'WPCOM_JSON_API__BASE', 'public-api.wordpress.com/rest/v1' );
171
172
		// needed?
173
		require_once ABSPATH . 'wp-admin/includes/admin.php';
174
175
		require_once JETPACK__PLUGIN_DIR . 'class.json-api.php';
176
		$api                        = WPCOM_JSON_API::init( $method, $url, $post_body );
177
		$api->token_details['user'] = $user_details;
178
		require_once JETPACK__PLUGIN_DIR . 'class.json-api-endpoints.php';
179
180
		$display_errors = ini_set( 'display_errors', 0 ); // phpcs:ignore WordPress.PHP.IniSet
181
		ob_start();
182
		$api->serve( false );
183
		$output = ob_get_clean();
184
		ini_set( 'display_errors', $display_errors ); // phpcs:ignore WordPress.PHP.IniSet
185
186
		$nonce = wp_generate_password( 10, false );
187
		$hmac  = hash_hmac( 'md5', $nonce . $output, $token->secret );
188
189
		wp_set_current_user( isset( $old_user->ID ) ? $old_user->ID : 0 );
190
191
		return array(
192
			(string) $output,
193
			(string) $nonce,
194
			(string) $hmac,
195
		);
196
	}
197
}
198