| 1 |
<?php |
| 2 |
/** |
| 3 |
* Publicize_Script_Data. |
| 4 |
* |
| 5 |
* @package automattic/jetpack-publicize |
| 6 |
*/ |
| 7 |
|
| 8 |
namespace Automattic\Jetpack\Publicize; |
| 9 |
|
| 10 |
use Automattic\Jetpack\Connection\Manager; |
| 11 |
use Automattic\Jetpack\Current_Plan; |
| 12 |
use Automattic\Jetpack\Plans; |
| 13 |
use Automattic\Jetpack\Publicize\Jetpack_Social_Settings\Settings; |
| 14 |
use Automattic\Jetpack\Publicize\Publicize_Utils as Utils; |
| 15 |
use Automattic\Jetpack\Publicize\Services as Publicize_Services; |
| 16 |
use Automattic\Jetpack\Status\Host; |
| 17 |
|
| 18 |
/** |
| 19 |
* Publicize_Script_Data class. |
| 20 |
*/ |
| 21 |
class Publicize_Script_Data { |
| 22 |
|
| 23 |
/** |
| 24 |
* The WordPress.com plan that unlocks Social's paid features on Simple sites. |
| 25 |
*/ |
| 26 |
private const UPGRADE_PLAN_SLUG = 'business-bundle'; |
| 27 |
|
| 28 |
/** |
| 29 |
* Get the publicize instance - properly typed |
| 30 |
* |
| 31 |
* @return Publicize |
| 32 |
*/ |
| 33 |
public static function publicize() { |
| 34 |
/** |
| 35 |
* Publicize instance. |
| 36 |
* |
| 37 |
* @var Publicize $publicize |
| 38 |
*/ |
| 39 |
global $publicize; |
| 40 |
|
| 41 |
if ( ! $publicize && function_exists( 'publicize_init' ) ) { |
| 42 |
// @phan-suppress-next-line PhanUndeclaredFunction - phan is dumb not to see the function_exists check |
| 43 |
publicize_init(); |
| 44 |
} |
| 45 |
|
| 46 |
return $publicize; |
| 47 |
} |
| 48 |
|
| 49 |
/** |
| 50 |
* Configure script data. |
| 51 |
*/ |
| 52 |
public static function configure() { |
| 53 |
add_filter( 'jetpack_admin_js_script_data', array( __CLASS__, 'set_admin_script_data' ), 10, 1 ); |
| 54 |
} |
| 55 |
|
| 56 |
/** |
| 57 |
* Set script data. |
| 58 |
* |
| 59 |
* @param array $data The script data. |
| 60 |
*/ |
| 61 |
public static function set_admin_script_data( $data ) { |
| 62 |
|
| 63 |
$data['social'] = apply_filters( 'jetpack_social_admin_script_data', self::get_admin_script_data(), $data ); |
| 64 |
|
| 65 |
if ( empty( $data['site']['plan']['product_slug'] ) ) { |
| 66 |
$data['site']['plan'] = Current_Plan::get(); |
| 67 |
} |
| 68 |
|
| 69 |
// Override features for simple sites. |
| 70 |
if ( ( new Host() )->is_wpcom_simple() ) { |
| 71 |
$data['site']['plan']['features'] = Current_Plan::get_simple_site_specific_features(); |
| 72 |
} |
| 73 |
|
| 74 |
$data['site']['wpcom']['blog_id'] = Manager::get_site_id( true ); |
| 75 |
|
| 76 |
self::set_wpcom_user_data( $data['user']['current_user'] ); |
| 77 |
|
| 78 |
return $data; |
| 79 |
} |
| 80 |
|
| 81 |
/** |
| 82 |
* Set wpcom user data. |
| 83 |
* |
| 84 |
* @param array $user_data The user data. |
| 85 |
*/ |
| 86 |
private static function set_wpcom_user_data( &$user_data ) { |
| 87 |
if ( ( new Host() )->is_wpcom_simple() ) { |
| 88 |
$wpcom_user_data = array( |
| 89 |
'ID' => get_current_user_id(), |
| 90 |
'login' => wp_get_current_user()->user_login, |
| 91 |
); |
| 92 |
} else { |
| 93 |
$wpcom_user_data = ( new Manager() )->get_connected_user_data(); |
| 94 |
} |
| 95 |
|
| 96 |
$user_data['wpcom'] = array_merge( |
| 97 |
$user_data['wpcom'] ?? array(), |
| 98 |
$wpcom_user_data ? $wpcom_user_data : array() |
| 99 |
); |
| 100 |
} |
| 101 |
|
| 102 |
/** |
| 103 |
* Get the script data for admin UI. |
| 104 |
* |
| 105 |
* @return array |
| 106 |
*/ |
| 107 |
public static function get_admin_script_data() { |
| 108 |
|
| 109 |
// Only set script data on the social settings page, |
| 110 |
// the Jetpack settings page, or the block editor. |
| 111 |
$should_set_script_data = Utils::is_jetpack_settings_page() |
| 112 |
|| Utils::is_social_settings_page() |
| 113 |
|| Utils::should_block_editor_have_social(); |
| 114 |
|
| 115 |
if ( ! $should_set_script_data ) { |
| 116 |
return array(); |
| 117 |
} |
| 118 |
|
| 119 |
$basic_data = array( |
| 120 |
'api_paths' => self::get_api_paths(), |
| 121 |
'assets_url' => plugins_url( '/build/', __DIR__ ), |
| 122 |
'is_publicize_enabled' => Utils::is_publicize_active(), |
| 123 |
'message_templates' => array(), |
| 124 |
'supported_services' => array(), |
| 125 |
'upgrade' => self::get_upgrade_data(), |
| 126 |
'urls' => array(), |
| 127 |
'settings' => self::get_social_settings(), |
| 128 |
'plugin_info' => self::get_plugin_info(), |
| 129 |
'nonces' => self::get_nonces(), |
| 130 |
); |
| 131 |
|
| 132 |
if ( ! Utils::is_publicize_active() ) { |
| 133 |
return $basic_data; |
| 134 |
} |
| 135 |
|
| 136 |
// Simple sites don't have a user connection. |
| 137 |
$is_publicize_configured = ( new Host() )->is_wpcom_simple() || Utils::is_connected(); |
| 138 |
|
| 139 |
if ( ! $is_publicize_configured ) { |
| 140 |
return $basic_data; |
| 141 |
} |
| 142 |
|
| 143 |
return array_merge( |
| 144 |
$basic_data, |
| 145 |
array( |
| 146 |
'supported_services' => self::get_supported_services(), |
| 147 |
'urls' => self::get_urls(), |
| 148 |
'store_initial_state' => self::get_store_initial_state(), |
| 149 |
'message_templates' => array( |
| 150 |
'placeholders' => Message_Templates_Placeholders::get_all(), |
| 151 |
), |
| 152 |
) |
| 153 |
); |
| 154 |
} |
| 155 |
|
| 156 |
/** |
| 157 |
* Get the plan a site needs to unlock Social's paid features. |
| 158 |
* |
| 159 |
* Null off Simple, which keeps the uncached `Plans::get_plan_short_name()` lookup |
| 160 |
* away from a path the block editor runs on every post edit. |
| 161 |
* |
| 162 |
* @return array|null The plan slug and short name, or null when there's nothing to upsell. |
| 163 |
*/ |
| 164 |
public static function get_upgrade_data() { |
| 165 |
|
| 166 |
if ( ! ( new Host() )->is_wpcom_simple() ) { |
| 167 |
return null; |
| 168 |
} |
| 169 |
|
| 170 |
if ( Current_Plan::supports( 'social-enhanced-publishing' ) ) { |
| 171 |
return null; |
| 172 |
} |
| 173 |
|
| 174 |
return array( |
| 175 |
'plan_slug' => self::UPGRADE_PLAN_SLUG, |
| 176 |
'plan_name' => Plans::get_plan_short_name( self::UPGRADE_PLAN_SLUG ), |
| 177 |
); |
| 178 |
} |
| 179 |
|
| 180 |
/** |
| 181 |
* Get the social settings. |
| 182 |
* |
| 183 |
* @return array |
| 184 |
*/ |
| 185 |
public static function get_social_settings() { |
| 186 |
|
| 187 |
$settings = ( new Settings() ); |
| 188 |
|
| 189 |
return array( |
| 190 |
'socialImageGenerator' => $settings->get_image_generator_settings(), |
| 191 |
'utmSettings' => $settings->get_utm_settings(), |
| 192 |
'socialNotes' => array( |
| 193 |
'enabled' => $settings->is_social_notes_enabled(), |
| 194 |
'config' => $settings->get_social_notes_config(), |
| 195 |
), |
| 196 |
'showPricingPage' => $settings->should_show_pricing_page(), |
| 197 |
'messageTemplate' => $settings->get_message_template(), |
| 198 |
); |
| 199 |
} |
| 200 |
|
| 201 |
/** |
| 202 |
* Get the plugin info. |
| 203 |
* |
| 204 |
* @return array |
| 205 |
*/ |
| 206 |
public static function get_plugin_info() { |
| 207 |
|
| 208 |
$social_version = null; |
| 209 |
$jetpack_version = null; |
| 210 |
|
| 211 |
if ( defined( 'JETPACK_SOCIAL_PLUGIN_ROOT_FILE' ) ) { |
| 212 |
|
| 213 |
$plugin_data = get_plugin_data( (string) constant( 'JETPACK_SOCIAL_PLUGIN_ROOT_FILE' ), false, false ); |
| 214 |
|
| 215 |
$social_version = $plugin_data['Version']; |
| 216 |
} |
| 217 |
|
| 218 |
if ( defined( 'JETPACK__VERSION' ) ) { |
| 219 |
$jetpack_version = constant( 'JETPACK__VERSION' ); |
| 220 |
} |
| 221 |
|
| 222 |
return array( |
| 223 |
'social' => array( |
| 224 |
'version' => $social_version, |
| 225 |
), |
| 226 |
'jetpack' => array( |
| 227 |
'version' => $jetpack_version, |
| 228 |
), |
| 229 |
); |
| 230 |
} |
| 231 |
|
| 232 |
/** |
| 233 |
* Get the social store initial state. |
| 234 |
* |
| 235 |
* @return array |
| 236 |
*/ |
| 237 |
public static function get_store_initial_state() { |
| 238 |
|
| 239 |
$post = get_post(); |
| 240 |
|
| 241 |
$share_status = array(); |
| 242 |
|
| 243 |
// get_post_share_status is not available on WPCOM yet. |
| 244 |
if ( Utils::should_block_editor_have_social() && $post ) { |
| 245 |
$share_status[ $post->ID ] = Share_Status::get_post_share_status( $post->ID ); |
| 246 |
} |
| 247 |
|
| 248 |
return array( |
| 249 |
'connectionData' => array( |
| 250 |
// Same gate the block editor assets are enqueued behind, so users who |
| 251 |
// never get the Social UI are not handed connection details either. |
| 252 |
'connections' => Utils::current_user_can_access_publicize_data() ? Connections::get_all_for_user() : array(), |
| 253 |
), |
| 254 |
'shareStatus' => $share_status, |
| 255 |
); |
| 256 |
} |
| 257 |
|
| 258 |
/** |
| 259 |
* Whether the site has the feature flag enabled. |
| 260 |
* |
| 261 |
* @deprecated 0.69.1 Use Current_Plan::supports() directly instead. |
| 262 |
* |
| 263 |
* @todo Remove this method After March 2026. |
| 264 |
* |
| 265 |
* @param string $feature The feature name to check for, without the "social-" prefix. |
| 266 |
* @return bool |
| 267 |
*/ |
| 268 |
public static function has_feature_flag( $feature ): bool { |
| 269 |
return Current_Plan::supports( 'social-' . $feature ); |
| 270 |
} |
| 271 |
|
| 272 |
/** |
| 273 |
* Get the list of supported Publicize services. |
| 274 |
* |
| 275 |
* @return array List of external services and their settings. |
| 276 |
*/ |
| 277 |
public static function get_supported_services() { |
| 278 |
return Publicize_Services::get_all(); |
| 279 |
} |
| 280 |
|
| 281 |
/** |
| 282 |
* Get the API paths. |
| 283 |
* |
| 284 |
* @return array |
| 285 |
*/ |
| 286 |
public static function get_api_paths() { |
| 287 |
|
| 288 |
return array( |
| 289 |
// The complete path will be like `/jetpack/v4/social/settings`. |
| 290 |
'socialToggleBase' => Utils::should_use_jetpack_module_endpoint() ? 'settings' : 'social/settings', |
| 291 |
'resharePost' => '/wpcom/v2/publicize/share-post/{postId}', |
| 292 |
); |
| 293 |
} |
| 294 |
|
| 295 |
/** |
| 296 |
* Get the URLs. |
| 297 |
* |
| 298 |
* @return array |
| 299 |
*/ |
| 300 |
public static function get_urls() { |
| 301 |
|
| 302 |
$urls = array( |
| 303 |
'connectionsManagementPage' => self::publicize()->publicize_connections_url(), |
| 304 |
); |
| 305 |
|
| 306 |
// Escape the URLs. |
| 307 |
array_walk( $urls, 'esc_url_raw' ); |
| 308 |
|
| 309 |
return $urls; |
| 310 |
} |
| 311 |
|
| 312 |
/** |
| 313 |
* Get nonces required by the Social admin UI. |
| 314 |
* |
| 315 |
* @return array |
| 316 |
*/ |
| 317 |
private static function get_nonces() { |
| 318 |
return array( |
| 319 |
'refresh_plan' => wp_create_nonce( Social_Admin_Page::REFRESH_PLAN_NONCE_ACTION ), |
| 320 |
); |
| 321 |
} |
| 322 |
} |
| 323 |
|