PluginProbe
Polylang / 3.8
Polylang v3.8
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
polylang / src / Options / Abstract_Option.php

Abstract_Option.php in Polylang 3.8, at src/Options/Abstract_Option.php

343 lines 7.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package Polylang
4 */
5
6 namespace WP_Syntex\Polylang\Options;
7
8 use WP_Error;
9 use WP_Term;
10 use WP_Syntex\Polylang\Options\Options;
11
12 defined( 'ABSPATH' ) || exit;
13
14 /**
15 * Class defining a single option.
16 *
17 * @since 3.7
18 *
19 * @phpstan-type SchemaType 'string'|'null'|'number'|'integer'|'boolean'|'array'|'object'
20 * @phpstan-type Schema array{
21 * type: SchemaType,
22 * description: string,
23 * default: mixed
24 * }
25 */
26 abstract class Abstract_Option {
27 /**
28 * Option value.
29 *
30 * @var mixed
31 */
32 protected $value;
33
34 /**
35 * Cached option JSON schema.
36 *
37 * @var array|null
38 *
39 * @phpstan-var Schema|null
40 */
41 private $schema;
42
43 /**
44 * Validation and sanitization errors.
45 *
46 * @var WP_Error
47 */
48 protected $errors;
49
50 /**
51 * Constructor.
52 *
53 * @since 3.7
54 *
55 * @param mixed $value Optional. Option value.
56 */
57 public function __construct( $value = null ) {
58 $this->errors = new WP_Error();
59
60 if ( ! isset( $value ) ) {
61 $this->value = $this->get_default();
62 return;
63 }
64
65 $value = rest_sanitize_value_from_schema( $this->prepare( $value ), $this->get_data_structure(), static::key() );
66
67 if ( ! is_wp_error( $value ) ) {
68 $this->value = $value;
69 } else {
70 $this->value = $this->get_default();
71 }
72 }
73
74 /**
75 * Returns option key.
76 *
77 * @since 3.7
78 *
79 * @return string
80 *
81 * @phpstan-return non-falsy-string
82 */
83 abstract public static function key(): string;
84
85 /**
86 * Sets option's value if valid, does nothing otherwise.
87 *
88 * @since 3.7
89 *
90 * @param mixed $value Value to set.
91 * @param Options $options All options.
92 * @return bool True if the value has been assigned. False in case of errors.
93 */
94 public function set( $value, Options $options ): bool {
95 $this->errors = new WP_Error(); // Reset errors.
96 $value = $this->prepare( $value );
97 $is_valid = rest_validate_value_from_schema( $value, $this->get_data_structure(), static::key() );
98
99 if ( is_wp_error( $is_valid ) ) {
100 // Blocking validation error.
101 $this->errors->merge_from( $is_valid );
102 return false;
103 }
104
105 $value = $this->sanitize( $value, $options );
106
107 if ( is_wp_error( $value ) ) {
108 // Blocking sanitization error.
109 $this->errors->merge_from( $value );
110 return false;
111 }
112
113 $this->value = $value;
114 return true;
115 }
116
117 /**
118 * Returns option's value.
119 *
120 * @since 3.7
121 *
122 * @return mixed
123 */
124 public function get() {
125 return $this->value;
126 }
127
128 /**
129 * Sets default option value.
130 *
131 * @since 3.7
132 *
133 * @return mixed The new value.
134 */
135 public function reset() {
136 $this->value = $this->get_default();
137 return $this->value;
138 }
139
140 /**
141 * Returns JSON schema of the option.
142 *
143 * @since 3.7
144 *
145 * @return array The schema.
146 *
147 * @phpstan-return Schema
148 */
149 public function get_schema(): array {
150 if ( is_array( $this->schema ) ) {
151 return $this->schema;
152 }
153
154 $this->schema = array_merge(
155 array(
156 'description' => $this->get_description(),
157 'default' => $this->get_default(),
158 ),
159 $this->get_data_structure()
160 );
161
162 return $this->schema;
163 }
164
165 /**
166 * Returns non-blocking sanitization errors.
167 *
168 * @since 3.7
169 *
170 * @return WP_Error
171 */
172 public function get_errors(): WP_Error {
173 return $this->errors;
174 }
175
176 /**
177 * Prepares a value before validation.
178 *
179 * @since 3.7
180 *
181 * @param mixed $value Value to format.
182 * @return mixed
183 */
184 protected function prepare( $value ) {
185 return $value;
186 }
187
188 /**
189 * Sanitizes option's value, can be overridden for specific cases not handled by `rest_sanitize_value_from_schema()`.
190 * Can populate the `$errors` property with blocking and non-blocking errors: in case of non-blocking errors,
191 * the value is sanitized and can be stored.
192 *
193 * @since 3.7
194 *
195 * @param mixed $value Value to sanitize.
196 * @param Options $options All options.
197 * @return mixed The sanitized value. An instance of `WP_Error` in case of blocking error.
198 */
199 protected function sanitize( $value, Options $options ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
200 return rest_sanitize_value_from_schema( $value, $this->get_data_structure(), static::key() );
201 }
202
203 /**
204 * Returns the default value.
205 *
206 * @since 3.7
207 *
208 * @return mixed
209 */
210 abstract protected function get_default();
211
212 /**
213 * Returns the JSON schema part specific to this option.
214 *
215 * @since 3.7
216 *
217 * @return array Partial schema.
218 *
219 * @phpstan-return array{type: SchemaType}
220 */
221 abstract protected function get_data_structure(): array;
222
223 /**
224 * Returns the description used in the JSON schema.
225 *
226 * @since 3.7
227 *
228 * @return string
229 */
230 abstract protected function get_description(): string;
231
232 /**
233 * Returns a list of language terms.
234 *
235 * @since 3.7
236 *
237 * @return array
238 *
239 * @phpstan-return list<WP_Term>
240 */
241 protected function get_language_terms(): array {
242 $language_terms = get_terms(
243 array(
244 'taxonomy' => 'language',
245 'hide_empty' => false,
246 )
247 );
248 return is_array( $language_terms ) ? $language_terms : array();
249 }
250
251 /**
252 * Adds a non-blocking error warning about unknown language slugs.
253 *
254 * @since 3.7
255 *
256 * @param array $language_slugs List of language slugs.
257 * @return void
258 */
259 protected function add_unknown_languages_warning( array $language_slugs ): void {
260 if ( 1 === count( $language_slugs ) ) {
261 /* translators: %s is a language slug. */
262 $message = __( 'The language %s is unknown and has been discarded.', 'polylang' );
263 } else {
264 /* translators: %s is a list of language slugs. */
265 $message = __( 'The languages %s are unknown and have been discarded.', 'polylang' );
266 }
267
268 $this->errors->add(
269 sprintf( 'pll_unknown_%s_languages', static::key() ),
270 sprintf(
271 $message,
272 wp_sprintf_l(
273 '%l',
274 array_map(
275 function ( $slug ) {
276 return "<code>{$slug}</code>";
277 },
278 $language_slugs
279 )
280 )
281 ),
282 'warning'
283 );
284 }
285
286 /**
287 * Adds information to the site health info array.
288 * Does nothing by default.
289 *
290 * @since 3.8
291 *
292 * @param Options $options An instance of the Options class providing additional configuration.
293 *
294 * @return array The updated site health information.
295 */
296 public function get_site_health_info( Options $options ): array { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
297 return array();
298 }
299
300 /**
301 * Renders site health information by appending additional fields.
302 *
303 * @since 3.8
304 *
305 * @param mixed $value The value to be added to the site health fields.
306 *
307 * @return array Updated array of site health information including the new fields.
308 */
309 protected function format_single_value_for_site_health_info( $value ): array {
310 if ( empty( $value ) ) {
311 return array();
312 }
313
314 return array(
315 'label' => ucfirst( static::key() ),
316 'value' => $value,
317 );
318 }
319
320 /**
321 * Formats an array to display in options information.
322 *
323 * @since 3.8
324 *
325 * @param array $array An array of formatted data.
326 * @return string
327 */
328 protected function format_array_for_site_health_info( array $array ): string {
329 array_walk(
330 $array,
331 function ( &$value, $key ) {
332 if ( is_array( $value ) ) {
333 $ids = implode( ' , ', $value );
334 $value = "$key => $ids";
335 } else {
336 $value = "$key => $value";
337 }
338 }
339 );
340 return implode( ' | ', $array );
341 }
342 }
343