Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
39.22% covered (danger)
39.22%
20 / 51
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
WPCOM_REST_API_V2_Endpoint_Update_Schedules_Capabilities
39.22% covered (danger)
39.22%
20 / 51
0.00% covered (danger)
0.00%
0 / 4
90.76
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 register_routes
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 get_items_permissions_check
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
3.33
 get_items
50.00% covered (danger)
50.00%
18 / 36
0.00% covered (danger)
0.00%
0 / 1
34.12
1<?php
2/**
3 * Endpoint to manage plugin and theme update schedules capabilities.
4 *
5 * Example: https://public-api.wordpress.com/wpcom/v2/update-schedules/$ID/capabilities
6 *
7 * @package automattic/scheduled-updates
8 */
9
10use Automattic\Jetpack\Constants;
11use Automattic\Jetpack\Status;
12use Automattic\Jetpack\Sync\Functions;
13
14/**
15 * Class WPCOM_REST_API_V2_Endpoint_Update_Schedules_Capabilities
16 */
17class WPCOM_REST_API_V2_Endpoint_Update_Schedules_Capabilities extends WP_REST_Controller {
18    /**
19     * The namespace of this controller's route.
20     *
21     * @var string
22     */
23    public $namespace = 'wpcom/v2';
24
25    /**
26     * The base of this controller's route.
27     *
28     * @var string
29     */
30    public $rest_base = 'update-schedules';
31
32    /**
33     * WPCOM_REST_API_V2_Endpoint_Update_Schedules_Capabilities constructor.
34     */
35    public function __construct() {
36        add_action( 'rest_api_init', array( $this, 'register_routes' ) );
37    }
38
39    /**
40     * Register routes.
41     */
42    public function register_routes() {
43        register_rest_route(
44            $this->namespace,
45            '/' . $this->rest_base . '/capabilities',
46            array(
47                array(
48                    'methods'             => WP_REST_Server::READABLE,
49                    'callback'            => array( $this, 'get_items' ),
50                    'permission_callback' => array( $this, 'get_items_permissions_check' ),
51                ),
52            )
53        );
54    }
55
56    /**
57     * Permission check for retrieving capabilities.
58     *
59     * @param WP_REST_Request $request Request object.
60     * @return bool|WP_Error
61     */
62    public function get_items_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
63        if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
64            return new WP_Error( 'rest_forbidden', __( 'Sorry, you are not allowed to access this endpoint.', 'jetpack-scheduled-updates' ), array( 'status' => 403 ) );
65        }
66
67        return current_user_can( 'update_plugins' );
68    }
69
70    /**
71     * Returns a list of capabilities for updating plugins, and errors if those capabilities are not met.
72     *
73     * @param WP_REST_Request $request Request object.
74     * @return WP_REST_Response
75     */
76    public function get_items( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
77        $reasons_can_not_autoupdate   = array();
78        $reasons_can_not_modify_files = array();
79
80        if ( ! Functions::file_system_write_access() ) {
81            $reasons_can_not_modify_files['has_no_file_system_write_access'] = __( 'The file permissions on this host prevent editing files.', 'jetpack-scheduled-updates' );
82        }
83
84        $disallow_file_mods = Constants::get_constant( 'DISALLOW_FILE_MODS' );
85        if ( $disallow_file_mods ) {
86            $reasons_can_not_modify_files['disallow_file_mods'] = __( 'File modifications are explicitly disabled by a site administrator.', 'jetpack-scheduled-updates' );
87        }
88
89        $automatic_updater_disabled = Constants::get_constant( 'AUTOMATIC_UPDATER_DISABLED' );
90        if ( $automatic_updater_disabled ) {
91            $reasons_can_not_autoupdate['automatic_updater_disabled'] = __( 'Any autoupdates are explicitly disabled by a site administrator.', 'jetpack-scheduled-updates' );
92        }
93
94        if ( is_multisite() ) {
95            if ( ( new Status() )->is_multi_network() ) {
96                $reasons_can_not_modify_files['is_multi_network'] = __( 'Multi network install are not supported.', 'jetpack-scheduled-updates' );
97            }
98            // Is the site the main site here.
99            if ( ! is_main_site() ) {
100                $reasons_can_not_modify_files['is_sub_site'] = __( 'The site is not the main network site', 'jetpack-scheduled-updates' );
101            }
102        }
103
104        $file_mod_capabilities = array(
105            'modify_files'     => empty( $reasons_can_not_modify_files ), // Install, remove, update.
106            'autoupdate_files' => empty( $reasons_can_not_modify_files ) && empty( $reasons_can_not_autoupdate ), // Enable autoupdates.
107        );
108
109        $errors = array();
110
111        if ( ! empty( $reasons_can_not_modify_files ) ) {
112            foreach ( $reasons_can_not_modify_files as $error_code => $error_message ) {
113                $errors[] = array(
114                    'code'    => $error_code,
115                    'message' => $error_message,
116                );
117            }
118        }
119
120        if ( ! $file_mod_capabilities['autoupdate_files'] ) {
121            foreach ( $reasons_can_not_autoupdate as $error_code => $error_message ) {
122                $errors[] = array(
123                    'code'    => $error_code,
124                    'message' => $error_message,
125                );
126            }
127        }
128
129        $errors = array_unique( $errors );
130        if ( ! empty( $errors ) ) {
131            $file_mod_capabilities['errors'] = $errors;
132        }
133
134        return rest_ensure_response( $file_mod_capabilities );
135    }
136}