/** * Update all Shipping Zone Locations. * * @param WP_REST_Request $request * @return WP_REST_Response|WP_Error */ public function update_items($request) { $zone = $this->get_zone($request['id']); if (is_wp_error($zone)) { return $zone; } $raw_locations = $request->get_json_params(); $locations = array(); foreach ((array) $raw_locations as $raw_location) { if (empty($raw_location['code']) || empty($raw_location['type'])) { continue; } $locations[] = $raw_location; } $zone->set_locations($locations); $zone->save(); return $this->get_items($request); }
/** * Toggles activation or deactivation of the JumpStart * * @since 4.3.0 * * @param WP_REST_Request $data { * Array of parameters received by request. * } * * @return bool|WP_Error True if toggling Jumpstart succeeded. Otherwise, a WP_Error instance with the corresponding error. */ public static function jumpstart_toggle($data) { $param = $data->get_json_params(); if ($param['active']) { return self::jumpstart_activate($data); } else { return self::jumpstart_deactivate($data); } }
/** * Add post meta fields. * * @param WP_Post $post * @param WP_REST_Request $request * @return bool|WP_Error */ protected function add_post_meta_fields($post, $request) { $data = $request->get_json_params(); $defaults = array('discount_type' => 'fixed_cart', 'amount' => 0, 'individual_use' => false, 'product_ids' => array(), 'exclude_product_ids' => array(), 'usage_limit' => '', 'usage_limit_per_user' => '', 'limit_usage_to_x_items' => '', 'usage_count' => '', 'expiry_date' => '', 'free_shipping' => false, 'product_categories' => array(), 'excluded_product_categories' => array(), 'exclude_sale_items' => false, 'minimum_amount' => '', 'maximum_amount' => '', 'email_restrictions' => array(), 'description' => ''); $data = wp_parse_args($data, $defaults); // Set coupon meta. update_post_meta($post->ID, 'discount_type', $data['discount_type']); update_post_meta($post->ID, 'coupon_amount', wc_format_decimal($data['amount'])); update_post_meta($post->ID, 'individual_use', true === $data['individual_use'] ? 'yes' : 'no'); update_post_meta($post->ID, 'product_ids', implode(',', array_filter(array_map('intval', $data['product_ids'])))); update_post_meta($post->ID, 'exclude_product_ids', implode(',', array_filter(array_map('intval', $data['exclude_product_ids'])))); update_post_meta($post->ID, 'usage_limit', absint($data['usage_limit'])); update_post_meta($post->ID, 'usage_limit_per_user', absint($data['usage_limit_per_user'])); update_post_meta($post->ID, 'limit_usage_to_x_items', absint($data['limit_usage_to_x_items'])); update_post_meta($post->ID, 'usage_count', absint($data['usage_count'])); update_post_meta($post->ID, 'expiry_date', $this->get_coupon_expiry_date(wc_clean($data['expiry_date']))); update_post_meta($post->ID, 'free_shipping', true === $data['free_shipping'] ? 'yes' : 'no'); update_post_meta($post->ID, 'product_categories', array_filter(array_map('intval', $data['product_categories']))); update_post_meta($post->ID, 'exclude_product_categories', array_filter(array_map('intval', $data['excluded_product_categories']))); update_post_meta($post->ID, 'exclude_sale_items', true === $data['exclude_sale_items'] ? 'yes' : 'no'); update_post_meta($post->ID, 'minimum_amount', wc_format_decimal($data['minimum_amount'])); update_post_meta($post->ID, 'maximum_amount', wc_format_decimal($data['maximum_amount'])); update_post_meta($post->ID, 'customer_email', array_filter(array_map('sanitize_email', $data['email_restrictions']))); return true; }
/** * 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)); } }
/** * If it's a valid Jetpack module and configuration parameters have been sent, update it. * * @since 4.1.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 static function update_module($data) { 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. $param = $data->get_json_params(); // Exit if no parameters were passed. if (!is_array($param)) { return new WP_Error('missing_option', esc_html__('Missing option.', 'jetpack'), array('status' => 404)); } // Get option name and value. $option = key($param); $value = current($param); // Get available module options. $options = self::get_module_available_options(); // If option is invalid, don't go any further. if (!in_array($option, array_keys($options))) { return new WP_Error('invalid_param', esc_html(sprintf(__('The option %s is invalid for this module.', 'jetpack'), $option)), array('status' => 404)); } // 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 module was updated.', 'jetpack')); // Used if there was an error. Can be overwritten with specific error messages. /* Translators: the variable is a module option name. */ $error = sprintf(__('The option %s was not updated.', 'jetpack'), $option); // Set to true if the option update was successful. $updated = false; // Properly cast value based on its type defined in endpoint accepted args. $value = self::cast_value($value, $options[$option]); 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 = self::_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 = self::_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 = self::_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(' ', '', $value))); if (is_wp_error($updated)) { $error = $updated->get_error_message(); } break; case 'show_headline': case 'show_thumbnails': $grouped_options = $grouped_options_current = 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': $grouped_options = $grouped_options_current = 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': $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': $sharer = new Sharing_Service(); $grouped_options = $sharer->get_global_options(); $grouped_options[$option] = $value; $updated = $sharer->set_global_options($grouped_options); break; case 'custom': $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': $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[] = $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; 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) { return new WP_Error('module_option_not_updated', esc_html($error), array('status' => 400)); } // The option was updated. return rest_ensure_response($response); }
/** * Used by endpoint to store changes * * @param WP_REST_Request $request Request from the REST API. * * @return array List of feedback per option if saving succeeded. */ public function set_configuration(WP_REST_Request $request) { return $this->storage->store($request->get_json_params()); }