Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
1.39% covered (danger)
1.39%
1 / 72
7.69% covered (danger)
7.69%
1 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
Abstract_Jetpack_Site
1.45% covered (danger)
1.45%
1 / 69
7.69% covered (danger)
7.69%
1 / 13
778.40
0.00% covered (danger)
0.00%
0 / 1
 get_constant
n/a
0 / 0
n/a
0 / 0
0
 current_theme_supports
n/a
0 / 0
n/a
0 / 0
0
 get_theme_support
n/a
0 / 0
n/a
0 / 0
0
 get_mock_option
n/a
0 / 0
n/a
0 / 0
0
 get_jetpack_version
n/a
0 / 0
n/a
0 / 0
0
 get_updates
n/a
0 / 0
n/a
0 / 0
0
 main_network_site
n/a
0 / 0
n/a
0 / 0
0
 wp_version
n/a
0 / 0
n/a
0 / 0
0
 max_upload_size
n/a
0 / 0
n/a
0 / 0
0
 is_main_network
n/a
0 / 0
n/a
0 / 0
0
 is_version_controlled
n/a
0 / 0
n/a
0 / 0
0
 file_system_write_access
n/a
0 / 0
n/a
0 / 0
0
 get_connection_active_plugins
n/a
0 / 0
n/a
0 / 0
0
 before_render
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 wp_memory_limit
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 wp_max_memory_limit
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 after_render
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
 after_render_options
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
20
 get_jetpack_modules
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 is_module_active
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 is_vip
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 featured_images_enabled
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 get_post_formats
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
 get_icon
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
30
 is_main_site
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
 is_a8c_publication
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php  // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2/**
3 * This class extends the SAL_Site class, providing the implementation for
4 * functions that were declared in that SAL_Site class as well as defining
5 * base functions to be implemented in class Jetpack_Site.
6 *
7 * @see class.json-api-site-jetpack.php for more context on
8 * the functions extended here.
9 *
10 * @package automattic/jetpack
11 */
12
13if ( ! defined( 'ABSPATH' ) ) {
14    exit( 0 );
15}
16
17require_once __DIR__ . '/class.json-api-site-base.php';
18
19/**
20 * Base class for Abstract_Jetpack_Site.
21 */
22abstract class Abstract_Jetpack_Site extends SAL_Site {
23
24    /**
25     * Defining a base get_constant() function to be extended in the Jetpack_Site class.
26     *
27     * If a Jetpack constant name has been defined, this will return the value of the constant.
28     *
29     * @param string $name the name of the Jetpack constant to check.
30     */
31    abstract protected function get_constant( $name );
32
33    /**
34     * Defining a base current_theme_supports() function to be extended in the Jetpack_Site class.
35     *
36     * Returns true if the current theme supports the $feature_name, false otherwise.
37     *
38     * @param string $feature_name the name of the Jetpack feature.
39     */
40    abstract protected function current_theme_supports( $feature_name );
41
42    /**
43     * Defining a base get_theme_support() function to be extended in the Jetpack_Site class.
44     *
45     * Gets theme support arguments to be checked against the specific Jetpack feature.
46     *
47     * @param string $feature_name the name of the Jetpack feature to check against.
48     */
49    abstract protected function get_theme_support( $feature_name );
50
51    /**
52     * Defining a base get_mock_option() function to be extended in the Jetpack_Site class.
53     *
54     * Retrieves a Jetpack option's value, given the option name.
55     *
56     * @param string $name the name of the Jetpack option, without the 'jetpack' prefix (eg. 'log' for 'jetpack_log').
57     */
58    abstract protected function get_mock_option( $name );
59
60    /**
61     * Defining a base get_jetpack_version() function to be extended in the Jetpack_Site class.
62     *
63     * Returns the current Jetpack version number.
64     */
65    abstract public function get_jetpack_version();
66
67    /**
68     * Defining a base get_updates() function to be extended in the Jetpack_Site class.
69     *
70     * Gets updates and then stores them in the jetpack_updates option, returning an array with the option schema.
71     */
72    abstract public function get_updates();
73
74    /**
75     * Defining a base main_network_site() function to be extended in the Jetpack_Site class.
76     *
77     * Returns the site URL for the current network.
78     */
79    abstract protected function main_network_site();
80
81    /**
82     * Defining a base wp_version() function to be extended in the Jetpack_Site class.
83     *
84     * Returns the WordPress version for the current site.
85     */
86    abstract protected function wp_version();
87
88    /**
89     * Defining a base max_upload_size() function to be extended in the Jetpack_Site class.
90     *
91     * Returns the maximum upload size allowed in php.ini.
92     */
93    abstract protected function max_upload_size();
94
95    /**
96     * Defining a base is_main_network() function to be extended in the Jetpack_Site class.
97     *
98     * Returns true if the site is within a system with a multiple networks, false otherwise.
99     *
100     * @see /projects/packages/status/src/class-status.php.
101     */
102    abstract protected function is_main_network();
103
104    /**
105     * Defining a base is_version_controlled() function to be extended in the Jetpack_Site class.
106     *
107     * Returns true if is_vcs_checkout discovers a version control checkout, false otherwise.
108     *
109     * @see projects/packages/sync/src/class-functions.php.
110     */
111    abstract protected function is_version_controlled();
112
113    /**
114     * Defining a base file_system_write_access() function to be extended in the Jetpack_Site class.
115     *
116     * Returns true if the site has file write access false otherwise.
117     *
118     * @see projects/packages/sync/src/class-functions.php.
119     */
120    abstract protected function file_system_write_access();
121
122    /**
123     * Fetch a list of active plugins that are using Jetpack Connection.
124     */
125    abstract protected function get_connection_active_plugins();
126
127    /**
128     * This function is implemented on WPCom sites, where a filter is removed which forces the URL to http.
129     *
130     * @see /wpcom/public.api/rest/sal/class.json-api-site-jetpack-shadow.php.
131     */
132    public function before_render() {
133    }
134
135    /**
136     * This function returns the value of the 'WP_MEMORY_LIMIT' constant.
137     *
138     * @return int|string
139     */
140    protected function wp_memory_limit() {
141        return $this->get_constant( 'WP_MEMORY_LIMIT' );
142    }
143
144    /**
145     * This function returns the value of the 'WP_MAX_MEMORY_LIMIT' constant.
146     *
147     * @return int|string
148     */
149    protected function wp_max_memory_limit() {
150        return $this->get_constant( 'WP_MAX_MEMORY_LIMIT' );
151    }
152
153    /**
154     * If a user has manage options permissions and the site is the main site of the network, make updates visible.
155     *
156     * Called after response_keys have been rendered, which itself is used to return all the necessary information for a site’s response.
157     *
158     * @param array $response an array of the response keys.
159     */
160    public function after_render( &$response ) {
161        if ( current_user_can( 'manage_options' ) && $this->is_main_site( $response ) ) {
162            $jetpack_update = $this->get_updates();
163            if ( ! empty( $jetpack_update ) ) {
164                // In previous version of Jetpack 3.4, 3.5, 3.6 we synced the wp_version into to jetpack_updates.
165                unset( $jetpack_update['wp_version'] );
166                // In previous version of Jetpack 3.4, 3.5, 3.6 we synced the site_is_version_controlled into to jetpack_updates.
167                unset( $jetpack_update['site_is_version_controlled'] );
168
169                $response['updates'] = $jetpack_update;
170            }
171        }
172    }
173
174    /**
175     * Extends the Jetpack options array with details including site constraints, WordPress and Jetpack versions, and plugins using the Jetpack connection.
176     *
177     * @param array $options an array of the Jetpack options.
178     */
179    public function after_render_options( &$options ) {
180        $options['jetpack_version'] = $this->get_jetpack_version();
181
182        $main_network_site = $this->main_network_site();
183        if ( $main_network_site ) {
184            $options['main_network_site'] = rtrim( $main_network_site, '/' );
185        }
186
187        $active_modules = Jetpack_Options::get_option( 'active_modules' );
188        if ( is_array( $active_modules ) ) {
189            $options['active_modules'] = (array) array_values( $active_modules );
190        }
191
192        $options['software_version']    = (string) $this->wp_version();
193        $options['max_upload_size']     = $this->max_upload_size();
194        $options['wp_memory_limit']     = $this->wp_memory_limit();
195        $options['wp_max_memory_limit'] = $this->wp_max_memory_limit();
196
197        // Sites have to prove that they are not main_network site.
198        // If the sync happends right then we should be able to see that we are not dealing with a network site.
199        $options['is_multi_network'] = (bool) $this->is_main_network();
200        $options['is_multi_site']    = (bool) $this->is_multisite();
201
202        $file_mod_disabled_reasons = array_keys(
203            array_filter(
204                array(
205                    'automatic_updater_disabled'      => (bool) $this->get_constant( 'AUTOMATIC_UPDATER_DISABLED' ),
206                    // WP AUTO UPDATE CORE defaults to minor, '1' if true and '0' if set to false.
207                    'wp_auto_update_core_disabled'    => ! ( (bool) $this->get_constant( 'WP_AUTO_UPDATE_CORE' ) ),
208                    'is_version_controlled'           => (bool) $this->is_version_controlled(),
209                    // By default we assume that site does have system write access if the value is not set yet.
210                    'has_no_file_system_write_access' => ! (bool) $this->file_system_write_access(),
211                    'disallow_file_mods'              => (bool) $this->get_constant( 'DISALLOW_FILE_MODS' ),
212                )
213            )
214        );
215
216        $options['file_mod_disabled'] = empty( $file_mod_disabled_reasons ) ? false : $file_mod_disabled_reasons;
217
218        $options['jetpack_connection_active_plugins'] = $this->get_connection_active_plugins();
219    }
220
221    /**
222     * This function returns the values of any active Jetpack modules.
223     *
224     * @return array
225     */
226    public function get_jetpack_modules() {
227        return array_values( Jetpack_Options::get_option( 'active_modules', array() ) );
228    }
229
230    /**
231     * This function returns true if a specified Jetpack module is active, false otherwise.
232     *
233     * @param string $module The Jetpack module name to check.
234     *
235     * @return bool
236     */
237    public function is_module_active( $module ) {
238        return in_array( $module, Jetpack_Options::get_option( 'active_modules', array() ), true );
239    }
240
241    /**
242     * This function returns false for a check as to whether a site is a VIP site or not.
243     *
244     * @return bool Always returns false.
245     */
246    public function is_vip() {
247        return false; // this may change for VIP Go sites, which sync using Jetpack.
248    }
249
250    /**
251     * If the site's current theme supports post thumbnails, return true (otherwise return false).
252     *
253     * @return bool
254     */
255    public function featured_images_enabled() {
256        return $this->current_theme_supports( 'post-thumbnails' );
257    }
258
259    /**
260     * Returns an array of supported post formats.
261     *
262     * @return array
263     */
264    public function get_post_formats() {
265        // deprecated - see separate endpoint. get a list of supported post formats.
266        $all_formats = get_post_format_strings();
267        $supported   = $this->get_theme_support( 'post-formats' );
268
269        $supported_formats = array();
270
271        if ( isset( $supported[0] ) ) {
272            foreach ( $supported[0] as $format ) {
273                $supported_formats[ $format ] = $all_formats[ $format ];
274            }
275        }
276
277        return $supported_formats;
278    }
279
280    /**
281     * Returns an array with site icon details.
282     *
283     * @return array
284     */
285    public function get_icon() {
286        $icon_id = get_option( 'site_icon' );
287        if ( empty( $icon_id ) ) {
288            $icon_id = Jetpack_Options::get_option( 'site_icon_id' );
289        }
290
291        if ( empty( $icon_id ) ) {
292            return null;
293        }
294
295        $icon = array_filter(
296            array(
297                'img' => wp_get_attachment_image_url( $icon_id, 'full' ),
298                'ico' => wp_get_attachment_image_url( $icon_id, array( 16, 16 ) ),
299            )
300        );
301
302        if ( empty( $icon ) ) {
303            return null;
304        }
305
306        if ( current_user_can( 'edit_posts', $icon_id ) ) {
307            $icon['media_id'] = (int) $icon_id;
308        }
309
310        return $icon;
311    }
312
313    /**
314     * Private methods
315     **/
316
317    /**
318     * This function returns true if the current site is the main network site, false otherwise.
319     *
320     * @param array $response The array of Jetpack response keys.
321     *
322     * @return bool
323     */
324    private function is_main_site( $response ) {
325        if ( isset( $response['options']->main_network_site ) && isset( $response['options']->unmapped_url ) ) {
326            $main_network_site_url = set_url_scheme( $response['options']->main_network_site, 'http' );
327            $unmapped_url          = set_url_scheme( $response['options']->unmapped_url, 'http' );
328            if ( $unmapped_url === $main_network_site_url ) {
329                return true;
330            }
331        }
332
333        return false;
334    }
335
336    /**
337     * For Jetpack sites this will always return false.
338     *
339     * This is extended for WordPress.com sites in wpcom/public.api/rest/sal/trait.json-api-site-wpcom.php.
340     *
341     * @param int $post_id The post id.
342     *
343     * @return bool
344     */
345    protected function is_a8c_publication( $post_id ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Extended and used in WordPress.com.
346        return false;
347    }
348}