← All changes
|
jetpack_vendor/automattic/jetpack-publicize/src/class-publicize.php
+670
-0
16.2-beta
→
16.3
View file →
| @@ -1,0 +1,670 @@ | ||
| 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 | +} | |