PluginProbe
Polylang / 3.7.7
Polylang v3.7.7
3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 3.0.3 All 233 releases
← All changes | settings/settings-module.php +71 -40 3.0.13.7.7 View file →
@@ -28,11 +28,17 @@
28 28 */
29 29 public $links_model;
30 30
31 31 /**
32 - * Stores if the module is active.
32 + * Key to use to manage the module activation state.
33 + * Possible values:
34 + * - An option key for a module that can be activated/deactivated.
35 + * - 'none' for a module that doesn't have a activation/deactivation setting.
36 + * - 'preview' for a preview module whose functionalities are available in the Pro version.
33 37 *
34 - * @var bool
38 + * @var string
39 + *
40 + * @phpstan-var non-falsy-string
35 41 */
36 42 public $active_option;
37 43
38 44 /**
@@ -46,8 +52,10 @@
46 52 * Stores the module name.
47 53 * It must be unique.
48 54 *
49 55 * @var string
56 + *
57 + * @phpstan-var non-falsy-string
50 58 */
51 59 public $module;
52 60
53 61 /**
@@ -80,9 +88,9 @@
80 88
81 89 /**
82 90 * Stores html form when provided by a child class.
83 91 *
84 - * @var bool|string
92 + * @var string|false
85 93 */
86 94 protected $form = false;
87 95
88 96 /**
@@ -89,14 +97,31 @@
89 97 * Constructor
90 98 *
91 99 * @since 1.8
92 100 *
93 - * @param object $polylang Polylang object
94 - * @param array $args
101 + * @param object $polylang The Polylang object.
102 + * @param array $args {
103 + * @type string $module Unique module name.
104 + * @type string $title The title of the settings module.
105 + * @type string $description The description of the settings module.
106 + * @type string $active_option Optional. Key to use to manage the module activation state.
107 + * Possible values:
108 + * - An option key for a module that can be activated/deactivated.
109 + * - 'none' for a module that doesn't have a activation/deactivation setting.
110 + * - 'preview' for a preview module whose functionalities are available in the Pro version.
111 + * Default is 'none'.
112 + * }
113 + *
114 + * @phpstan-param array{
115 + * module: non-falsy-string,
116 + * title: string,
117 + * description: string,
118 + * active_option?: non-falsy-string
119 + * } $args
95 120 */
96 121 public function __construct( &$polylang, $args ) {
97 - $this->options = &$polylang->options;
98 - $this->model = &$polylang->model;
122 + $this->options = &$polylang->options;
123 + $this->model = &$polylang->model;
99 124 $this->links_model = &$polylang->links_model;
100 125
101 126 $args = wp_parse_args(
102 127 $args,
@@ -102,12 +127,17 @@
102 127 $args,
103 128 array(
104 129 'title' => '',
105 130 'description' => '',
106 - 'active_option' => false,
131 + 'active_option' => 'none',
107 132 )
108 133 );
109 134
135 + if ( empty( $args['active_option'] ) ) {
136 + // Backward compatibility.
137 + $args['active_option'] = 'none';
138 + }
139 +
110 140 foreach ( $args as $prop => $value ) {
111 141 $this->$prop = $value;
112 142 }
113 143
@@ -139,14 +169,14 @@
139 169 'cancel' => sprintf( '<button type="button" class="button button-secondary cancel">%s</button>', esc_html__( 'Cancel', 'polylang' ) ),
140 170 'save' => sprintf( '<button type="button" class="button button-primary save">%s</button>', esc_html__( 'Save Changes', 'polylang' ) ),
141 171 );
142 172
143 - // Ajax action to save options
173 + // Ajax action to save options.
144 174 add_action( 'wp_ajax_pll_save_options', array( $this, 'save_options' ) );
145 175 }
146 176
147 177 /**
148 - * Tells if the module is active
178 + * Tells if the module is active.
149 179 *
150 180 * @since 1.8
151 181 *
152 182 * @return bool
@@ -151,13 +181,13 @@
151 181 *
152 182 * @return bool
153 183 */
154 184 public function is_active() {
155 - return empty( $this->active_option ) || ! empty( $this->options[ $this->active_option ] );
185 + return 'none' === $this->active_option || ( 'preview' !== $this->active_option && ! empty( $this->options[ $this->active_option ] ) );
156 186 }
157 187
158 188 /**
159 - * Activates the module
189 + * Activates the module.
160 190 *
161 191 * @since 1.8
162 192 *
163 193 * @return void
@@ -162,16 +192,15 @@
162 192 *
163 193 * @return void
164 194 */
165 195 public function activate() {
166 - if ( ! empty( $this->active_option ) ) {
196 + if ( 'none' !== $this->active_option && 'preview' !== $this->active_option ) {
167 197 $this->options[ $this->active_option ] = true;
168 - update_option( 'polylang', $this->options );
169 198 }
170 199 }
171 200
172 201 /**
173 - * Deactivates the module
202 + * Deactivates the module.
174 203 *
175 204 * @since 1.8
176 205 *
177 206 * @return void
@@ -176,16 +205,15 @@
176 205 *
177 206 * @return void
178 207 */
179 208 public function deactivate() {
180 - if ( ! empty( $this->active_option ) ) {
209 + if ( 'none' !== $this->active_option && 'preview' !== $this->active_option ) {
181 210 $this->options[ $this->active_option ] = false;
182 - update_option( 'polylang', $this->options );
183 211 }
184 212 }
185 213
186 214 /**
187 - * Protected method to display a configuration form
215 + * Protected method to display a configuration form.
188 216 *
189 217 * @since 1.8
190 218 *
191 219 * @return void
@@ -190,13 +218,13 @@
190 218 *
191 219 * @return void
192 220 */
193 221 protected function form() {
194 - // Child classes can provide a form
222 + // Child classes can provide a form.
195 223 }
196 224
197 225 /**
198 - * Public method returning the form if any
226 + * Public method returning the form if any.
199 227 *
200 228 * @since 1.8
201 229 *
202 230 * @return string
@@ -201,8 +229,12 @@
201 229 *
202 230 * @return string
203 231 */
204 232 public function get_form() {
233 + if ( ! $this->is_active() ) {
234 + return '';
235 + }
236 +
205 237 // Read the form only once
206 238 if ( false === $this->form ) {
207 239 ob_start();
208 240 $this->form();
@@ -212,21 +244,21 @@
212 244 return $this->form;
213 245 }
214 246
215 247 /**
216 - * Allows child classes to validate their options before saving
248 + * Allows child classes to prepare the received data before saving.
217 249 *
218 - * @since 1.8
250 + * @since 3.7
219 251 *
220 - * @param array $options Raw options
221 - * @return array Options
252 + * @param array $options Raw values to save.
253 + * @return array
222 254 */
223 - protected function update( $options ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
224 - return array(); // It's responsibility of the child class to decide what is saved
255 + protected function prepare_raw_data( array $options ): array {
256 + return $options;
225 257 }
226 258
227 259 /**
228 - * Ajax method to save the options
260 + * Ajax method to save the options.
229 261 *
230 262 * @since 1.8
231 263 *
232 264 * @return void
@@ -238,31 +270,30 @@
238 270 }
239 271
240 272 if ( isset( $_POST['module'] ) && $this->module === $_POST['module'] ) {
241 273 // It's up to the child class to decide which options are saved, whether there are errors or not
242 - $post = array_diff_key( $_POST, array_flip( array( 'action', 'module', 'pll_ajax_backend', '_pll_nonce' ) ) );
243 - $options = $this->update( $post );
244 - $this->options = array_merge( $this->options, $options );
245 - update_option( 'polylang', $this->options );
274 + $posted_options = array_diff_key( $_POST, array_flip( array( 'action', 'module', 'pll_ajax_backend', 'pll_ajax_settings', '_pll_nonce' ) ) );
275 + $errors = $this->options->merge( $this->prepare_raw_data( $posted_options ) );
246 276
247 277 // Refresh language cache in case home urls have been modified
248 278 $this->model->clean_languages_cache();
249 279
250 - // Refresh rewrite rules in case rewrite, hide_default, post types or taxonomies options have been modified
280 + // Refresh rewrite rules in case rewrite, hide_default, post types or taxonomies options have been modified
251 281 // Don't use flush_rewrite_rules as we don't have the right links model and permastruct
252 282 delete_option( 'rewrite_rules' );
253 283
254 284 ob_start();
255 285
256 - if ( ! get_settings_errors() ) {
286 + if ( ! $errors->has_errors() ) {
257 287 // Send update message
258 - add_settings_error( 'general', 'settings_updated', __( 'Settings saved.', 'polylang' ), 'updated' );
259 - settings_errors();
288 + pll_add_notice( new WP_Error( 'settings_updated', __( 'Settings saved.', 'polylang' ), 'success' ) );
289 + settings_errors( 'polylang' );
260 290 $x = new WP_Ajax_Response( array( 'what' => 'success', 'data' => ob_get_clean() ) );
261 291 $x->send();
262 292 } else {
263 293 // Send error messages
264 - settings_errors();
294 + pll_add_notice( $errors );
295 + settings_errors( 'polylang' );
265 296 $x = new WP_Ajax_Response( array( 'what' => 'error', 'data' => ob_get_clean() ) );
266 297 $x->send();
267 298 }
268 299 }
@@ -281,9 +312,9 @@
281 312 if ( $this->is_active() && $this->get_form() ) {
282 313 $actions[] = 'configure';
283 314 }
284 315
285 - if ( $this->active_option ) {
316 + if ( 'none' !== $this->active_option && 'preview' !== $this->active_option ) {
286 317 $actions[] = $this->is_active() ? 'deactivate' : 'activate';
287 318 }
288 319
289 320 if ( empty( $actions ) ) {
@@ -304,9 +335,9 @@
304 335 return array_intersect_key( $this->action_links, array_flip( $this->get_actions() ) );
305 336 }
306 337
307 338 /**
308 - * Default upgrade message ( to Pro version )
339 + * Default upgrade message (to Pro version).
309 340 *
310 341 * @since 1.9
311 342 *
312 343 * @return string
@@ -320,9 +351,9 @@
320 351 );
321 352 }
322 353
323 354 /**
324 - * Allows child classes to display an upgrade message
355 + * Allows child classes to display an upgrade message.
325 356 *
326 357 * @since 1.9
327 358 *
328 359 * @return string
@@ -327,9 +358,9 @@
327 358 *
328 359 * @return string
329 360 */
330 361 public function get_upgrade_message() {
331 - return '';
362 + return 'preview' === $this->active_option ? $this->default_upgrade_message() : '';
332 363 }
333 364
334 365 /**
335 366 * Get the buttons.