PluginProbe
Polylang / 3.7.3
Polylang v3.7.3
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 / include / Options / Abstract_Option.php

Abstract_Option.php in Polylang 3.7.3, at include/Options/Abstract_Option.php

284 lines 5.7 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 * }
23 */
24 abstract class Abstract_Option {
25 /**
26 * Option value.
27 *
28 * @var mixed
29 */
30 private $value;
31
32 /**
33 * Cached option JSON schema.
34 *
35 * @var array|null
36 *
37 * @phpstan-var Schema|null
38 */
39 private $schema;
40
41 /**
42 * Validation and sanitization errors.
43 *
44 * @var WP_Error
45 */
46 protected $errors;
47
48 /**
49 * Constructor.
50 *
51 * @since 3.7
52 *
53 * @param mixed $value Optional. Option value.
54 */
55 public function __construct( $value = null ) {
56 $this->errors = new WP_Error();
57
58 if ( ! isset( $value ) ) {
59 $this->value = $this->get_default();
60 return;
61 }
62
63 $value = rest_sanitize_value_from_schema( $this->prepare( $value ), $this->get_data_structure(), static::key() );
64
65 if ( ! is_wp_error( $value ) ) {
66 $this->value = $value;
67 } else {
68 $this->value = $this->get_default();
69 }
70 }
71
72 /**
73 * Returns option key.
74 *
75 * @since 3.7
76 *
77 * @return string
78 *
79 * @phpstan-return non-falsy-string
80 */
81 abstract public static function key(): string;
82
83 /**
84 * Sets option's value if valid, does nothing otherwise.
85 *
86 * @since 3.7
87 *
88 * @param mixed $value Value to set.
89 * @param Options $options All options.
90 * @return bool True if the value has been assigned. False in case of errors.
91 */
92 public function set( $value, Options $options ): bool {
93 $this->errors = new WP_Error(); // Reset errors.
94 $value = $this->prepare( $value );
95 $is_valid = rest_validate_value_from_schema( $value, $this->get_data_structure(), static::key() );
96
97 if ( is_wp_error( $is_valid ) ) {
98 // Blocking validation error.
99 $this->errors->merge_from( $is_valid );
100 return false;
101 }
102
103 $value = $this->sanitize( $value, $options );
104
105 if ( is_wp_error( $value ) ) {
106 // Blocking sanitization error.
107 $this->errors->merge_from( $value );
108 return false;
109 }
110
111 $this->value = $value;
112 return true;
113 }
114
115 /**
116 * Returns option's value.
117 *
118 * @since 3.7
119 *
120 * @return mixed
121 */
122 public function &get() {
123 return $this->value;
124 }
125
126 /**
127 * Sets default option value.
128 *
129 * @since 3.7
130 *
131 * @return mixed The new value.
132 */
133 public function reset() {
134 $this->value = $this->get_default();
135 return $this->value;
136 }
137
138 /**
139 * Returns JSON schema of the option.
140 *
141 * @since 3.7
142 *
143 * @return array The schema.
144 *
145 * @phpstan-return Schema
146 */
147 public function get_schema(): array {
148 if ( is_array( $this->schema ) ) {
149 return $this->schema;
150 }
151
152 $this->schema = array_merge(
153 array(
154 'description' => $this->get_description(),
155 'default' => $this->get_default(),
156 ),
157 $this->get_data_structure()
158 );
159
160 return $this->schema;
161 }
162
163 /**
164 * Returns non-blocking sanitization errors.
165 *
166 * @since 3.7
167 *
168 * @return WP_Error
169 */
170 public function get_errors(): WP_Error {
171 return $this->errors;
172 }
173
174 /**
175 * Prepares a value before validation.
176 *
177 * @since 3.7
178 *
179 * @param mixed $value Value to format.
180 * @return mixed
181 */
182 protected function prepare( $value ) {
183 return $value;
184 }
185
186 /**
187 * Sanitizes option's value, can be overridden for specific cases not handled by `rest_sanitize_value_from_schema()`.
188 * Can populate the `$errors` property with blocking and non-blocking errors: in case of non-blocking errors,
189 * the value is sanitized and can be stored.
190 *
191 * @since 3.7
192 *
193 * @param mixed $value Value to sanitize.
194 * @param Options $options All options.
195 * @return mixed The sanitized value. An instance of `WP_Error` in case of blocking error.
196 */
197 protected function sanitize( $value, Options $options ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
198 return rest_sanitize_value_from_schema( $value, $this->get_data_structure(), static::key() );
199 }
200
201 /**
202 * Returns the default value.
203 *
204 * @since 3.7
205 *
206 * @return mixed
207 */
208 abstract protected function get_default();
209
210 /**
211 * Returns the JSON schema part specific to this option.
212 *
213 * @since 3.7
214 *
215 * @return array Partial schema.
216 *
217 * @phpstan-return array{type: SchemaType}
218 */
219 abstract protected function get_data_structure(): array;
220
221 /**
222 * Returns the description used in the JSON schema.
223 *
224 * @since 3.7
225 *
226 * @return string
227 */
228 abstract protected function get_description(): string;
229
230 /**
231 * Returns a list of language terms.
232 *
233 * @since 3.7
234 *
235 * @return array
236 *
237 * @phpstan-return list<WP_Term>
238 */
239 protected function get_language_terms(): array {
240 $language_terms = get_terms(
241 array(
242 'taxonomy' => 'language',
243 'hide_empty' => false,
244 )
245 );
246 return is_array( $language_terms ) ? $language_terms : array();
247 }
248
249 /**
250 * Adds a non-blocking error warning about unknown language slugs.
251 *
252 * @since 3.7
253 *
254 * @param array $language_slugs List of language slugs.
255 * @return void
256 */
257 protected function add_unknown_languages_warning( array $language_slugs ): void {
258 if ( 1 === count( $language_slugs ) ) {
259 /* translators: %s is a language slug. */
260 $message = __( 'The language %s is unknown and has been discarded.', 'polylang' );
261 } else {
262 /* translators: %s is a list of language slugs. */
263 $message = __( 'The languages %s are unknown and have been discarded.', 'polylang' );
264 }
265
266 $this->errors->add(
267 sprintf( 'pll_unknown_%s_languages', static::key() ),
268 sprintf(
269 $message,
270 wp_sprintf_l(
271 '%l',
272 array_map(
273 function ( $slug ) {
274 return "<code>{$slug}</code>";
275 },
276 $language_slugs
277 )
278 )
279 ),
280 'warning'
281 );
282 }
283 }
284