PluginProbe
WooCommerce / 11.1.0-beta.1
WooCommerce v11.1.0-beta.1
11.1.0 11.1.0-rc.2 11.1.0-rc.1 11.1.0-beta.2 11.1.0-beta.1 11.0.1 11.0.0 11.0.0-rc.3 11.0.0-rc.2 11.0.0-rc.1 11.0.0-beta.2 11.0.0-beta.1 10.9.4 10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 All 648 releases
woocommerce / src / Admin / API / Options.php
Options.php
320 lines 10.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * REST API Options Controller
4 *
5 * Handles requests to get and update options in the wp_options table.
6 *
7 * IMPORTANT: This API is for legacy support only. DO NOT add new options here. See p90Yrv-2vK-p2#comment-6482 for more details.
8 * For new settings/options, use Settings REST API (https://developer.woocommerce.com/docs/apis/rest-api/v3/setting-options/#setting-option-properties) or create dedicated endpoints instead.
9 *
10 * Example:
11 * - Use register_rest_route() to create a new endpoint
12 * - Follow WooCommerce REST API standards
13 * - Implement proper permission checks
14 * - Add proper documentation
15 * See Automattic\WooCommerce\Admin\API\OnboardingProfile for examples.
16 */
17
18 declare(strict_types=1);
19
20 namespace Automattic\WooCommerce\Admin\API;
21
22 defined( 'ABSPATH' ) || exit;
23
24 /**
25 * Options Controller.
26 *
27 * @deprecated since 6.2.0
28 *
29 * @extends WC_REST_Data_Controller
30 */
31 class Options extends \WC_REST_Data_Controller {
32 /**
33 * Endpoint namespace.
34 *
35 * @var string
36 */
37 protected $namespace = 'wc-admin';
38
39 /**
40 * Route base.
41 *
42 * @var string
43 */
44 protected $rest_base = 'options';
45
46 /**
47 * Register routes.
48 */
49 public function register_routes() {
50 register_rest_route(
51 $this->namespace,
52 '/' . $this->rest_base,
53 array(
54 array(
55 'methods' => \WP_REST_Server::READABLE,
56 'callback' => array( $this, 'get_options' ),
57 'permission_callback' => array( $this, 'get_item_permissions_check' ),
58 ),
59 'schema' => array( $this, 'get_item_schema' ),
60 )
61 );
62
63 register_rest_route(
64 $this->namespace,
65 '/' . $this->rest_base,
66 array(
67 array(
68 'methods' => \WP_REST_Server::EDITABLE,
69 'callback' => array( $this, 'update_options' ),
70 'permission_callback' => array( $this, 'update_item_permissions_check' ),
71 ),
72 'schema' => array( $this, 'get_item_schema' ),
73 )
74 );
75 }
76
77 /**
78 * Check if a given request has access to get options.
79 *
80 * @param WP_REST_Request $request Full details about the request.
81 * @return WP_Error|boolean
82 */
83 public function get_item_permissions_check( $request ) {
84 $params = ( isset( $request['options'] ) && is_string( $request['options'] ) ) ? explode( ',', $request['options'] ) : array();
85
86 if ( ! $params ) {
87 return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'You must supply an array of options.', 'woocommerce' ), 500 );
88 }
89
90 foreach ( $params as $option ) {
91 if ( ! $this->user_has_permission( $option, $request ) ) {
92 return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view these options.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
93 }
94 }
95
96 return true;
97 }
98
99 /**
100 * Check if the user has permission given an option name.
101 *
102 * @param string $option Option name.
103 * @param WP_REST_Request $request Full details about the request.
104 * @param bool $is_update If the request is to update the option.
105 * @return boolean
106 */
107 public function user_has_permission( $option, $request, $is_update = false ) {
108 $permissions = $this->get_option_permissions( $request );
109
110 if ( isset( $permissions[ $option ] ) ) {
111 return $permissions[ $option ];
112 }
113
114 wc_deprecated_function( 'Automattic\WooCommerce\Admin\API\Options::' . ( $is_update ? 'update_options' : 'get_options' ), '6.3' );
115
116 // Disallow option updates in non-production environments unless the option is whitelisted, prompting developers to create specific endpoints in case they miss the deprecation notice.
117 if ( 'production' !== wp_get_environment_type() ) {
118 return false;
119 }
120
121 return current_user_can( 'manage_options' );
122 }
123
124 /**
125 * Check if a given request has access to update options.
126 *
127 * @param WP_REST_Request $request Full details about the request.
128 * @return WP_Error|boolean
129 */
130 public function update_item_permissions_check( $request ) {
131 $params = $request->get_json_params();
132
133 if ( ! is_array( $params ) ) {
134 return new \WP_Error( 'woocommerce_rest_cannot_update', __( 'You must supply an array of options and values.', 'woocommerce' ), 500 );
135 }
136
137 foreach ( $params as $option_name => $option_value ) {
138 if ( ! $this->user_has_permission( $option_name, $request, true ) ) {
139 return new \WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot manage these options.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
140 }
141 }
142
143 return true;
144 }
145
146 /**
147 * Get an array of options and respective permissions for the current user.
148 *
149 * @param WP_REST_Request $request Full details about the request.
150 * @return array
151 */
152 public function get_option_permissions( $request ) {
153 $permissions = self::get_default_option_permissions();
154 return apply_filters_deprecated( 'woocommerce_rest_api_option_permissions', array( $permissions, $request ), '6.3.0' );
155 }
156
157 /**
158 * Get the default available option permissions.
159 *
160 * @return array
161 */
162 public static function get_default_option_permissions() {
163 $is_woocommerce_admin = \Automattic\WooCommerce\Internal\Admin\Homescreen::is_admin_user();
164
165 /**
166 * IMPORTANT: This list is frozen for legacy support.
167 * New options MUST use dedicated endpoints instead of being added here.
168 */
169 $legacy_whitelisted_options = array(
170 'woocommerce_setup_jetpack_opted_in',
171 'woocommerce_stripe_settings',
172 'woocommerce-ppcp-settings',
173 'woocommerce_ppcp-gateway_setting',
174 'woocommerce_demo_store',
175 'woocommerce_demo_store_notice',
176 'woocommerce_ces_tracks_queue',
177 'woocommerce_navigation_intro_modal_dismissed',
178 'woocommerce_shipping_dismissed_timestamp',
179 'woocommerce_allow_tracking',
180 'woocommerce_task_list_keep_completed',
181 'woocommerce_default_homepage_layout',
182 'woocommerce_setup_jetpack_opted_in',
183 'woocommerce_no_sales_tax',
184 'woocommerce_calc_taxes',
185 'woocommerce_bacs_settings',
186 'woocommerce_bacs_accounts',
187 'woocommerce_settings_shipping_recommendations_hidden',
188 'woocommerce_task_list_dismissed_tasks',
189 'woocommerce_setting_payments_recommendations_hidden',
190 'woocommerce_abandoned_cart_recovery_recommendations_hidden',
191 'woocommerce_navigation_favorites_tooltip_hidden',
192 'woocommerce_admin_transient_notices_queue',
193 'woocommerce_task_list_hidden',
194 'woocommerce_task_list_complete',
195 'woocommerce_extended_task_list_hidden',
196 'woocommerce_ces_shown_for_actions',
197 'woocommerce_clear_ces_tracks_queue_for_page',
198 'woocommerce_admin_install_timestamp',
199 'woocommerce_task_list_tracked_completed_tasks',
200 'woocommerce_show_marketplace_suggestions',
201 'wc_connect_options',
202 'woocommerce_admin_created_default_shipping_zones',
203 'woocommerce_admin_reviewed_default_shipping_zones',
204 'woocommerce_admin_reviewed_store_location_settings',
205 'woocommerce_ces_product_feedback_shown',
206 'woocommerce_marketing_overview_multichannel_banner_dismissed',
207 'woocommerce_manage_stock',
208 'woocommerce_dimension_unit',
209 'woocommerce_weight_unit',
210 'woocommerce_product_editor_show_feedback_bar',
211 'woocommerce_single_variation_notice_dismissed',
212 'woocommerce_product_tour_modal_hidden',
213 'woocommerce_block_product_tour_shown',
214 'woocommerce_revenue_report_date_tour_shown',
215 'woocommerce_orders_report_date_tour_shown',
216 'woocommerce_show_prepublish_checks_enabled',
217 'woocommerce_date_type',
218 'date_format',
219 'time_format',
220 'woocommerce_onboarding_profile',
221 'woocommerce_default_country',
222 'blogname',
223 'wcpay_welcome_page_incentives_dismissed',
224 'wcpay_welcome_page_viewed_timestamp',
225 'wcpay_welcome_page_exit_survey_more_info_needed_timestamp',
226 'woocommerce_customize_store_onboarding_tour_hidden',
227 'woocommerce_customize_store_ai_suggestions',
228 'woocommerce_admin_customize_store_completed',
229 'woocommerce_admin_customize_store_completed_theme_id',
230 'woocommerce_admin_customize_store_survey_completed',
231 'woocommerce_coming_soon',
232 'woocommerce_store_pages_only',
233 'woocommerce_private_link',
234 'woocommerce_share_key',
235 'woocommerce_show_lys_tour',
236 'woocommerce_remote_variant_assignment',
237 'woocommerce_gateway_order',
238 'woocommerce_woopayments_nox_profile',
239 // WC Test helper options.
240 'wc-admin-test-helper-rest-api-filters',
241 'wc_admin_helper_feature_values',
242 );
243
244 $theme_permissions = array(
245 'theme_mods_' . get_stylesheet() => current_user_can( 'edit_theme_options' ),
246 'stylesheet' => current_user_can( 'edit_theme_options' ),
247 );
248
249 return array_merge(
250 array_fill_keys( $theme_permissions, current_user_can( 'edit_theme_options' ) ),
251 array_fill_keys( $legacy_whitelisted_options, $is_woocommerce_admin )
252 );
253 }
254
255 /**
256 * Gets an array of options and respective values.
257 *
258 * @param WP_REST_Request $request Full details about the request.
259 * @return array Options object with option values.
260 */
261 public function get_options( $request ) {
262 $options = array();
263
264 if ( empty( $request['options'] ) || ! is_string( $request['options'] ) ) {
265 return $options;
266 }
267
268 $params = explode( ',', $request['options'] );
269 foreach ( $params as $option ) {
270 $options[ $option ] = get_option( $option );
271 }
272
273 return $options;
274 }
275
276 /**
277 * Updates an array of objects.
278 *
279 * @param WP_REST_Request $request Full details about the request.
280 * @return array Options object with a boolean if the option was updated.
281 */
282 public function update_options( $request ) {
283 $params = $request->get_json_params();
284 $updated = array();
285
286 if ( ! is_array( $params ) ) {
287 return array();
288 }
289
290 foreach ( $params as $key => $value ) {
291 $updated[ $key ] = update_option( $key, $value );
292 }
293
294 return $updated;
295 }
296
297 /**
298 * Get the schema, conforming to JSON Schema.
299 *
300 * @return array
301 */
302 public function get_item_schema() {
303 $schema = array(
304 '$schema' => 'http://json-schema.org/draft-04/schema#',
305 'title' => 'options',
306 'type' => 'object',
307 'properties' => array(
308 'options' => array(
309 'type' => 'array',
310 'description' => __( 'Array of options with associated values.', 'woocommerce' ),
311 'context' => array( 'view' ),
312 'readonly' => true,
313 ),
314 ),
315 );
316
317 return $this->add_additional_fields_schema( $schema );
318 }
319 }
320