Automattic /
jetpack
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Register WP REST API endpoints for Jetpack. |
||
| 4 | * |
||
| 5 | * @author Automattic |
||
| 6 | */ |
||
| 7 | |||
| 8 | /** |
||
| 9 | * Disable direct access. |
||
| 10 | */ |
||
| 11 | if ( ! defined( 'ABSPATH' ) ) { |
||
| 12 | exit; |
||
| 13 | } |
||
| 14 | |||
| 15 | // Load WP_Error for error messages. |
||
| 16 | require_once ABSPATH . '/wp-includes/class-wp-error.php'; |
||
| 17 | |||
| 18 | // Register endpoints when WP REST API is initialized. |
||
| 19 | add_action( 'rest_api_init', array( 'Jetpack_Core_Json_Api_Endpoints', 'register_endpoints' ) ); |
||
| 20 | |||
| 21 | /** |
||
| 22 | * Class Jetpack_Core_Json_Api_Endpoints |
||
| 23 | * |
||
| 24 | * @since 4.3.0 |
||
| 25 | */ |
||
| 26 | class Jetpack_Core_Json_Api_Endpoints { |
||
| 27 | |||
| 28 | /** |
||
| 29 | * @var string Generic error message when user is not allowed to perform an action. |
||
| 30 | */ |
||
| 31 | public static $user_permissions_error_msg; |
||
| 32 | |||
| 33 | /** |
||
| 34 | * @var array Roles that can access Stats once they're granted access. |
||
| 35 | */ |
||
| 36 | public static $stats_roles; |
||
| 37 | |||
| 38 | /** |
||
| 39 | * Declare the Jetpack REST API endpoints. |
||
| 40 | * |
||
| 41 | * @since 4.3.0 |
||
| 42 | */ |
||
| 43 | public static function register_endpoints() { |
||
| 44 | |||
| 45 | // Load API endpoint base classes |
||
| 46 | require_once JETPACK__PLUGIN_DIR . '_inc/lib/core-api/class.jetpack-core-api-xmlrpc-consumer-endpoint.php'; |
||
| 47 | |||
| 48 | // Load API endpoints |
||
| 49 | require_once JETPACK__PLUGIN_DIR . '_inc/lib/core-api/class.jetpack-core-api-module-endpoints.php'; |
||
| 50 | |||
| 51 | self::$user_permissions_error_msg = esc_html__( |
||
| 52 | 'You do not have the correct user permissions to perform this action. |
||
| 53 | Please contact your site admin if you think this is a mistake.', |
||
| 54 | 'jetpack' |
||
| 55 | ); |
||
| 56 | |||
| 57 | self::$stats_roles = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' ); |
||
| 58 | |||
| 59 | Jetpack::load_xml_rpc_client(); |
||
| 60 | $ixr_client = new Jetpack_IXR_Client( array( 'user_id' => get_current_user_id() ) ); |
||
| 61 | $core_api_endpoint = new Jetpack_Core_API_Data( $ixr_client ); |
||
| 62 | $module_list_endpoint = new Jetpack_Core_API_Module_List_Endpoint(); |
||
| 63 | $module_data_endpoint = new Jetpack_Core_API_Module_Data_Endpoint(); |
||
| 64 | $module_toggle_endpoint = new Jetpack_Core_API_Module_Toggle_Endpoint( new Jetpack_IXR_Client() ); |
||
| 65 | |||
| 66 | // Get current connection status of Jetpack |
||
| 67 | register_rest_route( 'jetpack/v4', '/connection', array( |
||
| 68 | 'methods' => WP_REST_Server::READABLE, |
||
| 69 | 'callback' => __CLASS__ . '::jetpack_connection_status', |
||
| 70 | ) ); |
||
| 71 | |||
| 72 | // Fetches a fresh connect URL |
||
| 73 | register_rest_route( 'jetpack/v4', '/connection/url', array( |
||
| 74 | 'methods' => WP_REST_Server::READABLE, |
||
| 75 | 'callback' => __CLASS__ . '::build_connect_url', |
||
| 76 | 'permission_callback' => __CLASS__ . '::connect_url_permission_callback', |
||
| 77 | ) ); |
||
| 78 | |||
| 79 | // Get current user connection data |
||
| 80 | register_rest_route( 'jetpack/v4', '/connection/data', array( |
||
| 81 | 'methods' => WP_REST_Server::READABLE, |
||
| 82 | 'callback' => __CLASS__ . '::get_user_connection_data', |
||
| 83 | 'permission_callback' => __CLASS__ . '::get_user_connection_data_permission_callback', |
||
| 84 | ) ); |
||
| 85 | |||
| 86 | // Disconnect site from WordPress.com servers |
||
| 87 | register_rest_route( 'jetpack/v4', '/connection', array( |
||
| 88 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 89 | 'callback' => __CLASS__ . '::disconnect_site', |
||
| 90 | 'permission_callback' => __CLASS__ . '::disconnect_site_permission_callback', |
||
| 91 | ) ); |
||
| 92 | |||
| 93 | // Disconnect/unlink user from WordPress.com servers |
||
| 94 | register_rest_route( 'jetpack/v4', '/connection/user', array( |
||
| 95 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 96 | 'callback' => __CLASS__ . '::unlink_user', |
||
| 97 | 'permission_callback' => __CLASS__ . '::unlink_user_permission_callback', |
||
| 98 | ) ); |
||
| 99 | |||
| 100 | // Get current site data |
||
| 101 | register_rest_route( 'jetpack/v4', '/site', array( |
||
| 102 | 'methods' => WP_REST_Server::READABLE, |
||
| 103 | 'callback' => __CLASS__ . '::get_site_data', |
||
| 104 | 'permission_callback' => __CLASS__ . '::view_admin_page_permission_check', |
||
| 105 | ) ); |
||
| 106 | |||
| 107 | // Confirm that a site in identity crisis should be in staging mode |
||
| 108 | register_rest_route( 'jetpack/v4', '/identity-crisis/confirm-safe-mode', array( |
||
| 109 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 110 | 'callback' => __CLASS__ . '::confirm_safe_mode', |
||
| 111 | 'permission_callback' => __CLASS__ . '::identity_crisis_mitigation_permission_check', |
||
| 112 | ) ); |
||
| 113 | |||
| 114 | // IDC resolve: create an entirely new shadow site for this URL. |
||
| 115 | register_rest_route( 'jetpack/v4', '/identity-crisis/start-fresh', array( |
||
| 116 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 117 | 'callback' => __CLASS__ . '::start_fresh_connection', |
||
| 118 | 'permission_callback' => __CLASS__ . '::identity_crisis_mitigation_permission_check', |
||
| 119 | ) ); |
||
| 120 | |||
| 121 | // Handles the request to migrate stats and subscribers during an identity crisis. |
||
| 122 | register_rest_route( 'jetpack/v4', 'identity-crisis/migrate', array( |
||
| 123 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 124 | 'callback' => __CLASS__ . '::migrate_stats_and_subscribers', |
||
| 125 | 'permissison_callback' => __CLASS__ . '::identity_crisis_mitigation_permission_check', |
||
| 126 | ) ); |
||
| 127 | |||
| 128 | // Return all modules |
||
| 129 | register_rest_route( 'jetpack/v4', '/module/all', array( |
||
| 130 | 'methods' => WP_REST_Server::READABLE, |
||
| 131 | 'callback' => array( $module_list_endpoint, 'process' ), |
||
| 132 | 'permission_callback' => array( $module_list_endpoint, 'can_request' ), |
||
| 133 | ) ); |
||
| 134 | |||
| 135 | // Activate many modules |
||
| 136 | register_rest_route( 'jetpack/v4', '/module/all/active', array( |
||
| 137 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 138 | 'callback' => array( $module_list_endpoint, 'process' ), |
||
| 139 | 'permission_callback' => array( $module_list_endpoint, 'can_request' ), |
||
| 140 | 'args' => array( |
||
| 141 | 'modules' => array( |
||
| 142 | 'default' => '', |
||
| 143 | 'type' => 'array', |
||
| 144 | 'items' => array( |
||
| 145 | 'type' => 'string', |
||
| 146 | ), |
||
| 147 | 'required' => true, |
||
| 148 | 'validate_callback' => __CLASS__ . '::validate_module_list', |
||
| 149 | ), |
||
| 150 | 'active' => array( |
||
| 151 | 'default' => true, |
||
| 152 | 'type' => 'boolean', |
||
| 153 | 'required' => false, |
||
| 154 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 155 | ), |
||
| 156 | ) |
||
| 157 | ) ); |
||
| 158 | |||
| 159 | // Return a single module and update it when needed |
||
| 160 | register_rest_route( 'jetpack/v4', '/module/(?P<slug>[a-z\-]+)', array( |
||
| 161 | 'methods' => WP_REST_Server::READABLE, |
||
| 162 | 'callback' => array( $core_api_endpoint, 'process' ), |
||
| 163 | 'permission_callback' => array( $core_api_endpoint, 'can_request' ), |
||
| 164 | ) ); |
||
| 165 | |||
| 166 | // Activate and deactivate a module |
||
| 167 | register_rest_route( 'jetpack/v4', '/module/(?P<slug>[a-z\-]+)/active', array( |
||
| 168 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 169 | 'callback' => array( $module_toggle_endpoint, 'process' ), |
||
| 170 | 'permission_callback' => array( $module_toggle_endpoint, 'can_request' ), |
||
| 171 | 'args' => array( |
||
| 172 | 'active' => array( |
||
| 173 | 'default' => true, |
||
| 174 | 'type' => 'boolean', |
||
| 175 | 'required' => true, |
||
| 176 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 177 | ), |
||
| 178 | ) |
||
| 179 | ) ); |
||
| 180 | |||
| 181 | // Update a module |
||
| 182 | register_rest_route( 'jetpack/v4', '/module/(?P<slug>[a-z\-]+)', array( |
||
| 183 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 184 | 'callback' => array( $core_api_endpoint, 'process' ), |
||
| 185 | 'permission_callback' => array( $core_api_endpoint, 'can_request' ), |
||
| 186 | 'args' => self::get_updateable_parameters( 'any' ) |
||
| 187 | ) ); |
||
| 188 | |||
| 189 | // Get data for a specific module, i.e. Protect block count, WPCOM stats, |
||
| 190 | // Akismet spam count, etc. |
||
| 191 | register_rest_route( 'jetpack/v4', '/module/(?P<slug>[a-z\-]+)/data', array( |
||
| 192 | 'methods' => WP_REST_Server::READABLE, |
||
| 193 | 'callback' => array( $module_data_endpoint, 'process' ), |
||
| 194 | 'permission_callback' => array( $module_data_endpoint, 'can_request' ), |
||
| 195 | 'args' => array( |
||
| 196 | 'range' => array( |
||
| 197 | 'default' => 'day', |
||
| 198 | 'type' => 'string', |
||
| 199 | 'required' => false, |
||
| 200 | 'validate_callback' => __CLASS__ . '::validate_string', |
||
| 201 | ), |
||
| 202 | ) |
||
| 203 | ) ); |
||
| 204 | |||
| 205 | // Update any Jetpack module option or setting |
||
| 206 | register_rest_route( 'jetpack/v4', '/settings', array( |
||
| 207 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 208 | 'callback' => array( $core_api_endpoint, 'process' ), |
||
| 209 | 'permission_callback' => array( $core_api_endpoint, 'can_request' ), |
||
| 210 | 'args' => self::get_updateable_parameters( 'any' ) |
||
| 211 | ) ); |
||
| 212 | |||
| 213 | // Update a module |
||
| 214 | register_rest_route( 'jetpack/v4', '/settings/(?P<slug>[a-z\-]+)', array( |
||
| 215 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 216 | 'callback' => array( $core_api_endpoint, 'process' ), |
||
| 217 | 'permission_callback' => array( $core_api_endpoint, 'can_request' ), |
||
| 218 | 'args' => self::get_updateable_parameters() |
||
| 219 | ) ); |
||
| 220 | |||
| 221 | // Return all module settings |
||
| 222 | register_rest_route( 'jetpack/v4', '/settings/', array( |
||
| 223 | 'methods' => WP_REST_Server::READABLE, |
||
| 224 | 'callback' => array( $core_api_endpoint, 'process' ), |
||
| 225 | 'permission_callback' => array( $core_api_endpoint, 'can_request' ), |
||
| 226 | ) ); |
||
| 227 | |||
| 228 | // Reset all Jetpack options |
||
| 229 | register_rest_route( 'jetpack/v4', '/options/(?P<options>[a-z\-]+)', array( |
||
| 230 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 231 | 'callback' => __CLASS__ . '::reset_jetpack_options', |
||
| 232 | 'permission_callback' => __CLASS__ . '::manage_modules_permission_check', |
||
| 233 | ) ); |
||
| 234 | |||
| 235 | // Return current Jumpstart status |
||
| 236 | register_rest_route( 'jetpack/v4', '/jumpstart', array( |
||
| 237 | 'methods' => WP_REST_Server::READABLE, |
||
| 238 | 'callback' => __CLASS__ . '::jumpstart_status', |
||
| 239 | 'permission_callback' => __CLASS__ . '::update_settings_permission_check', |
||
| 240 | ) ); |
||
| 241 | |||
| 242 | // Update Jumpstart |
||
| 243 | register_rest_route( 'jetpack/v4', '/jumpstart', array( |
||
| 244 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 245 | 'callback' => __CLASS__ . '::jumpstart_toggle', |
||
| 246 | 'permission_callback' => __CLASS__ . '::manage_modules_permission_check', |
||
| 247 | 'args' => array( |
||
| 248 | 'active' => array( |
||
| 249 | 'required' => true, |
||
| 250 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 251 | ), |
||
| 252 | ), |
||
| 253 | ) ); |
||
| 254 | |||
| 255 | // Updates: get number of plugin updates available |
||
| 256 | register_rest_route( 'jetpack/v4', '/updates/plugins', array( |
||
| 257 | 'methods' => WP_REST_Server::READABLE, |
||
| 258 | 'callback' => __CLASS__ . '::get_plugin_update_count', |
||
| 259 | 'permission_callback' => __CLASS__ . '::view_admin_page_permission_check', |
||
| 260 | ) ); |
||
| 261 | |||
| 262 | // Dismiss Jetpack Notices |
||
| 263 | register_rest_route( 'jetpack/v4', '/notice/(?P<notice>[a-z\-_]+)', array( |
||
| 264 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 265 | 'callback' => __CLASS__ . '::dismiss_notice', |
||
| 266 | 'permission_callback' => __CLASS__ . '::view_admin_page_permission_check', |
||
| 267 | ) ); |
||
| 268 | |||
| 269 | // Plugins: get list of all plugins. |
||
| 270 | register_rest_route( 'jetpack/v4', '/plugins', array( |
||
| 271 | 'methods' => WP_REST_Server::READABLE, |
||
| 272 | 'callback' => __CLASS__ . '::get_plugins', |
||
| 273 | 'permission_callback' => __CLASS__ . '::activate_plugins_permission_check', |
||
| 274 | ) ); |
||
| 275 | |||
| 276 | // Plugins: check if the plugin is active. |
||
| 277 | register_rest_route( 'jetpack/v4', '/plugin/(?P<plugin>[a-z\/\.\-_]+)', array( |
||
| 278 | 'methods' => WP_REST_Server::READABLE, |
||
| 279 | 'callback' => __CLASS__ . '::get_plugin', |
||
| 280 | 'permission_callback' => __CLASS__ . '::activate_plugins_permission_check', |
||
| 281 | ) ); |
||
| 282 | } |
||
| 283 | |||
| 284 | /** |
||
| 285 | * Handles dismissing of Jetpack Notices |
||
| 286 | * |
||
| 287 | * @since 4.3.0 |
||
| 288 | * |
||
| 289 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 290 | * |
||
| 291 | * @return array|wp-error |
||
| 292 | */ |
||
| 293 | public static function dismiss_notice( $request ) { |
||
| 294 | $notice = $request['notice']; |
||
| 295 | |||
| 296 | if ( ! isset( $request['dismissed'] ) || $request['dismissed'] !== true ) { |
||
| 297 | return new WP_Error( 'invalid_param', esc_html__( 'Invalid parameter "dismissed".', 'jetpack' ), array( 'status' => 404 ) ); |
||
| 298 | } |
||
| 299 | |||
| 300 | if ( isset( $notice ) && ! empty( $notice ) ) { |
||
| 301 | switch( $notice ) { |
||
| 302 | case 'feedback_dash_request': |
||
| 303 | case 'welcome': |
||
| 304 | $notices = get_option( 'jetpack_dismissed_notices', array() ); |
||
| 305 | $notices[ $notice ] = true; |
||
| 306 | update_option( 'jetpack_dismissed_notices', $notices ); |
||
| 307 | return rest_ensure_response( get_option( 'jetpack_dismissed_notices', array() ) ); |
||
| 308 | |||
| 309 | default: |
||
| 310 | return new WP_Error( 'invalid_param', esc_html__( 'Invalid parameter "notice".', 'jetpack' ), array( 'status' => 404 ) ); |
||
| 311 | } |
||
| 312 | } |
||
| 313 | |||
| 314 | return new WP_Error( 'required_param', esc_html__( 'Missing parameter "notice".', 'jetpack' ), array( 'status' => 404 ) ); |
||
| 315 | } |
||
| 316 | |||
| 317 | /** |
||
| 318 | * Verify that the user can disconnect the site. |
||
| 319 | * |
||
| 320 | * @since 4.3.0 |
||
| 321 | * |
||
| 322 | * @return bool|WP_Error True if user is able to disconnect the site. |
||
| 323 | */ |
||
| 324 | public static function disconnect_site_permission_callback() { |
||
| 325 | if ( current_user_can( 'jetpack_disconnect' ) ) { |
||
| 326 | return true; |
||
| 327 | } |
||
| 328 | |||
| 329 | return new WP_Error( 'invalid_user_permission_jetpack_disconnect', self::$user_permissions_error_msg, array( 'status' => self::rest_authorization_required_code() ) ); |
||
| 330 | |||
| 331 | } |
||
| 332 | |||
| 333 | /** |
||
| 334 | * Verify that the user can get a connect/link URL |
||
| 335 | * |
||
| 336 | * @since 4.3.0 |
||
| 337 | * |
||
| 338 | * @return bool|WP_Error True if user is able to disconnect the site. |
||
| 339 | */ |
||
| 340 | View Code Duplication | public static function connect_url_permission_callback() { |
|
| 341 | if ( current_user_can( 'jetpack_connect_user' ) ) { |
||
| 342 | return true; |
||
| 343 | } |
||
| 344 | |||
| 345 | return new WP_Error( 'invalid_user_permission_jetpack_disconnect', self::$user_permissions_error_msg, array( 'status' => self::rest_authorization_required_code() ) ); |
||
| 346 | |||
| 347 | } |
||
| 348 | |||
| 349 | /** |
||
| 350 | * Verify that a user can get the data about the current user. |
||
| 351 | * Only those who can connect. |
||
| 352 | * |
||
| 353 | * @since 4.3.0 |
||
| 354 | * |
||
| 355 | * @uses Jetpack::is_user_connected(); |
||
| 356 | * |
||
| 357 | * @return bool|WP_Error True if user is able to unlink. |
||
| 358 | */ |
||
| 359 | View Code Duplication | public static function get_user_connection_data_permission_callback() { |
|
| 360 | if ( current_user_can( 'jetpack_connect_user' ) ) { |
||
| 361 | return true; |
||
| 362 | } |
||
| 363 | |||
| 364 | return new WP_Error( 'invalid_user_permission_user_connection_data', self::$user_permissions_error_msg, array( 'status' => self::rest_authorization_required_code() ) ); |
||
| 365 | } |
||
| 366 | |||
| 367 | /** |
||
| 368 | * Verify that a user can use the /connection/user endpoint. Has to be a registered user and be currently linked. |
||
| 369 | * |
||
| 370 | * @since 4.3.0 |
||
| 371 | * |
||
| 372 | * @uses Jetpack::is_user_connected(); |
||
| 373 | * |
||
| 374 | * @return bool|WP_Error True if user is able to unlink. |
||
| 375 | */ |
||
| 376 | public static function unlink_user_permission_callback() { |
||
| 377 | if ( current_user_can( 'jetpack_connect_user' ) && Jetpack::is_user_connected( get_current_user_id() ) ) { |
||
| 378 | return true; |
||
| 379 | } |
||
| 380 | |||
| 381 | return new WP_Error( 'invalid_user_permission_unlink_user', self::$user_permissions_error_msg, array( 'status' => self::rest_authorization_required_code() ) ); |
||
| 382 | } |
||
| 383 | |||
| 384 | /** |
||
| 385 | * Verify that user can manage Jetpack modules. |
||
| 386 | * |
||
| 387 | * @since 4.3.0 |
||
| 388 | * |
||
| 389 | * @return bool Whether user has the capability 'jetpack_manage_modules'. |
||
| 390 | */ |
||
| 391 | public static function manage_modules_permission_check() { |
||
| 392 | if ( current_user_can( 'jetpack_manage_modules' ) ) { |
||
| 393 | return true; |
||
| 394 | } |
||
| 395 | |||
| 396 | return new WP_Error( 'invalid_user_permission_manage_modules', self::$user_permissions_error_msg, array( 'status' => self::rest_authorization_required_code() ) ); |
||
| 397 | } |
||
| 398 | |||
| 399 | /** |
||
| 400 | * Verify that user can update Jetpack modules. |
||
| 401 | * |
||
| 402 | * @since 4.3.0 |
||
| 403 | * |
||
| 404 | * @return bool Whether user has the capability 'jetpack_configure_modules'. |
||
| 405 | */ |
||
| 406 | View Code Duplication | public static function configure_modules_permission_check() { |
|
| 407 | if ( current_user_can( 'jetpack_configure_modules' ) ) { |
||
| 408 | return true; |
||
| 409 | } |
||
| 410 | |||
| 411 | return new WP_Error( 'invalid_user_permission_configure_modules', self::$user_permissions_error_msg, array( 'status' => self::rest_authorization_required_code() ) ); |
||
| 412 | } |
||
| 413 | |||
| 414 | /** |
||
| 415 | * Verify that user can view Jetpack admin page. |
||
| 416 | * |
||
| 417 | * @since 4.3.0 |
||
| 418 | * |
||
| 419 | * @return bool Whether user has the capability 'jetpack_admin_page'. |
||
| 420 | */ |
||
| 421 | View Code Duplication | public static function view_admin_page_permission_check() { |
|
| 422 | if ( current_user_can( 'jetpack_admin_page' ) ) { |
||
| 423 | return true; |
||
| 424 | } |
||
| 425 | |||
| 426 | return new WP_Error( 'invalid_user_permission_view_admin', self::$user_permissions_error_msg, array( 'status' => self::rest_authorization_required_code() ) ); |
||
| 427 | } |
||
| 428 | |||
| 429 | /** |
||
| 430 | * Verify that user can mitigate an identity crisis. |
||
| 431 | * |
||
| 432 | * @since 4.4.0 |
||
| 433 | * |
||
| 434 | * @return bool Whether user has capability 'jetpack_disconnect'. |
||
| 435 | */ |
||
| 436 | public static function identity_crisis_mitigation_permission_check() { |
||
| 437 | if ( current_user_can( 'jetpack_disconnect' ) ) { |
||
| 438 | return true; |
||
| 439 | } |
||
| 440 | |||
| 441 | return new WP_Error( 'invalid_user_permission_identity_crisis', self::$user_permissions_error_msg, array( 'status' => self::rest_authorization_required_code() ) ); |
||
| 442 | } |
||
| 443 | |||
| 444 | /** |
||
| 445 | * Verify that user can update Jetpack general settings. |
||
| 446 | * |
||
| 447 | * @since 4.3.0 |
||
| 448 | * |
||
| 449 | * @return bool Whether user has the capability 'update_settings_permission_check'. |
||
| 450 | */ |
||
| 451 | View Code Duplication | public static function update_settings_permission_check() { |
|
| 452 | if ( current_user_can( 'jetpack_configure_modules' ) ) { |
||
| 453 | return true; |
||
| 454 | } |
||
| 455 | |||
| 456 | return new WP_Error( 'invalid_user_permission_manage_settings', self::$user_permissions_error_msg, array( 'status' => self::rest_authorization_required_code() ) ); |
||
| 457 | } |
||
| 458 | |||
| 459 | /** |
||
| 460 | * Verify that user can view Jetpack admin page and can activate plugins. |
||
| 461 | * |
||
| 462 | * @since 4.3.0 |
||
| 463 | * |
||
| 464 | * @return bool Whether user has the capability 'jetpack_admin_page' and 'activate_plugins'. |
||
| 465 | */ |
||
| 466 | View Code Duplication | public static function activate_plugins_permission_check() { |
|
| 467 | if ( current_user_can( 'jetpack_admin_page' ) && current_user_can( 'activate_plugins' ) ) { |
||
| 468 | return true; |
||
| 469 | } |
||
| 470 | |||
| 471 | return new WP_Error( 'invalid_user_permission_activate_plugins', self::$user_permissions_error_msg, array( 'status' => self::rest_authorization_required_code() ) ); |
||
| 472 | } |
||
| 473 | |||
| 474 | /** |
||
| 475 | * Contextual HTTP error code for authorization failure. |
||
| 476 | * |
||
| 477 | * Taken from rest_authorization_required_code() in WP-API plugin until is added to core. |
||
| 478 | * @see https://github.com/WP-API/WP-API/commit/7ba0ae6fe4f605d5ffe4ee85b1cd5f9fb46900a6 |
||
| 479 | * |
||
| 480 | * @since 4.3.0 |
||
| 481 | * |
||
| 482 | * @return int |
||
| 483 | */ |
||
| 484 | public static function rest_authorization_required_code() { |
||
| 485 | return is_user_logged_in() ? 403 : 401; |
||
| 486 | } |
||
| 487 | |||
| 488 | /** |
||
| 489 | * Get connection status for this Jetpack site. |
||
| 490 | * |
||
| 491 | * @since 4.3.0 |
||
| 492 | * |
||
| 493 | * @return bool True if site is connected |
||
| 494 | */ |
||
| 495 | public static function jetpack_connection_status() { |
||
| 496 | return rest_ensure_response( array( |
||
| 497 | 'isActive' => Jetpack::is_active(), |
||
| 498 | 'isStaging' => Jetpack::is_staging_site(), |
||
| 499 | 'devMode' => array( |
||
| 500 | 'isActive' => Jetpack::is_development_mode(), |
||
| 501 | 'constant' => defined( 'JETPACK_DEV_DEBUG' ) && JETPACK_DEV_DEBUG, |
||
| 502 | 'url' => site_url() && false === strpos( site_url(), '.' ), |
||
| 503 | 'filter' => apply_filters( 'jetpack_development_mode', false ), |
||
| 504 | ), |
||
| 505 | ) |
||
| 506 | ); |
||
| 507 | } |
||
| 508 | |||
| 509 | /** |
||
| 510 | * Disconnects Jetpack from the WordPress.com Servers |
||
| 511 | * |
||
| 512 | * @uses Jetpack::disconnect(); |
||
| 513 | * @since 4.3.0 |
||
| 514 | * |
||
| 515 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 516 | * |
||
| 517 | * @return bool|WP_Error True if Jetpack successfully disconnected. |
||
| 518 | */ |
||
| 519 | View Code Duplication | public static function disconnect_site( $request ) { |
|
| 520 | |||
| 521 | if ( ! isset( $request['isActive'] ) || $request['isActive'] !== false ) { |
||
| 522 | return new WP_Error( 'invalid_param', esc_html__( 'Invalid Parameter', 'jetpack' ), array( 'status' => 404 ) ); |
||
| 523 | } |
||
| 524 | |||
| 525 | if ( Jetpack::is_active() ) { |
||
| 526 | Jetpack::disconnect(); |
||
| 527 | return rest_ensure_response( array( 'code' => 'success' ) ); |
||
| 528 | } |
||
| 529 | |||
| 530 | return new WP_Error( 'disconnect_failed', esc_html__( 'Was not able to disconnect the site. Please try again.', 'jetpack' ), array( 'status' => 400 ) ); |
||
| 531 | } |
||
| 532 | |||
| 533 | /** |
||
| 534 | * Gets a new connect raw URL with fresh nonce. |
||
| 535 | * |
||
| 536 | * @uses Jetpack::disconnect(); |
||
| 537 | * @since 4.3.0 |
||
| 538 | * |
||
| 539 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
|
0 ignored issues
–
show
|
|||
| 540 | * |
||
| 541 | * @return string|WP_Error A raw URL if the connection URL could be built; error message otherwise. |
||
| 542 | */ |
||
| 543 | public static function build_connect_url() { |
||
| 544 | $url = Jetpack::init()->build_connect_url( true, false, false ); |
||
| 545 | if ( $url ) { |
||
| 546 | return rest_ensure_response( $url ); |
||
| 547 | } |
||
| 548 | |||
| 549 | return new WP_Error( 'build_connect_url_failed', esc_html__( 'Unable to build the connect URL. Please reload the page and try again.', 'jetpack' ), array( 'status' => 400 ) ); |
||
| 550 | } |
||
| 551 | |||
| 552 | /** |
||
| 553 | * Get miscellaneous user data related to the connection. Similar data available in old "My Jetpack". |
||
| 554 | * Information about the master/primary user. |
||
| 555 | * Information about the current user. |
||
| 556 | * |
||
| 557 | * @since 4.3.0 |
||
| 558 | * |
||
| 559 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
|
0 ignored issues
–
show
There is no parameter named
$request. Was it maybe removed?
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. Consider the following example. The parameter /**
* @param array $germany
* @param array $island
* @param array $italy
*/
function finale($germany, $island) {
return "2:1";
}
The most likely cause is that the parameter was removed, but the annotation was not. Loading history...
|
|||
| 560 | * |
||
| 561 | * @return object |
||
| 562 | */ |
||
| 563 | public static function get_user_connection_data() { |
||
| 564 | require_once( JETPACK__PLUGIN_DIR . '_inc/lib/admin-pages/class.jetpack-react-page.php' ); |
||
| 565 | |||
| 566 | $response = array( |
||
| 567 | // 'othersLinked' => Jetpack::get_other_linked_admins(), |
||
| 568 | 'currentUser' => jetpack_current_user_data(), |
||
| 569 | ); |
||
| 570 | return rest_ensure_response( $response ); |
||
| 571 | } |
||
| 572 | |||
| 573 | /** |
||
| 574 | * Returns the proper name for Jetpack Holiday Snow setting. |
||
| 575 | * When the REST route starts, the holiday-snow.php file where jetpack_holiday_snow_option_name() function is defined is not loaded, |
||
| 576 | * so where using this to replicate it and have the same functionality. |
||
| 577 | * |
||
| 578 | * @since 4.4.0 |
||
| 579 | * |
||
| 580 | * @return string |
||
| 581 | */ |
||
| 582 | public static function holiday_snow_option_name() { |
||
| 583 | /** This filter is documented in modules/holiday-snow.php */ |
||
| 584 | return apply_filters( 'jetpack_holiday_snow_option_name', 'jetpack_holiday_snow_enabled' ); |
||
| 585 | } |
||
| 586 | |||
| 587 | /** |
||
| 588 | * Update a single miscellaneous setting for this Jetpack installation, like Holiday Snow. |
||
| 589 | * |
||
| 590 | * @since 4.3.0 |
||
| 591 | * |
||
| 592 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 593 | * |
||
| 594 | * @return object Jetpack miscellaneous settings. |
||
| 595 | */ |
||
| 596 | public static function update_setting( $request ) { |
||
| 597 | // Get parameters to update the module. |
||
| 598 | $param = $request->get_params(); |
||
| 599 | |||
| 600 | // Exit if no parameters were passed. |
||
| 601 | View Code Duplication | if ( ! is_array( $param ) ) { |
|
| 602 | return new WP_Error( 'missing_setting', esc_html__( 'Missing setting.', 'jetpack' ), array( 'status' => 404 ) ); |
||
| 603 | } |
||
| 604 | |||
| 605 | // Get option name and value. |
||
| 606 | $option = key( $param ); |
||
| 607 | $value = current( $param ); |
||
| 608 | |||
| 609 | // Log success or not |
||
| 610 | $updated = false; |
||
| 611 | |||
| 612 | switch ( $option ) { |
||
| 613 | case self::holiday_snow_option_name(): |
||
| 614 | $updated = update_option( $option, ( true == (bool) $value ) ? 'letitsnow' : '' ); |
||
| 615 | break; |
||
| 616 | } |
||
| 617 | |||
| 618 | if ( $updated ) { |
||
| 619 | return rest_ensure_response( array( |
||
| 620 | 'code' => 'success', |
||
| 621 | 'message' => esc_html__( 'Setting updated.', 'jetpack' ), |
||
| 622 | 'value' => $value, |
||
| 623 | ) ); |
||
| 624 | } |
||
| 625 | |||
| 626 | return new WP_Error( 'setting_not_updated', esc_html__( 'The setting was not updated.', 'jetpack' ), array( 'status' => 400 ) ); |
||
| 627 | } |
||
| 628 | |||
| 629 | /** |
||
| 630 | * Unlinks current user from the WordPress.com Servers. |
||
| 631 | * |
||
| 632 | * @since 4.3.0 |
||
| 633 | * @uses Jetpack::unlink_user |
||
| 634 | * |
||
| 635 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 636 | * |
||
| 637 | * @return bool|WP_Error True if user successfully unlinked. |
||
| 638 | */ |
||
| 639 | View Code Duplication | public static function unlink_user( $request ) { |
|
| 640 | |||
| 641 | if ( ! isset( $request['linked'] ) || $request['linked'] !== false ) { |
||
| 642 | return new WP_Error( 'invalid_param', esc_html__( 'Invalid Parameter', 'jetpack' ), array( 'status' => 404 ) ); |
||
| 643 | } |
||
| 644 | |||
| 645 | if ( Jetpack::unlink_user() ) { |
||
| 646 | return rest_ensure_response( |
||
| 647 | array( |
||
| 648 | 'code' => 'success' |
||
| 649 | ) |
||
| 650 | ); |
||
| 651 | } |
||
| 652 | |||
| 653 | return new WP_Error( 'unlink_user_failed', esc_html__( 'Was not able to unlink the user. Please try again.', 'jetpack' ), array( 'status' => 400 ) ); |
||
| 654 | } |
||
| 655 | |||
| 656 | /** |
||
| 657 | * Get site data, including for example, the site's current plan. |
||
| 658 | * |
||
| 659 | * @since 4.3.0 |
||
| 660 | * |
||
| 661 | * @return array Array of Jetpack modules. |
||
| 662 | */ |
||
| 663 | public static function get_site_data() { |
||
| 664 | |||
| 665 | if ( $site_id = Jetpack_Options::get_option( 'id' ) ) { |
||
| 666 | $response = Jetpack_Client::wpcom_json_api_request_as_blog( sprintf( '/sites/%d', $site_id ), '1.1' ); |
||
| 667 | |||
| 668 | if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { |
||
| 669 | return new WP_Error( 'site_data_fetch_failed', esc_html__( 'Failed fetching site data. Try again later.', 'jetpack' ), array( 'status' => 400 ) ); |
||
| 670 | } |
||
| 671 | |||
| 672 | // Save plan details in the database for future use without API calls |
||
| 673 | $results = json_decode( $response['body'], true ); |
||
| 674 | |||
| 675 | if ( is_array( $results ) && isset( $results['plan'] ) ) { |
||
| 676 | update_option( 'jetpack_active_plan', $results['plan'] ); |
||
| 677 | } |
||
| 678 | |||
| 679 | return rest_ensure_response( array( |
||
| 680 | 'code' => 'success', |
||
| 681 | 'message' => esc_html__( 'Site data correctly received.', 'jetpack' ), |
||
| 682 | 'data' => wp_remote_retrieve_body( $response ), |
||
| 683 | ) |
||
| 684 | ); |
||
| 685 | } |
||
| 686 | |||
| 687 | return new WP_Error( 'site_id_missing', esc_html__( 'The ID of this site does not exist.', 'jetpack' ), array( 'status' => 404 ) ); |
||
| 688 | } |
||
| 689 | |||
| 690 | /** |
||
| 691 | * Handles identity crisis mitigation, confirming safe mode for this site. |
||
| 692 | * |
||
| 693 | * @since 4.4.0 |
||
| 694 | * |
||
| 695 | * @return bool | WP_Error True if option is properly set. |
||
| 696 | */ |
||
| 697 | public static function confirm_safe_mode() { |
||
| 698 | $updated = Jetpack_Options::update_option( 'safe_mode_confirmed', true ); |
||
| 699 | if ( $updated ) { |
||
| 700 | return rest_ensure_response( |
||
| 701 | array( |
||
| 702 | 'code' => 'success' |
||
| 703 | ) |
||
| 704 | ); |
||
| 705 | } |
||
| 706 | return new WP_Error( |
||
| 707 | 'error_setting_jetpack_safe_mode', |
||
| 708 | esc_html__( 'Could not confirm safe mode.', 'jetpack' ), |
||
| 709 | array( 'status' => 500 ) |
||
| 710 | ); |
||
| 711 | } |
||
| 712 | |||
| 713 | /** |
||
| 714 | * Handles identity crisis mitigation, migrating stats and subscribers from old url to this, new url. |
||
| 715 | * |
||
| 716 | * @since 4.4.0 |
||
| 717 | * |
||
| 718 | * @return bool | WP_Error True if option is properly set. |
||
| 719 | */ |
||
| 720 | public static function migrate_stats_and_subscribers() { |
||
| 721 | if ( Jetpack_Options::get_option( 'sync_error_idc' ) && ! Jetpack_Options::delete_option( 'sync_error_idc' ) ) { |
||
| 722 | return new WP_Error( |
||
| 723 | 'error_deleting_sync_error_idc', |
||
| 724 | esc_html__( 'Could not delete sync error option.', 'jetpack' ), |
||
| 725 | array( 'status' => 500 ) |
||
| 726 | ); |
||
| 727 | } |
||
| 728 | |||
| 729 | if ( Jetpack_Options::get_option( 'migrate_for_idc' ) || Jetpack_Options::update_option( 'migrate_for_idc', true ) ) { |
||
| 730 | return rest_ensure_response( |
||
| 731 | array( |
||
| 732 | 'code' => 'success' |
||
| 733 | ) |
||
| 734 | ); |
||
| 735 | } |
||
| 736 | return new WP_Error( |
||
| 737 | 'error_setting_jetpack_migrate', |
||
| 738 | esc_html__( 'Could not confirm migration.', 'jetpack' ), |
||
| 739 | array( 'status' => 500 ) |
||
| 740 | ); |
||
| 741 | } |
||
| 742 | |||
| 743 | /** |
||
| 744 | * This IDC resolution will disconnect the site and re-connect to a completely new |
||
| 745 | * and separate shadow site than the original. |
||
| 746 | * |
||
| 747 | * It will first will disconnect the site without phoning home as to not disturb the production site. |
||
| 748 | * It then builds a fresh connection URL and sends it back along with the response. |
||
| 749 | * |
||
| 750 | * @since 4.4.0 |
||
| 751 | * @return bool|WP_Error |
||
| 752 | */ |
||
| 753 | public static function start_fresh_connection() { |
||
| 754 | // First clear the options / disconnect. |
||
| 755 | Jetpack::disconnect(); |
||
| 756 | return self::build_connect_url(); |
||
| 757 | } |
||
| 758 | |||
| 759 | /** |
||
| 760 | * Reset Jetpack options |
||
| 761 | * |
||
| 762 | * @since 4.3.0 |
||
| 763 | * |
||
| 764 | * @param WP_REST_Request $request { |
||
| 765 | * Array of parameters received by request. |
||
| 766 | * |
||
| 767 | * @type string $options Available options to reset are options|modules |
||
| 768 | * } |
||
| 769 | * |
||
| 770 | * @return bool|WP_Error True if options were reset. Otherwise, a WP_Error instance with the corresponding error. |
||
| 771 | */ |
||
| 772 | public static function reset_jetpack_options( $request ) { |
||
| 773 | |||
| 774 | if ( ! isset( $request['reset'] ) || $request['reset'] !== true ) { |
||
| 775 | return new WP_Error( 'invalid_param', esc_html__( 'Invalid Parameter', 'jetpack' ), array( 'status' => 404 ) ); |
||
| 776 | } |
||
| 777 | |||
| 778 | if ( isset( $request['options'] ) ) { |
||
| 779 | $data = $request['options']; |
||
| 780 | |||
| 781 | switch( $data ) { |
||
| 782 | case ( 'options' ) : |
||
| 783 | $options_to_reset = Jetpack::get_jetpack_options_for_reset(); |
||
| 784 | |||
| 785 | // Reset the Jetpack options |
||
| 786 | foreach ( $options_to_reset['jp_options'] as $option_to_reset ) { |
||
| 787 | Jetpack_Options::delete_option( $option_to_reset ); |
||
| 788 | } |
||
| 789 | |||
| 790 | foreach ( $options_to_reset['wp_options'] as $option_to_reset ) { |
||
| 791 | delete_option( $option_to_reset ); |
||
| 792 | } |
||
| 793 | |||
| 794 | // Reset to default modules |
||
| 795 | $default_modules = Jetpack::get_default_modules(); |
||
| 796 | Jetpack::update_active_modules( $default_modules ); |
||
| 797 | |||
| 798 | // Jumpstart option is special |
||
| 799 | Jetpack_Options::update_option( 'jumpstart', 'new_connection' ); |
||
| 800 | return rest_ensure_response( array( |
||
| 801 | 'code' => 'success', |
||
| 802 | 'message' => esc_html__( 'Jetpack options reset.', 'jetpack' ), |
||
| 803 | ) ); |
||
| 804 | break; |
||
|
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. Loading history...
|
|||
| 805 | |||
| 806 | case 'modules': |
||
| 807 | $default_modules = Jetpack::get_default_modules(); |
||
| 808 | Jetpack::update_active_modules( $default_modules ); |
||
| 809 | return rest_ensure_response( array( |
||
| 810 | 'code' => 'success', |
||
| 811 | 'message' => esc_html__( 'Modules reset to default.', 'jetpack' ), |
||
| 812 | ) ); |
||
| 813 | break; |
||
|
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. Loading history...
|
|||
| 814 | |||
| 815 | default: |
||
| 816 | return new WP_Error( 'invalid_param', esc_html__( 'Invalid Parameter', 'jetpack' ), array( 'status' => 404 ) ); |
||
| 817 | } |
||
| 818 | } |
||
| 819 | |||
| 820 | return new WP_Error( 'required_param', esc_html__( 'Missing parameter "type".', 'jetpack' ), array( 'status' => 404 ) ); |
||
| 821 | } |
||
| 822 | |||
| 823 | /** |
||
| 824 | * Retrieves the current status of Jumpstart. |
||
| 825 | * |
||
| 826 | * @since 4.5.0 |
||
| 827 | * |
||
| 828 | * @return bool |
||
| 829 | */ |
||
| 830 | public static function jumpstart_status() { |
||
| 831 | return array( |
||
| 832 | 'status' => Jetpack_Options::get_option( 'jumpstart' ) |
||
| 833 | ); |
||
| 834 | } |
||
| 835 | |||
| 836 | /** |
||
| 837 | * Toggles activation or deactivation of the JumpStart |
||
| 838 | * |
||
| 839 | * @since 4.3.0 |
||
| 840 | * |
||
| 841 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 842 | * |
||
| 843 | * @return bool|WP_Error True if toggling Jumpstart succeeded. Otherwise, a WP_Error instance with the corresponding error. |
||
| 844 | */ |
||
| 845 | public static function jumpstart_toggle( $request ) { |
||
| 846 | |||
| 847 | if ( $request[ 'active' ] ) { |
||
| 848 | return self::jumpstart_activate( $request ); |
||
| 849 | } else { |
||
| 850 | return self::jumpstart_deactivate( $request ); |
||
| 851 | } |
||
| 852 | } |
||
| 853 | |||
| 854 | /** |
||
| 855 | * Activates a series of valid Jetpack modules and initializes some options. |
||
| 856 | * |
||
| 857 | * @since 4.3.0 |
||
| 858 | * |
||
| 859 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 860 | * |
||
| 861 | * @return bool|WP_Error True if Jumpstart succeeded. Otherwise, a WP_Error instance with the corresponding error. |
||
| 862 | */ |
||
| 863 | public static function jumpstart_activate( $request ) { |
||
|
0 ignored issues
–
show
|
|||
| 864 | $modules = Jetpack::get_available_modules(); |
||
| 865 | $activate_modules = array(); |
||
| 866 | foreach ( $modules as $module ) { |
||
| 867 | $module_info = Jetpack::get_module( $module ); |
||
| 868 | if ( isset( $module_info['feature'] ) && is_array( $module_info['feature'] ) && in_array( 'Jumpstart', $module_info['feature'] ) ) { |
||
| 869 | $activate_modules[] = $module; |
||
| 870 | } |
||
| 871 | } |
||
| 872 | |||
| 873 | // Collect success/error messages like modules that are properly activated. |
||
| 874 | $result = array( |
||
| 875 | 'activated_modules' => array(), |
||
| 876 | 'failed_modules' => array(), |
||
| 877 | ); |
||
| 878 | |||
| 879 | // Update the jumpstart option |
||
| 880 | if ( 'new_connection' === Jetpack_Options::get_option( 'jumpstart' ) ) { |
||
| 881 | $result['jumpstart_activated'] = Jetpack_Options::update_option( 'jumpstart', 'jumpstart_activated' ); |
||
| 882 | } |
||
| 883 | |||
| 884 | // Check for possible conflicting plugins |
||
| 885 | $module_slugs_filtered = Jetpack::init()->filter_default_modules( $activate_modules ); |
||
| 886 | |||
| 887 | foreach ( $module_slugs_filtered as $module_slug ) { |
||
| 888 | Jetpack::log( 'activate', $module_slug ); |
||
| 889 | if ( Jetpack::activate_module( $module_slug, false, false ) ) { |
||
| 890 | $result['activated_modules'][] = $module_slug; |
||
| 891 | } else { |
||
| 892 | $result['failed_modules'][] = $module_slug; |
||
| 893 | } |
||
| 894 | } |
||
| 895 | |||
| 896 | // Set the default sharing buttons and set to display on posts if none have been set. |
||
| 897 | $sharing_services = get_option( 'sharing-services' ); |
||
| 898 | $sharing_options = get_option( 'sharing-options' ); |
||
| 899 | if ( empty( $sharing_services['visible'] ) ) { |
||
| 900 | // Default buttons to set |
||
| 901 | $visible = array( |
||
| 902 | 'twitter', |
||
| 903 | 'facebook', |
||
| 904 | 'google-plus-1', |
||
| 905 | ); |
||
| 906 | $hidden = array(); |
||
| 907 | |||
| 908 | // Set some sharing settings |
||
| 909 | if ( class_exists( 'Sharing_Service' ) ) { |
||
| 910 | $sharing = new Sharing_Service(); |
||
| 911 | $sharing_options['global'] = array( |
||
| 912 | 'button_style' => 'icon', |
||
| 913 | 'sharing_label' => $sharing->default_sharing_label, |
||
| 914 | 'open_links' => 'same', |
||
| 915 | 'show' => array( 'post' ), |
||
| 916 | 'custom' => isset( $sharing_options['global']['custom'] ) ? $sharing_options['global']['custom'] : array() |
||
| 917 | ); |
||
| 918 | |||
| 919 | $result['sharing_options'] = update_option( 'sharing-options', $sharing_options ); |
||
| 920 | $result['sharing_services'] = update_option( 'sharing-services', array( 'visible' => $visible, 'hidden' => $hidden ) ); |
||
| 921 | } |
||
| 922 | } |
||
| 923 | |||
| 924 | // If all Jumpstart modules were activated |
||
| 925 | View Code Duplication | if ( empty( $result['failed_modules'] ) ) { |
|
| 926 | return rest_ensure_response( array( |
||
| 927 | 'code' => 'success', |
||
| 928 | 'message' => esc_html__( 'Jumpstart done.', 'jetpack' ), |
||
| 929 | 'data' => $result, |
||
| 930 | ) ); |
||
| 931 | } |
||
| 932 | |||
| 933 | return new WP_Error( 'jumpstart_failed', esc_html( sprintf( _n( 'Jumpstart failed activating this module: %s.', 'Jumpstart failed activating these modules: %s.', count( $result['failed_modules'] ), 'jetpack' ), join( ', ', $result['failed_modules'] ) ) ), array( 'status' => 400 ) ); |
||
| 934 | } |
||
| 935 | |||
| 936 | /** |
||
| 937 | * Dismisses Jumpstart so user is not prompted to go through it again. |
||
| 938 | * |
||
| 939 | * @since 4.3.0 |
||
| 940 | * |
||
| 941 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 942 | * |
||
| 943 | * @return bool|WP_Error True if Jumpstart was disabled or was nothing to dismiss. Otherwise, a WP_Error instance with a message. |
||
| 944 | */ |
||
| 945 | public static function jumpstart_deactivate( $request ) { |
||
|
0 ignored issues
–
show
|
|||
| 946 | |||
| 947 | // If dismissed, flag the jumpstart option as such. |
||
| 948 | if ( 'new_connection' === Jetpack_Options::get_option( 'jumpstart' ) ) { |
||
| 949 | if ( Jetpack_Options::update_option( 'jumpstart', 'jumpstart_dismissed' ) ) { |
||
| 950 | return rest_ensure_response( array( |
||
| 951 | 'code' => 'success', |
||
| 952 | 'message' => esc_html__( 'Jumpstart dismissed.', 'jetpack' ), |
||
| 953 | ) ); |
||
| 954 | } else { |
||
| 955 | return new WP_Error( 'jumpstart_failed_dismiss', esc_html__( 'Jumpstart could not be dismissed.', 'jetpack' ), array( 'status' => 400 ) ); |
||
| 956 | } |
||
| 957 | } |
||
| 958 | |||
| 959 | // If this was not a new connection and there was nothing to dismiss, don't fail. |
||
| 960 | return rest_ensure_response( array( |
||
| 961 | 'code' => 'success', |
||
| 962 | 'message' => esc_html__( 'Nothing to dismiss. This was not a new connection.', 'jetpack' ), |
||
| 963 | ) ); |
||
| 964 | } |
||
| 965 | |||
| 966 | /** |
||
| 967 | * Get the query parameters to update module options or general settings. |
||
| 968 | * |
||
| 969 | * @since 4.3.0 |
||
| 970 | * @since 4.4.0 Accepts a $selector parameter. |
||
| 971 | * |
||
| 972 | * @param string $selector Selects a set of options to update, Can be empty, a module slug or 'any'. |
||
| 973 | * |
||
| 974 | * @return array |
||
| 975 | */ |
||
| 976 | public static function get_updateable_parameters( $selector = '' ) { |
||
| 977 | $parameters = array( |
||
| 978 | 'context' => array( |
||
| 979 | 'default' => 'edit', |
||
| 980 | ), |
||
| 981 | ); |
||
| 982 | |||
| 983 | return array_merge( $parameters, self::get_updateable_data_list( $selector ) ); |
||
| 984 | } |
||
| 985 | |||
| 986 | /** |
||
| 987 | * Returns a list of module options or general settings that can be updated. |
||
| 988 | * |
||
| 989 | * @since 4.3.0 |
||
| 990 | * @since 4.4.0 Accepts 'any' as a parameter which will make it return the entire list. |
||
| 991 | * |
||
| 992 | * @param string|array $selector Module slug, 'any', or an array of parameters. |
||
| 993 | * If empty, it's assumed we're updating a module and we'll try to get its slug. |
||
| 994 | * If 'any' the full list is returned. |
||
| 995 | * If it's an array of parameters, includes the elements by matching keys. |
||
| 996 | * |
||
| 997 | * @return array |
||
| 998 | */ |
||
| 999 | public static function get_updateable_data_list( $selector = '' ) { |
||
| 1000 | |||
| 1001 | $options = array( |
||
| 1002 | |||
| 1003 | // Carousel |
||
| 1004 | 'carousel_background_color' => array( |
||
| 1005 | 'description' => esc_html__( 'Color scheme.', 'jetpack' ), |
||
| 1006 | 'type' => 'string', |
||
| 1007 | 'default' => 'black', |
||
| 1008 | 'enum' => array( |
||
| 1009 | 'black', |
||
| 1010 | 'white', |
||
| 1011 | ), |
||
| 1012 | 'enum_labels' => array( |
||
| 1013 | 'black' => esc_html__( 'Black', 'jetpack' ), |
||
| 1014 | 'white' => esc_html__( 'White', 'jetpack' ), |
||
| 1015 | ), |
||
| 1016 | 'validate_callback' => __CLASS__ . '::validate_list_item', |
||
| 1017 | 'jp_group' => 'carousel', |
||
| 1018 | ), |
||
| 1019 | 'carousel_display_exif' => array( |
||
| 1020 | 'description' => wp_kses( sprintf( __( 'Show photo metadata (<a href="http://en.wikipedia.org/wiki/Exchangeable_image_file_format" target="_blank">Exif</a>) in carousel, when available.', 'jetpack' ) ), array( 'a' => array( 'href' => true, 'target' => true ) ) ), |
||
| 1021 | 'type' => 'boolean', |
||
| 1022 | 'default' => 0, |
||
| 1023 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1024 | 'jp_group' => 'carousel', |
||
| 1025 | ), |
||
| 1026 | |||
| 1027 | // Comments |
||
| 1028 | 'highlander_comment_form_prompt' => array( |
||
| 1029 | 'description' => esc_html__( 'Greeting Text', 'jetpack' ), |
||
| 1030 | 'type' => 'string', |
||
| 1031 | 'default' => esc_html__( 'Leave a Reply', 'jetpack' ), |
||
| 1032 | 'sanitize_callback' => 'sanitize_text_field', |
||
| 1033 | 'jp_group' => 'comments', |
||
| 1034 | ), |
||
| 1035 | 'jetpack_comment_form_color_scheme' => array( |
||
| 1036 | 'description' => esc_html__( "Color scheme", 'jetpack' ), |
||
| 1037 | 'type' => 'string', |
||
| 1038 | 'default' => 'light', |
||
| 1039 | 'enum' => array( |
||
| 1040 | 'light', |
||
| 1041 | 'dark', |
||
| 1042 | 'transparent', |
||
| 1043 | ), |
||
| 1044 | 'enum_labels' => array( |
||
| 1045 | 'light' => esc_html__( 'Light', 'jetpack' ), |
||
| 1046 | 'dark' => esc_html__( 'Dark', 'jetpack' ), |
||
| 1047 | 'transparent' => esc_html__( 'Transparent', 'jetpack' ), |
||
| 1048 | ), |
||
| 1049 | 'validate_callback' => __CLASS__ . '::validate_list_item', |
||
| 1050 | 'jp_group' => 'comments', |
||
| 1051 | ), |
||
| 1052 | |||
| 1053 | // Custom Content Types |
||
| 1054 | 'jetpack_portfolio' => array( |
||
| 1055 | 'description' => esc_html__( 'Enable or disable Jetpack portfolio post type.', 'jetpack' ), |
||
| 1056 | 'type' => 'boolean', |
||
| 1057 | 'default' => 0, |
||
| 1058 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1059 | 'jp_group' => 'custom-content-types', |
||
| 1060 | ), |
||
| 1061 | 'jetpack_portfolio_posts_per_page' => array( |
||
| 1062 | 'description' => esc_html__( 'Number of entries to show at most in Portfolio pages.', 'jetpack' ), |
||
| 1063 | 'type' => 'integer', |
||
| 1064 | 'default' => 10, |
||
| 1065 | 'validate_callback' => __CLASS__ . '::validate_posint', |
||
| 1066 | 'jp_group' => 'custom-content-types', |
||
| 1067 | ), |
||
| 1068 | 'jetpack_testimonial' => array( |
||
| 1069 | 'description' => esc_html__( 'Enable or disable Jetpack testimonial post type.', 'jetpack' ), |
||
| 1070 | 'type' => 'boolean', |
||
| 1071 | 'default' => 0, |
||
| 1072 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1073 | 'jp_group' => 'custom-content-types', |
||
| 1074 | ), |
||
| 1075 | 'jetpack_testimonial_posts_per_page' => array( |
||
| 1076 | 'description' => esc_html__( 'Number of entries to show at most in Testimonial pages.', 'jetpack' ), |
||
| 1077 | 'type' => 'integer', |
||
| 1078 | 'default' => 10, |
||
| 1079 | 'validate_callback' => __CLASS__ . '::validate_posint', |
||
| 1080 | 'jp_group' => 'custom-content-types', |
||
| 1081 | ), |
||
| 1082 | |||
| 1083 | // Galleries |
||
| 1084 | 'tiled_galleries' => array( |
||
| 1085 | 'description' => esc_html__( 'Display all your gallery pictures in a cool mosaic.', 'jetpack' ), |
||
| 1086 | 'type' => 'boolean', |
||
| 1087 | 'default' => 0, |
||
| 1088 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1089 | 'jp_group' => 'tiled-gallery', |
||
| 1090 | ), |
||
| 1091 | |||
| 1092 | 'gravatar_disable_hovercards' => array( |
||
| 1093 | 'description' => esc_html__( "View people's profiles when you mouse over their Gravatars", 'jetpack' ), |
||
| 1094 | 'type' => 'string', |
||
| 1095 | 'default' => 'enabled', |
||
| 1096 | // Not visible. This is used as the checkbox value. |
||
| 1097 | 'enum' => array( |
||
| 1098 | 'enabled', |
||
| 1099 | 'disabled', |
||
| 1100 | ), |
||
| 1101 | 'enum_labels' => array( |
||
| 1102 | 'enabled' => esc_html__( 'Enabled', 'jetpack' ), |
||
| 1103 | 'disabled' => esc_html__( 'Disabled', 'jetpack' ), |
||
| 1104 | ), |
||
| 1105 | 'validate_callback' => __CLASS__ . '::validate_list_item', |
||
| 1106 | 'jp_group' => 'gravatar-hovercards', |
||
| 1107 | ), |
||
| 1108 | |||
| 1109 | // Infinite Scroll |
||
| 1110 | 'infinite_scroll' => array( |
||
| 1111 | 'description' => esc_html__( 'To infinity and beyond', 'jetpack' ), |
||
| 1112 | 'type' => 'boolean', |
||
| 1113 | 'default' => 1, |
||
| 1114 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1115 | 'jp_group' => 'infinite-scroll', |
||
| 1116 | ), |
||
| 1117 | 'infinite_scroll_google_analytics' => array( |
||
| 1118 | 'description' => esc_html__( 'Use Google Analytics with Infinite Scroll', 'jetpack' ), |
||
| 1119 | 'type' => 'boolean', |
||
| 1120 | 'default' => 0, |
||
| 1121 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1122 | 'jp_group' => 'infinite-scroll', |
||
| 1123 | ), |
||
| 1124 | |||
| 1125 | // Likes |
||
| 1126 | 'wpl_default' => array( |
||
| 1127 | 'description' => esc_html__( 'WordPress.com Likes are', 'jetpack' ), |
||
| 1128 | 'type' => 'string', |
||
| 1129 | 'default' => 'on', |
||
| 1130 | 'enum' => array( |
||
| 1131 | 'on', |
||
| 1132 | 'off', |
||
| 1133 | ), |
||
| 1134 | 'enum_labels' => array( |
||
| 1135 | 'on' => esc_html__( 'On for all posts', 'jetpack' ), |
||
| 1136 | 'off' => esc_html__( 'Turned on per post', 'jetpack' ), |
||
| 1137 | ), |
||
| 1138 | 'validate_callback' => __CLASS__ . '::validate_list_item', |
||
| 1139 | 'jp_group' => 'likes', |
||
| 1140 | ), |
||
| 1141 | 'social_notifications_like' => array( |
||
| 1142 | 'description' => esc_html__( 'Send email notification when someone likes a post', 'jetpack' ), |
||
| 1143 | 'type' => 'boolean', |
||
| 1144 | 'default' => 1, |
||
| 1145 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1146 | 'jp_group' => 'likes', |
||
| 1147 | ), |
||
| 1148 | |||
| 1149 | // Markdown |
||
| 1150 | 'wpcom_publish_comments_with_markdown' => array( |
||
| 1151 | 'description' => esc_html__( 'Use Markdown for comments.', 'jetpack' ), |
||
| 1152 | 'type' => 'boolean', |
||
| 1153 | 'default' => 0, |
||
| 1154 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1155 | 'jp_group' => 'markdown', |
||
| 1156 | ), |
||
| 1157 | 'wpcom_publish_posts_with_markdown' => array( |
||
| 1158 | 'description' => esc_html__( 'Use Markdown for posts.', 'jetpack' ), |
||
| 1159 | 'type' => 'boolean', |
||
| 1160 | 'default' => 0, |
||
| 1161 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1162 | 'jp_group' => 'markdown', |
||
| 1163 | ), |
||
| 1164 | |||
| 1165 | // Mobile Theme |
||
| 1166 | 'wp_mobile_excerpt' => array( |
||
| 1167 | 'description' => esc_html__( 'Excerpts', 'jetpack' ), |
||
| 1168 | 'type' => 'boolean', |
||
| 1169 | 'default' => 0, |
||
| 1170 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1171 | 'jp_group' => 'minileven', |
||
| 1172 | ), |
||
| 1173 | 'wp_mobile_featured_images' => array( |
||
| 1174 | 'description' => esc_html__( 'Featured Images', 'jetpack' ), |
||
| 1175 | 'type' => 'boolean', |
||
| 1176 | 'default' => 0, |
||
| 1177 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1178 | 'jp_group' => 'minileven', |
||
| 1179 | ), |
||
| 1180 | 'wp_mobile_app_promos' => array( |
||
| 1181 | 'description' => esc_html__( 'Show a promo for the WordPress mobile apps in the footer of the mobile theme.', 'jetpack' ), |
||
| 1182 | 'type' => 'boolean', |
||
| 1183 | 'default' => 0, |
||
| 1184 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1185 | 'jp_group' => 'minileven', |
||
| 1186 | ), |
||
| 1187 | |||
| 1188 | // Monitor |
||
| 1189 | 'monitor_receive_notifications' => array( |
||
| 1190 | 'description' => esc_html__( 'Receive Monitor Email Notifications.', 'jetpack' ), |
||
| 1191 | 'type' => 'boolean', |
||
| 1192 | 'default' => 0, |
||
| 1193 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1194 | 'jp_group' => 'monitor', |
||
| 1195 | ), |
||
| 1196 | |||
| 1197 | // Post by Email |
||
| 1198 | 'post_by_email_address' => array( |
||
| 1199 | 'description' => esc_html__( 'Email Address', 'jetpack' ), |
||
| 1200 | 'type' => 'string', |
||
| 1201 | 'default' => 'noop', |
||
| 1202 | 'enum' => array( |
||
| 1203 | 'noop', |
||
| 1204 | 'create', |
||
| 1205 | 'regenerate', |
||
| 1206 | 'delete', |
||
| 1207 | ), |
||
| 1208 | 'enum_labels' => array( |
||
| 1209 | 'noop' => '', |
||
| 1210 | 'create' => esc_html__( 'Create Post by Email address', 'jetpack' ), |
||
| 1211 | 'regenerate' => esc_html__( 'Regenerate Post by Email address', 'jetpack' ), |
||
| 1212 | 'delete' => esc_html__( 'Delete Post by Email address', 'jetpack' ), |
||
| 1213 | ), |
||
| 1214 | 'validate_callback' => __CLASS__ . '::validate_list_item', |
||
| 1215 | 'jp_group' => 'post-by-email', |
||
| 1216 | ), |
||
| 1217 | |||
| 1218 | // Protect |
||
| 1219 | 'jetpack_protect_key' => array( |
||
| 1220 | 'description' => esc_html__( 'Protect API key', 'jetpack' ), |
||
| 1221 | 'type' => 'string', |
||
| 1222 | 'default' => '', |
||
| 1223 | 'validate_callback' => __CLASS__ . '::validate_alphanum', |
||
| 1224 | 'jp_group' => 'protect', |
||
| 1225 | ), |
||
| 1226 | 'jetpack_protect_global_whitelist' => array( |
||
| 1227 | 'description' => esc_html__( 'Protect global whitelist', 'jetpack' ), |
||
| 1228 | 'type' => 'string', |
||
| 1229 | 'default' => '', |
||
| 1230 | 'validate_callback' => __CLASS__ . '::validate_string', |
||
| 1231 | 'sanitize_callback' => 'esc_textarea', |
||
| 1232 | 'jp_group' => 'protect', |
||
| 1233 | ), |
||
| 1234 | |||
| 1235 | // Sharing |
||
| 1236 | 'sharing_services' => array( |
||
| 1237 | 'description' => esc_html__( 'Enabled Services and those hidden behind a button', 'jetpack' ), |
||
| 1238 | 'type' => 'object', |
||
| 1239 | 'default' => array( |
||
| 1240 | 'visible' => array( 'twitter', 'facebook', 'google-plus-1' ), |
||
| 1241 | 'hidden' => array(), |
||
| 1242 | ), |
||
| 1243 | 'validate_callback' => __CLASS__ . '::validate_services', |
||
| 1244 | 'jp_group' => 'sharedaddy', |
||
| 1245 | ), |
||
| 1246 | 'button_style' => array( |
||
| 1247 | 'description' => esc_html__( 'Button Style', 'jetpack' ), |
||
| 1248 | 'type' => 'string', |
||
| 1249 | 'default' => 'icon', |
||
| 1250 | 'enum' => array( |
||
| 1251 | 'icon-text', |
||
| 1252 | 'icon', |
||
| 1253 | 'text', |
||
| 1254 | 'official', |
||
| 1255 | ), |
||
| 1256 | 'enum_labels' => array( |
||
| 1257 | 'icon-text' => esc_html__( 'Icon + text', 'jetpack' ), |
||
| 1258 | 'icon' => esc_html__( 'Icon only', 'jetpack' ), |
||
| 1259 | 'text' => esc_html__( 'Text only', 'jetpack' ), |
||
| 1260 | 'official' => esc_html__( 'Official buttons', 'jetpack' ), |
||
| 1261 | ), |
||
| 1262 | 'validate_callback' => __CLASS__ . '::validate_list_item', |
||
| 1263 | 'jp_group' => 'sharedaddy', |
||
| 1264 | ), |
||
| 1265 | 'sharing_label' => array( |
||
| 1266 | 'description' => esc_html__( 'Sharing Label', 'jetpack' ), |
||
| 1267 | 'type' => 'string', |
||
| 1268 | 'default' => '', |
||
| 1269 | 'validate_callback' => __CLASS__ . '::validate_string', |
||
| 1270 | 'sanitize_callback' => 'esc_html', |
||
| 1271 | 'jp_group' => 'sharedaddy', |
||
| 1272 | ), |
||
| 1273 | 'show' => array( |
||
| 1274 | 'description' => esc_html__( 'Views where buttons are shown', 'jetpack' ), |
||
| 1275 | 'type' => 'array', |
||
| 1276 | 'items' => array( |
||
| 1277 | 'type' => 'string' |
||
| 1278 | ), |
||
| 1279 | 'default' => array( 'post' ), |
||
| 1280 | 'validate_callback' => __CLASS__ . '::validate_sharing_show', |
||
| 1281 | 'jp_group' => 'sharedaddy', |
||
| 1282 | ), |
||
| 1283 | 'jetpack-twitter-cards-site-tag' => array( |
||
| 1284 | 'description' => esc_html__( "The Twitter username of the owner of this site's domain.", 'jetpack' ), |
||
| 1285 | 'type' => 'string', |
||
| 1286 | 'default' => '', |
||
| 1287 | 'validate_callback' => __CLASS__ . '::validate_twitter_username', |
||
| 1288 | 'sanitize_callback' => 'esc_html', |
||
| 1289 | 'jp_group' => 'sharedaddy', |
||
| 1290 | ), |
||
| 1291 | 'sharedaddy_disable_resources' => array( |
||
| 1292 | 'description' => esc_html__( 'Disable CSS and JS', 'jetpack' ), |
||
| 1293 | 'type' => 'boolean', |
||
| 1294 | 'default' => 0, |
||
| 1295 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1296 | 'jp_group' => 'sharedaddy', |
||
| 1297 | ), |
||
| 1298 | 'custom' => array( |
||
| 1299 | 'description' => esc_html__( 'Custom sharing services added by user.', 'jetpack' ), |
||
| 1300 | 'type' => 'object', |
||
| 1301 | 'default' => array( |
||
| 1302 | 'sharing_name' => '', |
||
| 1303 | 'sharing_url' => '', |
||
| 1304 | 'sharing_icon' => '', |
||
| 1305 | ), |
||
| 1306 | 'validate_callback' => __CLASS__ . '::validate_custom_service', |
||
| 1307 | 'jp_group' => 'sharedaddy', |
||
| 1308 | ), |
||
| 1309 | // Not an option, but an action that can be perfomed on the list of custom services passing the service ID. |
||
| 1310 | 'sharing_delete_service' => array( |
||
| 1311 | 'description' => esc_html__( 'Delete custom sharing service.', 'jetpack' ), |
||
| 1312 | 'type' => 'string', |
||
| 1313 | 'default' => '', |
||
| 1314 | 'validate_callback' => __CLASS__ . '::validate_custom_service_id', |
||
| 1315 | 'jp_group' => 'sharedaddy', |
||
| 1316 | ), |
||
| 1317 | |||
| 1318 | // SSO |
||
| 1319 | 'jetpack_sso_require_two_step' => array( |
||
| 1320 | 'description' => esc_html__( 'Require Two-Step Authentication', 'jetpack' ), |
||
| 1321 | 'type' => 'boolean', |
||
| 1322 | 'default' => 0, |
||
| 1323 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1324 | 'jp_group' => 'sso', |
||
| 1325 | ), |
||
| 1326 | 'jetpack_sso_match_by_email' => array( |
||
| 1327 | 'description' => esc_html__( 'Match by Email', 'jetpack' ), |
||
| 1328 | 'type' => 'boolean', |
||
| 1329 | 'default' => 0, |
||
| 1330 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1331 | 'jp_group' => 'sso', |
||
| 1332 | ), |
||
| 1333 | |||
| 1334 | // Subscriptions |
||
| 1335 | 'stb_enabled' => array( |
||
| 1336 | 'description' => esc_html__( "Show a <em>'follow blog'</em> option in the comment form", 'jetpack' ), |
||
| 1337 | 'type' => 'boolean', |
||
| 1338 | 'default' => 1, |
||
| 1339 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1340 | 'jp_group' => 'subscriptions', |
||
| 1341 | ), |
||
| 1342 | 'stc_enabled' => array( |
||
| 1343 | 'description' => esc_html__( "Show a <em>'follow comments'</em> option in the comment form", 'jetpack' ), |
||
| 1344 | 'type' => 'boolean', |
||
| 1345 | 'default' => 1, |
||
| 1346 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1347 | 'jp_group' => 'subscriptions', |
||
| 1348 | ), |
||
| 1349 | |||
| 1350 | // Related Posts |
||
| 1351 | 'show_headline' => array( |
||
| 1352 | 'description' => esc_html__( 'Show a "Related" header to more clearly separate the related section from posts', 'jetpack' ), |
||
| 1353 | 'type' => 'boolean', |
||
| 1354 | 'default' => 1, |
||
| 1355 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1356 | 'jp_group' => 'related-posts', |
||
| 1357 | ), |
||
| 1358 | 'show_thumbnails' => array( |
||
| 1359 | 'description' => esc_html__( 'Use a large and visually striking layout', 'jetpack' ), |
||
| 1360 | 'type' => 'boolean', |
||
| 1361 | 'default' => 0, |
||
| 1362 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1363 | 'jp_group' => 'related-posts', |
||
| 1364 | ), |
||
| 1365 | |||
| 1366 | // Spelling and Grammar - After the Deadline |
||
| 1367 | 'onpublish' => array( |
||
| 1368 | 'description' => esc_html__( 'Proofread when a post or page is first published.', 'jetpack' ), |
||
| 1369 | 'type' => 'boolean', |
||
| 1370 | 'default' => 0, |
||
| 1371 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1372 | 'jp_group' => 'after-the-deadline', |
||
| 1373 | ), |
||
| 1374 | 'onupdate' => array( |
||
| 1375 | 'description' => esc_html__( 'Proofread when a post or page is updated.', 'jetpack' ), |
||
| 1376 | 'type' => 'boolean', |
||
| 1377 | 'default' => 0, |
||
| 1378 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1379 | 'jp_group' => 'after-the-deadline', |
||
| 1380 | ), |
||
| 1381 | 'Bias Language' => array( |
||
| 1382 | 'description' => esc_html__( 'Bias Language', 'jetpack' ), |
||
| 1383 | 'type' => 'boolean', |
||
| 1384 | 'default' => 0, |
||
| 1385 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1386 | 'jp_group' => 'after-the-deadline', |
||
| 1387 | ), |
||
| 1388 | 'Cliches' => array( |
||
| 1389 | 'description' => esc_html__( 'Clichés', 'jetpack' ), |
||
| 1390 | 'type' => 'boolean', |
||
| 1391 | 'default' => 0, |
||
| 1392 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1393 | 'jp_group' => 'after-the-deadline', |
||
| 1394 | ), |
||
| 1395 | 'Complex Expression' => array( |
||
| 1396 | 'description' => esc_html__( 'Complex Phrases', 'jetpack' ), |
||
| 1397 | 'type' => 'boolean', |
||
| 1398 | 'default' => 0, |
||
| 1399 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1400 | 'jp_group' => 'after-the-deadline', |
||
| 1401 | ), |
||
| 1402 | 'Diacritical Marks' => array( |
||
| 1403 | 'description' => esc_html__( 'Diacritical Marks', 'jetpack' ), |
||
| 1404 | 'type' => 'boolean', |
||
| 1405 | 'default' => 0, |
||
| 1406 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1407 | 'jp_group' => 'after-the-deadline', |
||
| 1408 | ), |
||
| 1409 | 'Double Negative' => array( |
||
| 1410 | 'description' => esc_html__( 'Double Negatives', 'jetpack' ), |
||
| 1411 | 'type' => 'boolean', |
||
| 1412 | 'default' => 0, |
||
| 1413 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1414 | 'jp_group' => 'after-the-deadline', |
||
| 1415 | ), |
||
| 1416 | 'Hidden Verbs' => array( |
||
| 1417 | 'description' => esc_html__( 'Hidden Verbs', 'jetpack' ), |
||
| 1418 | 'type' => 'boolean', |
||
| 1419 | 'default' => 0, |
||
| 1420 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1421 | 'jp_group' => 'after-the-deadline', |
||
| 1422 | ), |
||
| 1423 | 'Jargon Language' => array( |
||
| 1424 | 'description' => esc_html__( 'Jargon', 'jetpack' ), |
||
| 1425 | 'type' => 'boolean', |
||
| 1426 | 'default' => 0, |
||
| 1427 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1428 | 'jp_group' => 'after-the-deadline', |
||
| 1429 | ), |
||
| 1430 | 'Passive voice' => array( |
||
| 1431 | 'description' => esc_html__( 'Passive Voice', 'jetpack' ), |
||
| 1432 | 'type' => 'boolean', |
||
| 1433 | 'default' => 0, |
||
| 1434 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1435 | 'jp_group' => 'after-the-deadline', |
||
| 1436 | ), |
||
| 1437 | 'Phrases to Avoid' => array( |
||
| 1438 | 'description' => esc_html__( 'Phrases to Avoid', 'jetpack' ), |
||
| 1439 | 'type' => 'boolean', |
||
| 1440 | 'default' => 0, |
||
| 1441 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1442 | 'jp_group' => 'after-the-deadline', |
||
| 1443 | ), |
||
| 1444 | 'Redundant Expression' => array( |
||
| 1445 | 'description' => esc_html__( 'Redundant Phrases', 'jetpack' ), |
||
| 1446 | 'type' => 'boolean', |
||
| 1447 | 'default' => 0, |
||
| 1448 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1449 | 'jp_group' => 'after-the-deadline', |
||
| 1450 | ), |
||
| 1451 | 'guess_lang' => array( |
||
| 1452 | 'description' => esc_html__( 'Use automatically detected language to proofread posts and pages', 'jetpack' ), |
||
| 1453 | 'type' => 'boolean', |
||
| 1454 | 'default' => 0, |
||
| 1455 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1456 | 'jp_group' => 'after-the-deadline', |
||
| 1457 | ), |
||
| 1458 | 'ignored_phrases' => array( |
||
| 1459 | 'description' => esc_html__( 'Add Phrase to be ignored', 'jetpack' ), |
||
| 1460 | 'type' => 'string', |
||
| 1461 | 'default' => '', |
||
| 1462 | 'sanitize_callback' => 'esc_html', |
||
| 1463 | 'jp_group' => 'after-the-deadline', |
||
| 1464 | ), |
||
| 1465 | 'unignore_phrase' => array( |
||
| 1466 | 'description' => esc_html__( 'Remove Phrase from being ignored', 'jetpack' ), |
||
| 1467 | 'type' => 'string', |
||
| 1468 | 'default' => '', |
||
| 1469 | 'sanitize_callback' => 'esc_html', |
||
| 1470 | 'jp_group' => 'after-the-deadline', |
||
| 1471 | ), |
||
| 1472 | |||
| 1473 | // Verification Tools |
||
| 1474 | 'google' => array( |
||
| 1475 | 'description' => esc_html__( 'Google Search Console', 'jetpack' ), |
||
| 1476 | 'type' => 'string', |
||
| 1477 | 'default' => '', |
||
| 1478 | 'validate_callback' => __CLASS__ . '::validate_verification_service', |
||
| 1479 | 'jp_group' => 'verification-tools', |
||
| 1480 | ), |
||
| 1481 | 'bing' => array( |
||
| 1482 | 'description' => esc_html__( 'Bing Webmaster Center', 'jetpack' ), |
||
| 1483 | 'type' => 'string', |
||
| 1484 | 'default' => '', |
||
| 1485 | 'validate_callback' => __CLASS__ . '::validate_verification_service', |
||
| 1486 | 'jp_group' => 'verification-tools', |
||
| 1487 | ), |
||
| 1488 | 'pinterest' => array( |
||
| 1489 | 'description' => esc_html__( 'Pinterest Site Verification', 'jetpack' ), |
||
| 1490 | 'type' => 'string', |
||
| 1491 | 'default' => '', |
||
| 1492 | 'validate_callback' => __CLASS__ . '::validate_verification_service', |
||
| 1493 | 'jp_group' => 'verification-tools', |
||
| 1494 | ), |
||
| 1495 | 'yandex' => array( |
||
| 1496 | 'description' => esc_html__( 'Yandex Site Verification', 'jetpack' ), |
||
| 1497 | 'type' => 'string', |
||
| 1498 | 'default' => '', |
||
| 1499 | 'validate_callback' => __CLASS__ . '::validate_verification_service', |
||
| 1500 | 'jp_group' => 'verification-tools', |
||
| 1501 | ), |
||
| 1502 | 'enable_header_ad' => array( |
||
| 1503 | 'description' => esc_html__( 'Display an ad unit at the top of each page.', 'jetpack' ), |
||
| 1504 | 'type' => 'boolean', |
||
| 1505 | 'default' => 0, |
||
| 1506 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1507 | 'jp_group' => 'wordads', |
||
| 1508 | ), |
||
| 1509 | 'wordads_approved' => array( |
||
| 1510 | 'description' => esc_html__( 'Is site approved for WordAds?', 'jetpack' ), |
||
| 1511 | 'type' => 'boolean', |
||
| 1512 | 'default' => 0, |
||
| 1513 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1514 | 'jp_group' => 'wordads', |
||
| 1515 | ), |
||
| 1516 | |||
| 1517 | // Google Analytics |
||
| 1518 | 'google_analytics_tracking_id' => array( |
||
| 1519 | 'description' => esc_html__( 'Google Analytics', 'jetpack' ), |
||
| 1520 | 'type' => 'string', |
||
| 1521 | 'default' => '', |
||
| 1522 | 'validate_callback' => __CLASS__ . '::validate_alphanum', |
||
| 1523 | 'jp_group' => 'google-analytics', |
||
| 1524 | ), |
||
| 1525 | |||
| 1526 | // Stats |
||
| 1527 | 'admin_bar' => array( |
||
| 1528 | 'description' => esc_html__( 'Put a chart showing 48 hours of views in the admin bar.', 'jetpack' ), |
||
| 1529 | 'type' => 'boolean', |
||
| 1530 | 'default' => 1, |
||
| 1531 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1532 | 'jp_group' => 'stats', |
||
| 1533 | ), |
||
| 1534 | 'roles' => array( |
||
| 1535 | 'description' => esc_html__( 'Select the roles that will be able to view stats reports.', 'jetpack' ), |
||
| 1536 | 'type' => 'array', |
||
| 1537 | 'items' => array( |
||
| 1538 | 'type' => 'string' |
||
| 1539 | ), |
||
| 1540 | 'default' => array( 'administrator' ), |
||
| 1541 | 'validate_callback' => __CLASS__ . '::validate_stats_roles', |
||
| 1542 | 'sanitize_callback' => __CLASS__ . '::sanitize_stats_allowed_roles', |
||
| 1543 | 'jp_group' => 'stats', |
||
| 1544 | ), |
||
| 1545 | 'count_roles' => array( |
||
| 1546 | 'description' => esc_html__( 'Count the page views of registered users who are logged in.', 'jetpack' ), |
||
| 1547 | 'type' => 'array', |
||
| 1548 | 'items' => array( |
||
| 1549 | 'type' => 'string' |
||
| 1550 | ), |
||
| 1551 | 'default' => array( 'administrator' ), |
||
| 1552 | 'validate_callback' => __CLASS__ . '::validate_stats_roles', |
||
| 1553 | 'jp_group' => 'stats', |
||
| 1554 | ), |
||
| 1555 | 'blog_id' => array( |
||
| 1556 | 'description' => esc_html__( 'Blog ID.', 'jetpack' ), |
||
| 1557 | 'type' => 'boolean', |
||
| 1558 | 'default' => 0, |
||
| 1559 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1560 | 'jp_group' => 'stats', |
||
| 1561 | ), |
||
| 1562 | 'do_not_track' => array( |
||
| 1563 | 'description' => esc_html__( 'Do not track.', 'jetpack' ), |
||
| 1564 | 'type' => 'boolean', |
||
| 1565 | 'default' => 1, |
||
| 1566 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1567 | 'jp_group' => 'stats', |
||
| 1568 | ), |
||
| 1569 | 'hide_smile' => array( |
||
| 1570 | 'description' => esc_html__( 'Hide the stats smiley face image.', 'jetpack' ), |
||
| 1571 | 'type' => 'boolean', |
||
| 1572 | 'default' => 1, |
||
| 1573 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1574 | 'jp_group' => 'stats', |
||
| 1575 | ), |
||
| 1576 | 'version' => array( |
||
| 1577 | 'description' => esc_html__( 'Version.', 'jetpack' ), |
||
| 1578 | 'type' => 'integer', |
||
| 1579 | 'default' => 9, |
||
| 1580 | 'validate_callback' => __CLASS__ . '::validate_posint', |
||
| 1581 | 'jp_group' => 'stats', |
||
| 1582 | ), |
||
| 1583 | |||
| 1584 | // Settings - Not a module |
||
| 1585 | self::holiday_snow_option_name() => array( |
||
| 1586 | 'description' => '', |
||
| 1587 | 'type' => 'boolean', |
||
| 1588 | 'default' => 0, |
||
| 1589 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1590 | 'jp_group' => 'settings', |
||
| 1591 | ), |
||
| 1592 | |||
| 1593 | // Akismet - Not a module, but a plugin. The options can be passed and handled differently. |
||
| 1594 | 'akismet_show_user_comments_approved' => array( |
||
| 1595 | 'description' => '', |
||
| 1596 | 'type' => 'boolean', |
||
| 1597 | 'default' => 0, |
||
| 1598 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1599 | 'jp_group' => 'settings', |
||
| 1600 | ), |
||
| 1601 | |||
| 1602 | ); |
||
| 1603 | |||
| 1604 | // Add modules to list so they can be toggled |
||
| 1605 | $modules = Jetpack::get_available_modules(); |
||
| 1606 | if ( is_array( $modules ) && ! empty( $modules ) ) { |
||
| 1607 | $module_args = array( |
||
| 1608 | 'description' => '', |
||
| 1609 | 'type' => 'boolean', |
||
| 1610 | 'default' => 0, |
||
| 1611 | 'validate_callback' => __CLASS__ . '::validate_boolean', |
||
| 1612 | 'jp_group' => 'modules', |
||
| 1613 | ); |
||
| 1614 | foreach( $modules as $module ) { |
||
| 1615 | $options[ $module ] = $module_args; |
||
| 1616 | } |
||
| 1617 | } |
||
| 1618 | |||
| 1619 | if ( is_array( $selector ) ) { |
||
| 1620 | |||
| 1621 | // Return only those options whose keys match $selector keys |
||
| 1622 | return array_intersect_key( $options, $selector ); |
||
| 1623 | } |
||
| 1624 | |||
| 1625 | if ( 'any' === $selector ) { |
||
| 1626 | |||
| 1627 | // Toggle module or update any module option or any general setting |
||
| 1628 | return $options; |
||
| 1629 | } |
||
| 1630 | |||
| 1631 | // We're updating the options for a single module. |
||
| 1632 | if ( empty( $selector ) ) { |
||
| 1633 | $selector = self::get_module_requested(); |
||
| 1634 | } |
||
| 1635 | $selected = array(); |
||
| 1636 | foreach ( $options as $option => $attributes ) { |
||
| 1637 | |||
| 1638 | // Not adding an isset( $attributes['jp_group'] ) because if it's not set, it must be fixed, otherwise options will fail. |
||
| 1639 | if ( $selector === $attributes['jp_group'] ) { |
||
| 1640 | $selected[ $option ] = $attributes; |
||
| 1641 | } |
||
| 1642 | } |
||
| 1643 | return $selected; |
||
| 1644 | } |
||
| 1645 | |||
| 1646 | /** |
||
| 1647 | * Validates that the parameter is either a pure boolean or a numeric string that can be mapped to a boolean. |
||
| 1648 | * |
||
| 1649 | * @since 4.3.0 |
||
| 1650 | * |
||
| 1651 | * @param string|bool $value Value to check. |
||
| 1652 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 1653 | * @param string $param Name of the parameter passed to endpoint holding $value. |
||
| 1654 | * |
||
| 1655 | * @return bool |
||
| 1656 | */ |
||
| 1657 | public static function validate_boolean( $value, $request, $param ) { |
||
| 1658 | if ( ! is_bool( $value ) && ! ( ( ctype_digit( $value ) || is_numeric( $value ) ) && in_array( $value, array( 0, 1 ) ) ) ) { |
||
| 1659 | return new WP_Error( 'invalid_param', sprintf( esc_html__( '%s must be true, false, 0 or 1.', 'jetpack' ), $param ) ); |
||
| 1660 | } |
||
| 1661 | return true; |
||
| 1662 | } |
||
| 1663 | |||
| 1664 | /** |
||
| 1665 | * Validates that the parameter is a positive integer. |
||
| 1666 | * |
||
| 1667 | * @since 4.3.0 |
||
| 1668 | * |
||
| 1669 | * @param int $value Value to check. |
||
| 1670 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 1671 | * @param string $param Name of the parameter passed to endpoint holding $value. |
||
| 1672 | * |
||
| 1673 | * @return bool |
||
| 1674 | */ |
||
| 1675 | public static function validate_posint( $value = 0, $request, $param ) { |
||
| 1676 | if ( ! is_numeric( $value ) || $value <= 0 ) { |
||
| 1677 | return new WP_Error( 'invalid_param', sprintf( esc_html__( '%s must be a positive integer.', 'jetpack' ), $param ) ); |
||
| 1678 | } |
||
| 1679 | return true; |
||
| 1680 | } |
||
| 1681 | |||
| 1682 | /** |
||
| 1683 | * Validates that the parameter belongs to a list of admitted values. |
||
| 1684 | * |
||
| 1685 | * @since 4.3.0 |
||
| 1686 | * |
||
| 1687 | * @param string $value Value to check. |
||
| 1688 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 1689 | * @param string $param Name of the parameter passed to endpoint holding $value. |
||
| 1690 | * |
||
| 1691 | * @return bool |
||
| 1692 | */ |
||
| 1693 | public static function validate_list_item( $value = '', $request, $param ) { |
||
| 1694 | $attributes = $request->get_attributes(); |
||
| 1695 | if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { |
||
| 1696 | return new WP_Error( 'invalid_param', sprintf( esc_html__( '%s not recognized', 'jetpack' ), $param ) ); |
||
| 1697 | } |
||
| 1698 | $args = $attributes['args'][ $param ]; |
||
| 1699 | if ( ! empty( $args['enum'] ) ) { |
||
| 1700 | |||
| 1701 | // If it's an associative array, use the keys to check that the value is among those admitted. |
||
| 1702 | $enum = ( count( array_filter( array_keys( $args['enum'] ), 'is_string' ) ) > 0 ) ? array_keys( $args['enum'] ) : $args['enum']; |
||
| 1703 | View Code Duplication | if ( ! in_array( $value, $enum ) ) { |
|
| 1704 | return new WP_Error( 'invalid_param_value', sprintf( |
||
| 1705 | /* Translators: first variable is the parameter passed to endpoint that holds the list item, the second is a list of admitted values. */ |
||
| 1706 | esc_html__( '%1$s must be one of %2$s', 'jetpack' ), $param, implode( ', ', $enum ) |
||
| 1707 | ) ); |
||
| 1708 | } |
||
| 1709 | } |
||
| 1710 | return true; |
||
| 1711 | } |
||
| 1712 | |||
| 1713 | /** |
||
| 1714 | * Validates that the parameter belongs to a list of admitted values. |
||
| 1715 | * |
||
| 1716 | * @since 4.3.0 |
||
| 1717 | * |
||
| 1718 | * @param string $value Value to check. |
||
| 1719 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 1720 | * @param string $param Name of the parameter passed to endpoint holding $value. |
||
| 1721 | * |
||
| 1722 | * @return bool |
||
| 1723 | */ |
||
| 1724 | public static function validate_module_list( $value = '', $request, $param ) { |
||
| 1725 | View Code Duplication | if ( ! is_array( $value ) ) { |
|
| 1726 | return new WP_Error( 'invalid_param_value', sprintf( esc_html__( '%s must be an array', 'jetpack' ), $param ) ); |
||
| 1727 | } |
||
| 1728 | |||
| 1729 | $modules = Jetpack::get_available_modules(); |
||
| 1730 | |||
| 1731 | View Code Duplication | if ( count( array_intersect( $value, $modules ) ) != count( $value ) ) { |
|
| 1732 | return new WP_Error( 'invalid_param_value', sprintf( esc_html__( '%s must be a list of valid modules', 'jetpack' ), $param ) ); |
||
| 1733 | } |
||
| 1734 | |||
| 1735 | return true; |
||
| 1736 | } |
||
| 1737 | |||
| 1738 | /** |
||
| 1739 | * Validates that the parameter is an alphanumeric or empty string (to be able to clear the field). |
||
| 1740 | * |
||
| 1741 | * @since 4.3.0 |
||
| 1742 | * |
||
| 1743 | * @param string $value Value to check. |
||
| 1744 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 1745 | * @param string $param Name of the parameter passed to endpoint holding $value. |
||
| 1746 | * |
||
| 1747 | * @return bool |
||
| 1748 | */ |
||
| 1749 | public static function validate_alphanum( $value = '', $request, $param ) { |
||
| 1750 | View Code Duplication | if ( ! empty( $value ) && ( ! is_string( $value ) || ! preg_match( '/^[a-z0-9]+$/i', $value ) ) ) { |
|
| 1751 | return new WP_Error( 'invalid_param', sprintf( esc_html__( '%s must be an alphanumeric string.', 'jetpack' ), $param ) ); |
||
| 1752 | } |
||
| 1753 | return true; |
||
| 1754 | } |
||
| 1755 | |||
| 1756 | /** |
||
| 1757 | * Validates that the parameter is a tag or id for a verification service, or an empty string (to be able to clear the field). |
||
| 1758 | * |
||
| 1759 | * @since 4.6.0 |
||
| 1760 | * |
||
| 1761 | * @param string $value Value to check. |
||
| 1762 | * @param WP_REST_Request $request |
||
| 1763 | * @param string $param Name of the parameter passed to endpoint holding $value. |
||
| 1764 | * |
||
| 1765 | * @return bool |
||
| 1766 | */ |
||
| 1767 | public static function validate_verification_service( $value = '', $request, $param ) { |
||
| 1768 | View Code Duplication | if ( ! empty( $value ) && ! ( is_string( $value ) && ( preg_match( '/^[a-z0-9_-]+$/i', $value ) || preg_match( '#^<meta name="([a-z0-9_\-.:]+)?" content="([a-z0-9_-]+)?" />$#i', $value ) ) ) ) { |
|
| 1769 | return new WP_Error( 'invalid_param', sprintf( esc_html__( '%s must be an alphanumeric string or a verification tag.', 'jetpack' ), $param ) ); |
||
| 1770 | } |
||
| 1771 | return true; |
||
| 1772 | } |
||
| 1773 | |||
| 1774 | /** |
||
| 1775 | * Validates that the parameter is among the roles allowed for Stats. |
||
| 1776 | * |
||
| 1777 | * @since 4.3.0 |
||
| 1778 | * |
||
| 1779 | * @param string|bool $value Value to check. |
||
| 1780 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 1781 | * @param string $param Name of the parameter passed to endpoint holding $value. |
||
| 1782 | * |
||
| 1783 | * @return bool |
||
| 1784 | */ |
||
| 1785 | public static function validate_stats_roles( $value, $request, $param ) { |
||
| 1786 | if ( ! empty( $value ) && ! array_intersect( self::$stats_roles, $value ) ) { |
||
| 1787 | return new WP_Error( 'invalid_param', sprintf( |
||
| 1788 | /* Translators: first variable is the name of a parameter passed to endpoint holding the role that will be checked, the second is a list of roles allowed to see stats. The parameter is checked against this list. */ |
||
| 1789 | esc_html__( '%1$s must be %2$s.', 'jetpack' ), $param, join( ', ', self::$stats_roles ) |
||
| 1790 | ) ); |
||
| 1791 | } |
||
| 1792 | return true; |
||
| 1793 | } |
||
| 1794 | |||
| 1795 | /** |
||
| 1796 | * Validates that the parameter is among the views where the Sharing can be displayed. |
||
| 1797 | * |
||
| 1798 | * @since 4.3.0 |
||
| 1799 | * |
||
| 1800 | * @param string|bool $value Value to check. |
||
| 1801 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 1802 | * @param string $param Name of the parameter passed to endpoint holding $value. |
||
| 1803 | * |
||
| 1804 | * @return bool |
||
| 1805 | */ |
||
| 1806 | public static function validate_sharing_show( $value, $request, $param ) { |
||
| 1807 | $views = array( 'index', 'post', 'page', 'attachment', 'jetpack-portfolio' ); |
||
| 1808 | View Code Duplication | if ( ! is_array( $value ) ) { |
|
| 1809 | return new WP_Error( 'invalid_param', sprintf( esc_html__( '%s must be an array of post types.', 'jetpack' ), $param ) ); |
||
| 1810 | } |
||
| 1811 | if ( ! array_intersect( $views, $value ) ) { |
||
| 1812 | return new WP_Error( 'invalid_param', sprintf( |
||
| 1813 | /* Translators: first variable is the name of a parameter passed to endpoint holding the post type where Sharing will be displayed, the second is a list of post types where Sharing can be displayed */ |
||
| 1814 | esc_html__( '%1$s must be %2$s.', 'jetpack' ), $param, join( ', ', $views ) |
||
| 1815 | ) ); |
||
| 1816 | } |
||
| 1817 | return true; |
||
| 1818 | } |
||
| 1819 | |||
| 1820 | /** |
||
| 1821 | * Validates that the parameter is among the views where the Sharing can be displayed. |
||
| 1822 | * |
||
| 1823 | * @since 4.3.0 |
||
| 1824 | * |
||
| 1825 | * @param string|bool $value { |
||
| 1826 | * Value to check received by request. |
||
| 1827 | * |
||
| 1828 | * @type array $visible List of slug of services to share to that are displayed directly in the page. |
||
| 1829 | * @type array $hidden List of slug of services to share to that are concealed in a folding menu. |
||
| 1830 | * } |
||
| 1831 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 1832 | * @param string $param Name of the parameter passed to endpoint holding $value. |
||
| 1833 | * |
||
| 1834 | * @return bool |
||
| 1835 | */ |
||
| 1836 | public static function validate_services( $value, $request, $param ) { |
||
| 1837 | View Code Duplication | if ( ! is_array( $value ) || ! isset( $value['visible'] ) || ! isset( $value['hidden'] ) ) { |
|
| 1838 | return new WP_Error( 'invalid_param', sprintf( esc_html__( '%s must be an array with visible and hidden items.', 'jetpack' ), $param ) ); |
||
| 1839 | } |
||
| 1840 | |||
| 1841 | // Allow to clear everything. |
||
| 1842 | if ( empty( $value['visible'] ) && empty( $value['hidden'] ) ) { |
||
| 1843 | return true; |
||
| 1844 | } |
||
| 1845 | |||
| 1846 | View Code Duplication | if ( ! class_exists( 'Sharing_Service' ) && ! @include( JETPACK__PLUGIN_DIR . 'modules/sharedaddy/sharing-service.php' ) ) { |
|
| 1847 | return new WP_Error( 'invalid_param', esc_html__( 'Failed loading required dependency Sharing_Service.', 'jetpack' ) ); |
||
| 1848 | } |
||
| 1849 | $sharer = new Sharing_Service(); |
||
| 1850 | $services = array_keys( $sharer->get_all_services() ); |
||
| 1851 | |||
| 1852 | if ( |
||
| 1853 | ( ! empty( $value['visible'] ) && ! array_intersect( $value['visible'], $services ) ) |
||
| 1854 | || |
||
| 1855 | ( ! empty( $value['hidden'] ) && ! array_intersect( $value['hidden'], $services ) ) ) |
||
| 1856 | { |
||
| 1857 | return new WP_Error( 'invalid_param', sprintf( |
||
| 1858 | /* Translators: placeholder 1 is a parameter holding the services passed to endpoint, placeholder 2 is a list of all Jetpack Sharing services */ |
||
| 1859 | esc_html__( '%1$s visible and hidden items must be a list of %2$s.', 'jetpack' ), $param, join( ', ', $services ) |
||
| 1860 | ) ); |
||
| 1861 | } |
||
| 1862 | return true; |
||
| 1863 | } |
||
| 1864 | |||
| 1865 | /** |
||
| 1866 | * Validates that the parameter has enough information to build a custom sharing button. |
||
| 1867 | * |
||
| 1868 | * @since 4.3.0 |
||
| 1869 | * |
||
| 1870 | * @param string|bool $value Value to check. |
||
| 1871 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 1872 | * @param string $param Name of the parameter passed to endpoint holding $value. |
||
| 1873 | * |
||
| 1874 | * @return bool |
||
| 1875 | */ |
||
| 1876 | public static function validate_custom_service( $value, $request, $param ) { |
||
| 1877 | View Code Duplication | if ( ! is_array( $value ) || ! isset( $value['sharing_name'] ) || ! isset( $value['sharing_url'] ) || ! isset( $value['sharing_icon'] ) ) { |
|
| 1878 | return new WP_Error( 'invalid_param', sprintf( esc_html__( '%s must be an array with sharing name, url and icon.', 'jetpack' ), $param ) ); |
||
| 1879 | } |
||
| 1880 | |||
| 1881 | // Allow to clear everything. |
||
| 1882 | if ( empty( $value['sharing_name'] ) && empty( $value['sharing_url'] ) && empty( $value['sharing_icon'] ) ) { |
||
| 1883 | return true; |
||
| 1884 | } |
||
| 1885 | |||
| 1886 | View Code Duplication | if ( ! class_exists( 'Sharing_Service' ) && ! @include( JETPACK__PLUGIN_DIR . 'modules/sharedaddy/sharing-service.php' ) ) { |
|
| 1887 | return new WP_Error( 'invalid_param', esc_html__( 'Failed loading required dependency Sharing_Service.', 'jetpack' ) ); |
||
| 1888 | } |
||
| 1889 | |||
| 1890 | if ( ( ! empty( $value['sharing_name'] ) && ! is_string( $value['sharing_name'] ) ) |
||
| 1891 | || ( ! empty( $value['sharing_url'] ) && ! is_string( $value['sharing_url'] ) ) |
||
| 1892 | || ( ! empty( $value['sharing_icon'] ) && ! is_string( $value['sharing_icon'] ) ) ) { |
||
| 1893 | return new WP_Error( 'invalid_param', sprintf( esc_html__( '%s needs sharing name, url and icon.', 'jetpack' ), $param ) ); |
||
| 1894 | } |
||
| 1895 | return true; |
||
| 1896 | } |
||
| 1897 | |||
| 1898 | /** |
||
| 1899 | * Validates that the parameter is a custom sharing service ID like 'custom-1461976264'. |
||
| 1900 | * |
||
| 1901 | * @since 4.3.0 |
||
| 1902 | * |
||
| 1903 | * @param string $value Value to check. |
||
| 1904 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 1905 | * @param string $param Name of the parameter passed to endpoint holding $value. |
||
| 1906 | * |
||
| 1907 | * @return bool |
||
| 1908 | */ |
||
| 1909 | public static function validate_custom_service_id( $value = '', $request, $param ) { |
||
| 1910 | View Code Duplication | if ( ! empty( $value ) && ( ! is_string( $value ) || ! preg_match( '/custom\-[0-1]+/i', $value ) ) ) { |
|
| 1911 | return new WP_Error( 'invalid_param', sprintf( esc_html__( "%s must be a string prefixed with 'custom-' and followed by a numeric ID.", 'jetpack' ), $param ) ); |
||
| 1912 | } |
||
| 1913 | |||
| 1914 | View Code Duplication | if ( ! class_exists( 'Sharing_Service' ) && ! @include( JETPACK__PLUGIN_DIR . 'modules/sharedaddy/sharing-service.php' ) ) { |
|
| 1915 | return new WP_Error( 'invalid_param', esc_html__( 'Failed loading required dependency Sharing_Service.', 'jetpack' ) ); |
||
| 1916 | } |
||
| 1917 | $sharer = new Sharing_Service(); |
||
| 1918 | $services = array_keys( $sharer->get_all_services() ); |
||
| 1919 | |||
| 1920 | View Code Duplication | if ( ! empty( $value ) && ! in_array( $value, $services ) ) { |
|
| 1921 | return new WP_Error( 'invalid_param', sprintf( esc_html__( '%s is not a registered custom sharing service.', 'jetpack' ), $param ) ); |
||
| 1922 | } |
||
| 1923 | |||
| 1924 | return true; |
||
| 1925 | } |
||
| 1926 | |||
| 1927 | /** |
||
| 1928 | * Validates that the parameter is a Twitter username or empty string (to be able to clear the field). |
||
| 1929 | * |
||
| 1930 | * @since 4.3.0 |
||
| 1931 | * |
||
| 1932 | * @param string $value Value to check. |
||
| 1933 | * @param WP_REST_Request $request |
||
| 1934 | * @param string $param Name of the parameter passed to endpoint holding $value. |
||
| 1935 | * |
||
| 1936 | * @return bool |
||
| 1937 | */ |
||
| 1938 | public static function validate_twitter_username( $value = '', $request, $param ) { |
||
| 1939 | View Code Duplication | if ( ! empty( $value ) && ( ! is_string( $value ) || ! preg_match( '/^@?\w{1,15}$/i', $value ) ) ) { |
|
| 1940 | return new WP_Error( 'invalid_param', sprintf( esc_html__( '%s must be a Twitter username.', 'jetpack' ), $param ) ); |
||
| 1941 | } |
||
| 1942 | return true; |
||
| 1943 | } |
||
| 1944 | |||
| 1945 | /** |
||
| 1946 | * Validates that the parameter is a string. |
||
| 1947 | * |
||
| 1948 | * @since 4.3.0 |
||
| 1949 | * |
||
| 1950 | * @param string $value Value to check. |
||
| 1951 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 1952 | * @param string $param Name of the parameter passed to endpoint holding $value. |
||
| 1953 | * |
||
| 1954 | * @return bool |
||
| 1955 | */ |
||
| 1956 | public static function validate_string( $value = '', $request, $param ) { |
||
| 1957 | if ( ! is_string( $value ) ) { |
||
| 1958 | return new WP_Error( 'invalid_param', sprintf( esc_html__( '%s must be a string.', 'jetpack' ), $param ) ); |
||
| 1959 | } |
||
| 1960 | return true; |
||
| 1961 | } |
||
| 1962 | |||
| 1963 | /** |
||
| 1964 | * If for some reason the roles allowed to see Stats are empty (for example, user tampering with checkboxes), |
||
| 1965 | * return an array with only 'administrator' as the allowed role and save it for 'roles' option. |
||
| 1966 | * |
||
| 1967 | * @since 4.3.0 |
||
| 1968 | * |
||
| 1969 | * @param string|bool $value Value to check. |
||
| 1970 | * |
||
| 1971 | * @return bool |
||
| 1972 | */ |
||
| 1973 | public static function sanitize_stats_allowed_roles( $value ) { |
||
| 1974 | if ( empty( $value ) ) { |
||
| 1975 | return array( 'administrator' ); |
||
| 1976 | } |
||
| 1977 | return $value; |
||
| 1978 | } |
||
| 1979 | |||
| 1980 | /** |
||
| 1981 | * Get the currently accessed route and return the module slug in it. |
||
| 1982 | * |
||
| 1983 | * @since 4.3.0 |
||
| 1984 | * |
||
| 1985 | * @param string $route Regular expression for the endpoint with the module slug to return. |
||
| 1986 | * |
||
| 1987 | * @return array |
||
| 1988 | */ |
||
| 1989 | public static function get_module_requested( $route = '/module/(?P<slug>[a-z\-]+)' ) { |
||
| 1990 | |||
| 1991 | if ( empty( $GLOBALS['wp']->query_vars['rest_route'] ) ) { |
||
| 1992 | return ''; |
||
| 1993 | } |
||
| 1994 | |||
| 1995 | preg_match( "#$route#", $GLOBALS['wp']->query_vars['rest_route'], $module ); |
||
| 1996 | |||
| 1997 | if ( empty( $module['slug'] ) ) { |
||
| 1998 | return ''; |
||
| 1999 | } |
||
| 2000 | |||
| 2001 | return $module['slug']; |
||
| 2002 | } |
||
| 2003 | |||
| 2004 | /** |
||
| 2005 | * Adds extra information for modules. |
||
| 2006 | * |
||
| 2007 | * @since 4.3.0 |
||
| 2008 | * |
||
| 2009 | * @param string $modules Can be a single module or a list of modules. |
||
| 2010 | * @param null|string $slug Slug of the module in the first parameter. |
||
| 2011 | * |
||
| 2012 | * @return array |
||
| 2013 | */ |
||
| 2014 | public static function prepare_modules_for_response( $modules = '', $slug = null ) { |
||
| 2015 | if ( get_option( 'permalink_structure' ) ) { |
||
| 2016 | $sitemap_url = home_url( '/sitemap.xml' ); |
||
| 2017 | $news_sitemap_url = home_url( '/news-sitemap.xml' ); |
||
| 2018 | } else { |
||
| 2019 | $sitemap_url = home_url( '/?jetpack-sitemap=true' ); |
||
| 2020 | $news_sitemap_url = home_url( '/?jetpack-news-sitemap=true' ); |
||
| 2021 | } |
||
| 2022 | /** This filter is documented in modules/sitemaps/sitemaps.php */ |
||
| 2023 | $sitemap_url = apply_filters( 'jetpack_sitemap_location', $sitemap_url ); |
||
| 2024 | /** This filter is documented in modules/sitemaps/sitemaps.php */ |
||
| 2025 | $news_sitemap_url = apply_filters( 'jetpack_news_sitemap_location', $news_sitemap_url ); |
||
| 2026 | |||
| 2027 | if ( is_null( $slug ) && isset( $modules['sitemaps'] ) ) { |
||
| 2028 | // Is a list of modules |
||
| 2029 | $modules['sitemaps']['extra']['sitemap_url'] = $sitemap_url; |
||
| 2030 | $modules['sitemaps']['extra']['news_sitemap_url'] = $news_sitemap_url; |
||
| 2031 | } elseif ( 'sitemaps' == $slug ) { |
||
| 2032 | // It's a single module |
||
| 2033 | $modules['extra']['sitemap_url'] = $sitemap_url; |
||
| 2034 | $modules['extra']['news_sitemap_url'] = $news_sitemap_url; |
||
| 2035 | } |
||
| 2036 | return $modules; |
||
| 2037 | } |
||
| 2038 | |||
| 2039 | /** |
||
| 2040 | * Remove 'validate_callback' item from options available for module. |
||
| 2041 | * Fetch current option value and add to array of module options. |
||
| 2042 | * Prepare values of module options that need special handling, like those saved in wpcom. |
||
| 2043 | * |
||
| 2044 | * @since 4.3.0 |
||
| 2045 | * |
||
| 2046 | * @param string $module Module slug. |
||
| 2047 | * @return array |
||
| 2048 | */ |
||
| 2049 | public static function prepare_options_for_response( $module = '' ) { |
||
| 2050 | $options = self::get_updateable_data_list( $module ); |
||
| 2051 | |||
| 2052 | if ( ! is_array( $options ) || empty( $options ) ) { |
||
| 2053 | return $options; |
||
| 2054 | } |
||
| 2055 | |||
| 2056 | foreach ( $options as $key => $value ) { |
||
| 2057 | |||
| 2058 | if ( isset( $options[ $key ]['validate_callback'] ) ) { |
||
| 2059 | unset( $options[ $key ]['validate_callback'] ); |
||
| 2060 | } |
||
| 2061 | |||
| 2062 | $default_value = isset( $options[ $key ]['default'] ) ? $options[ $key ]['default'] : ''; |
||
| 2063 | |||
| 2064 | $current_value = get_option( $key, $default_value ); |
||
| 2065 | |||
| 2066 | $options[ $key ]['current_value'] = self::cast_value( $current_value, $options[ $key ] ); |
||
| 2067 | } |
||
| 2068 | |||
| 2069 | // Some modules need special treatment. |
||
| 2070 | switch ( $module ) { |
||
| 2071 | |||
| 2072 | case 'monitor': |
||
| 2073 | // Status of user notifications |
||
| 2074 | $options['monitor_receive_notifications']['current_value'] = self::cast_value( self::get_remote_value( 'monitor', 'monitor_receive_notifications' ), $options['monitor_receive_notifications'] ); |
||
| 2075 | break; |
||
| 2076 | |||
| 2077 | case 'post-by-email': |
||
| 2078 | // Email address |
||
| 2079 | $options['post_by_email_address']['current_value'] = self::cast_value( self::get_remote_value( 'post-by-email', 'post_by_email_address' ), $options['post_by_email_address'] ); |
||
| 2080 | break; |
||
| 2081 | |||
| 2082 | case 'protect': |
||
| 2083 | // Protect |
||
| 2084 | $options['jetpack_protect_key']['current_value'] = get_site_option( 'jetpack_protect_key', false ); |
||
| 2085 | if ( ! function_exists( 'jetpack_protect_format_whitelist' ) ) { |
||
| 2086 | @include( JETPACK__PLUGIN_DIR . 'modules/protect/shared-functions.php' ); |
||
| 2087 | } |
||
| 2088 | $options['jetpack_protect_global_whitelist']['current_value'] = jetpack_protect_format_whitelist(); |
||
| 2089 | break; |
||
| 2090 | |||
| 2091 | case 'related-posts': |
||
| 2092 | // It's local, but it must be broken apart since it's saved as an array. |
||
| 2093 | $options = self::split_options( $options, Jetpack_Options::get_option( 'relatedposts' ) ); |
||
| 2094 | break; |
||
| 2095 | |||
| 2096 | case 'verification-tools': |
||
| 2097 | // It's local, but it must be broken apart since it's saved as an array. |
||
| 2098 | $options = self::split_options( $options, get_option( 'verification_services_codes' ) ); |
||
| 2099 | break; |
||
| 2100 | |||
| 2101 | case 'google-analytics': |
||
| 2102 | $wga = get_option( 'jetpack_wga' ); |
||
| 2103 | $code = ''; |
||
| 2104 | if ( is_array( $wga ) && array_key_exists( 'code', $wga ) ) { |
||
| 2105 | $code = $wga[ 'code' ]; |
||
| 2106 | } |
||
| 2107 | $options[ 'google_analytics_tracking_id' ][ 'current_value' ] = $code; |
||
| 2108 | break; |
||
| 2109 | |||
| 2110 | View Code Duplication | case 'sharedaddy': |
|
| 2111 | // It's local, but it must be broken apart since it's saved as an array. |
||
| 2112 | if ( ! class_exists( 'Sharing_Service' ) && ! @include( JETPACK__PLUGIN_DIR . 'modules/sharedaddy/sharing-service.php' ) ) { |
||
| 2113 | break; |
||
| 2114 | } |
||
| 2115 | $sharer = new Sharing_Service(); |
||
| 2116 | $options = self::split_options( $options, $sharer->get_global_options() ); |
||
| 2117 | $options['sharing_services']['current_value'] = $sharer->get_blog_services(); |
||
| 2118 | break; |
||
| 2119 | |||
| 2120 | case 'after-the-deadline': |
||
| 2121 | if ( ! function_exists( 'AtD_get_options' ) ) { |
||
| 2122 | @include( JETPACK__PLUGIN_DIR . 'modules/after-the-deadline.php' ); |
||
| 2123 | } |
||
| 2124 | $atd_options = array_merge( AtD_get_options( get_current_user_id(), 'AtD_options' ), AtD_get_options( get_current_user_id(), 'AtD_check_when' ) ); |
||
| 2125 | unset( $atd_options['name'] ); |
||
| 2126 | foreach ( $atd_options as $key => $value ) { |
||
| 2127 | $options[ $key ]['current_value'] = self::cast_value( $value, $options[ $key ] ); |
||
| 2128 | } |
||
| 2129 | $atd_options = AtD_get_options( get_current_user_id(), 'AtD_guess_lang' ); |
||
| 2130 | $options['guess_lang']['current_value'] = self::cast_value( isset( $atd_options['true'] ), $options[ 'guess_lang' ] ); |
||
| 2131 | $options['ignored_phrases']['current_value'] = AtD_get_setting( get_current_user_id(), 'AtD_ignored_phrases' ); |
||
| 2132 | unset( $options['unignore_phrase'] ); |
||
| 2133 | break; |
||
| 2134 | |||
| 2135 | case 'stats': |
||
| 2136 | // It's local, but it must be broken apart since it's saved as an array. |
||
| 2137 | if ( ! function_exists( 'stats_get_options' ) ) { |
||
| 2138 | @include( JETPACK__PLUGIN_DIR . 'modules/stats.php' ); |
||
| 2139 | } |
||
| 2140 | $options = self::split_options( $options, stats_get_options() ); |
||
| 2141 | break; |
||
| 2142 | } |
||
| 2143 | |||
| 2144 | return $options; |
||
| 2145 | } |
||
| 2146 | |||
| 2147 | /** |
||
| 2148 | * Splits module options saved as arrays like relatedposts or verification_services_codes into separate options to be returned in the response. |
||
| 2149 | * |
||
| 2150 | * @since 4.3.0 |
||
| 2151 | * |
||
| 2152 | * @param array $separate_options Array of options admitted by the module. |
||
| 2153 | * @param array $grouped_options Option saved as array to be splitted. |
||
| 2154 | * @param string $prefix Optional prefix for the separate option keys. |
||
| 2155 | * |
||
| 2156 | * @return array |
||
| 2157 | */ |
||
| 2158 | public static function split_options( $separate_options, $grouped_options, $prefix = '' ) { |
||
| 2159 | if ( is_array( $grouped_options ) ) { |
||
| 2160 | foreach ( $grouped_options as $key => $value ) { |
||
| 2161 | $option_key = $prefix . $key; |
||
| 2162 | if ( isset( $separate_options[ $option_key ] ) ) { |
||
| 2163 | $separate_options[ $option_key ]['current_value'] = self::cast_value( $grouped_options[ $key ], $separate_options[ $option_key ] ); |
||
| 2164 | } |
||
| 2165 | } |
||
| 2166 | } |
||
| 2167 | return $separate_options; |
||
| 2168 | } |
||
| 2169 | |||
| 2170 | /** |
||
| 2171 | * Perform a casting to the value specified in the option definition. |
||
| 2172 | * |
||
| 2173 | * @since 4.3.0 |
||
| 2174 | * |
||
| 2175 | * @param mixed $value Value to cast to the proper type. |
||
| 2176 | * @param array $definition Type to cast the value to. |
||
| 2177 | * |
||
| 2178 | * @return bool|float|int|string |
||
| 2179 | */ |
||
| 2180 | public static function cast_value( $value, $definition ) { |
||
| 2181 | if ( $value === 'NULL' ) { |
||
| 2182 | return null; |
||
| 2183 | } |
||
| 2184 | |||
| 2185 | if ( isset( $definition['type'] ) ) { |
||
| 2186 | switch ( $definition['type'] ) { |
||
| 2187 | case 'boolean': |
||
| 2188 | if ( 'true' === $value ) { |
||
| 2189 | return true; |
||
| 2190 | } elseif ( 'false' === $value ) { |
||
| 2191 | return false; |
||
| 2192 | } |
||
| 2193 | return (bool) $value; |
||
| 2194 | break; |
||
|
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. Loading history...
|
|||
| 2195 | |||
| 2196 | case 'integer': |
||
| 2197 | return (int) $value; |
||
| 2198 | break; |
||
|
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. Loading history...
|
|||
| 2199 | |||
| 2200 | case 'float': |
||
| 2201 | return (float) $value; |
||
| 2202 | break; |
||
|
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. Loading history...
|
|||
| 2203 | |||
| 2204 | case 'string': |
||
| 2205 | return (string) $value; |
||
| 2206 | break; |
||
|
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. Loading history...
|
|||
| 2207 | } |
||
| 2208 | } |
||
| 2209 | return $value; |
||
| 2210 | } |
||
| 2211 | |||
| 2212 | /** |
||
| 2213 | * Get a value not saved locally. |
||
| 2214 | * |
||
| 2215 | * @since 4.3.0 |
||
| 2216 | * |
||
| 2217 | * @param string $module Module slug. |
||
| 2218 | * @param string $option Option name. |
||
| 2219 | * |
||
| 2220 | * @return bool Whether user is receiving notifications or not. |
||
| 2221 | */ |
||
| 2222 | public static function get_remote_value( $module, $option ) { |
||
| 2223 | |||
| 2224 | if ( in_array( $module, array( 'post-by-email' ), true ) ) { |
||
| 2225 | $option .= get_current_user_id(); |
||
| 2226 | } |
||
| 2227 | |||
| 2228 | // If option doesn't exist, 'does_not_exist' will be returned. |
||
| 2229 | $value = get_option( $option, 'does_not_exist' ); |
||
| 2230 | |||
| 2231 | // If option exists, just return it. |
||
| 2232 | if ( 'does_not_exist' !== $value ) { |
||
| 2233 | return $value; |
||
| 2234 | } |
||
| 2235 | |||
| 2236 | // Only check a remote option if Jetpack is connected. |
||
| 2237 | if ( ! Jetpack::is_active() ) { |
||
| 2238 | return false; |
||
| 2239 | } |
||
| 2240 | |||
| 2241 | // If the module is inactive, load the class to use the method. |
||
| 2242 | if ( ! did_action( 'jetpack_module_loaded_' . $module ) ) { |
||
| 2243 | // Class can't be found so do nothing. |
||
| 2244 | if ( ! @include( Jetpack::get_module_path( $module ) ) ) { |
||
| 2245 | return false; |
||
| 2246 | } |
||
| 2247 | } |
||
| 2248 | |||
| 2249 | // Do what is necessary for each module. |
||
| 2250 | switch ( $module ) { |
||
| 2251 | case 'monitor': |
||
| 2252 | $monitor = new Jetpack_Monitor(); |
||
| 2253 | $value = $monitor->user_receives_notifications( false ); |
||
| 2254 | break; |
||
| 2255 | |||
| 2256 | case 'post-by-email': |
||
| 2257 | $post_by_email = new Jetpack_Post_By_Email(); |
||
| 2258 | $value = $post_by_email->get_post_by_email_address(); |
||
| 2259 | if ( $value === null ) { |
||
| 2260 | $value = 'NULL'; // sentinel value so it actually gets set |
||
| 2261 | } |
||
| 2262 | break; |
||
| 2263 | } |
||
| 2264 | |||
| 2265 | // Normalize value to boolean. |
||
| 2266 | if ( is_wp_error( $value ) || is_null( $value ) ) { |
||
| 2267 | $value = false; |
||
| 2268 | } |
||
| 2269 | |||
| 2270 | // Save option to use it next time. |
||
| 2271 | update_option( $option, $value ); |
||
| 2272 | |||
| 2273 | return $value; |
||
| 2274 | } |
||
| 2275 | |||
| 2276 | /** |
||
| 2277 | * Get number of plugin updates available. |
||
| 2278 | * |
||
| 2279 | * @since 4.3.0 |
||
| 2280 | * |
||
| 2281 | * @return mixed|WP_Error Number of plugin updates available. Otherwise, a WP_Error instance with the corresponding error. |
||
| 2282 | */ |
||
| 2283 | public static function get_plugin_update_count() { |
||
| 2284 | $updates = wp_get_update_data(); |
||
| 2285 | if ( isset( $updates['counts'] ) && isset( $updates['counts']['plugins'] ) ) { |
||
| 2286 | $count = $updates['counts']['plugins']; |
||
| 2287 | if ( 0 == $count ) { |
||
| 2288 | $response = array( |
||
| 2289 | 'code' => 'success', |
||
| 2290 | 'message' => esc_html__( 'All plugins are up-to-date. Keep up the good work!', 'jetpack' ), |
||
| 2291 | 'count' => 0, |
||
| 2292 | ); |
||
| 2293 | } else { |
||
| 2294 | $response = array( |
||
| 2295 | 'code' => 'updates-available', |
||
| 2296 | 'message' => esc_html( sprintf( _n( '%s plugin need updating.', '%s plugins need updating.', $count, 'jetpack' ), $count ) ), |
||
| 2297 | 'count' => $count, |
||
| 2298 | ); |
||
| 2299 | } |
||
| 2300 | return rest_ensure_response( $response ); |
||
| 2301 | } |
||
| 2302 | |||
| 2303 | return new WP_Error( 'not_found', esc_html__( 'Could not check updates for plugins on this site.', 'jetpack' ), array( 'status' => 404 ) ); |
||
| 2304 | } |
||
| 2305 | |||
| 2306 | |||
| 2307 | /** |
||
| 2308 | * Returns a list of all plugins in the site. |
||
| 2309 | * |
||
| 2310 | * @since 4.2.0 |
||
| 2311 | * @uses get_plugins() |
||
| 2312 | * |
||
| 2313 | * @return array |
||
| 2314 | */ |
||
| 2315 | private static function core_get_plugins() { |
||
| 2316 | if ( ! function_exists( 'get_plugins' ) ) { |
||
| 2317 | require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
||
| 2318 | } |
||
| 2319 | /** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */ |
||
| 2320 | $plugins = apply_filters( 'all_plugins', get_plugins() ); |
||
| 2321 | |||
| 2322 | if ( is_array( $plugins ) && ! empty( $plugins ) ) { |
||
| 2323 | foreach ( $plugins as $plugin_slug => $plugin_data ) { |
||
| 2324 | $plugins[ $plugin_slug ]['active'] = self::core_is_plugin_active( $plugin_slug ); |
||
| 2325 | } |
||
| 2326 | return $plugins; |
||
| 2327 | } |
||
| 2328 | |||
| 2329 | return array(); |
||
| 2330 | } |
||
| 2331 | |||
| 2332 | /** |
||
| 2333 | * Checks if the queried plugin is active. |
||
| 2334 | * |
||
| 2335 | * @since 4.2.0 |
||
| 2336 | * @uses is_plugin_active() |
||
| 2337 | * |
||
| 2338 | * @return bool |
||
| 2339 | */ |
||
| 2340 | private static function core_is_plugin_active( $plugin ) { |
||
| 2341 | if ( ! function_exists( 'get_plugins' ) ) { |
||
| 2342 | require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
||
| 2343 | } |
||
| 2344 | |||
| 2345 | return is_plugin_active( $plugin ); |
||
| 2346 | } |
||
| 2347 | |||
| 2348 | /** |
||
| 2349 | * Get plugins data in site. |
||
| 2350 | * |
||
| 2351 | * @since 4.2.0 |
||
| 2352 | * |
||
| 2353 | * @return WP_REST_Response|WP_Error List of plugins in the site. Otherwise, a WP_Error instance with the corresponding error. |
||
| 2354 | */ |
||
| 2355 | public static function get_plugins() { |
||
| 2356 | $plugins = self::core_get_plugins(); |
||
| 2357 | |||
| 2358 | if ( ! empty( $plugins ) ) { |
||
| 2359 | return rest_ensure_response( $plugins ); |
||
| 2360 | } |
||
| 2361 | |||
| 2362 | return new WP_Error( 'not_found', esc_html__( 'Unable to list plugins.', 'jetpack' ), array( 'status' => 404 ) ); |
||
| 2363 | } |
||
| 2364 | |||
| 2365 | /** |
||
| 2366 | * Get data about the queried plugin. Currently it only returns whether the plugin is active or not. |
||
| 2367 | * |
||
| 2368 | * @since 4.2.0 |
||
| 2369 | * |
||
| 2370 | * @param WP_REST_Request $request { |
||
| 2371 | * Array of parameters received by request. |
||
| 2372 | * |
||
| 2373 | * @type string $slug Plugin slug with the syntax 'plugin-directory/plugin-main-file.php'. |
||
| 2374 | * } |
||
| 2375 | * |
||
| 2376 | * @return bool|WP_Error True if module was activated. Otherwise, a WP_Error instance with the corresponding error. |
||
| 2377 | */ |
||
| 2378 | public static function get_plugin( $request ) { |
||
| 2379 | |||
| 2380 | $plugins = self::core_get_plugins(); |
||
| 2381 | |||
| 2382 | if ( empty( $plugins ) ) { |
||
| 2383 | return new WP_Error( 'no_plugins_found', esc_html__( 'This site has no plugins.', 'jetpack' ), array( 'status' => 404 ) ); |
||
| 2384 | } |
||
| 2385 | |||
| 2386 | $plugin = stripslashes( $request['plugin'] ); |
||
| 2387 | |||
| 2388 | if ( ! in_array( $plugin, array_keys( $plugins ) ) ) { |
||
| 2389 | return new WP_Error( 'plugin_not_found', esc_html( sprintf( __( 'Plugin %s is not installed.', 'jetpack' ), $plugin ) ), array( 'status' => 404 ) ); |
||
| 2390 | } |
||
| 2391 | |||
| 2392 | $plugin_data = $plugins[ $plugin ]; |
||
| 2393 | |||
| 2394 | $plugin_data['active'] = self::core_is_plugin_active( $plugin ); |
||
| 2395 | |||
| 2396 | return rest_ensure_response( array( |
||
| 2397 | 'code' => 'success', |
||
| 2398 | 'message' => esc_html__( 'Plugin found.', 'jetpack' ), |
||
| 2399 | 'data' => $plugin_data |
||
| 2400 | ) ); |
||
| 2401 | } |
||
| 2402 | |||
| 2403 | } // class end |
||
| 2404 |
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.
Consider the following example. The parameter
$italyis not defined by the methodfinale(...).The most likely cause is that the parameter was removed, but the annotation was not.