Completed
Push — renovate/node-12.x ( 02b777...439792 )
by
unknown
45:19 queued 36:16
created

Jetpack_Keyring_Service_Helper::add_sharing_menu()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 3
nop 0
dl 0
loc 20
rs 9.6
c 0
b 0
f 0
1
<?php
2
3
use Automattic\Jetpack\Connection\Secrets;
4
5
class Jetpack_Keyring_Service_Helper {
6
	/**
7
	 * @var Jetpack_Keyring_Service_Helper
8
	 **/
9
	private static $instance = null;
10
11
	/**
12
	 * Whether the `sharing` page is registered.
13
	 *
14
	 * @var bool
15
	 */
16
	private static $is_sharing_page_registered = false;
17
18
	static function init() {
19
		if ( is_null( self::$instance ) ) {
20
			self::$instance = new Jetpack_Keyring_Service_Helper;
21
		}
22
23
		return self::$instance;
24
	}
25
26
	public static $SERVICES = array(
27
		'facebook' => array(
28
			'for' => 'publicize'
29
		),
30
		'twitter' => array(
31
			'for' => 'publicize'
32
		),
33
		'linkedin' => array(
34
			'for' => 'publicize'
35
		),
36
		'tumblr' => array(
37
			'for' => 'publicize'
38
		),
39
		'path' => array(
40
			'for' => 'publicize'
41
		),
42
		'google_plus' => array(
43
			'for' => 'publicize'
44
		),
45
		'google_site_verification' => array(
46
			'for' => 'other'
47
		)
48
	);
49
50
	/**
51
	 * Constructor
52
	 */
53
	private function __construct() {
54
		add_action( 'admin_menu', array( __CLASS__, 'register_sharing_page' ) );
55
56
		add_action( 'load-settings_page_sharing', array( __CLASS__, 'admin_page_load' ), 9 );
57
	}
58
59
	/**
60
	 * We need a `sharing` page to be able to connect and disconnect services.
61
	 */
62
	public static function register_sharing_page() {
63
		if ( self::$is_sharing_page_registered ) {
64
			return;
65
		}
66
67
		self::$is_sharing_page_registered = true;
68
69
		if ( ! current_user_can( 'manage_options' ) ) {
70
			return;
71
		}
72
73
		global $_registered_pages;
74
75
		require_once ABSPATH . 'wp-admin/includes/plugin.php';
76
77
		$hookname = get_plugin_page_hookname( 'sharing', 'options-general.php' );
78
		add_action( $hookname, array( __CLASS__, 'admin_page_load' ) );
79
		$_registered_pages[ $hookname ] = true; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
80
	}
81
82
	function get_services( $filter = 'all' ) {
83
		$services = array();
84
85 View Code Duplication
		if ( 'all' === $filter ) {
86
			return $services;
87
		} else {
88
			$connected_services = array();
89
			foreach ( $services as $service => $empty ) {
90
				$connections = $this->get_connections( $service );
0 ignored issues
show
Bug introduced by
The method get_connections() does not seem to exist on object<Jetpack_Keyring_Service_Helper>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
91
				if ( $connections ) {
92
					$connected_services[ $service ] = $connections;
93
				}
94
			}
95
			return $connected_services;
96
		}
97
	}
98
99
	/**
100
	 * Gets a URL to the public-api actions. Works like WP's admin_url
101
	 *
102
	 * @param string $service Shortname of a specific service.
103
	 *
104
	 * @return URL to specific public-api process
105
	 */
106
	// on WordPress.com this is/calls Keyring::admin_url
107
	static function api_url( $service = false, $params = array() ) {
108
		/**
109
		 * Filters the API URL used to interact with WordPress.com.
110
		 *
111
		 * @since 2.0.0
112
		 *
113
		 * @param string https://public-api.wordpress.com/connect/?jetpack=publicize Default Publicize API URL.
114
		 */
115
		$url = apply_filters( 'publicize_api_url', 'https://public-api.wordpress.com/connect/?jetpack=publicize' );
116
117
		if ( $service ) {
118
			$url = add_query_arg( array( 'service' => $service ), $url );
119
		}
120
121
		if ( count( $params ) ) {
122
			$url = add_query_arg( $params, $url );
123
		}
124
125
		return $url;
126
	}
127
128 View Code Duplication
	static function connect_url( $service_name, $for ) {
129
		return add_query_arg(
130
			array(
131
				'action'   => 'request',
132
				'service'  => $service_name,
133
				'kr_nonce' => wp_create_nonce( 'keyring-request' ),
134
				'nonce'    => wp_create_nonce( "keyring-request-$service_name" ),
135
				'for'      => $for,
136
			),
137
			admin_url( 'options-general.php?page=sharing' )
138
		);
139
	}
140
141 View Code Duplication
	static function refresh_url( $service_name, $for ) {
142
		return add_query_arg(
143
			array(
144
				'action'   => 'request',
145
				'service'  => $service_name,
146
				'kr_nonce' => wp_create_nonce( 'keyring-request' ),
147
				'refresh'  => 1,
148
				'for'      => $for,
149
				'nonce'    => wp_create_nonce( "keyring-request-$service_name" ),
150
			),
151
			admin_url( 'options-general.php?page=sharing' )
152
		);
153
	}
154
155 View Code Duplication
	static function disconnect_url( $service_name, $id ) {
156
		return add_query_arg(
157
			array(
158
				'action'   => 'delete',
159
				'service'  => $service_name,
160
				'id'       => $id,
161
				'kr_nonce' => wp_create_nonce( 'keyring-request' ),
162
				'nonce'    => wp_create_nonce( "keyring-request-$service_name" ),
163
			),
164
			admin_url( 'options-general.php?page=sharing' )
165
		);
166
	}
167
168
	static function admin_page_load() {
169
		if ( isset( $_GET['action'] ) ) {
170
			if ( isset( $_GET['service'] ) ) {
171
				$service_name = $_GET['service'];
172
			}
173
174
			switch ( $_GET['action'] ) {
175
176
				case 'request':
177
					check_admin_referer( 'keyring-request', 'kr_nonce' );
178
					check_admin_referer( "keyring-request-$service_name", 'nonce' );
0 ignored issues
show
Bug introduced by
The variable $service_name 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...
179
180
					$verification = ( new Secrets() )->generate( 'publicize' );
181
					if ( ! $verification ) {
182
						$url = Jetpack::admin_url( 'jetpack#/settings' );
183
						wp_die( sprintf( __( "Jetpack is not connected. Please connect Jetpack by visiting <a href='%s'>Settings</a>.", 'jetpack' ), $url ) );
184
185
					}
186
					$stats_options = get_option( 'stats_options' );
187
					$wpcom_blog_id = Jetpack_Options::get_option( 'id' );
188
					$wpcom_blog_id = ! empty( $wpcom_blog_id ) ? $wpcom_blog_id : $stats_options['blog_id'];
189
190
					$user     = wp_get_current_user();
191
					$redirect = Jetpack_Keyring_Service_Helper::api_url( $service_name, urlencode_deep( array(
192
						'action'       => 'request',
193
						'redirect_uri' => add_query_arg( array( 'action' => 'done' ), menu_page_url( 'sharing', false ) ),
194
						'for'          => 'publicize',
195
						// required flag that says this connection is intended for publicize
196
						'siteurl'      => site_url(),
197
						'state'        => $user->ID,
198
						'blog_id'      => $wpcom_blog_id,
199
						'secret_1'     => $verification['secret_1'],
200
						'secret_2'     => $verification['secret_2'],
201
						'eol'          => $verification['exp'],
202
					) ) );
203
					wp_redirect( $redirect );
204
					exit;
205
					break;
0 ignored issues
show
Unused Code introduced by
break; 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...
206
207
				case 'completed':
208
					$xml = new Jetpack_IXR_Client();
209
					$xml->query( 'jetpack.fetchPublicizeConnections' );
210
211
					if ( ! $xml->isError() ) {
212
						$response = $xml->getResponse();
213
						Jetpack_Options::update_option( 'publicize_connections', $response );
214
					}
215
216
					break;
217
218
				case 'delete':
219
					$id = $_GET['id'];
220
221
					check_admin_referer( 'keyring-request', 'kr_nonce' );
222
					check_admin_referer( "keyring-request-$service_name", 'nonce' );
223
224
					Jetpack_Keyring_Service_Helper::disconnect( $service_name, $id );
225
226
					do_action( 'connection_disconnected', $service_name );
227
					break;
228
			}
229
		}
230
	}
231
232
	/**
233
	 * Remove a Publicize connection
234
	 */
235
	static function disconnect( $service_name, $connection_id, $_blog_id = false, $_user_id = false, $force_delete = false ) {
236
		$xml = new Jetpack_IXR_Client();
237
		$xml->query( 'jetpack.deletePublicizeConnection', $connection_id );
238
239
		if ( ! $xml->isError() ) {
240
			Jetpack_Options::update_option( 'publicize_connections', $xml->getResponse() );
241
		} else {
242
			return false;
243
		}
244
	}
245
246
}
247