Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
25.49% covered (danger)
25.49%
13 / 51
58.33% covered (warning)
58.33%
7 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
Publicize_Utils
25.49% covered (danger)
25.49%
13 / 51
58.33% covered (warning)
58.33%
7 / 12
512.19
0.00% covered (danger)
0.00%
0 / 1
 is_social_settings_page
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
12
 is_jetpack_settings_page
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
3
 should_block_editor_have_social
16.67% covered (danger)
16.67%
2 / 12
0.00% covered (danger)
0.00%
0 / 1
55.88
 is_connected
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 is_publicize_active
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 can_open_social_dashboard
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 current_user_can_access_publicize_data
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 is_wpcom
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 assert_is_wpcom
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 should_use_jetpack_module_endpoint
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
3
 endpoint_deprecated_warning
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
6
 make_proper_response
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2/**
3 * Publicize_Utils.
4 *
5 * @package automattic/jetpack-publicize
6 */
7
8namespace Automattic\Jetpack\Publicize;
9
10use Automattic\Jetpack\Connection\Manager;
11use Automattic\Jetpack\Modules;
12use Automattic\Jetpack\Status\Host;
13use WP_Error;
14
15/**
16 * Publicize_Utils class.
17 */
18class Publicize_Utils {
19
20    /**
21     * Whether the current page is the social settings page.
22     */
23    public static function is_social_settings_page() {
24        $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
25
26        return ! empty( $screen ) && 'jetpack_page_jetpack-social' === $screen->base;
27    }
28
29    /**
30     * Whether the current page is the Jetpack settings page.
31     */
32    public static function is_jetpack_settings_page() {
33        $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
34
35        // Older Jetpack plugins still render Settings at page=jetpack.
36        return ! empty( $screen ) && in_array( $screen->base, array( 'jetpack_page_jetpack-settings', 'toplevel_page_jetpack' ), true );
37    }
38
39    /**
40     * Whether the block editor should have the social features.
41     *
42     * @return bool
43     */
44    public static function should_block_editor_have_social() {
45        if ( ! is_admin() ) {
46            return false;
47        }
48
49        $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
50
51        if ( empty( $screen ) || ! $screen->is_block_editor() ) {
52            return false;
53        }
54
55        $needs_jetpack_connection = ! ( new Host() )->is_wpcom_platform();
56
57        if ( $needs_jetpack_connection && ! self::is_connected() ) {
58            return false;
59        }
60
61        $post_type = get_post_type();
62
63        if ( empty( $post_type ) || ! post_type_supports( $post_type, 'publicize' ) ) {
64            return false;
65        }
66
67        return true;
68    }
69
70    /**
71     * Helper to check that we have a Jetpack connection.
72     */
73    public static function is_connected() {
74
75        $connection = new Manager();
76
77        return $connection->is_connected() && $connection->has_connected_user();
78    }
79
80    /**
81     * Check if the Publicize module is active.
82     *
83     * @return bool
84     */
85    public static function is_publicize_active() {
86        return ( new Modules() )->is_active( 'publicize' );
87    }
88
89    /**
90     * Whether the current user may open the Social dashboard: admins can turn Social on, so they see it while Publicize is off.
91     *
92     * @since $$next-version$$
93     *
94     * @return bool
95     */
96    public static function can_open_social_dashboard() {
97        return current_user_can( 'manage_options' ) || self::is_publicize_active();
98    }
99
100    /**
101     * Whether the current user may be shown Publicize data.
102     *
103     * The single definition of that gate. Both the block editor assets and the
104     * script data ask this, and when they disagreed the script data handed
105     * connection details to users the editor UI was never loaded for.
106     *
107     * Prefers the Publicize instance so any future override is honored, and falls
108     * back to evaluating the capability directly when the global is not set, so the
109     * answer never depends on initialization order.
110     *
111     * @return bool
112     */
113    public static function current_user_can_access_publicize_data() {
114
115        global $publicize;
116
117        if ( $publicize instanceof Publicize_Base ) {
118            return $publicize->current_user_can_access_publicize_data();
119        }
120
121        /** This filter is documented in projects/packages/publicize/src/class-publicize-base.php */
122        return current_user_can( apply_filters( 'jetpack_publicize_capability', 'publish_posts' ) );
123    }
124
125    /**
126     * Check if we are on WPCOM.
127     *
128     * @return bool
129     */
130    public static function is_wpcom() {
131        return ( new Host() )->is_wpcom_simple();
132    }
133
134    /**
135     * Assert that the method is only called on WPCOM.
136     *
137     * @param string $method The method name.
138     *
139     * @throws \Exception If the method is not called on WPCOM.
140     */
141    public static function assert_is_wpcom( $method ) {
142        if ( ! self::is_wpcom() ) {
143            throw new \Exception( esc_html( "Method $method can only be called on WordPress.com." ) );
144        }
145    }
146
147    /**
148     * Check if the new module endpoint is available in the used Jetpack version.
149     * We need the module status in response that's why we do the version check https://github.com/Automattic/jetpack/pull/41461/files#diff-f8e5ef1115599de750b64143dd1901554254eddd95ab4371b6b6b3b2a5914224R638-R642.
150     * More: https://github.com/Automattic/jetpack/pull/41596.
151     *
152     * @return bool
153     */
154    public static function should_use_jetpack_module_endpoint() {
155        return class_exists( 'Jetpack' ) && defined( 'JETPACK__VERSION' ) && ( version_compare( (string) JETPACK__VERSION, '14.3', '>=' ) );
156    }
157
158    /**
159     * Log a warning that a deprecated endpoint was called.
160     *
161     * @param string $function_name        The function name.
162     * @param string $version              The version in which the endpoint was deprecated.
163     * @param string $deprecated_endpoint  The deprecated endpoint.
164     * @param string $alternative_endpoint The alternative endpoint.
165     */
166    public static function endpoint_deprecated_warning( $function_name, $version, $deprecated_endpoint, $alternative_endpoint = '' ) {
167
168        $messages = array(
169            sprintf(
170                /* translators: %s: REST API endpoint. */
171                esc_html__( '%1$s endpoint has been deprecated.', 'jetpack-publicize-pkg' ),
172                '"' . $deprecated_endpoint . '"'
173            ),
174        );
175
176        if ( ! empty( $alternative_endpoint ) ) {
177            $messages[] = sprintf(
178                /* translators: %s: alternative endpoint. */
179                esc_html__( 'Please use %s endpoint instead.', 'jetpack-publicize-pkg' ),
180                '"' . $alternative_endpoint . '"'
181            );
182        }
183
184        $messages[] = esc_html__( 'Please update all the Jetpack plugins to the latest version.', 'jetpack-publicize-pkg' );
185
186        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- We have done it above.
187        _doing_it_wrong( esc_html( $function_name ), implode( ' ', $messages ), $version );
188    }
189
190    /**
191     * Forward remote response to client with error handling.
192     *
193     * @param array|WP_Error $response Response from WPCOM.
194     *
195     * @return array|WP_Error
196     */
197    public static function make_proper_response( $response ) {
198        if ( is_wp_error( $response ) ) {
199            return $response;
200        }
201
202        $body        = json_decode( wp_remote_retrieve_body( $response ), true );
203        $status_code = wp_remote_retrieve_response_code( $response );
204
205        if ( 200 === $status_code ) {
206            return $body;
207        }
208
209        return new WP_Error(
210            isset( $body['error'] ) ? 'remote-error-' . $body['error'] : 'remote-error',
211            $body['message'] ?? 'unknown remote error',
212            array( 'status' => $status_code )
213        );
214    }
215}