Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
37.16% |
68 / 183 |
|
16.67% |
5 / 30 |
CRAP | |
0.00% |
0 / 1 |
| Publicize | |
37.16% |
68 / 183 |
|
16.67% |
5 / 30 |
2286.78 | |
0.00% |
0 / 1 |
| __construct | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
| add_disconnect_notice | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| force_user_connection | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
| admin_page_warning | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
| admin_page_load | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
| display_connection_error | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
| disconnect | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| receive_updated_publicize_connections | |
75.00% |
6 / 8 |
|
0.00% |
0 / 1 |
2.06 | |||
| filter_usable_connections | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
7 | |||
| register_update_publicize_connections_xmlrpc_method | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
| get_all_connections | |
71.43% |
5 / 7 |
|
0.00% |
0 / 1 |
3.21 | |||
| get_connections | |
90.91% |
10 / 11 |
|
0.00% |
0 / 1 |
8.05 | |||
| get_all_connections_for_user | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
110 | |||
| add_connection_test_results | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
30 | |||
| get_connection_for_user | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
| get_connection_id | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| get_connection_unique_id | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| get_connection_meta | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
| display_disconnected | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
| globalization | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
20 | |||
| globalize_connection | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
| unglobalize_connection | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
| refresh_connections | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
20 | |||
| clear_connections_transient | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| connect_url | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| refresh_url | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| disconnect_url | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| get_services | |
94.74% |
18 / 19 |
|
0.00% |
0 / 1 |
4.00 | |||
| get_connection | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| flag_post_for_publicize | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
6 | |||
| test_connection | |
0.00% |
0 / 24 |
|
0.00% |
0 / 1 |
42 | |||
| post_is_done_sharing | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
| save_publicized | |
80.00% |
4 / 5 |
|
0.00% |
0 / 1 |
4.13 | |||
| set_post_flags | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
20 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * Publicize class. |
| 4 | * |
| 5 | * @package automattic/jetpack-publicize |
| 6 | */ |
| 7 | |
| 8 | namespace Automattic\Jetpack\Publicize; |
| 9 | |
| 10 | use Automattic\Jetpack\Connection\Client; |
| 11 | use Jetpack_IXR_Client; |
| 12 | use Jetpack_Options; |
| 13 | use WP_Error; |
| 14 | use WP_Post; |
| 15 | |
| 16 | /** |
| 17 | * Extend the base class with Jetpack-specific functionality. |
| 18 | */ |
| 19 | class Publicize extends Publicize_Base { |
| 20 | |
| 21 | const JETPACK_SOCIAL_CONNECTIONS_TRANSIENT = 'jetpack_social_connections'; |
| 22 | |
| 23 | /** |
| 24 | * Transitory storage of connection testing results. |
| 25 | * |
| 26 | * @var array |
| 27 | */ |
| 28 | private $test_connection_results = array(); |
| 29 | |
| 30 | /** |
| 31 | * Property to store the results of fetching the connections. |
| 32 | * |
| 33 | * @var null|array |
| 34 | */ |
| 35 | private $current_connections = null; |
| 36 | |
| 37 | /** |
| 38 | * Add hooks. |
| 39 | */ |
| 40 | public function __construct() { |
| 41 | parent::__construct(); |
| 42 | |
| 43 | add_filter( 'jetpack_xmlrpc_unauthenticated_methods', array( $this, 'register_update_publicize_connections_xmlrpc_method' ) ); |
| 44 | |
| 45 | add_filter( 'jetpack_published_post_flags', array( $this, 'set_post_flags' ), 10, 2 ); |
| 46 | |
| 47 | add_action( 'wp_insert_post', array( $this, 'save_publicized' ), 11, 2 ); |
| 48 | |
| 49 | add_action( 'connection_disconnected', array( $this, 'add_disconnect_notice' ) ); |
| 50 | } |
| 51 | |
| 52 | /** |
| 53 | * Add a notice when a connection has been disconnected. |
| 54 | */ |
| 55 | public function add_disconnect_notice() { |
| 56 | add_action( 'admin_notices', array( $this, 'display_disconnected' ) ); |
| 57 | } |
| 58 | |
| 59 | /** |
| 60 | * Force user connection before showing the Publicize UI. |
| 61 | * |
| 62 | * @deprecated 0.88.0 Settings > Sharing no longer hosts the Publicize UI. |
| 63 | * |
| 64 | * @return void |
| 65 | */ |
| 66 | public function force_user_connection() { |
| 67 | _deprecated_function( __METHOD__, 'publicize-0.88.0' ); |
| 68 | } |
| 69 | |
| 70 | /** |
| 71 | * Show a warning when Publicize does not have a connection. |
| 72 | * |
| 73 | * @deprecated 0.88.0 Settings > Sharing no longer hosts the Publicize UI. |
| 74 | * |
| 75 | * @return void |
| 76 | */ |
| 77 | public function admin_page_warning() { |
| 78 | _deprecated_function( __METHOD__, 'publicize-0.88.0' ); |
| 79 | } |
| 80 | |
| 81 | /** |
| 82 | * Show error on settings page if applicable. |
| 83 | * |
| 84 | * @deprecated 0.88.0 Settings > Sharing no longer hosts connection errors. |
| 85 | * |
| 86 | * @return void |
| 87 | */ |
| 88 | public function admin_page_load() { |
| 89 | _deprecated_function( __METHOD__, 'publicize-0.88.0' ); |
| 90 | } |
| 91 | |
| 92 | /** |
| 93 | * Display an error message. |
| 94 | * |
| 95 | * @deprecated 0.88.0 Settings > Sharing no longer hosts connection errors. |
| 96 | * |
| 97 | * @return void |
| 98 | */ |
| 99 | public function display_connection_error() { |
| 100 | _deprecated_function( __METHOD__, 'publicize-0.88.0' ); |
| 101 | } |
| 102 | |
| 103 | /** |
| 104 | * Remove a Publicize Connection. |
| 105 | * |
| 106 | * @param string $service_name 'facebook', 'twitter', etc. |
| 107 | * @param string $connection_id Connection ID. |
| 108 | * @param false|int $_blog_id The blog ID. Use false (default) for the current blog. |
| 109 | * @param false|int $_user_id The user ID. Use false (default) for the current user. |
| 110 | * @param bool $force_delete Whether to skip permissions checks. |
| 111 | * @return false|void False on failure. Void on success. |
| 112 | */ |
| 113 | public function disconnect( $service_name, $connection_id, $_blog_id = false, $_user_id = false, $force_delete = false ) { |
| 114 | return Keyring_Helper::disconnect( $service_name, $connection_id, $_blog_id, $_user_id, $force_delete ); |
| 115 | } |
| 116 | |
| 117 | /** |
| 118 | * Set updated Publicize connections in a transient. |
| 119 | * |
| 120 | * @param mixed $publicize_connections Updated connections. |
| 121 | * @return true |
| 122 | */ |
| 123 | public function receive_updated_publicize_connections( $publicize_connections ) { |
| 124 | |
| 125 | $publicize_connections = self::filter_usable_connections( $publicize_connections ); |
| 126 | |
| 127 | // Populate the cache with the new data. |
| 128 | Connections::get_all( array( 'ignore_cache' => true ) ); |
| 129 | |
| 130 | $expiry = 3600 * 4; |
| 131 | if ( ! set_transient( self::JETPACK_SOCIAL_CONNECTIONS_TRANSIENT, $publicize_connections, $expiry ) ) { |
| 132 | // If the transient has beeen set in another request, the call to set_transient can fail. If so, |
| 133 | // we can delete the transient and try again. |
| 134 | $this->clear_connections_transient(); |
| 135 | set_transient( self::JETPACK_SOCIAL_CONNECTIONS_TRANSIENT, $publicize_connections, $expiry ); |
| 136 | } |
| 137 | // Regardless of whether the transient is set ok, let's set and use the local property for this request. |
| 138 | $this->current_connections = $publicize_connections; |
| 139 | return true; |
| 140 | } |
| 141 | |
| 142 | /** |
| 143 | * Drop connections we cannot attribute to a user. |
| 144 | * |
| 145 | * A missing user ID reads as "shared with everyone" in is_global_connection(), so such a |
| 146 | * connection would be exposed to every user on the site. User ID 0 is a genuine shared |
| 147 | * connection and is kept; unknown fields pass through, as WPCOM adds to this payload. |
| 148 | * |
| 149 | * @param mixed $publicize_connections Connections, keyed by service name. |
| 150 | * @return array |
| 151 | */ |
| 152 | private static function filter_usable_connections( $publicize_connections ) { |
| 153 | // An empty payload is valid - it means the site has no connections left. |
| 154 | if ( ! is_array( $publicize_connections ) ) { |
| 155 | return array(); |
| 156 | } |
| 157 | |
| 158 | $usable_connections = array(); |
| 159 | |
| 160 | foreach ( $publicize_connections as $service_name => $connections_for_service ) { |
| 161 | if ( ! is_array( $connections_for_service ) ) { |
| 162 | continue; |
| 163 | } |
| 164 | |
| 165 | foreach ( $connections_for_service as $id => $connection ) { |
| 166 | if ( ! isset( $connection['connection_data']['user_id'] ) || ! is_numeric( $connection['connection_data']['user_id'] ) ) { |
| 167 | continue; |
| 168 | } |
| 169 | |
| 170 | $usable_connections[ $service_name ][ $id ] = $connection; |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | return $usable_connections; |
| 175 | } |
| 176 | |
| 177 | /** |
| 178 | * Add method to update Publicize connections. |
| 179 | * |
| 180 | * @todo Kept as a fallback for the jetpack/v4/publicize/connections/sync REST endpoint that replaced it; remove after a few releases (CONNECT-446). |
| 181 | * |
| 182 | * @param array $methods Array of registered methods. |
| 183 | * @return array |
| 184 | */ |
| 185 | public function register_update_publicize_connections_xmlrpc_method( $methods ) { |
| 186 | return array_merge( |
| 187 | $methods, |
| 188 | array( |
| 189 | 'jetpack.updatePublicizeConnections' => array( $this, 'receive_updated_publicize_connections' ), |
| 190 | ) |
| 191 | ); |
| 192 | } |
| 193 | |
| 194 | /** |
| 195 | * Get a list of all connections. |
| 196 | * |
| 197 | * Google Plus is no longer a functional service, so we remove it from the list. |
| 198 | * |
| 199 | * @return array |
| 200 | */ |
| 201 | public function get_all_connections() { |
| 202 | $this->refresh_connections(); |
| 203 | |
| 204 | $connections = $this->current_connections; |
| 205 | |
| 206 | if ( empty( $connections ) ) { |
| 207 | $connections = array(); |
| 208 | } |
| 209 | |
| 210 | if ( isset( $connections['google_plus'] ) ) { |
| 211 | unset( $connections['google_plus'] ); |
| 212 | } |
| 213 | return $connections; |
| 214 | } |
| 215 | |
| 216 | /** |
| 217 | * Get connections for a specific service. |
| 218 | * |
| 219 | * @param string $service_name 'facebook', 'twitter', etc. |
| 220 | * @param false|int $_blog_id The blog ID. Use false (default) for the current blog. |
| 221 | * @param false|int $_user_id The user ID. Use false (default) for the current user. |
| 222 | * @return false|object[]|array[] |
| 223 | */ |
| 224 | public function get_connections( $service_name, $_blog_id = false, $_user_id = false ) { |
| 225 | if ( false === $_user_id ) { |
| 226 | $_user_id = $this->user_id(); |
| 227 | } |
| 228 | |
| 229 | $connections = $this->get_all_connections(); |
| 230 | $connections_to_return = array(); |
| 231 | |
| 232 | if ( ! empty( $connections ) && is_array( $connections ) ) { |
| 233 | if ( ! empty( $connections[ $service_name ] ) ) { |
| 234 | foreach ( $connections[ $service_name ] as $id => $connection ) { |
| 235 | if ( $this->is_global_connection( $connection ) || $_user_id === (int) $connection['connection_data']['user_id'] ) { |
| 236 | $connections_to_return[ $id ] = $connection; |
| 237 | } |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | return $connections_to_return; |
| 242 | } |
| 243 | |
| 244 | return false; |
| 245 | } |
| 246 | |
| 247 | /** |
| 248 | * Get all connections for a specific user. |
| 249 | * |
| 250 | * @param array $args Arguments to run operations such as force refresh and connection test results. |
| 251 | * @return array |
| 252 | */ |
| 253 | public function get_all_connections_for_user( $args = array() ) { |
| 254 | if ( ( isset( $args['clear_cache'] ) && $args['clear_cache'] ) |
| 255 | || ( isset( $args['test_connections'] ) && $args['test_connections'] ) ) { |
| 256 | $this->clear_connections_transient(); |
| 257 | } |
| 258 | $connections = $this->get_all_connections(); |
| 259 | |
| 260 | $connections_to_return = array(); |
| 261 | if ( ! empty( $connections ) ) { |
| 262 | foreach ( (array) $connections as $service_name => $connections_for_service ) { |
| 263 | foreach ( $connections_for_service as $id => $connection ) { |
| 264 | $user_id = (int) $connection['connection_data']['user_id']; |
| 265 | if ( $user_id === 0 || $this->user_id() === $user_id ) { |
| 266 | $connections_to_return[ $service_name ][ $id ] = $connection; |
| 267 | } |
| 268 | } |
| 269 | } |
| 270 | } |
| 271 | |
| 272 | return $connections_to_return; |
| 273 | } |
| 274 | |
| 275 | /** |
| 276 | * To add the connection test results to the connections. |
| 277 | * |
| 278 | * @param array $connections The Jetpack Social connections. |
| 279 | |
| 280 | * @return array |
| 281 | */ |
| 282 | public function add_connection_test_results( $connections ) { |
| 283 | $path = sprintf( '/sites/%d/publicize/connection-test-results', absint( Jetpack_Options::get_option( 'id' ) ) ); |
| 284 | $response = Client::wpcom_json_api_request_as_user( $path, '2', array(), null, 'wpcom' ); |
| 285 | $connection_results = json_decode( wp_remote_retrieve_body( $response ), true ); |
| 286 | $connection_results_map = array(); |
| 287 | |
| 288 | foreach ( $connection_results as $connection_result ) { |
| 289 | $connection_results_map[ $connection_result['connection_id'] ] = $connection_result['test_success'] ? 'ok' : 'broken'; |
| 290 | } |
| 291 | foreach ( $connections as $key => $connection ) { |
| 292 | if ( isset( $connection_results_map[ $connection['connection_id'] ] ) ) { |
| 293 | $connections[ $key ]['status'] = $connection_results_map[ $connection['connection_id'] ]; |
| 294 | } |
| 295 | } |
| 296 | |
| 297 | return $connections; |
| 298 | } |
| 299 | |
| 300 | /** |
| 301 | * Get a connections for a user. |
| 302 | * |
| 303 | * @param int $connection_id The connection_id. |
| 304 | |
| 305 | * @return array |
| 306 | */ |
| 307 | public function get_connection_for_user( $connection_id ) { |
| 308 | foreach ( $this->get_all_connections_for_user() as $connection ) { |
| 309 | if ( (int) $connection['connection_id'] === (int) $connection_id ) { |
| 310 | return $connection; |
| 311 | } |
| 312 | } |
| 313 | return array(); |
| 314 | } |
| 315 | |
| 316 | /** |
| 317 | * Get the ID of a connection. |
| 318 | * |
| 319 | * @param array $connection The connection. |
| 320 | * @return string |
| 321 | */ |
| 322 | public function get_connection_id( $connection ) { |
| 323 | return $connection['connection_data']['id']; |
| 324 | } |
| 325 | |
| 326 | /** |
| 327 | * Get the unique ID of a connection. |
| 328 | * |
| 329 | * @param array $connection The connection. |
| 330 | * @return string |
| 331 | */ |
| 332 | public function get_connection_unique_id( $connection ) { |
| 333 | return $connection['connection_data']['token_id']; |
| 334 | } |
| 335 | |
| 336 | /** |
| 337 | * Get the meta of a connection. |
| 338 | * |
| 339 | * @param array $connection The connection. |
| 340 | * @return array |
| 341 | */ |
| 342 | public function get_connection_meta( $connection ) { |
| 343 | $connection['user_id'] = $connection['connection_data']['user_id']; // Allows for shared connections. |
| 344 | return $connection; |
| 345 | } |
| 346 | |
| 347 | /** |
| 348 | * Show a message that the connection has been removed. |
| 349 | */ |
| 350 | public function display_disconnected() { |
| 351 | echo "<div class='updated'>\n"; |
| 352 | echo '<p>' . esc_html( __( 'That connection has been removed.', 'jetpack-publicize-pkg' ) ) . "</p>\n"; |
| 353 | echo "</div>\n\n"; |
| 354 | } |
| 355 | |
| 356 | /** |
| 357 | * If applicable, globalize a connection. |
| 358 | * |
| 359 | * @param string $connection_id Connection ID. |
| 360 | */ |
| 361 | public function globalization( $connection_id ) { |
| 362 | if ( isset( $_REQUEST['global'] ) && 'on' === $_REQUEST['global'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nonce check happens earlier in the process before we get here |
| 363 | if ( ! current_user_can( $this->GLOBAL_CAP ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase |
| 364 | return; |
| 365 | } |
| 366 | |
| 367 | $this->globalize_connection( $connection_id ); |
| 368 | } |
| 369 | } |
| 370 | |
| 371 | /** |
| 372 | * Globalize a connection. |
| 373 | * |
| 374 | * @param string $connection_id Connection ID. |
| 375 | */ |
| 376 | public function globalize_connection( $connection_id ) { |
| 377 | $xml = new Jetpack_IXR_Client(); |
| 378 | $xml->query( 'jetpack.globalizePublicizeConnection', $connection_id, 'globalize' ); |
| 379 | |
| 380 | if ( ! $xml->isError() ) { |
| 381 | $response = $xml->getResponse(); |
| 382 | $this->receive_updated_publicize_connections( $response ); |
| 383 | } |
| 384 | } |
| 385 | |
| 386 | /** |
| 387 | * Unglobalize a connection. |
| 388 | * |
| 389 | * @param string $connection_id Connection ID. |
| 390 | */ |
| 391 | public function unglobalize_connection( $connection_id ) { |
| 392 | $xml = new Jetpack_IXR_Client(); |
| 393 | $xml->query( 'jetpack.globalizePublicizeConnection', $connection_id, 'unglobalize' ); |
| 394 | |
| 395 | if ( ! $xml->isError() ) { |
| 396 | $response = $xml->getResponse(); |
| 397 | $this->receive_updated_publicize_connections( $response ); |
| 398 | } |
| 399 | } |
| 400 | |
| 401 | /** |
| 402 | * Grabs a fresh copy of the publicize connections data, if the cache is busted. |
| 403 | */ |
| 404 | public function refresh_connections() { |
| 405 | if ( null !== $this->current_connections ) { |
| 406 | return; |
| 407 | } |
| 408 | |
| 409 | $connections = get_transient( self::JETPACK_SOCIAL_CONNECTIONS_TRANSIENT ); |
| 410 | if ( false === $connections ) { |
| 411 | $xml = new Jetpack_IXR_Client(); |
| 412 | $xml->query( 'jetpack.fetchPublicizeConnections' ); |
| 413 | if ( ! $xml->isError() ) { |
| 414 | $response = $xml->getResponse(); |
| 415 | $this->receive_updated_publicize_connections( $response ); |
| 416 | } |
| 417 | return; |
| 418 | } |
| 419 | $this->current_connections = $connections; |
| 420 | } |
| 421 | |
| 422 | /** |
| 423 | * Delete the transient. |
| 424 | */ |
| 425 | public function clear_connections_transient() { |
| 426 | delete_transient( self::JETPACK_SOCIAL_CONNECTIONS_TRANSIENT ); |
| 427 | } |
| 428 | |
| 429 | /** |
| 430 | * Get the Publicize connect URL from Keyring. |
| 431 | * |
| 432 | * @param string $service_name Name of the service to get connect URL for. |
| 433 | * @param string $for What the URL is for. Default 'publicize'. |
| 434 | * @return string |
| 435 | */ |
| 436 | public function connect_url( $service_name, $for = 'publicize' ) { |
| 437 | return Keyring_Helper::connect_url( $service_name, $for ); |
| 438 | } |
| 439 | |
| 440 | /** |
| 441 | * Get the Publicize refresh URL from Keyring. |
| 442 | * |
| 443 | * @param string $service_name Name of the service to get refresh URL for. |
| 444 | * @param string $for What the URL is for. Default 'publicize'. |
| 445 | * @return string |
| 446 | */ |
| 447 | public function refresh_url( $service_name, $for = 'publicize' ) { |
| 448 | return Keyring_Helper::refresh_url( $service_name, $for ); |
| 449 | } |
| 450 | |
| 451 | /** |
| 452 | * Get the Publicize disconnect URL from Keyring. |
| 453 | * |
| 454 | * @param string $service_name Name of the service to get disconnect URL for. |
| 455 | * @param mixed $id ID of the conenction to disconnect. |
| 456 | * @return string |
| 457 | */ |
| 458 | public function disconnect_url( $service_name, $id ) { |
| 459 | return Keyring_Helper::disconnect_url( $service_name, $id ); |
| 460 | } |
| 461 | |
| 462 | /** |
| 463 | * Get social networks, either all available or only those that the site is connected to. |
| 464 | * |
| 465 | * @since 0.1.0 |
| 466 | * @since-jetpack 2.0.0 |
| 467 | * |
| 468 | * @since-jetpack 6.6.0 Removed Path. Service closed October 2018. |
| 469 | * |
| 470 | * @param string $filter Select the list of services that will be returned. Defaults to 'all', accepts 'connected'. |
| 471 | * @param false|int $_blog_id Get services for a specific blog by ID, or set to false for current blog. Default false. |
| 472 | * @param false|int $_user_id Get services for a specific user by ID, or set to false for current user. Default false. |
| 473 | * @return array List of social networks. |
| 474 | */ |
| 475 | public function get_services( $filter = 'all', $_blog_id = false, $_user_id = false ) { |
| 476 | $services = array( |
| 477 | 'facebook' => array(), |
| 478 | 'twitter' => array(), |
| 479 | 'linkedin' => array(), |
| 480 | 'tumblr' => array(), |
| 481 | 'mastodon' => array(), |
| 482 | 'instagram-business' => array(), |
| 483 | 'nextdoor' => array(), |
| 484 | 'threads' => array(), |
| 485 | 'bluesky' => array(), |
| 486 | ); |
| 487 | |
| 488 | if ( 'all' === $filter ) { |
| 489 | return $services; |
| 490 | } |
| 491 | |
| 492 | $connected_services = array(); |
| 493 | foreach ( $services as $service_name => $empty ) { |
| 494 | $connections = $this->get_connections( $service_name, $_blog_id, $_user_id ); |
| 495 | if ( $connections ) { |
| 496 | $connected_services[ $service_name ] = $connections; |
| 497 | } |
| 498 | } |
| 499 | return $connected_services; |
| 500 | } |
| 501 | |
| 502 | /** |
| 503 | * Get a specific connection. Stub. |
| 504 | * |
| 505 | * @param string $service_name 'facebook', 'twitter', etc. |
| 506 | * @param string $connection_id Connection ID. |
| 507 | * @param false|int $_blog_id The blog ID. Use false (default) for the current blog. |
| 508 | * @param false|int $_user_id The user ID. Use false (default) for the current user. |
| 509 | * @return void |
| 510 | */ |
| 511 | public function get_connection( $service_name, $connection_id, $_blog_id = false, $_user_id = false ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable |
| 512 | // Stub. |
| 513 | } |
| 514 | |
| 515 | /** |
| 516 | * Flag a post for Publicize after publishing. |
| 517 | * |
| 518 | * @param string $new_status New status of the post. |
| 519 | * @param string $old_status Old status of the post. |
| 520 | * @param WP_Post $post Post object. |
| 521 | */ |
| 522 | public function flag_post_for_publicize( $new_status, $old_status, $post ) { |
| 523 | if ( ! $post instanceof \WP_Post || ! $this->post_type_is_publicizeable( $post->post_type ) ) { |
| 524 | return; |
| 525 | } |
| 526 | |
| 527 | $should_publicize = $this->should_submit_post_pre_checks( $post ); |
| 528 | |
| 529 | if ( 'publish' === $new_status && 'publish' !== $old_status ) { |
| 530 | /** |
| 531 | * Determines whether a post being published gets publicized. |
| 532 | * |
| 533 | * Side-note: Possibly our most alliterative filter name. |
| 534 | * |
| 535 | * @since 0.1.0 No longer defaults to true. Adds checks to not publicize based on different contexts. |
| 536 | * @since-jetpack 4.1.0 |
| 537 | * |
| 538 | * @param bool $should_publicize Should the post be publicized? Default to true. |
| 539 | * @param WP_POST $post Current Post object. |
| 540 | */ |
| 541 | $should_publicize = apply_filters( 'publicize_should_publicize_published_post', $should_publicize, $post ); |
| 542 | |
| 543 | if ( $should_publicize ) { |
| 544 | update_post_meta( $post->ID, $this->PENDING, true ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase |
| 545 | } |
| 546 | } |
| 547 | } |
| 548 | |
| 549 | /** |
| 550 | * Test a connection. |
| 551 | * |
| 552 | * @param string $service_name Name of the service. |
| 553 | * @param array $connection Connection to be tested. |
| 554 | */ |
| 555 | public function test_connection( $service_name, $connection ) { |
| 556 | $id = $this->get_connection_id( $connection ); |
| 557 | |
| 558 | if ( array_key_exists( $id, $this->test_connection_results ) ) { |
| 559 | return $this->test_connection_results[ $id ]; |
| 560 | } |
| 561 | |
| 562 | $xml = new Jetpack_IXR_Client(); |
| 563 | $xml->query( 'jetpack.testPublicizeConnection', $id ); |
| 564 | |
| 565 | // Bail if all is well. |
| 566 | if ( ! $xml->isError() ) { |
| 567 | $this->test_connection_results[ $id ] = true; |
| 568 | return true; |
| 569 | } |
| 570 | |
| 571 | $xml_response = $xml->getResponse(); |
| 572 | $connection_test_message = $xml_response['faultString']; |
| 573 | $connection_error_code = ( empty( $xml_response['faultCode'] ) || ! is_int( $xml_response['faultCode'] ) ) |
| 574 | ? -1 |
| 575 | : $xml_response['faultCode']; |
| 576 | |
| 577 | // Set up refresh if the user can. |
| 578 | $user_can_refresh = current_user_can( $this->GLOBAL_CAP ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase |
| 579 | if ( $user_can_refresh ) { |
| 580 | /* translators: %s is the name of a social media service */ |
| 581 | $refresh_text = sprintf( _x( 'Refresh connection with %s', 'Refresh connection with {social media service}', 'jetpack-publicize-pkg' ), $this->get_service_label( $service_name ) ); |
| 582 | $refresh_url = $this->refresh_url( $service_name ); |
| 583 | } |
| 584 | |
| 585 | $error_data = array( |
| 586 | 'user_can_refresh' => $user_can_refresh, |
| 587 | 'refresh_text' => $refresh_text ?? null, |
| 588 | 'refresh_url' => $refresh_url ?? null, |
| 589 | ); |
| 590 | |
| 591 | $this->test_connection_results[ $id ] = new WP_Error( $connection_error_code, $connection_test_message, $error_data ); |
| 592 | |
| 593 | return $this->test_connection_results[ $id ]; |
| 594 | } |
| 595 | |
| 596 | /** |
| 597 | * Checks if post has already been shared by Publicize in the past. |
| 598 | * |
| 599 | * Jetpack uses two methods: |
| 600 | * 1. A POST_DONE . 'all' postmeta flag, or |
| 601 | * 2. if the post has already been published. |
| 602 | * |
| 603 | * @since 0.1.0 |
| 604 | * @since-jetpack 6.7.0 |
| 605 | * |
| 606 | * @param integer $post_id Optional. Post ID to query connection status for: will use current post if missing. |
| 607 | * |
| 608 | * @return bool True if post has already been shared by Publicize, false otherwise. |
| 609 | */ |
| 610 | public function post_is_done_sharing( $post_id = null ) { |
| 611 | // Defaults to current post if $post_id is null. |
| 612 | $post = get_post( $post_id ); |
| 613 | if ( null === $post ) { |
| 614 | return false; |
| 615 | } |
| 616 | |
| 617 | return 'publish' === $post->post_status || get_post_meta( $post->ID, $this->POST_DONE . 'all', true ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase |
| 618 | } |
| 619 | |
| 620 | /** |
| 621 | * Save a flag locally to indicate that this post has already been Publicized via the selected |
| 622 | * connections. |
| 623 | * |
| 624 | * @param int $post_ID Post ID. |
| 625 | * @param WP_Post $post Post object. |
| 626 | */ |
| 627 | public function save_publicized( $post_ID, $post = null ) { |
| 628 | if ( null === $post ) { |
| 629 | return; |
| 630 | } |
| 631 | // Only do this when a post transitions to being published. |
| 632 | // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase |
| 633 | if ( get_post_meta( $post->ID, $this->PENDING, false ) && $this->post_type_is_publicizeable( $post->post_type ) ) { |
| 634 | delete_post_meta( $post->ID, $this->PENDING ); |
| 635 | update_post_meta( $post->ID, $this->POST_DONE . 'all', true ); |
| 636 | } |
| 637 | // phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase |
| 638 | } |
| 639 | |
| 640 | /** |
| 641 | * Set post flags for Publicize. |
| 642 | * |
| 643 | * @param array $flags List of flags. |
| 644 | * @param WP_Post $post Post object. |
| 645 | * @return array |
| 646 | */ |
| 647 | public function set_post_flags( $flags, $post ) { |
| 648 | $flags['publicize_post'] = false; |
| 649 | if ( ! $this->post_type_is_publicizeable( $post->post_type ) ) { |
| 650 | return $flags; |
| 651 | } |
| 652 | |
| 653 | $should_publicize = $this->should_submit_post_pre_checks( $post ); |
| 654 | |
| 655 | /** This filter is already documented in modules/publicize/publicize-jetpack.php */ |
| 656 | if ( ! apply_filters( 'publicize_should_publicize_published_post', $should_publicize, $post ) ) { |
| 657 | return $flags; |
| 658 | } |
| 659 | |
| 660 | $connected_services = $this->get_all_connections(); |
| 661 | |
| 662 | if ( empty( $connected_services ) ) { |
| 663 | return $flags; |
| 664 | } |
| 665 | |
| 666 | $flags['publicize_post'] = true; |
| 667 | |
| 668 | return $flags; |
| 669 | } |
| 670 | } |