/**
* Updates site settings for authorized users
*
* @return (array)
*/
public function update_settings()
{
// $this->input() retrieves posted arguments whitelisted and casted to the $request_format
// specs that get passed in when this class is instantiated
/**
* Filters the settings to be updated on the site.
*
* @module json-api
*
* @since 3.6.0
*
* @param array $input Associative array of site settings to be updated.
*/
$input = apply_filters('rest_api_update_site_settings', $this->input());
$jetpack_relatedposts_options = array();
$sharing_options = array();
$updated = array();
foreach ($input as $key => $value) {
if (!is_array($value)) {
$value = trim($value);
}
$value = wp_unslash($value);
switch ($key) {
case 'default_ping_status':
case 'default_comment_status':
// settings are stored as closed|open
$coerce_value = $value ? 'open' : 'closed';
if (update_option($key, $coerce_value)) {
$updated[$key] = $value;
}
break;
case 'jetpack_protect_whitelist':
if (function_exists('jetpack_protect_save_whitelist')) {
$result = jetpack_protect_save_whitelist($value);
if (is_wp_error($result)) {
return $result;
}
$updated[$key] = jetpack_protect_format_whitelist();
}
break;
case 'jetpack_sync_non_public_post_stati':
Jetpack_Options::update_option('sync_non_public_post_stati', $value);
break;
case 'jetpack_relatedposts_enabled':
case 'jetpack_relatedposts_show_thumbnails':
case 'jetpack_relatedposts_show_headline':
if (!$this->jetpack_relatedposts_supported()) {
break;
}
if ('jetpack_relatedposts_enabled' === $key && method_exists('Jetpack', 'is_module_active') && $this->jetpack_relatedposts_supported()) {
$before_action = Jetpack::is_module_active('related-posts');
if ($value) {
Jetpack::activate_module('related-posts', false, false);
} else {
Jetpack::deactivate_module('related-posts');
}
$after_action = Jetpack::is_module_active('related-posts');
if ($after_action == $before_action) {
break;
}
}
$just_the_key = substr($key, 21);
$jetpack_relatedposts_options[$just_the_key] = $value;
break;
case 'social_notifications_like':
case 'social_notifications_reblog':
case 'social_notifications_subscribe':
// settings are stored as on|off
$coerce_value = $value ? 'on' : 'off';
if (update_option($key, $coerce_value)) {
$updated[$key] = $value;
}
break;
case 'wga':
if (!isset($value['code']) || !preg_match('/^$|^UA-[\\d-]+$/i', $value['code'])) {
return new WP_Error('invalid_code', 'Invalid UA ID');
}
$wga = get_option('wga', array());
$wga['code'] = $value['code'];
// maintain compatibility with wp-google-analytics
if (update_option('wga', $wga)) {
$updated[$key] = $value;
}
$enabled_or_disabled = $wga['code'] ? 'enabled' : 'disabled';
/** This action is documented in modules/widgets/social-media-icons.php */
do_action('jetpack_bump_stats_extras', 'google-analytics', $enabled_or_disabled);
$business_plugins = WPCOM_Business_Plugins::instance();
$business_plugins->activate_plugin('wp-google-analytics');
break;
case 'jetpack_testimonial':
case 'jetpack_portfolio':
case 'jetpack_comment_likes_enabled':
// settings are stored as 1|0
$coerce_value = (int) $value;
if (update_option($key, $coerce_value)) {
$updated[$key] = (bool) $value;
}
break;
case 'jetpack_testimonial_posts_per_page':
case 'jetpack_portfolio_posts_per_page':
// settings are stored as numeric
$coerce_value = (int) $value;
if (update_option($key, $coerce_value)) {
$updated[$key] = $coerce_value;
}
break;
// Sharing options
// Sharing options
case 'sharing_button_style':
case 'sharing_show':
case 'sharing_open_links':
$sharing_options[preg_replace('/^sharing_/', '', $key)] = $value;
break;
case 'sharing_label':
$sharing_options[$key] = $value;
break;
// Keyring token option
// Keyring token option
case 'eventbrite_api_token':
// These options can only be updated for sites hosted on WordPress.com
if (defined('IS_WPCOM') && IS_WPCOM) {
if (empty($value) || WPCOM_JSON_API::is_falsy($value)) {
if (delete_option($key)) {
$updated[$key] = null;
}
} else {
if (update_option($key, $value)) {
$updated[$key] = (int) $value;
}
}
}
break;
case 'holidaysnow':
if (empty($value) || WPCOM_JSON_API::is_falsy($value)) {
if (function_exists('jetpack_holiday_snow_option_name') && delete_option(jetpack_holiday_snow_option_name())) {
$updated[$key] = false;
}
} else {
if (function_exists('jetpack_holiday_snow_option_name') && update_option(jetpack_holiday_snow_option_name(), 'letitsnow')) {
$updated[$key] = true;
}
}
break;
case 'timezone_string':
// Map UTC+- timezones to gmt_offsets and set timezone_string to empty
// https://github.com/WordPress/WordPress/blob/4.4.2/wp-admin/options.php#L175
if (!empty($value) && preg_match('/^UTC[+-]/', $value)) {
$gmt_offset = preg_replace('/UTC\\+?/', '', $value);
if (update_option('gmt_offset', $gmt_offset)) {
$updated['gmt_offset'] = $gmt_offset;
}
$value = '';
}
// Always set timezone_string either with the given value or with an
// empty string
if (update_option($key, $value)) {
$updated[$key] = $value;
}
break;
case 'site_icon':
// settings are stored as deletable numeric (all empty
// values as delete intent), validated as media image
if (empty($value) || WPCOM_JSON_API::is_falsy($value)) {
if (delete_option($key)) {
$updated[$key] = null;
}
} else {
if (is_numeric($value)) {
$coerce_value = (int) $value;
if (wp_attachment_is_image($coerce_value) && update_option($key, $coerce_value)) {
$updated[$key] = $coerce_value;
}
}
}
break;
case Jetpack_SEO_Utils::FRONT_PAGE_META_OPTION:
if (!Jetpack_SEO_Utils::is_enabled_jetpack_seo() && !Jetpack_SEO_Utils::has_grandfathered_front_page_meta()) {
return new WP_Error('unauthorized', __('SEO tools are not enabled for this site.', 'jetpack'), 403);
}
if (!is_string($value)) {
return new WP_Error('invalid_input', __('Invalid SEO meta description value.', 'jetpack'), 400);
}
$new_description = Jetpack_SEO_Utils::update_front_page_meta_description($value);
if (!empty($new_description)) {
$updated[$key] = $new_description;
}
break;
case Jetpack_SEO_Titles::TITLE_FORMATS_OPTION:
if (!Jetpack_SEO_Utils::is_enabled_jetpack_seo()) {
return new WP_Error('unauthorized', __('SEO tools are not enabled for this site.', 'jetpack'), 403);
}
if (!Jetpack_SEO_Titles::are_valid_title_formats($value)) {
return new WP_Error('invalid_input', __('Invalid SEO title format.', 'jetpack'), 400);
}
$new_title_formats = Jetpack_SEO_Titles::update_title_formats($value);
if (!empty($new_title_formats)) {
$updated[$key] = $new_title_formats;
}
break;
case 'verification_services_codes':
$verification_codes = jetpack_verification_validate($value);
if (update_option('verification_services_codes', $verification_codes)) {
$updated[$key] = $verification_codes;
}
break;
default:
//allow future versions of this endpoint to support additional settings keys
if (has_filter('site_settings_endpoint_update_' . $key)) {
/**
* Filter current site setting value to be updated.
*
* @module json-api
*
* @since 3.9.3
*
* @param mixed $response_item A single site setting value.
*/
$value = apply_filters('site_settings_endpoint_update_' . $key, $value);
$updated[$key] = $value;
continue;
}
// no worries, we've already whitelisted and casted arguments above
if (update_option($key, $value)) {
$updated[$key] = $value;
}
}
}
if (count($jetpack_relatedposts_options)) {
// track new jetpack_relatedposts options against old
$old_relatedposts_options = Jetpack_Options::get_option('relatedposts');
if (Jetpack_Options::update_option('relatedposts', $jetpack_relatedposts_options)) {
foreach ($jetpack_relatedposts_options as $key => $value) {
if ($value !== $old_relatedposts_options[$key]) {
$updated['jetpack_relatedposts_' . $key] = $value;
}
}
}
}
if (!empty($sharing_options) && class_exists('Sharing_Service')) {
$ss = new Sharing_Service();
// Merge current values with updated, since Sharing_Service expects
// all values to be included when updating
$current_sharing_options = $ss->get_global_options();
foreach ($current_sharing_options as $key => $val) {
if (!isset($sharing_options[$key])) {
$sharing_options[$key] = $val;
}
}
$updated_social_options = $ss->set_global_options($sharing_options);
if (isset($input['sharing_button_style'])) {
$updated['sharing_button_style'] = (string) $updated_social_options['button_style'];
}
if (isset($input['sharing_label'])) {
// Sharing_Service won't report label as updated if set to default
$updated['sharing_label'] = (string) $sharing_options['sharing_label'];
}
if (isset($input['sharing_show'])) {
$updated['sharing_show'] = (array) $updated_social_options['show'];
}
if (isset($input['sharing_open_links'])) {
$updated['sharing_open_links'] = (string) $updated_social_options['open_links'];
}
}
return array('updated' => $updated);
}