/**
  * Remove 'validate_callback' item from options available for module.
  * Fetch current option value and add to array of module options.
  * Prepare values of module options that need special handling, like those saved in wpcom.
  *
  * @since 4.3.0
  *
  * @param string $module Module slug.
  * @return array
  */
 public static function prepare_options_for_response($module = '')
 {
     $options = self::get_module_available_options($module);
     if (!is_array($options) || empty($options)) {
         return $options;
     }
     foreach ($options as $key => $value) {
         if (isset($options[$key]['validate_callback'])) {
             unset($options[$key]['validate_callback']);
         }
         $default_value = isset($options[$key]['default']) ? $options[$key]['default'] : '';
         $current_value = get_option($key, $default_value);
         $options[$key]['current_value'] = self::cast_value($current_value, $options[$key]);
     }
     // Some modules need special treatment.
     switch ($module) {
         case 'monitor':
             // Status of user notifications
             $options['monitor_receive_notifications']['current_value'] = self::cast_value(self::get_remote_value('monitor', 'monitor_receive_notifications'), $options['monitor_receive_notifications']);
             break;
         case 'post-by-email':
             // Email address
             $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']);
             break;
         case 'protect':
             // Protect
             $options['jetpack_protect_key']['current_value'] = get_site_option('jetpack_protect_key', false);
             if (!function_exists('jetpack_protect_format_whitelist')) {
                 @(include JETPACK__PLUGIN_DIR . 'modules/protect/shared-functions.php');
             }
             $options['jetpack_protect_global_whitelist']['current_value'] = jetpack_protect_format_whitelist();
             break;
         case 'related-posts':
             // It's local, but it must be broken apart since it's saved as an array.
             $options = self::split_options($options, Jetpack_Options::get_option('relatedposts'));
             break;
         case 'verification-tools':
             // It's local, but it must be broken apart since it's saved as an array.
             $options = self::split_options($options, get_option('verification_services_codes'));
             break;
         case 'sharedaddy':
             // It's local, but it must be broken apart since it's saved as an array.
             if (!class_exists('Sharing_Service') && !@(include JETPACK__PLUGIN_DIR . 'modules/sharedaddy/sharing-service.php')) {
                 break;
             }
             $sharer = new Sharing_Service();
             $options = self::split_options($options, $sharer->get_global_options());
             $options['sharing_services']['current_value'] = $sharer->get_blog_services();
             break;
         case 'site-icon':
             // Return site icon ID and URL to make it more complete.
             $options['site_icon_id']['current_value'] = Jetpack_Options::get_option('site_icon_id');
             if (!function_exists('jetpack_site_icon_url')) {
                 @(include JETPACK__PLUGIN_DIR . 'modules/site-icon/site-icon-functions.php');
             }
             $options['site_icon_url']['current_value'] = jetpack_site_icon_url();
             break;
         case 'after-the-deadline':
             if (!function_exists('AtD_get_options')) {
                 @(include JETPACK__PLUGIN_DIR . 'modules/after-the-deadline.php');
             }
             $atd_options = array_merge(AtD_get_options(get_current_user_id(), 'AtD_options'), AtD_get_options(get_current_user_id(), 'AtD_check_when'));
             unset($atd_options['name']);
             foreach ($atd_options as $key => $value) {
                 $options[$key]['current_value'] = self::cast_value($value, $options[$key]);
             }
             $atd_options = AtD_get_options(get_current_user_id(), 'AtD_guess_lang');
             $options['guess_lang']['current_value'] = self::cast_value(isset($atd_options['true']), $options['guess_lang']);
             $options['ignored_phrases']['current_value'] = AtD_get_setting(get_current_user_id(), 'AtD_ignored_phrases');
             unset($options['unignore_phrase']);
             break;
         case 'minileven':
             $options['wp_mobile_excerpt']['current_value'] = 1 === intval($options['wp_mobile_excerpt']['current_value']) ? 'enabled' : 'disabled';
             $options['wp_mobile_featured_images']['current_value'] = 1 === intval($options['wp_mobile_featured_images']['current_value']) ? 'enabled' : 'disabled';
             break;
         case 'stats':
             // It's local, but it must be broken apart since it's saved as an array.
             if (!function_exists('stats_get_options')) {
                 @(include JETPACK__PLUGIN_DIR . 'modules/stats.php');
             }
             $options = self::split_options($options, stats_get_options());
             break;
     }
     return $options;
 }
function AtD_display_options_form()
{
    /* grab our user and validate their existence */
    $user = wp_get_current_user();
    if (!$user || $user->ID == 0) {
        return;
    }
    $options_show_types = AtD_get_options($user->ID, 'AtD_options');
    $options_check_when = AtD_get_options($user->ID, 'AtD_check_when');
    $options_guess_lang = AtD_get_options($user->ID, 'AtD_guess_lang');
    ?>
   <table class="form-table">
      <tr valign="top">
         <th scope="row"> <a name="atd"></a> <?php 
    _e('Proofreading', 'jetpack');
    ?>
</th>
		 <td>
   <p><?php 
    _e('Automatically proofread content when:', 'jetpack');
    ?>

   <p><?php 
    AtD_print_option('onpublish', __('a post or page is first published', 'jetpack'), $options_check_when);
    echo '<br />';
    AtD_print_option('onupdate', __('a post or page is updated', 'jetpack'), $options_check_when);
    ?>
</p>

   <p style="font-weight: bold"><?php 
    _e('English Options', 'jetpack');
    ?>
</font>

   <p><?php 
    _e('Enable proofreading for the following grammar and style rules when writing posts and pages:', 'jetpack');
    ?>
</p>

   <p><?php 
    AtD_print_option('Bias Language', __('Bias Language', 'jetpack'), $options_show_types);
    echo '<br />';
    AtD_print_option('Cliches', __('Clich&eacute;s', 'jetpack'), $options_show_types);
    echo '<br />';
    AtD_print_option('Complex Expression', __('Complex Phrases', 'jetpack'), $options_show_types);
    echo '<br />';
    AtD_print_option('Diacritical Marks', __('Diacritical Marks', 'jetpack'), $options_show_types);
    echo '<br />';
    AtD_print_option('Double Negative', __('Double Negatives', 'jetpack'), $options_show_types);
    echo '<br />';
    AtD_print_option('Hidden Verbs', __('Hidden Verbs', 'jetpack'), $options_show_types);
    echo '<br />';
    AtD_print_option('Jargon Language', __('Jargon', 'jetpack'), $options_show_types);
    echo '<br />';
    AtD_print_option('Passive voice', __('Passive Voice', 'jetpack'), $options_show_types);
    echo '<br />';
    AtD_print_option('Phrases to Avoid', __('Phrases to Avoid', 'jetpack'), $options_show_types);
    echo '<br />';
    AtD_print_option('Redundant Expression', __('Redundant Phrases', 'jetpack'), $options_show_types);
    ?>
</p>
   <p><?php 
    printf(__('<a href="%s">Learn more</a> about these options.', 'jetpack'), 'http://support.wordpress.com/proofreading/');
    ?>
</p>

   <p style="font-weight: bold"><?php 
    _e('Language', 'jetpack');
    ?>
</font>

   <p><?php 
    printf(__('The proofreader supports English, French, German, Portuguese, and Spanish. Your <a href="%s">WPLANG</a> value is the default proofreading language.', 'jetpack'), 'http://codex.wordpress.org/Installing_WordPress_in_Your_Language');
    ?>
</p>

   <p><?php 
    AtD_print_option('true', __('Use automatically detected language to proofread posts and pages', 'jetpack'), $options_guess_lang);
    ?>
</p>

<?php 
}
 /**
  * If it's a valid Jetpack module and configuration parameters have been sent, update it.
  *
  * @since 4.3.0
  *
  * @param WP_REST_Request $data {
  *     Array of parameters received by request.
  *
  *     @type string $slug Module slug.
  * }
  *
  * @return bool|WP_Error True if module was updated. Otherwise, a WP_Error instance with the corresponding error.
  */
 public function update_data($data)
 {
     // If it's null, we're trying to update many module options from different modules.
     if (is_null($data['slug'])) {
         // Value admitted by Jetpack_Core_Json_Api_Endpoints::get_updateable_data_list that will make it return all module options.
         // It will not be passed. It's just checked in this method to pass that method a string or array.
         $data['slug'] = 'any';
     } else {
         if (!Jetpack::is_module($data['slug'])) {
             return new WP_Error('not_found', esc_html__('The requested Jetpack module was not found.', 'jetpack'), array('status' => 404));
         }
         if (!Jetpack::is_module_active($data['slug'])) {
             return new WP_Error('inactive', esc_html__('The requested Jetpack module is inactive.', 'jetpack'), array('status' => 409));
         }
     }
     // Get parameters to update the module.
     $params = $data->get_json_params();
     // Exit if no parameters were passed.
     if (!is_array($params)) {
         return new WP_Error('missing_options', esc_html__('Missing options.', 'jetpack'), array('status' => 404));
     }
     // Get available module options.
     $options = Jetpack_Core_Json_Api_Endpoints::get_updateable_data_list('any' === $data['slug'] ? $params : $data['slug']);
     // Prepare to toggle module if needed
     $toggle_module = new Jetpack_Core_API_Module_Toggle_Endpoint(new Jetpack_IXR_Client());
     // Options that are invalid or failed to update.
     $invalid = array_keys(array_diff_key($params, $options));
     $not_updated = array();
     // Remove invalid options
     $params = array_intersect_key($params, $options);
     // Used if response is successful. The message can be overwritten and additional data can be added here.
     $response = array('code' => 'success', 'message' => esc_html__('The requested Jetpack data updates were successful.', 'jetpack'));
     // If there are modules to activate, activate them first so they're ready when their options are set.
     foreach ($params as $option => $value) {
         if ('modules' === $options[$option]['jp_group']) {
             // Used if there was an error. Can be overwritten with specific error messages.
             $error = '';
             // Set to true if the module toggling was successful.
             $updated = false;
             // Check if user can toggle the module.
             if ($toggle_module->can_request()) {
                 // Activate or deactivate the module according to the value passed.
                 $toggle_result = $value ? $toggle_module->activate_module($option) : $toggle_module->deactivate_module($option);
                 if (is_wp_error($toggle_result)) {
                     $error = $toggle_result->get_error_message();
                 } else {
                     $updated = true;
                 }
             } else {
                 $error = Jetpack_Core_Json_Api_Endpoints::$user_permissions_error_msg;
             }
             // The module was not toggled.
             if (!$updated) {
                 $not_updated[$option] = $error;
             }
             // Remove module from list so we don't go through it again.
             unset($params[$option]);
         }
     }
     foreach ($params as $option => $value) {
         // Used if there was an error. Can be overwritten with specific error messages.
         $error = '';
         // Set to true if the option update was successful.
         $updated = false;
         // Get option attributes, including the group it belongs to.
         $option_attrs = $options[$option];
         // If this is a module option and the related module isn't active for any reason, continue with the next one.
         if ('settings' !== $option_attrs['jp_group']) {
             if (!Jetpack::is_module($option_attrs['jp_group'])) {
                 $not_updated[$option] = esc_html__('The requested Jetpack module was not found.', 'jetpack');
                 continue;
             }
             if (!Jetpack::is_module_active($option_attrs['jp_group'])) {
                 $not_updated[$option] = esc_html__('The requested Jetpack module is inactive.', 'jetpack');
                 continue;
             }
         }
         // Properly cast value based on its type defined in endpoint accepted args.
         $value = Jetpack_Core_Json_Api_Endpoints::cast_value($value, $option_attrs);
         switch ($option) {
             case 'monitor_receive_notifications':
                 $monitor = new Jetpack_Monitor();
                 // If we got true as response, consider it done.
                 $updated = true === $monitor->update_option_receive_jetpack_monitor_notification($value);
                 break;
             case 'post_by_email_address':
                 if ('create' == $value) {
                     $result = $this->_process_post_by_email('jetpack.createPostByEmailAddress', esc_html__('Unable to create the Post by Email address. Please try again later.', 'jetpack'));
                 } elseif ('regenerate' == $value) {
                     $result = $this->_process_post_by_email('jetpack.regeneratePostByEmailAddress', esc_html__('Unable to regenerate the Post by Email address. Please try again later.', 'jetpack'));
                 } elseif ('delete' == $value) {
                     $result = $this->_process_post_by_email('jetpack.deletePostByEmailAddress', esc_html__('Unable to delete the Post by Email address. Please try again later.', 'jetpack'));
                 } else {
                     $result = false;
                 }
                 // If we got an email address (create or regenerate) or 1 (delete), consider it done.
                 if (preg_match('/[a-z0-9]+@post.wordpress.com/', $result)) {
                     $response[$option] = $result;
                     $updated = true;
                 } elseif (1 == $result) {
                     $updated = true;
                 } elseif (is_array($result) && isset($result['message'])) {
                     $error = $result['message'];
                 }
                 break;
             case 'jetpack_protect_key':
                 $protect = Jetpack_Protect_Module::instance();
                 if ('create' == $value) {
                     $result = $protect->get_protect_key();
                 } else {
                     $result = false;
                 }
                 // If we got one of Protect keys, consider it done.
                 if (preg_match('/[a-z0-9]{40,}/i', $result)) {
                     $response[$option] = $result;
                     $updated = true;
                 }
                 break;
             case 'jetpack_protect_global_whitelist':
                 $updated = jetpack_protect_save_whitelist(explode(PHP_EOL, str_replace(array(' ', ','), array('', "\n"), $value)));
                 if (is_wp_error($updated)) {
                     $error = $updated->get_error_message();
                 }
                 break;
             case 'show_headline':
             case 'show_thumbnails':
                 $grouped_options = $grouped_options_current = (array) Jetpack_Options::get_option('relatedposts');
                 $grouped_options[$option] = $value;
                 // If option value was the same, consider it done.
                 $updated = $grouped_options_current != $grouped_options ? Jetpack_Options::update_option('relatedposts', $grouped_options) : true;
                 break;
             case 'google':
             case 'bing':
             case 'pinterest':
             case 'yandex':
                 $grouped_options = $grouped_options_current = (array) get_option('verification_services_codes');
                 $grouped_options[$option] = $value;
                 // If option value was the same, consider it done.
                 $updated = $grouped_options_current != $grouped_options ? update_option('verification_services_codes', $grouped_options) : true;
                 break;
             case 'sharing_services':
                 if (!class_exists('Sharing_Service') && !@(include JETPACK__PLUGIN_DIR . 'modules/sharedaddy/sharing-service.php')) {
                     break;
                 }
                 $sharer = new Sharing_Service();
                 // If option value was the same, consider it done.
                 $updated = $value != $sharer->get_blog_services() ? $sharer->set_blog_services($value['visible'], $value['hidden']) : true;
                 break;
             case 'button_style':
             case 'sharing_label':
             case 'show':
                 if (!class_exists('Sharing_Service') && !@(include JETPACK__PLUGIN_DIR . 'modules/sharedaddy/sharing-service.php')) {
                     break;
                 }
                 $sharer = new Sharing_Service();
                 $grouped_options = $sharer->get_global_options();
                 $grouped_options[$option] = $value;
                 $updated = $sharer->set_global_options($grouped_options);
                 break;
             case 'custom':
                 if (!class_exists('Sharing_Service') && !@(include JETPACK__PLUGIN_DIR . 'modules/sharedaddy/sharing-service.php')) {
                     break;
                 }
                 $sharer = new Sharing_Service();
                 $updated = $sharer->new_service(stripslashes($value['sharing_name']), stripslashes($value['sharing_url']), stripslashes($value['sharing_icon']));
                 // Return new custom service
                 $response[$option] = $updated;
                 break;
             case 'sharing_delete_service':
                 if (!class_exists('Sharing_Service') && !@(include JETPACK__PLUGIN_DIR . 'modules/sharedaddy/sharing-service.php')) {
                     break;
                 }
                 $sharer = new Sharing_Service();
                 $updated = $sharer->delete_service($value);
                 break;
             case 'jetpack-twitter-cards-site-tag':
                 $value = trim(ltrim(strip_tags($value), '@'));
                 $updated = get_option($option) !== $value ? update_option($option, $value) : true;
                 break;
             case 'onpublish':
             case 'onupdate':
             case 'Bias Language':
             case 'Cliches':
             case 'Complex Expression':
             case 'Diacritical Marks':
             case 'Double Negative':
             case 'Hidden Verbs':
             case 'Jargon Language':
             case 'Passive voice':
             case 'Phrases to Avoid':
             case 'Redundant Expression':
             case 'guess_lang':
                 if (in_array($option, array('onpublish', 'onupdate'))) {
                     $atd_option = 'AtD_check_when';
                 } elseif ('guess_lang' == $option) {
                     $atd_option = 'AtD_guess_lang';
                     $option = 'true';
                 } else {
                     $atd_option = 'AtD_options';
                 }
                 $user_id = get_current_user_id();
                 $grouped_options_current = AtD_get_options($user_id, $atd_option);
                 unset($grouped_options_current['name']);
                 $grouped_options = $grouped_options_current;
                 if ($value && !isset($grouped_options[$option])) {
                     $grouped_options[$option] = $value;
                 } elseif (!$value && isset($grouped_options[$option])) {
                     unset($grouped_options[$option]);
                 }
                 // If option value was the same, consider it done, otherwise try to update it.
                 $options_to_save = implode(',', array_keys($grouped_options));
                 $updated = $grouped_options != $grouped_options_current ? AtD_update_setting($user_id, $atd_option, $options_to_save) : true;
                 break;
             case 'ignored_phrases':
             case 'unignore_phrase':
                 $user_id = get_current_user_id();
                 $atd_option = 'AtD_ignored_phrases';
                 $grouped_options = $grouped_options_current = explode(',', AtD_get_setting($user_id, $atd_option));
                 if ('ignored_phrases' == $option) {
                     $grouped_options = explode(',', $value);
                 } else {
                     $index = array_search($value, $grouped_options);
                     if (false !== $index) {
                         unset($grouped_options[$index]);
                         $grouped_options = array_values($grouped_options);
                     }
                 }
                 $ignored_phrases = implode(',', array_filter(array_map('strip_tags', $grouped_options)));
                 $updated = $grouped_options != $grouped_options_current ? AtD_update_setting($user_id, $atd_option, $ignored_phrases) : true;
                 break;
             case 'admin_bar':
             case 'roles':
             case 'count_roles':
             case 'blog_id':
             case 'do_not_track':
             case 'hide_smile':
             case 'version':
                 $grouped_options = $grouped_options_current = (array) get_option('stats_options');
                 $grouped_options[$option] = $value;
                 // If option value was the same, consider it done.
                 $updated = $grouped_options_current != $grouped_options ? update_option('stats_options', $grouped_options) : true;
                 break;
             case Jetpack_Core_Json_Api_Endpoints::holiday_snow_option_name():
                 $updated = get_option($option) != $value ? update_option($option, (bool) $value ? 'letitsnow' : '') : true;
                 break;
             case 'wp_mobile_featured_images':
             case 'wp_mobile_excerpt':
                 $value = 'enabled' === $value ? '1' : '0';
                 // break intentionally omitted
             // break intentionally omitted
             default:
                 // If option value was the same, consider it done.
                 $updated = get_option($option) != $value ? update_option($option, $value) : true;
                 break;
         }
         // The option was not updated.
         if (!$updated) {
             $not_updated[$option] = $error;
         }
     }
     if (empty($invalid) && empty($not_updated)) {
         // The option was updated.
         return rest_ensure_response($response);
     } else {
         $invalid_count = count($invalid);
         $not_updated_count = count($not_updated);
         $error = '';
         if ($invalid_count > 0) {
             $error = sprintf(_n('Invalid option: %s.', 'Invalid options: %s.', $invalid_count, 'jetpack'), join(', ', $invalid));
         }
         if ($not_updated_count > 0) {
             $not_updated_messages = array();
             foreach ($not_updated as $not_updated_option => $not_updated_message) {
                 if (!empty($not_updated_message)) {
                     $not_updated_messages[] = sprintf(__('Extra info for %1$s: %2$s', 'jetpack'), $not_updated_option, $not_updated_message);
                 }
             }
             if (!empty($error)) {
                 $error .= ' ';
             }
             $error .= sprintf(_n('Option not updated: %s.', 'Options not updated: %s.', $not_updated_count, 'jetpack'), join(', ', array_keys($not_updated)));
             if (!empty($not_updated_messages)) {
                 $error .= ' ' . join('. ', $not_updated_messages);
             }
         }
         // There was an error because some options were updated but others were invalid or failed to update.
         return new WP_Error('some_updated', esc_html($error), array('status' => 400));
     }
 }