WC_Admin_Settings

WC_Admin_Settings Class.

Defined (1)

The class is defined in the following location(s).

/includes/admin/class-wc-admin-settings.php  
  1. class WC_Admin_Settings { 
  2.  
  3. /** 
  4. * Setting pages. 
  5. * @var array 
  6. */ 
  7. private static $settings = array(); 
  8.  
  9. /** 
  10. * Error messages. 
  11. * @var array 
  12. */ 
  13. private static $errors = array(); 
  14.  
  15. /** 
  16. * Update messages. 
  17. * @var array 
  18. */ 
  19. private static $messages = array(); 
  20.  
  21. /** 
  22. * Include the settings page classes. 
  23. */ 
  24. public static function get_settings_pages() { 
  25. if ( empty( self::$settings ) ) { 
  26. $settings = array(); 
  27.  
  28. include_once( dirname( __FILE__ ) . '/settings/class-wc-settings-page.php' ); 
  29.  
  30. $settings[] = include( 'settings/class-wc-settings-general.php' ); 
  31. $settings[] = include( 'settings/class-wc-settings-products.php' ); 
  32. $settings[] = include( 'settings/class-wc-settings-tax.php' ); 
  33. $settings[] = include( 'settings/class-wc-settings-shipping.php' ); 
  34. $settings[] = include( 'settings/class-wc-settings-checkout.php' ); 
  35. $settings[] = include( 'settings/class-wc-settings-accounts.php' ); 
  36. $settings[] = include( 'settings/class-wc-settings-emails.php' ); 
  37. $settings[] = include( 'settings/class-wc-settings-integrations.php' ); 
  38. $settings[] = include( 'settings/class-wc-settings-api.php' ); 
  39.  
  40. self::$settings = apply_filters( 'woocommerce_get_settings_pages', $settings ); 
  41.  
  42. return self::$settings; 
  43.  
  44. /** 
  45. * Save the settings. 
  46. */ 
  47. public static function save() { 
  48. global $current_tab; 
  49.  
  50. if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'woocommerce-settings' ) ) { 
  51. die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) ); 
  52.  
  53. // Trigger actions 
  54. do_action( 'woocommerce_settings_save_' . $current_tab ); 
  55. do_action( 'woocommerce_update_options_' . $current_tab ); 
  56. do_action( 'woocommerce_update_options' ); 
  57.  
  58. self::add_message( __( 'Your settings have been saved.', 'woocommerce' ) ); 
  59. self::check_download_folder_protection(); 
  60.  
  61. // Clear any unwanted data and flush rules 
  62. delete_transient( 'woocommerce_cache_excluded_uris' ); 
  63. WC()->query->init_query_vars(); 
  64. WC()->query->add_endpoints(); 
  65. wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); 
  66.  
  67. do_action( 'woocommerce_settings_saved' ); 
  68.  
  69. /** 
  70. * Add a message. 
  71. * @param string $text 
  72. */ 
  73. public static function add_message( $text ) { 
  74. self::$messages[] = $text; 
  75.  
  76. /** 
  77. * Add an error. 
  78. * @param string $text 
  79. */ 
  80. public static function add_error( $text ) { 
  81. self::$errors[] = $text; 
  82.  
  83. /** 
  84. * Output messages + errors. 
  85. * @return string 
  86. */ 
  87. public static function show_messages() { 
  88. if ( sizeof( self::$errors ) > 0 ) { 
  89. foreach ( self::$errors as $error ) { 
  90. echo '<div id="message" class="error inline"><p><strong>' . esc_html( $error ) . '</strong></p></div>'; 
  91. } elseif ( sizeof( self::$messages ) > 0 ) { 
  92. foreach ( self::$messages as $message ) { 
  93. echo '<div id="message" class="updated inline"><p><strong>' . esc_html( $message ) . '</strong></p></div>'; 
  94.  
  95. /** 
  96. * Settings page. 
  97. * Handles the display of the main woocommerce settings page in admin. 
  98. */ 
  99. public static function output() { 
  100. global $current_section, $current_tab; 
  101.  
  102. $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; 
  103.  
  104. do_action( 'woocommerce_settings_start' ); 
  105.  
  106. wp_enqueue_script( 'woocommerce_settings', WC()->plugin_url() . '/assets/js/admin/settings' . $suffix . '.js', array( 'jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'iris', 'select2' ), WC()->version, true ); 
  107.  
  108. wp_localize_script( 'woocommerce_settings', 'woocommerce_settings_params', array( 
  109. 'i18n_nav_warning' => __( 'The changes you made will be lost if you navigate away from this page.', 'woocommerce' ),  
  110. ) ); 
  111.  
  112. // Include settings pages 
  113. self::get_settings_pages(); 
  114.  
  115. // Get current tab/section 
  116. $current_tab = empty( $_GET['tab'] ) ? 'general' : sanitize_title( $_GET['tab'] ); 
  117. $current_section = empty( $_REQUEST['section'] ) ? '' : sanitize_title( $_REQUEST['section'] ); 
  118.  
  119. // Save settings if data has been posted 
  120. if ( ! empty( $_POST ) ) { 
  121. self::save(); 
  122.  
  123. // Add any posted messages 
  124. if ( ! empty( $_GET['wc_error'] ) ) { 
  125. self::add_error( stripslashes( $_GET['wc_error'] ) ); 
  126.  
  127. if ( ! empty( $_GET['wc_message'] ) ) { 
  128. self::add_message( stripslashes( $_GET['wc_message'] ) ); 
  129.  
  130. // Get tabs for the settings page 
  131. $tabs = apply_filters( 'woocommerce_settings_tabs_array', array() ); 
  132.  
  133. include( dirname( __FILE__ ) . '/views/html-admin-settings.php' ); 
  134.  
  135. /** 
  136. * Get a setting from the settings API. 
  137. * @param mixed $option_name 
  138. * @return string 
  139. */ 
  140. public static function get_option( $option_name, $default = '' ) { 
  141. // Array value 
  142. if ( strstr( $option_name, '[' ) ) { 
  143.  
  144. parse_str( $option_name, $option_array ); 
  145.  
  146. // Option name is first key 
  147. $option_name = current( array_keys( $option_array ) ); 
  148.  
  149. // Get value 
  150. $option_values = get_option( $option_name, '' ); 
  151.  
  152. $key = key( $option_array[ $option_name ] ); 
  153.  
  154. if ( isset( $option_values[ $key ] ) ) { 
  155. $option_value = $option_values[ $key ]; 
  156. } else { 
  157. $option_value = null; 
  158.  
  159. // Single value 
  160. } else { 
  161. $option_value = get_option( $option_name, null ); 
  162.  
  163. if ( is_array( $option_value ) ) { 
  164. $option_value = array_map( 'stripslashes', $option_value ); 
  165. } elseif ( ! is_null( $option_value ) ) { 
  166. $option_value = stripslashes( $option_value ); 
  167.  
  168. return ( null === $option_value ) ? $default : $option_value; 
  169.  
  170. /** 
  171. * Output admin fields. 
  172. * Loops though the woocommerce options array and outputs each field. 
  173. * @param array $options Opens array to output 
  174. */ 
  175. public static function output_fields( $options ) { 
  176. foreach ( $options as $value ) { 
  177. if ( ! isset( $value['type'] ) ) { 
  178. continue; 
  179. if ( ! isset( $value['id'] ) ) { 
  180. $value['id'] = ''; 
  181. if ( ! isset( $value['title'] ) ) { 
  182. $value['title'] = isset( $value['name'] ) ? $value['name'] : ''; 
  183. if ( ! isset( $value['class'] ) ) { 
  184. $value['class'] = ''; 
  185. if ( ! isset( $value['css'] ) ) { 
  186. $value['css'] = ''; 
  187. if ( ! isset( $value['default'] ) ) { 
  188. $value['default'] = ''; 
  189. if ( ! isset( $value['desc'] ) ) { 
  190. $value['desc'] = ''; 
  191. if ( ! isset( $value['desc_tip'] ) ) { 
  192. $value['desc_tip'] = false; 
  193. if ( ! isset( $value['placeholder'] ) ) { 
  194. $value['placeholder'] = ''; 
  195.  
  196. // Custom attribute handling 
  197. $custom_attributes = array(); 
  198.  
  199. if ( ! empty( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) { 
  200. foreach ( $value['custom_attributes'] as $attribute => $attribute_value ) { 
  201. $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"'; 
  202.  
  203. // Description handling 
  204. $field_description = self::get_field_description( $value ); 
  205. extract( $field_description ); 
  206.  
  207. // Switch based on type 
  208. switch ( $value['type'] ) { 
  209.  
  210. // Section Titles 
  211. case 'title': 
  212. if ( ! empty( $value['title'] ) ) { 
  213. echo '<h2>' . esc_html( $value['title'] ) . '</h2>'; 
  214. if ( ! empty( $value['desc'] ) ) { 
  215. echo wpautop( wptexturize( wp_kses_post( $value['desc'] ) ) ); 
  216. echo '<table class="form-table">' . "\n\n"; 
  217. if ( ! empty( $value['id'] ) ) { 
  218. do_action( 'woocommerce_settings_' . sanitize_title( $value['id'] ) ); 
  219. break; 
  220.  
  221. // Section Ends 
  222. case 'sectionend': 
  223. if ( ! empty( $value['id'] ) ) { 
  224. do_action( 'woocommerce_settings_' . sanitize_title( $value['id'] ) . '_end' ); 
  225. echo '</table>'; 
  226. if ( ! empty( $value['id'] ) ) { 
  227. do_action( 'woocommerce_settings_' . sanitize_title( $value['id'] ) . '_after' ); 
  228. break; 
  229.  
  230. // Standard text inputs and subtypes like 'number' 
  231. case 'text': 
  232. case 'email': 
  233. case 'number': 
  234. case 'password' : 
  235. $option_value = self::get_option( $value['id'], $value['default'] ); 
  236.  
  237. ?><tr valign="top"> 
  238. <th scope="row" class="titledesc"> 
  239. <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label> 
  240. <?php echo $tooltip_html; ?> 
  241. </th> 
  242. <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>"> 
  243. <input 
  244. name="<?php echo esc_attr( $value['id'] ); ?>" 
  245. id="<?php echo esc_attr( $value['id'] ); ?>" 
  246. type="<?php echo esc_attr( $value['type'] ); ?>" 
  247. style="<?php echo esc_attr( $value['css'] ); ?>" 
  248. value="<?php echo esc_attr( $option_value ); ?>" 
  249. class="<?php echo esc_attr( $value['class'] ); ?>" 
  250. placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>" 
  251. <?php echo implode( ' ', $custom_attributes ); ?> 
  252. /> <?php echo $description; ?> 
  253. </td> 
  254. </tr><?php 
  255. break; 
  256.  
  257. // Color picker. 
  258. case 'color' : 
  259. $option_value = self::get_option( $value['id'], $value['default'] ); 
  260.  
  261. ?><tr valign="top"> 
  262. <th scope="row" class="titledesc"> 
  263. <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label> 
  264. <?php echo $tooltip_html; ?> 
  265. </th> 
  266. <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">‎ 
  267. <span class="colorpickpreview" style="background: <?php echo esc_attr( $option_value ); ?>"></span> 
  268. <input 
  269. name="<?php echo esc_attr( $value['id'] ); ?>" 
  270. id="<?php echo esc_attr( $value['id'] ); ?>" 
  271. type="text" 
  272. dir="ltr" 
  273. style="<?php echo esc_attr( $value['css'] ); ?>" 
  274. value="<?php echo esc_attr( $option_value ); ?>" 
  275. class="<?php echo esc_attr( $value['class'] ); ?>colorpick" 
  276. placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>" 
  277. <?php echo implode( ' ', $custom_attributes ); ?> 
  278. />‎ <?php echo $description; ?> 
  279. <div id="colorPickerDiv_<?php echo esc_attr( $value['id'] ); ?>" class="colorpickdiv" style="z-index: 100;background:#eee;border:1px solid #ccc;position:absolute;display:none;"></div> 
  280. </td> 
  281. </tr><?php 
  282. break; 
  283.  
  284. // Textarea 
  285. case 'textarea': 
  286.  
  287. $option_value = self::get_option( $value['id'], $value['default'] ); 
  288.  
  289. ?><tr valign="top"> 
  290. <th scope="row" class="titledesc"> 
  291. <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label> 
  292. <?php echo $tooltip_html; ?> 
  293. </th> 
  294. <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>"> 
  295. <?php echo $description; ?> 
  296.  
  297. <textarea 
  298. name="<?php echo esc_attr( $value['id'] ); ?>" 
  299. id="<?php echo esc_attr( $value['id'] ); ?>" 
  300. style="<?php echo esc_attr( $value['css'] ); ?>" 
  301. class="<?php echo esc_attr( $value['class'] ); ?>" 
  302. placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>" 
  303. <?php echo implode( ' ', $custom_attributes ); ?> 
  304. ><?php echo esc_textarea( $option_value ); ?></textarea> 
  305. </td> 
  306. </tr><?php 
  307. break; 
  308.  
  309. // Select boxes 
  310. case 'select' : 
  311. case 'multiselect' : 
  312.  
  313. $option_value = self::get_option( $value['id'], $value['default'] ); 
  314.  
  315. ?><tr valign="top"> 
  316. <th scope="row" class="titledesc"> 
  317. <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label> 
  318. <?php echo $tooltip_html; ?> 
  319. </th> 
  320. <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>"> 
  321. <select 
  322. name="<?php echo esc_attr( $value['id'] ); ?><?php echo ( 'multiselect' === $value['type'] ) ? '[]' : ''; ?>" 
  323. id="<?php echo esc_attr( $value['id'] ); ?>" 
  324. style="<?php echo esc_attr( $value['css'] ); ?>" 
  325. class="<?php echo esc_attr( $value['class'] ); ?>" 
  326. <?php echo implode( ' ', $custom_attributes ); ?> 
  327. <?php echo ( 'multiselect' == $value['type'] ) ? 'multiple="multiple"' : ''; ?> 
  328. <?php 
  329. foreach ( $value['options'] as $key => $val ) { 
  330. ?> 
  331. <option value="<?php echo esc_attr( $key ); ?>" <?php 
  332.  
  333. if ( is_array( $option_value ) ) { 
  334. selected( in_array( $key, $option_value ), true ); 
  335. } else { 
  336. selected( $option_value, $key ); 
  337.  
  338. ?>><?php echo $val ?></option> 
  339. <?php 
  340. ?> 
  341. </select> <?php echo $description; ?> 
  342. </td> 
  343. </tr><?php 
  344. break; 
  345.  
  346. // Radio inputs 
  347. case 'radio' : 
  348.  
  349. $option_value = self::get_option( $value['id'], $value['default'] ); 
  350.  
  351. ?><tr valign="top"> 
  352. <th scope="row" class="titledesc"> 
  353. <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label> 
  354. <?php echo $tooltip_html; ?> 
  355. </th> 
  356. <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>"> 
  357. <fieldset> 
  358. <?php echo $description; ?> 
  359. <ul> 
  360. <?php 
  361. foreach ( $value['options'] as $key => $val ) { 
  362. ?> 
  363. <li> 
  364. <label><input 
  365. name="<?php echo esc_attr( $value['id'] ); ?>" 
  366. value="<?php echo $key; ?>" 
  367. type="radio" 
  368. style="<?php echo esc_attr( $value['css'] ); ?>" 
  369. class="<?php echo esc_attr( $value['class'] ); ?>" 
  370. <?php echo implode( ' ', $custom_attributes ); ?> 
  371. <?php checked( $key, $option_value ); ?> 
  372. /> <?php echo $val ?></label> 
  373. </li> 
  374. <?php 
  375. ?> 
  376. </ul> 
  377. </fieldset> 
  378. </td> 
  379. </tr><?php 
  380. break; 
  381.  
  382. // Checkbox input 
  383. case 'checkbox' : 
  384.  
  385. $option_value = self::get_option( $value['id'], $value['default'] ); 
  386. $visbility_class = array(); 
  387.  
  388. if ( ! isset( $value['hide_if_checked'] ) ) { 
  389. $value['hide_if_checked'] = false; 
  390. if ( ! isset( $value['show_if_checked'] ) ) { 
  391. $value['show_if_checked'] = false; 
  392. if ( 'yes' == $value['hide_if_checked'] || 'yes' == $value['show_if_checked'] ) { 
  393. $visbility_class[] = 'hidden_option'; 
  394. if ( 'option' == $value['hide_if_checked'] ) { 
  395. $visbility_class[] = 'hide_options_if_checked'; 
  396. if ( 'option' == $value['show_if_checked'] ) { 
  397. $visbility_class[] = 'show_options_if_checked'; 
  398.  
  399. if ( ! isset( $value['checkboxgroup'] ) || 'start' == $value['checkboxgroup'] ) { 
  400. ?> 
  401. <tr valign="top" class="<?php echo esc_attr( implode( ' ', $visbility_class ) ); ?>"> 
  402. <th scope="row" class="titledesc"><?php echo esc_html( $value['title'] ) ?></th> 
  403. <td class="forminp forminp-checkbox"> 
  404. <fieldset> 
  405. <?php 
  406. } else { 
  407. ?> 
  408. <fieldset class="<?php echo esc_attr( implode( ' ', $visbility_class ) ); ?>"> 
  409. <?php 
  410.  
  411. if ( ! empty( $value['title'] ) ) { 
  412. ?> 
  413. <legend class="screen-reader-text"><span><?php echo esc_html( $value['title'] ) ?></span></legend> 
  414. <?php 
  415.  
  416. ?> 
  417. <label for="<?php echo $value['id'] ?>"> 
  418. <input 
  419. name="<?php echo esc_attr( $value['id'] ); ?>" 
  420. id="<?php echo esc_attr( $value['id'] ); ?>" 
  421. type="checkbox" 
  422. class="<?php echo esc_attr( isset( $value['class'] ) ? $value['class'] : '' ); ?>" 
  423. value="1" 
  424. <?php checked( $option_value, 'yes' ); ?> 
  425. <?php echo implode( ' ', $custom_attributes ); ?> 
  426. /> <?php echo $description ?> 
  427. </label> <?php echo $tooltip_html; ?> 
  428. <?php 
  429.  
  430. if ( ! isset( $value['checkboxgroup'] ) || 'end' == $value['checkboxgroup'] ) { 
  431. ?> 
  432. </fieldset> 
  433. </td> 
  434. </tr> 
  435. <?php 
  436. } else { 
  437. ?> 
  438. </fieldset> 
  439. <?php 
  440. break; 
  441.  
  442. // Image width settings 
  443. case 'image_width' : 
  444.  
  445. $image_size = str_replace( '_image_size', '', $value['id'] ); 
  446. $size = wc_get_image_size( $image_size ); 
  447. $width = isset( $size['width'] ) ? $size['width'] : $value['default']['width']; 
  448. $height = isset( $size['height'] ) ? $size['height'] : $value['default']['height']; 
  449. $crop = isset( $size['crop'] ) ? $size['crop'] : $value['default']['crop']; 
  450. $disabled_attr = ''; 
  451. $disabled_message = ''; 
  452.  
  453. if ( has_filter( 'woocommerce_get_image_size_' . $image_size ) ) { 
  454. $disabled_attr = 'disabled="disabled"'; 
  455. $disabled_message = "<p><small>" . __( 'The settings of this image size have been disabled because its values are being overwritten by a filter.', 'woocommerce' ) . "</small></p>"; 
  456.  
  457. ?><tr valign="top"> 
  458. <th scope="row" class="titledesc"><?php echo esc_html( $value['title'] ) ?> <?php echo $tooltip_html . $disabled_message; ?></th> 
  459. <td class="forminp image_width_settings"> 
  460.  
  461. <input name="<?php echo esc_attr( $value['id'] ); ?>[width]" <?php echo $disabled_attr; ?> id="<?php echo esc_attr( $value['id'] ); ?>-width" type="text" size="3" value="<?php echo $width; ?>" /> × <input name="<?php echo esc_attr( $value['id'] ); ?>[height]" <?php echo $disabled_attr; ?> id="<?php echo esc_attr( $value['id'] ); ?>-height" type="text" size="3" value="<?php echo $height; ?>" />px 
  462.  
  463. <label><input name="<?php echo esc_attr( $value['id'] ); ?>[crop]" <?php echo $disabled_attr; ?> id="<?php echo esc_attr( $value['id'] ); ?>-crop" type="checkbox" value="1" <?php checked( 1, $crop ); ?> /> <?php _e( 'Hard crop?', 'woocommerce' ); ?></label> 
  464.  
  465. </td> 
  466. </tr><?php 
  467. break; 
  468.  
  469. // Single page selects 
  470. case 'single_select_page' : 
  471.  
  472. $args = array( 
  473. 'name' => $value['id'],  
  474. 'id' => $value['id'],  
  475. 'sort_column' => 'menu_order',  
  476. 'sort_order' => 'ASC',  
  477. 'show_option_none' => ' ',  
  478. 'class' => $value['class'],  
  479. 'echo' => false,  
  480. 'selected' => absint( self::get_option( $value['id'] ) ),  
  481. ); 
  482.  
  483. if ( isset( $value['args'] ) ) { 
  484. $args = wp_parse_args( $value['args'], $args ); 
  485.  
  486. ?><tr valign="top" class="single_select_page"> 
  487. <th scope="row" class="titledesc"><?php echo esc_html( $value['title'] ) ?> <?php echo $tooltip_html; ?></th> 
  488. <td class="forminp"> 
  489. <?php echo str_replace( ' id=', " data-placeholder='" . esc_attr__( 'Select a page…', 'woocommerce' ) . "' style='" . $value['css'] . "' class='" . $value['class'] . "' id=", wp_dropdown_pages( $args ) ); ?> <?php echo $description; ?> 
  490. </td> 
  491. </tr><?php 
  492. break; 
  493.  
  494. // Single country selects 
  495. case 'single_select_country' : 
  496. $country_setting = (string) self::get_option( $value['id'] ); 
  497.  
  498. if ( strstr( $country_setting, ':' ) ) { 
  499. $country_setting = explode( ':', $country_setting ); 
  500. $country = current( $country_setting ); 
  501. $state = end( $country_setting ); 
  502. } else { 
  503. $country = $country_setting; 
  504. $state = '*'; 
  505. ?><tr valign="top"> 
  506. <th scope="row" class="titledesc"> 
  507. <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label> 
  508. <?php echo $tooltip_html; ?> 
  509. </th> 
  510. <td class="forminp"><select name="<?php echo esc_attr( $value['id'] ); ?>" style="<?php echo esc_attr( $value['css'] ); ?>" data-placeholder="<?php esc_attr_e( 'Choose a country…', 'woocommerce' ); ?>" aria-label="<?php esc_attr_e( 'Country', 'woocommerce' ) ?>" class="wc-enhanced-select"> 
  511. <?php WC()->countries->country_dropdown_options( $country, $state ); ?> 
  512. </select> <?php echo $description; ?> 
  513. </td> 
  514. </tr><?php 
  515. break; 
  516.  
  517. // Country multiselects 
  518. case 'multi_select_countries' : 
  519.  
  520. $selections = (array) self::get_option( $value['id'] ); 
  521.  
  522. if ( ! empty( $value['options'] ) ) { 
  523. $countries = $value['options']; 
  524. } else { 
  525. $countries = WC()->countries->countries; 
  526.  
  527. asort( $countries ); 
  528. ?><tr valign="top"> 
  529. <th scope="row" class="titledesc"> 
  530. <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label> 
  531. <?php echo $tooltip_html; ?> 
  532. </th> 
  533. <td class="forminp"> 
  534. <select multiple="multiple" name="<?php echo esc_attr( $value['id'] ); ?>[]" style="width:350px" data-placeholder="<?php esc_attr_e( 'Choose countries…', 'woocommerce' ); ?>" aria-label="<?php esc_attr_e( 'Country', 'woocommerce' ) ?>" class="wc-enhanced-select"> 
  535. <?php 
  536. if ( ! empty( $countries ) ) { 
  537. foreach ( $countries as $key => $val ) { 
  538. echo '<option value="' . esc_attr( $key ) . '" ' . selected( in_array( $key, $selections ), true, false ) . '>' . $val . '</option>'; 
  539. ?> 
  540. </select> <?php echo ( $description ) ? $description : ''; ?> <br /><a class="select_all button" href="#"><?php _e( 'Select all', 'woocommerce' ); ?></a> <a class="select_none button" href="#"><?php _e( 'Select none', 'woocommerce' ); ?></a> 
  541. </td> 
  542. </tr><?php 
  543. break; 
  544.  
  545. // Default: run an action 
  546. default: 
  547. do_action( 'woocommerce_admin_field_' . $value['type'], $value ); 
  548. break; 
  549.  
  550. /** 
  551. * Helper function to get the formatted description and tip HTML for a 
  552. * given form field. Plugins can call this when implementing their own custom 
  553. * settings types. 
  554. * @param array $value The form field value array 
  555. * @return array The description and tip as a 2 element array 
  556. */ 
  557. public static function get_field_description( $value ) { 
  558. $description = ''; 
  559. $tooltip_html = ''; 
  560.  
  561. if ( true === $value['desc_tip'] ) { 
  562. $tooltip_html = $value['desc']; 
  563. } elseif ( ! empty( $value['desc_tip'] ) ) { 
  564. $description = $value['desc']; 
  565. $tooltip_html = $value['desc_tip']; 
  566. } elseif ( ! empty( $value['desc'] ) ) { 
  567. $description = $value['desc']; 
  568.  
  569. if ( $description && in_array( $value['type'], array( 'textarea', 'radio' ) ) ) { 
  570. $description = '<p style="margin-top:0">' . wp_kses_post( $description ) . '</p>'; 
  571. } elseif ( $description && in_array( $value['type'], array( 'checkbox' ) ) ) { 
  572. $description = wp_kses_post( $description ); 
  573. } elseif ( $description ) { 
  574. $description = '<span class="description">' . wp_kses_post( $description ) . '</span>'; 
  575.  
  576. if ( $tooltip_html && in_array( $value['type'], array( 'checkbox' ) ) ) { 
  577. $tooltip_html = '<p class="description">' . $tooltip_html . '</p>'; 
  578. } elseif ( $tooltip_html ) { 
  579. $tooltip_html = wc_help_tip( $tooltip_html ); 
  580.  
  581. return array( 
  582. 'description' => $description,  
  583. 'tooltip_html' => $tooltip_html,  
  584. ); 
  585.  
  586. /** 
  587. * Save admin fields. 
  588. * Loops though the woocommerce options array and outputs each field. 
  589. * @param array $options Options array to output 
  590. * @param array $data Optional. Data to use for saving. Defaults to $_POST. 
  591. * @return bool 
  592. */ 
  593. public static function save_fields( $options, $data = null ) { 
  594. if ( is_null( $data ) ) { 
  595. $data = $_POST; 
  596. if ( empty( $data ) ) { 
  597. return false; 
  598.  
  599. // Options to update will be stored here and saved later. 
  600. $update_options = array(); 
  601.  
  602. // Loop options and get values to save. 
  603. foreach ( $options as $option ) { 
  604. if ( ! isset( $option['id'] ) || ! isset( $option['type'] ) ) { 
  605. continue; 
  606.  
  607. // Get posted value. 
  608. if ( strstr( $option['id'], '[' ) ) { 
  609. parse_str( $option['id'], $option_name_array ); 
  610. $option_name = current( array_keys( $option_name_array ) ); 
  611. $setting_name = key( $option_name_array[ $option_name ] ); 
  612. $raw_value = isset( $data[ $option_name ][ $setting_name ] ) ? wp_unslash( $data[ $option_name ][ $setting_name ] ) : null; 
  613. } else { 
  614. $option_name = $option['id']; 
  615. $setting_name = ''; 
  616. $raw_value = isset( $data[ $option['id'] ] ) ? wp_unslash( $data[ $option['id'] ] ) : null; 
  617.  
  618. // Format the value based on option type. 
  619. switch ( $option['type'] ) { 
  620. case 'checkbox' : 
  621. $value = '1' === $raw_value || 'yes' === $raw_value ? 'yes' : 'no'; 
  622. break; 
  623. case 'textarea' : 
  624. $value = wp_kses_post( trim( $raw_value ) ); 
  625. break; 
  626. case 'multiselect' : 
  627. case 'multi_select_countries' : 
  628. $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) ); 
  629. break; 
  630. case 'image_width' : 
  631. $value = array(); 
  632. if ( isset( $raw_value['width'] ) ) { 
  633. $value['width'] = wc_clean( $raw_value['width'] ); 
  634. $value['height'] = wc_clean( $raw_value['height'] ); 
  635. $value['crop'] = isset( $raw_value['crop'] ) ? 1 : 0; 
  636. } else { 
  637. $value['width'] = $option['default']['width']; 
  638. $value['height'] = $option['default']['height']; 
  639. $value['crop'] = $option['default']['crop']; 
  640. break; 
  641. case 'select': 
  642. $allowed_values = empty( $option['options'] ) ? array() : array_keys( $option['options'] ); 
  643. if ( empty( $option['default'] ) && empty( $allowed_values ) ) { 
  644. $value = null; 
  645. break; 
  646. $default = ( empty( $option['default'] ) ? $allowed_values[0] : $option['default'] ); 
  647. $value = in_array( $raw_value, $allowed_values ) ? $raw_value : $default; 
  648. break; 
  649. default : 
  650. $value = wc_clean( $raw_value ); 
  651. break; 
  652.  
  653. /** 
  654. * Fire an action when a certain 'type' of field is being saved. 
  655. * @deprecated 2.4.0 - doesn't allow manipulation of values! 
  656. */ 
  657. if ( has_action( 'woocommerce_update_option_' . sanitize_title( $option['type'] ) ) ) { 
  658. wc_deprecated_function( 'The woocommerce_update_option_X action', '2.4.0', 'woocommerce_admin_settings_sanitize_option filter' ); 
  659. do_action( 'woocommerce_update_option_' . sanitize_title( $option['type'] ), $option ); 
  660. continue; 
  661.  
  662. /** 
  663. * Sanitize the value of an option. 
  664. * @since 2.4.0 
  665. */ 
  666. $value = apply_filters( 'woocommerce_admin_settings_sanitize_option', $value, $option, $raw_value ); 
  667.  
  668. /** 
  669. * Sanitize the value of an option by option name. 
  670. * @since 2.4.0 
  671. */ 
  672. $value = apply_filters( "woocommerce_admin_settings_sanitize_option_$option_name", $value, $option, $raw_value ); 
  673.  
  674. if ( is_null( $value ) ) { 
  675. continue; 
  676.  
  677. // Check if option is an array and handle that differently to single values. 
  678. if ( $option_name && $setting_name ) { 
  679. if ( ! isset( $update_options[ $option_name ] ) ) { 
  680. $update_options[ $option_name ] = get_option( $option_name, array() ); 
  681. if ( ! is_array( $update_options[ $option_name ] ) ) { 
  682. $update_options[ $option_name ] = array(); 
  683. $update_options[ $option_name ][ $setting_name ] = $value; 
  684. } else { 
  685. $update_options[ $option_name ] = $value; 
  686.  
  687. /** 
  688. * Fire an action before saved. 
  689. * @deprecated 2.4.0 - doesn't allow manipulation of values! 
  690. */ 
  691. do_action( 'woocommerce_update_option', $option ); 
  692.  
  693. // Save all options in our array. 
  694. foreach ( $update_options as $name => $value ) { 
  695. update_option( $name, $value ); 
  696.  
  697. return true; 
  698.  
  699. /** 
  700. * Checks which method we're using to serve downloads. 
  701. * If using force or x-sendfile, this ensures the .htaccess is in place. 
  702. */ 
  703. public static function check_download_folder_protection() { 
  704. $upload_dir = wp_upload_dir(); 
  705. $downloads_url = $upload_dir['basedir'] . '/woocommerce_uploads'; 
  706. $download_method = get_option( 'woocommerce_file_download_method' ); 
  707.  
  708. if ( 'redirect' == $download_method ) { 
  709.  
  710. // Redirect method - don't protect 
  711. if ( file_exists( $downloads_url . '/.htaccess' ) ) { 
  712. unlink( $downloads_url . '/.htaccess' ); 
  713. } else { 
  714.  
  715. // Force method - protect, add rules to the htaccess file 
  716. if ( ! file_exists( $downloads_url . '/.htaccess' ) ) { 
  717. if ( $file_handle = @fopen( $downloads_url . '/.htaccess', 'w' ) ) { 
  718. fwrite( $file_handle, 'deny from all' ); 
  719. fclose( $file_handle );