Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
15.18% covered (danger)
15.18%
17 / 112
7.69% covered (danger)
7.69%
1 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
Publicize_Script_Data
15.18% covered (danger)
15.18%
17 / 112
7.69% covered (danger)
7.69%
1 / 13
739.46
0.00% covered (danger)
0.00%
0 / 1
 publicize
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 configure
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 set_admin_script_data
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 set_wpcom_user_data
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
 get_admin_script_data
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 1
56
 get_upgrade_data
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 get_social_settings
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 get_plugin_info
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
12
 get_store_initial_state
90.00% covered (success)
90.00%
9 / 10
0.00% covered (danger)
0.00%
0 / 1
4.02
 has_feature_flag
n/a
0 / 0
n/a
0 / 0
1
 get_supported_services
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 get_api_paths
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 get_urls
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 get_nonces
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Publicize_Script_Data.
4 *
5 * @package automattic/jetpack-publicize
6 */
7
8namespace Automattic\Jetpack\Publicize;
9
10use Automattic\Jetpack\Connection\Manager;
11use Automattic\Jetpack\Current_Plan;
12use Automattic\Jetpack\Plans;
13use Automattic\Jetpack\Publicize\Jetpack_Social_Settings\Settings;
14use Automattic\Jetpack\Publicize\Publicize_Utils as Utils;
15use Automattic\Jetpack\Publicize\Services as Publicize_Services;
16use Automattic\Jetpack\Status\Host;
17
18/**
19 * Publicize_Script_Data class.
20 */
21class 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}