class-wc-settings-page.php
7.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
<?php
/**
* WooCommerce Settings Page/Tab
*
* @package WooCommerce\Admin
* @version 2.1.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_Settings_Page', false ) ) :
/**
* WC_Settings_Page.
*/
abstract class WC_Settings_Page {
/**
* Setting page id.
*
* @var string
*/
protected $id = '';
/**
* Setting page label.
*
* @var string
*/
protected $label = '';
/**
* Constructor.
*/
public function __construct() {
add_filter( 'woocommerce_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
add_action( 'woocommerce_sections_' . $this->id, array( $this, 'output_sections' ) );
add_action( 'woocommerce_settings_' . $this->id, array( $this, 'output' ) );
add_action( 'woocommerce_settings_save_' . $this->id, array( $this, 'save' ) );
}
/**
* Get settings page ID.
*
* @since 3.0.0
* @return string
*/
public function get_id() {
return $this->id;
}
/**
* Get settings page label.
*
* @since 3.0.0
* @return string
*/
public function get_label() {
return $this->label;
}
/**
* Add this page to settings.
*
* @param array $pages The settings array where we'll add ourselves.
*
* @return mixed
*/
public function add_settings_page( $pages ) {
$pages[ $this->id ] = $this->label;
return $pages;
}
/**
* Get settings array for the default section.
*
* External settings classes (registered via 'woocommerce_get_settings_pages' filter)
* might have redefined this method as "get_settings($section_id='')", thus we need
* to use this method internally instead of 'get_settings_for_section' to register settings
* and render settings pages.
*
* *But* we can't just redefine the method as "get_settings($section_id='')" here, since this
* will break on PHP 8 if any external setting class have it as 'get_settings()'.
*
* Thus we leave the method signature as is and use 'func_get_arg' to get the setting id
* if it's supplied, and we use this method internally; but it's deprecated and should
* otherwise never be used.
*
* @deprecated 5.4.0 Use 'get_settings_for_section' (passing an empty string for default section)
*
* @return array Settings array, each item being an associative array representing a setting.
*/
public function get_settings() {
$section_id = 0 === func_num_args() ? '' : func_get_arg( 0 );
return $this->get_settings_for_section( $section_id );
}
/**
* Get settings array.
*
* The strategy for getting the settings is as follows:
*
* - If a method named 'get_settings_for_{section_id}_section' exists in the class
* it will be invoked (for the default '' section, the method name is 'get_settings_for_default_section').
* Derived classes can implement these methods as required.
*
* - Otherwise, 'get_settings_for_section_core' will be invoked. Derived classes can override it
* as an alternative to implementing 'get_settings_for_{section_id}_section' methods.
*
* @param string $section_id The id of the section to return settings for, an empty string for the default section.
*
* @return array Settings array, each item being an associative array representing a setting.
*/
final public function get_settings_for_section( $section_id ) {
if ( '' === $section_id ) {
$method_name = 'get_settings_for_default_section';
} else {
$method_name = "get_settings_for_{$section_id}_section";
}
if ( method_exists( $this, $method_name ) ) {
$settings = $this->$method_name();
} else {
$settings = $this->get_settings_for_section_core( $section_id );
}
return apply_filters( 'woocommerce_get_settings_' . $this->id, $settings, $section_id );
}
/**
* Get the settings for a given section.
* This method is invoked from 'get_settings_for_section' when no 'get_settings_for_{current_section}_section'
* method exists in the class.
*
* When overriding, note that the 'woocommerce_get_settings_' filter must NOT be triggered,
* as this is already done by 'get_settings_for_section'.
*
* @param string $section_id The section name to get the settings for.
*
* @return array Settings array, each item being an associative array representing a setting.
*/
protected function get_settings_for_section_core( $section_id ) {
return array();
}
/**
* Get all sections for this page, both the own ones and the ones defined via filters.
*
* @return array
*/
public function get_sections() {
$sections = $this->get_own_sections();
return apply_filters( 'woocommerce_get_sections_' . $this->id, $sections );
}
/**
* Get own sections for this page.
* Derived classes should override this method if they define sections.
* There should always be one default section with an empty string as identifier.
*
* Example:
* return array(
* '' => __( 'General', 'woocommerce' ),
* 'foobars' => __( 'Foos & Bars', 'woocommerce' ),
* );
*
* @return array An associative array where keys are section identifiers and the values are translated section names.
*/
protected function get_own_sections() {
return array( '' => __( 'General', 'woocommerce' ) );
}
/**
* Output sections.
*/
public function output_sections() {
global $current_section;
$sections = $this->get_sections();
if ( empty( $sections ) || 1 === count( $sections ) ) {
return;
}
echo '<ul class="subsubsub">';
$array_keys = array_keys( $sections );
foreach ( $sections as $id => $label ) {
$url = admin_url( 'admin.php?page=wc-settings&tab=' . $this->id . '§ion=' . sanitize_title( $id ) );
$class = ( $current_section === $id ? 'current' : '' );
$separator = ( end( $array_keys ) === $id ? '' : '|' );
$text = esc_html( $label );
echo "<li><a href='$url' class='$class'>$text</a> $separator </li>"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
echo '</ul><br class="clear" />';
}
/**
* Output the HTML for the settings.
*/
public function output() {
global $current_section;
// We can't use "get_settings_for_section" here
// for compatibility with derived classes overriding "get_settings".
$settings = $this->get_settings( $current_section );
WC_Admin_Settings::output_fields( $settings );
}
/**
* Save settings and trigger the 'woocommerce_update_options_'.id action.
*/
public function save() {
$this->save_settings_for_current_section();
$this->do_update_options_action();
}
/**
* Save settings for current section.
*/
protected function save_settings_for_current_section() {
global $current_section;
// We can't use "get_settings_for_section" here
// for compatibility with derived classes overriding "get_settings".
$settings = $this->get_settings( $current_section );
WC_Admin_Settings::save_fields( $settings );
}
/**
* Trigger the 'woocommerce_update_options_'.id action.
*
* @param string $section_id Section to trigger the action for, or null for current section.
*/
protected function do_update_options_action( $section_id = null ) {
global $current_section;
if ( is_null( $section_id ) ) {
$section_id = $current_section;
}
if ( $section_id ) {
do_action( 'woocommerce_update_options_' . $this->id . '_' . $section_id );
}
}
}
endif;