PluginProbe ʕ •ᴥ•ʔ
Admin and Site Enhancements (ASE) / 6.9.1
Admin and Site Enhancements (ASE) v6.9.1
9.1.0 9.0.2 9.0.1 9.0.0 8.9.2 8.9.1 8.9.0 8.8.8 8.8.7 8.8.6 8.8.5 8.8.4 8.8.3 8.8.2 8.8.1 8.8.0 8.7.3 8.7.2 8.7.1 8.2.1 8.2.2 8.2.3 8.3.0 8.3.1 8.3.2 8.4.0 8.4.1 8.4.2 8.5.0 8.5.1 8.5.2 8.6.0 8.6.1 8.6.2 8.7.0 5.0.1 5.0.2 5.0.2.1 5.0.2.2 5.0.2.3 5.0.2.4 5.1.0 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.8.0 5.8.1 6.0.0 6.0.3 6.0.4 6.0.5 6.0.5.1 6.0.6 6.0.7 6.0.8.1 6.1.0 6.1.3 6.2.0 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.7 6.3.0 6.3.1 6.3.2 6.4.0 6.5.0 6.5.1 6.6.0 6.7.0 6.8.0 6.8.2 6.8.3 6.9.0 6.9.1 6.9.10 6.9.11 6.9.12 6.9.13.1 6.9.13.2 6.9.2 6.9.3 6.9.4 6.9.5 6.9.6 6.9.7 6.9.8 6.9.9 7.0.0 7.0.2 7.0.2.1 7.0.2.2 7.0.2.3 7.0.3 7.1.0 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2.0 7.2.1 7.3.0 7.3.1 7.3.2 7.3.3 7.4.0 7.4.2 7.4.4 7.4.5 7.4.6 7.4.7 7.4.8 7.5.0 7.5.1 7.5.2 7.5.3 7.5.4 7.6.0 7.6.1 7.6.1.1 7.6.10 7.6.11 7.6.2 7.6.3 7.6.4 7.6.5 7.6.6 7.6.7 7.6.7.1 7.6.8 7.6.9 7.7.0 7.8.0 7.8.1 7.8.10 7.8.11 7.8.12 7.8.13 7.8.14 7.8.15 7.8.16 7.8.17 7.8.18 7.8.2 7.8.3 7.8.4 7.8.5 7.8.5.1 7.8.6 7.8.7 7.8.8 7.8.9 7.9.0 7.9.1 7.9.10 7.9.11 7.9.2 7.9.3 7.9.4 7.9.5 7.9.6 7.9.7 7.9.8 7.9.9 8.0.0 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.0.6 8.0.7 8.0.8 8.1.0 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 trunk 1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 1.7.0 1.8.0 1.9.0 2.0.0 2.1.0 2.2.0 2.3.0 2.4.0 2.5.0 2.6.0 2.7.0 2.8.0 2.8.1 2.8.2 2.8.3 2.9.0 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.2.0 3.3.0 3.4.0 3.5.0 3.6.1 3.7.0 3.8.0 3.9.0 3.9.1 3.9.2 4.0.0 4.0.1 4.1.0 4.2.0 4.2.1 4.2.2 4.3.0 4.3.1 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.1 4.8.2 4.8.3 4.9.0 4.9.1 4.9.2 4.9.3 5.0.0
admin-site-enhancements / classes / class-settings-fields-render.php
admin-site-enhancements / classes Last commit date
class-activation.php 2 years ago class-admin-interface.php 2 years ago class-common-methods.php 2 years ago class-content-management.php 2 years ago class-custom-code.php 2 years ago class-deactivation.php 2 years ago class-disable-components.php 2 years ago class-login-logout.php 2 years ago class-optimizations.php 2 years ago class-security.php 2 years ago class-settings-fields-render.php 2 years ago class-settings-sanitization.php 2 years ago class-settings-sections-fields.php 2 years ago class-utilities.php 2 years ago
class-settings-fields-render.php
1108 lines
1 <?php
2
3 namespace ASENHA\Classes;
4
5 /**
6 * Class related to rendering of settings fields on the admin page
7 *
8 * @since 2.2.0
9 */
10 class Settings_Fields_Render
11 {
12 /**
13 * Render checkbox field as a toggle/switcher
14 *
15 * @since 1.0.0
16 */
17 function render_checkbox_toggle( $args )
18 {
19 $option_name = $args['option_name'];
20
21 if ( !empty($option_name) ) {
22 $options = get_option( $option_name, array() );
23 } else {
24 $options = get_option( ASENHA_SLUG_U, array() );
25 }
26
27 $field_name = $args['field_name'];
28 $field_description = $args['field_description'];
29 $field_option_value = ( array_key_exists( $args['field_id'], $options ) ? $options[$args['field_id']] : false );
30 echo '<input type="checkbox" id="' . esc_attr( $field_name ) . '" class="asenha-field-checkbox" name="' . esc_attr( $field_name ) . '" ' . checked( $field_option_value, true, false ) . '>' ;
31 echo '<label for="' . esc_attr( $field_name ) . '"></label>' ;
32 // For field with additional options / sub-fields, we add a wrapper to enclose field descriptions
33 if ( array_key_exists( 'field_options_wrapper', $args ) && $args['field_options_wrapper'] ) {
34 // For when the options / sub-fields occupy lengthy vertical space, we add show all / less toggler
35
36 if ( array_key_exists( 'field_options_moreless', $args ) && $args['field_options_moreless'] ) {
37 echo '<div class="asenha-field-with-options field-show-more">' ;
38 echo '<a id="' . $args['field_slug'] . '-show-moreless" class="show-more-less show-more" href="#">Expand &#9660;</a>' ;
39 echo '<div class="asenha-field-options-wrapper wrapper-show-more">' ;
40 } else {
41 echo '<div class="asenha-field-with-options">' ;
42 echo '<div class="asenha-field-options-wrapper">' ;
43 }
44
45 }
46 echo '<div class="asenha-field-description">' . wp_kses_post( $field_description ) . '</div>' ;
47 // For field with additional options / sub-fields, we add wrapper for them
48 if ( array_key_exists( 'field_options_wrapper', $args ) && $args['field_options_wrapper'] ) {
49 echo '<div class="asenha-subfields" style="display:none"></div>' ;
50 }
51 // For field with additional options / sub-fields, we add a wrapper to enclose field descriptions
52
53 if ( array_key_exists( 'field_options_wrapper', $args ) && $args['field_options_wrapper'] ) {
54 echo '</div>' ;
55 echo '</div>' ;
56 }
57
58 }
59
60 /**
61 * Render checkbox field as sub-field of a toggle/switcher checkbox
62 *
63 * @since 1.9.0
64 */
65 function render_checkbox_plain( $args )
66 {
67 $option_name = $args['option_name'];
68
69 if ( !empty($option_name) ) {
70 $options = get_option( $option_name, array() );
71 } else {
72 $options = get_option( ASENHA_SLUG_U, array() );
73 }
74
75 $field_name = $args['field_name'];
76 $field_label = $args['field_label'];
77 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : false );
78 echo '<input type="checkbox" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox" name="' . esc_attr( $field_name ) . '" ' . checked( $field_option_value, true, false ) . '>' ;
79 echo '<label for="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox-label">' . wp_kses_post( $field_label ) . '</label>' ;
80 }
81
82 /**
83 * Render checkbox field as sub-field of a toggle/switcher checkbox
84 *
85 * @since 1.3.0
86 */
87 function render_checkbox_subfield( $args )
88 {
89 $option_name = $args['option_name'];
90
91 if ( !empty($option_name) ) {
92 $options = get_option( $option_name, array() );
93 } else {
94 $options = get_option( ASENHA_SLUG_U, array() );
95 }
96
97 $field_name = $args['field_name'];
98 $field_label = $args['field_label'];
99
100 if ( 'enable_duplication_for' == $args['parent_field_id'] ) {
101 // Default is true/enabled. Usually for options introduced at a later date where the previous default is true/enabled.
102 $default_value = true;
103 } else {
104 // Default is false / checked
105 $default_value = false;
106 }
107
108 $field_option_value = ( isset( $options[$args['parent_field_id']][$args['field_id']] ) ? $options[$args['parent_field_id']][$args['field_id']] : $default_value );
109 echo '<input type="checkbox" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox" name="' . esc_attr( $field_name ) . '" ' . checked( $field_option_value, true, false ) . '>' ;
110 echo '<label for="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox-label">' . wp_kses_post( $field_label ) . '</label>' ;
111 }
112
113 /**
114 * Render radio buttons field as sub-field of a toggle/switcher checkbox
115 *
116 * @since 1.3.0
117 */
118 function render_radio_buttons_subfield( $args )
119 {
120 $option_name = $args['option_name'];
121
122 if ( !empty($option_name) ) {
123 $options = get_option( $option_name, array() );
124 } else {
125 $options = get_option( ASENHA_SLUG_U, array() );
126 }
127
128 $field_id = $args['field_id'];
129 $field_name = $args['field_name'];
130 // $field_label = $args['field_label'];
131 $field_radios = $args['field_radios'];
132
133 if ( !empty($args['field_default']) ) {
134 $default_value = $args['field_default'];
135 } else {
136 $default_value = false;
137 }
138
139 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : $default_value );
140 foreach ( $field_radios as $radio_label => $radio_value ) {
141 echo '<input type="radio" id="' . esc_attr( $field_id . '_' . $radio_value ) . '" class="asenha-subfield-radio-button" name="' . esc_attr( $field_name ) . '" value="' . $radio_value . '" ' . checked( $radio_value, $field_option_value, false ) . '>' ;
142 echo '<label for="' . esc_attr( $field_id . '_' . $radio_value ) . '" class="asenha-subfield-radio-button-label">' . wp_kses_post( $radio_label ) . '</label>' ;
143 }
144 }
145
146 /**
147 * Render text field as sub-field of a toggle/switcher checkbox
148 *
149 * @since 1.4.0
150 */
151 function render_text_subfield( $args )
152 {
153 $option_name = $args['option_name'];
154
155 if ( !empty($option_name) ) {
156 $options = get_option( $option_name, array() );
157 } else {
158 $options = get_option( ASENHA_SLUG_U, array() );
159 }
160
161 $field_id = $args['field_id'];
162 $field_name = $args['field_name'];
163 $field_type = $args['field_type'];
164 $field_prefix = $args['field_prefix'];
165 $field_suffix = $args['field_suffix'];
166 $field_description = $args['field_description'];
167 $field_placeholder = ( isset( $args['field_placeholder'] ) ? $args['field_placeholder'] : '' );
168 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
169
170 if ( !empty($field_prefix) && !empty($field_suffix) ) {
171 $field_classname = ' with-prefix with-suffix';
172 } elseif ( !empty($field_prefix) && empty($field_suffix) ) {
173 $field_classname = ' with-prefix';
174 } elseif ( empty($field_prefix) && !empty($field_suffix) ) {
175 $field_classname = ' with-suffix';
176 } else {
177 $field_classname = '';
178 }
179
180
181 if ( $field_id == 'custom_login_slug' ) {
182 $field_placeholder = 'e.g. backend';
183 } elseif ( $field_id == 'default_login_redirect_slug' ) {
184 $field_placeholder = 'e.g. my-account';
185 } elseif ( $field_id == 'redirect_after_login_to_slug' ) {
186 $field_placeholder = 'e.g. my-account';
187 } elseif ( $field_id == 'redirect_after_logout_to_slug' ) {
188 $field_placeholder = 'e.g. come-visit-again';
189 } elseif ( $field_id == 'login_fails_allowed' ) {
190 $field_placeholder = '3';
191 } elseif ( $field_id == 'login_lockout_maxcount' ) {
192 $field_placeholder = '3';
193 } else {
194 }
195
196 echo $field_prefix . '<input type="text" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-text' . esc_attr( $field_classname ) . '" name="' . esc_attr( $field_name ) . '" placeholder="' . esc_attr( $field_placeholder ) . '" value="' . esc_attr( $field_option_value ) . '">' . $field_suffix ;
197 echo '<label for="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox-label">' . esc_html( $field_description ) . '</label>' ;
198 }
199
200 /**
201 * Render description field as sub-field of a toggle/switcher checkbox
202 *
203 * @since 4.6.0
204 */
205 function render_description_subfield( $args )
206 {
207 $field_description = $args['field_description'];
208 echo '<div class="asenha-subfield-description">' . $field_description . '</div>' ;
209 }
210
211 /**
212 * Render heading for sub-fields of a toggle/switcher checkbox
213 *
214 * @since 5.0.0
215 */
216 function render_subfields_heading( $args )
217 {
218 $subfields_heading = $args['subfields_heading'];
219 echo '<div class="asenha-subfields-heading">' . $subfields_heading . '</div>' ;
220 }
221
222 /**
223 * Render password field as sub-field of a toggle/switcher checkbox
224 *
225 * @since 4.1.0
226 */
227 function render_password_subfield( $args )
228 {
229 $option_name = $args['option_name'];
230
231 if ( !empty($option_name) ) {
232 $options = get_option( $option_name, array() );
233 } else {
234 $options = get_option( ASENHA_SLUG_U, array() );
235 }
236
237 $field_id = $args['field_id'];
238 $field_name = $args['field_name'];
239 $field_type = $args['field_type'];
240 $field_prefix = $args['field_prefix'];
241 $field_suffix = $args['field_suffix'];
242 $field_description = $args['field_description'];
243 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
244
245 if ( !empty($field_prefix) && !empty($field_suffix) ) {
246 $field_classname = ' with-prefix with-suffix';
247 } elseif ( !empty($field_prefix) && empty($field_suffix) ) {
248 $field_classname = ' with-prefix';
249 } elseif ( empty($field_prefix) && !empty($field_suffix) ) {
250 $field_classname = ' with-suffix';
251 } else {
252 $field_classname = '';
253 }
254
255 $placeholder = '';
256 echo $field_prefix . '<input type="password" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-password' . esc_attr( $field_classname ) . '" name="' . esc_attr( $field_name ) . '" placeholder="' . esc_attr( $placeholder ) . '" size="24" autocomplete="off" value="' . $field_option_value . '">' . $field_suffix ;
257 echo '<label for="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox-label">' . esc_html( $field_description ) . '</label>' ;
258 }
259
260 /**
261 * Render number field as sub-field of a toggle/switcher checkbox
262 *
263 * @since 1.4.0
264 */
265 function render_number_subfield( $args )
266 {
267 $option_name = $args['option_name'];
268
269 if ( !empty($option_name) ) {
270 $options = get_option( $option_name, array() );
271 } else {
272 $options = get_option( ASENHA_SLUG_U, array() );
273 }
274
275 $field_id = $args['field_id'];
276 $field_name = $args['field_name'];
277 $field_type = $args['field_type'];
278 $field_prefix = $args['field_prefix'];
279 $field_suffix = $args['field_suffix'];
280 $field_intro = $args['field_intro'];
281 $field_description = ( isset( $args['field_description'] ) ? $args['field_description'] : '' );
282 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
283
284 if ( !empty($field_prefix) && !empty($field_suffix) ) {
285 $field_classname = ' with-prefix with-suffix';
286 } elseif ( !empty($field_prefix) && empty($field_suffix) ) {
287 $field_classname = ' with-prefix';
288 } elseif ( empty($field_prefix) && !empty($field_suffix) ) {
289 $field_classname = ' with-suffix';
290 } else {
291 $field_classname = '';
292 }
293
294
295 if ( $field_id == 'revisions_max_number' || $field_id == 'custom_frontend_css_priority' || $field_id == 'head_code_priority' || $field_id == 'body_code_priority' || $field_id == 'footer_code_priority' ) {
296 $placeholder = '10';
297 } elseif ( $field_id == 'convert_to_webp_quality' ) {
298 $placeholder = '82';
299 } else {
300 $placeholder = '';
301 }
302
303 echo '<div class="asenha-subfield-number-wrapper">' ;
304 if ( !empty($field_intro) ) {
305 echo '<div class="asenha-subfield-number-intro">' . wp_kses_post( $field_intro ) . '</div>' ;
306 }
307 echo '<div>' . $field_prefix . '<input type="number" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-number' . esc_attr( $field_classname ) . '" name="' . esc_attr( $field_name ) . '" placeholder="' . esc_attr( $placeholder ) . '" value="' . esc_attr( $field_option_value ) . '">' . $field_suffix . '</div>' ;
308 if ( !empty($field_description) ) {
309 echo '<div class="asenha-subfield-number-description">' . wp_kses_post( $field_description ) . '</div>' ;
310 }
311 echo '</div>' ;
312 }
313
314 /**
315 * Render select field as sub-field of a toggle/switcher checkbox
316 *
317 * @since 1.4.0
318 */
319 function render_select_subfield( $args )
320 {
321 $option_name = $args['option_name'];
322
323 if ( !empty($option_name) ) {
324 $options = get_option( $option_name, array() );
325 } else {
326 $options = get_option( ASENHA_SLUG_U, array() );
327 }
328
329 $field_id = $args['field_id'];
330 $field_name = $args['field_name'];
331 $field_type = $args['field_type'];
332 $field_prefix = $args['field_prefix'];
333 $field_suffix = $args['field_suffix'];
334 $field_select_options = $args['field_select_options'];
335 $field_select_default = $args['field_select_default'];
336 $field_intro = $args['field_intro'];
337 $field_description = $args['field_description'];
338
339 if ( !empty($args['field_select_default']) ) {
340 $default_value = $args['field_select_default'];
341 } else {
342 $default_value = false;
343 }
344
345 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : $default_value );
346
347 if ( !empty($field_prefix) && !empty($field_suffix) ) {
348 $field_classname = ' with-prefix with-suffix';
349 } elseif ( !empty($field_prefix) && empty($field_suffix) ) {
350 $field_classname = ' with-prefix';
351 } elseif ( empty($field_prefix) && !empty($field_suffix) ) {
352 $field_classname = ' with-suffix';
353 } else {
354 $field_classname = '';
355 }
356
357
358 if ( $args['display_none_on_load'] ) {
359 $inline_style = ' style="display:none;"';
360 } else {
361 $inline_style = '';
362 }
363
364 echo '<div class="asenha-subfield-select-wrapper">' ;
365 if ( !empty($field_intro) ) {
366 echo '<div class="asenha-subfield-select-intro">' . wp_kses_post( $field_intro ) . '</div>' ;
367 }
368 echo '<div' . $inline_style . ' class="asenha-subfield-select-inner">' . $field_prefix ;
369 echo '<select name="' . $field_name . '" class="asenha-subfield-select' . esc_attr( $field_classname ) . '">' ;
370 foreach ( $field_select_options as $label => $value ) {
371 echo '<option value="' . $value . '" ' . selected( $value, $field_option_value, false ) . '>' . $label . '</option>' ;
372 }
373 echo '</select>' ;
374 echo $field_suffix . '</div>' ;
375 if ( !empty($field_description) ) {
376 echo '<div class="asenha-subfield-select-description">' . wp_kses_post( $field_description ) . '</div>' ;
377 }
378 echo '</div>' ;
379 }
380
381 /**
382 * Render textarea field as sub-field of a toggle/switcher checkbox
383 *
384 * @since 2.3.0
385 */
386 function render_textarea_subfield( $args )
387 {
388 $option_name = $args['option_name'];
389
390 if ( !empty($option_name) ) {
391 $options = get_option( $option_name, array() );
392 } else {
393 $options = get_option( ASENHA_SLUG_U, array() );
394 }
395
396 $field_id = $args['field_id'];
397 $field_slug = $args['field_slug'];
398 $field_name = $args['field_name'];
399 $field_type = $args['field_type'];
400 $field_rows = $args['field_rows'];
401 $field_intro = $args['field_intro'];
402 $field_description = $args['field_description'];
403 $field_placeholder = ( isset( $args['field_placeholder'] ) ? $args['field_placeholder'] : '' );
404 // Always load textarea content from robots.txt URL, whether it's a real, custom-made robots.txt file or a virtual one generated by WordPress
405
406 if ( 'robots_txt_content' == $field_id ) {
407
408 if ( array_key_exists( 'manage_robots_txt', $options ) ) {
409
410 if ( !$options['manage_robots_txt'] ) {
411 // Manage robots.txt feature is NOT enabled
412
413 if ( array_key_exists( 'robots_txt_content', $options ) && $options['robots_txt_content'] ) {
414 $field_option_value = $options['robots_txt_content'];
415 } else {
416 $robots_txt_content = wp_remote_get( get_site_url() . '/robots.txt' );
417 $robots_txt_content = esc_textarea( trim( wp_remote_retrieve_body( $robots_txt_content ) ) );
418 $field_option_value = $robots_txt_content;
419 }
420
421 } else {
422 // Manage robots.txt feature is enabled
423
424 if ( array_key_exists( 'robots_txt_content', $options ) && $options['robots_txt_content'] ) {
425 $field_option_value = $options['robots_txt_content'];
426 } else {
427 $robots_txt_content = wp_remote_get( get_site_url() . '/robots.txt' );
428 $robots_txt_content = esc_textarea( trim( wp_remote_retrieve_body( $robots_txt_content ) ) );
429 $field_option_value = $robots_txt_content;
430 }
431
432 }
433
434 } else {
435 // Manage robots.txt feature has never been enabled yet
436 $robots_txt_content = wp_remote_get( get_site_url() . '/robots.txt' );
437 $robots_txt_content = esc_textarea( trim( wp_remote_retrieve_body( $robots_txt_content ) ) );
438 $field_option_value = $robots_txt_content;
439 }
440
441 } else {
442 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
443 }
444
445 echo '<div class="asenha-subfield-textarea-wrapper">' ;
446 if ( !empty($field_intro) ) {
447 echo '<div class="asenha-subfield-textarea-intro">' . wp_kses_post( $field_intro ) . '</div>' ;
448 }
449 echo '<textarea rows="' . $field_rows . '" class="asenha-subfield-textarea" id="' . esc_attr( $field_name ) . '" name="' . esc_attr( $field_name ) . '" placeholder="' . esc_attr( $field_placeholder ) . '">' . esc_textarea( $field_option_value ) . '</textarea>' ;
450 if ( !empty($field_description) ) {
451 echo '<div class="asenha-subfield-textarea-description">' . wp_kses_post( $field_description ) . '</div>' ;
452 }
453 echo '</div>' ;
454 }
455
456 /**
457 * Render textarea field as sub-field of a toggle/switcher checkbox
458 *
459 * @since 2.3.0
460 */
461 function render_wpeditor_subfield( $args )
462 {
463 $option_name = $args['option_name'];
464
465 if ( !empty($option_name) ) {
466 $options = get_option( $option_name, array() );
467 } else {
468 $options = get_option( ASENHA_SLUG_U, array() );
469 }
470
471 $field_id = $args['field_id'];
472 $field_slug = $args['field_slug'];
473 $field_name = $args['field_name'];
474 $field_type = $args['field_type'];
475 $field_rows = $args['field_rows'];
476 $field_intro = $args['field_intro'];
477 $field_description = $args['field_description'];
478 $field_placeholder = ( isset( $args['field_placeholder'] ) ? $args['field_placeholder'] : '' );
479 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
480 echo '<div class="asenha-subfield-wpeditor-wrapper">' ;
481 if ( !empty($field_intro) ) {
482 echo '<div class="asenha-subfield-wpeditor-intro">' . wp_kses_post( $field_intro ) . '</div>' ;
483 }
484 $content = $field_option_value;
485 $textarea_name = $field_name;
486 $editor_id = str_replace( array( '[', ']' ), array( '--', '' ), $field_name );
487 // https://developer.wordpress.org/reference/classes/_wp_editors/parse_settings/
488 $settings = array(
489 'media_buttons' => false,
490 'textarea_name' => $textarea_name,
491 'textarea_rows' => $field_rows,
492 'tiny_mce' => true,
493 'tinymce' => array(
494 'toolbar1' => 'bold,italic,underline,separator,link,unlink,undo,redo',
495 'content_css' => ASENHA_URL . 'assets/css/settings-wpeditor.css',
496 ),
497 'editor_css' => '',
498 'quicktags' => false,
499 );
500 echo wp_editor( $content, $editor_id, $settings ) ;
501 if ( !empty($field_description) ) {
502 echo '<div class="asenha-subfield-wpeditor-description">' . wp_kses_post( $field_description ) . '</div>' ;
503 }
504 echo '</div>' ;
505 }
506
507 /**
508 * Render test email subfield for Email Delivery module
509 *
510 * @since 5.3.0
511 */
512 function render_custom_html( $args )
513 {
514 // name attribute is emptied so this input will be excluded from saving into ASENHA option
515 echo $args['html'] ;
516 }
517
518 /**
519 * Render media subfield
520 *
521 * @since 6.2.2
522 */
523 function render_media_subfield( $args )
524 {
525 $field_id = $args['field_id'];
526 $field_slug = $args['field_slug'];
527 $field_name = $args['field_name'];
528 $field_media_frame_title = $args['field_media_frame_title'];
529 $field_media_frame_multiple = $args['field_media_frame_multiple'];
530 $field_media_frame_library_type = $args['field_media_frame_library_type'];
531 $field_media_frame_button_text = $args['field_media_frame_button_text'];
532 $field_intro = $args['field_intro'];
533 $field_description = $args['field_description'];
534 $options = get_option( $args['option_name'], array() );
535 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : '' );
536 ?>
537 <div class="media-subfield-wrapper">
538 <input id="<?php
539 echo esc_attr( $field_slug ) ;
540 ?>" class="image-picker" type="text" size="36" name="<?php
541 echo esc_attr( $field_name ) ;
542 ?>" value="<?php
543 echo esc_url( $field_option_value ) ;
544 ?>" />
545 <button id="<?php
546 echo esc_attr( $field_slug ) ;
547 ?>-button" class="image-picker-button button-secondary">Select an Image</button>
548 </div>
549 <?php
550 }
551
552 /**
553 * Render media subfield
554 *
555 * @since 6.2.2
556 */
557 function render_color_picker_subfield( $args )
558 {
559 $common_methods = new Common_Methods();
560 $field_id = $args['field_id'];
561 $field_slug = $args['field_slug'];
562 $field_name = $args['field_name'];
563 $field_intro = $args['field_intro'];
564 $field_description = $args['field_description'];
565 $field_default_value = $args['field_default_value'];
566 $options = get_option( $args['option_name'], array() );
567 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : '' );
568 ?>
569 <div class="color-subfield-wrapper">
570 <input type="text" id="<?php
571 echo esc_attr( $field_slug ) ;
572 ?>" name="<?php
573 echo esc_attr( $field_name ) ;
574 ?>" value="<?php
575 echo $common_methods->sanitize_hex_color( $field_option_value ) ;
576 ?>" data-default-color="<?php
577 echo $common_methods->sanitize_hex_color( $field_default_value ) ;
578 ?>" class="color-picker"/>
579 </div>
580 <?php
581 }
582
583 /**
584 * Render sortable menu field
585 *
586 * @since 2.0.0
587 */
588 function render_sortable_menu( $args )
589 {
590 ?>
591 <div class="subfield-description">Drag and drop menu items to the desired position. Optionally change 3rd party plugin/theme's menu item titles or hide some items until toggled by clicking "Show All" at the bottom of the admin menu.</div>
592 <?php
593 ?>
594 <ul id="custom-admin-menu" class="menu ui-sortable">
595 <?php
596 global $menu, $submenu ;
597 $common_methods = new Common_Methods();
598 $option_name = $args['option_name'];
599
600 if ( !empty($option_name) ) {
601 $options = get_option( $option_name, array() );
602 } else {
603 $options = get_option( ASENHA_SLUG_U, array() );
604 }
605
606 // Set menu items to be excluded from title renaming. These are from WordPress core.
607 $renaming_not_allowed = array(
608 'menu-dashboard',
609 'menu-pages',
610 'menu-posts',
611 'menu-media',
612 'menu-comments',
613 'menu-appearance',
614 'menu-plugins',
615 'menu-users',
616 'menu-tools',
617 'menu-settings'
618 );
619 // Get custom menu item titles
620
621 if ( array_key_exists( 'custom_menu_titles', $options ) ) {
622 $custom_menu_titles = $options['custom_menu_titles'];
623 $custom_menu_titles = explode( ',', $custom_menu_titles );
624 } else {
625 $custom_menu_titles = array();
626 }
627
628 // Get menu items hidden by toggle
629 $menu_hidden_by_toggle = $common_methods->get_menu_hidden_by_toggle();
630 $i = 1;
631 // Check if there's an existing custom menu order data stored in options
632
633 if ( array_key_exists( 'custom_menu_order', $options ) ) {
634 $custom_menu = $options['custom_menu_order'];
635 $custom_menu = explode( ',', $custom_menu );
636 $menu_key_in_use = array();
637 // Render sortables with data in custom menu order
638 foreach ( $custom_menu as $custom_menu_item ) {
639 foreach ( $menu as $menu_key => $menu_info ) {
640
641 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
642 $menu_item_title = $menu_info[2];
643 $menu_item_id = $menu_info[2];
644 } else {
645 $menu_item_title = $menu_info[0];
646 $menu_item_id = $menu_info[5];
647 }
648
649 $menu_url_fragment = '';
650
651 if ( $custom_menu_item == $menu_item_id ) {
652 $menu_item_id_transformed = $common_methods->transform_menu_item_id( $menu_item_id );
653 ?>
654 <li id="<?php
655 echo esc_attr( $menu_item_id ) ;
656 ?>" class="menu-item parent-menu-item menu-item-depth-0">
657 <div class="menu-item-bar">
658 <div class="menu-item-handle">
659 <span class="dashicons dashicons-menu"></span>
660 <div class="item-title">
661 <div class="title-wrapper">
662 <span class="menu-item-title">
663 <?php
664
665 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
666 $separator_name_ori = $menu_info[2];
667 $separator_name = str_replace( 'separator', 'Separator-', $separator_name_ori );
668 $separator_name = str_replace( '--last', '-Last', $separator_name );
669 $separator_name = str_replace( '--woocommerce', '--WooCommerce', $separator_name );
670 echo '~~ ' . esc_html( $separator_name ) . ' ~~' ;
671 } else {
672
673 if ( in_array( $menu_item_id, $renaming_not_allowed ) ) {
674 $menu_item_title = $menu_info[0];
675 echo wp_kses_post( $common_methods->strip_html_tags_and_content( $menu_item_title ) ) ;
676 } else {
677 // Get defaul/custom menu item title
678 foreach ( $custom_menu_titles as $custom_menu_title ) {
679 // At this point, $custom_menu_title value looks like toplevel_page_snippets__Code Snippets
680 $custom_menu_title = explode( '__', $custom_menu_title );
681
682 if ( $custom_menu_title[0] == $menu_item_id ) {
683 $menu_item_title = $common_methods->strip_html_tags_and_content( $custom_menu_title[1] );
684 // e.g. Code Snippets
685 break;
686 // stop foreach loop so $menu_item_title is not overwritten in the next iteration
687 } else {
688 $menu_item_title = $common_methods->strip_html_tags_and_content( $menu_info[0] );
689 }
690
691 }
692 ?>
693 <input type="text" value="<?php
694 echo wp_kses_post( $menu_item_title ) ;
695 ?>" class="menu-item-custom-title" data-menu-item-id="<?php
696 echo esc_attr( $menu_item_id ) ;
697 ?>">
698 <?php
699 }
700
701 }
702
703 ?>
704 </span><!-- end of .menu-item-title -->
705 <?php
706 ?>
707 </div><!-- end of .title-wrapper -->
708 <div class="options-for-hiding">
709 <?php
710 $hide_text = 'Hide until toggled';
711 $checkbox_class = 'parent-menu-hide-checkbox';
712 ?>
713 <label class="menu-item-checkbox-label">
714 <?php
715
716 if ( in_array( $custom_menu_item, $menu_hidden_by_toggle ) ) {
717 ?>
718 <input type="checkbox" id="hide-status-for-<?php
719 echo esc_attr( $menu_item_id_transformed ) ;
720 ?>" class="<?php
721 echo esc_attr( $checkbox_class ) ;
722 ?>" data-menu-item-title="<?php
723 echo esc_attr( $common_methods->strip_html_tags_and_content( $menu_item_title ) ) ;
724 ?>" data-menu-item-id="<?php
725 echo esc_attr( $menu_item_id_transformed ) ;
726 ?>" data-menu-item-id-ori="<?php
727 echo esc_attr( $menu_item_id ) ;
728 ?>" data-menu-url-fragment="<?php
729 echo esc_attr( $menu_url_fragment ) ;
730 ?>" checked>
731 <span><?php
732 echo esc_html( $hide_text ) ;
733 ?></span>
734 <?php
735 } else {
736 ?>
737 <input type="checkbox" id="hide-status-for-<?php
738 echo esc_attr( $menu_item_id_transformed ) ;
739 ?>" class="<?php
740 echo esc_attr( $checkbox_class ) ;
741 ?>" data-menu-item-title="<?php
742 echo esc_attr( $common_methods->strip_html_tags_and_content( $menu_item_title ) ) ;
743 ?>" data-menu-item-id="<?php
744 echo esc_attr( $menu_item_id_transformed ) ;
745 ?>" data-menu-item-id-ori="<?php
746 echo esc_attr( $menu_item_id ) ;
747 ?>" data-menu-url-fragment="<?php
748 echo esc_attr( $menu_url_fragment ) ;
749 ?>">
750 <span><?php
751 echo esc_html( $hide_text ) ;
752 ?></span>
753 <?php
754 }
755
756 ?>
757 </label>
758 <?php
759 ?>
760 </div><!-- end of .options-for-hiding -->
761 </div><!-- end of .item-title -->
762 </div><!-- end of .menu-item-handle -->
763 </div><!-- end of .menu-item-bar -->
764 <?php
765 $i = 1;
766 ?>
767 </li>
768 <?php
769 $menu_key_in_use[] = $menu_key;
770 }
771
772 }
773 }
774 // Render the rest of the current menu towards the end of the sortables
775 foreach ( $menu as $menu_key => $menu_info ) {
776
777 if ( !in_array( $menu_key, $menu_key_in_use ) ) {
778
779 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
780 $menu_item_id = $menu_info[2];
781 } else {
782 $menu_item_id = $menu_info[5];
783 }
784
785 $menu_item_title = $menu_info[0];
786 $menu_url_fragment = '';
787 // Strip tags
788 $menu_item_title = $common_methods->strip_html_tags_and_content( $menu_item_title );
789 // Exclude Show All/Less toggles
790
791 if ( false === strpos( $menu_item_id, 'toplevel_page_asenha_' ) ) {
792 $menu_item_id_transformed = $common_methods->transform_menu_item_id( $menu_item_id );
793 ?>
794 <li id="<?php
795 echo esc_attr( $menu_item_id ) ;
796 ?>" class="menu-item parent-menu-item menu-item-depth-0">
797 <div class="menu-item-bar">
798 <div class="menu-item-handle">
799 <span class="dashicons dashicons-menu"></span>
800 <div class="item-title">
801 <div class="title-wrapper">
802 <span class="menu-item-title">
803 <?php
804
805 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
806 $separator_name_ori = $menu_info[2];
807 $separator_name = str_replace( 'separator', 'Separator-', $separator_name_ori );
808 $separator_name = str_replace( '--last', '-Last', $separator_name );
809 $separator_name = str_replace( '--woocommerce', '--WooCommerce', $separator_name );
810 echo '~~ ' . esc_html( $separator_name ) . ' ~~' ;
811 } else {
812 ?>
813 <input type="text" value="<?php
814 echo wp_kses_post( $menu_item_title ) ;
815 ?>" class="menu-item-custom-title" data-menu-item-id="<?php
816 echo esc_attr( $menu_item_id ) ;
817 ?>">
818 <?php
819 }
820
821 ?>
822 </span>
823 <?php
824 ?>
825 </div>
826 <div class="options-for-hiding">
827 <?php
828 $hide_text = 'Hide until toggled';
829 $checkbox_class = 'parent-menu-hide-checkbox';
830 ?>
831 <label class="menu-item-checkbox-label">
832 <input type="checkbox" id="hide-status-for-<?php
833 echo esc_attr( $menu_item_id_transformed ) ;
834 ?>" class="<?php
835 echo esc_attr( $checkbox_class ) ;
836 ?>" data-menu-item-id="<?php
837 echo esc_attr( $menu_item_id_transformed ) ;
838 ?>">
839 <span><?php
840 echo esc_html( $hide_text ) ;
841 ?></span>
842 </label>
843 <?php
844 ?>
845 </div><!-- end of .options-for-hiding -->
846 </div><!-- end of .item-title -->
847 </div><!-- end of .menu-item-handle -->
848 </div><!-- end of .menu-item-bar -->
849 <?php
850 $i = 1;
851 ?>
852 </li><!-- end of .menu-item -->
853 <?php
854 }
855
856 }
857
858 }
859 } else {
860 // No custom menu order has been saved yet
861 // Render sortables with existing items in the admin menu
862 foreach ( $menu as $menu_key => $menu_info ) {
863
864 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
865 $menu_item_id = $menu_info[2];
866 } else {
867 $menu_item_id = $menu_info[5];
868 }
869
870 $menu_url_fragment = '';
871 $menu_item_title = $menu_info[0];
872 $menu_item_id_transformed = $common_methods->transform_menu_item_id( $menu_item_id );
873 // Strip tags
874 $menu_item_title = $common_methods->strip_html_tags_and_content( $menu_item_title );
875 ?>
876 <li id="<?php
877 echo esc_attr( $menu_item_id ) ;
878 ?>" class="menu-item parent-menu-item menu-item-depth-0">
879 <div class="menu-item-bar">
880 <div class="menu-item-handle">
881 <span class="dashicons dashicons-menu"></span>
882 <div class="item-title">
883 <div class="title-wrapper">
884 <span class="menu-item-title">
885 <?php
886
887 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
888 $separator_name_ori = $menu_info[2];
889 $separator_name = str_replace( 'separator', 'Separator-', $separator_name_ori );
890 $separator_name = str_replace( '--last', '-Last', $separator_name );
891 $separator_name = str_replace( '--woocommerce', '--WooCommerce', $separator_name );
892 echo '~~ ' . esc_html( $separator_name ) . ' ~~' ;
893 } else {
894
895 if ( in_array( $menu_item_id, $renaming_not_allowed ) ) {
896 echo wp_kses_post( $menu_item_title ) ;
897 } else {
898 ?>
899 <input type="text" value="<?php
900 echo wp_kses_post( $menu_item_title ) ;
901 ?>" class="menu-item-custom-title" data-menu-item-id="<?php
902 echo esc_attr( $menu_item_id ) ;
903 ?>">
904 <?php
905 }
906
907 }
908
909 ?>
910 </span>
911 <?php
912 ?>
913 </div><!-- end of .title-wrapper -->
914 <div class="options-for-hiding">
915 <?php
916 $hide_text = 'Hide until toggled';
917 $checkbox_class = 'parent-menu-hide-checkbox';
918 ?>
919 <label class="menu-item-checkbox-label">
920 <input type="checkbox" id="hide-status-for-<?php
921 echo esc_attr( $menu_item_id_transformed ) ;
922 ?>" class="<?php
923 echo esc_attr( $checkbox_class ) ;
924 ?>" data-menu-item-id="<?php
925 echo esc_attr( $menu_item_id_transformed ) ;
926 ?>">
927 <span><?php
928 echo esc_html( $hide_text ) ;
929 ?></span>
930 </label>
931 <?php
932 ?>
933 </div><!-- end of .options-for-hiding -->
934 </div><!-- end of .item-title -->
935 </div><!-- end of .menu-item-handle -->
936 </div><!-- end of .menu-item-bar -->
937 <?php
938 $i = 1;
939 ?>
940 </li>
941 <?php
942 }
943 }
944
945 ?>
946 </ul>
947 <?php
948 // Hidden input field to store custom menu order (from options as is, or sortupdate) upon clicking Save Changes.
949 $field_id = $args['field_id'];
950 $field_name = $args['field_name'];
951 $field_description = $args['field_description'];
952 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
953 echo '<input type="hidden" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-text" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $field_option_value ) . '">' ;
954 // Hidden input field to store custom menu titles (from options as is, or custom values entered on each non-WP-default menu items.
955 $field_id = 'custom_menu_titles';
956 $field_name = ASENHA_SLUG_U . '[' . $field_id . ']';
957 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : '' );
958 echo '<input type="hidden" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-text" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $field_option_value ) . '">' ;
959 // Hidden input field to store hidden menu items (from options as is, or 'Hide' checkbox clicks) upon clicking Save Changes.
960 $field_id = 'custom_menu_hidden';
961 $field_name = ASENHA_SLUG_U . '[' . $field_id . ']';
962 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : '' );
963 echo '<input type="hidden" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-text" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $field_option_value ) . '">' ;
964 }
965
966 /**
967 * Render textarea field as sub-field of a toggle/switcher checkbox
968 *
969 * @since 2.3.0
970 */
971 function render_datatable( $args )
972 {
973 global $wpdb ;
974 $option_name = $args['option_name'];
975
976 if ( !empty($option_name) ) {
977 $options = get_option( $option_name, array() );
978 } else {
979 $options = get_option( ASENHA_SLUG_U, array() );
980 }
981
982 $field_id = $args['field_id'];
983 $field_slug = $args['field_slug'];
984 $field_name = $args['field_name'];
985 $field_type = $args['field_type'];
986 $field_description = $args['field_description'];
987 $table_title = $args['table_title'];
988 $table_name = $args['table_name'];
989 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
990 ?>
991 <table id="login-attempts-log" class="wp-list-table widefat striped datatable">
992 <thead>
993 <tr class="datatable-tr">
994 <th class="datatable-th">IP Address<br />Last Username</th>
995 <th class="datatable-th">Attempts<br />Lockouts</th>
996 <th class="datatable-th">Last Attempt On</th>
997 </tr>
998 </thead>
999 <tbody>
1000 <?php
1001 $limit = 1000;
1002 $sql = $wpdb->prepare( "SELECT * FROM {$table_name} ORDER BY unixtime DESC LIMIT %d", array( $limit ) );
1003 $entries = $wpdb->get_results( $sql, ARRAY_A );
1004 foreach ( $entries as $entry ) {
1005 $unixtime = $entry['unixtime'];
1006
1007 if ( function_exists( 'wp_date' ) ) {
1008 $date = wp_date( 'F j, Y', $unixtime );
1009 $time = wp_date( 'H:i:s', $unixtime );
1010 } else {
1011 $date = date_i18n( 'F j, Y', $unixtime );
1012 $time = date_i18n( 'H:i:s', $unixtime );
1013 }
1014
1015 ?>
1016 <tr class="datatable-tr">
1017 <td class="datatable-td"><?php
1018 echo esc_html( $entry['ip_address'] ) ;
1019 ?><br /><?php
1020 echo esc_html( $entry['username'] ) ;
1021 ?></td>
1022 <td class="datatable-td"><?php
1023 echo esc_html( $entry['fail_count'] ) ;
1024 ?><br /><?php
1025 echo esc_html( $entry['lockout_count'] ) ;
1026 ?></td>
1027 <td class="datatable-td"><?php
1028 echo esc_html( $date ) ;
1029 ?><br /><?php
1030 echo esc_html( $time ) ;
1031 ?></td>
1032 </tr>
1033 <?php
1034 }
1035 ?>
1036 </tbody>
1037 </table>
1038 <?php
1039 echo '<input type="hidden" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-datatable" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $field_option_value ) . '">' ;
1040 }
1041
1042 /**
1043 * Render checks and status for AVIF support
1044 *
1045 * @link https://php.watch/versions/8.1/gd-avif
1046 * @since 5.7.0
1047 */
1048 public function render_avif_support_status()
1049 {
1050 // Check status of GD extension and it's AVIF support
1051
1052 if ( extension_loaded( 'gd' ) && function_exists( 'gd_info' ) ) {
1053 $is_gd_enabled = true;
1054 $gd_info = gd_info();
1055 $gd_version = $gd_info['GD Version'];
1056 $gd_avif_support = ( isset( $gd_info['AVIF Support'] ) ? isset( $gd_info['AVIF Support'] ) : false );
1057
1058 if ( $gd_avif_support ) {
1059 $gd_status = $gd_version . ' <span class="supported">with AVIF support</span>';
1060 } else {
1061 $gd_status = $gd_version . ' <span class="unsupported">without AVIF support</span>';
1062 }
1063
1064 } else {
1065 $is_gd_enabled = false;
1066 $gd_avif_support = false;
1067 $gd_status = 'Not available';
1068 }
1069
1070 // Check status of ImageMagick library and it's AVIF support
1071
1072 if ( extension_loaded( 'imagick' ) && class_exists( 'Imagick' ) ) {
1073 $is_imagick_enabled = true;
1074 $imagick_version = \Imagick::getVersion();
1075
1076 if ( preg_match( '/((?:[0-9]+\\.?)+)/', $imagick_version['versionString'], $matches ) ) {
1077 $imagick_version = $matches[0];
1078 } else {
1079 $imagick_version = $imagick_version['versionString'];
1080 }
1081
1082
1083 if ( version_compare( $imagick_version, '7.0.25', '>=' ) ) {
1084 $imagick_avif_support = true;
1085 $imagick_status = $imagick_version . ' <span class="supported">with AVIF support</span>';
1086 } else {
1087 $imagick_avif_support = false;
1088 $imagick_status = $imagick_version . ' <span class="unsupported">without AVIF support</span>';
1089 }
1090
1091 } else {
1092 $is_imagick_enabled = false;
1093 $imagick_avif_support = false;
1094 $imagick_status = 'Not available';
1095 }
1096
1097 echo '<div class="asenha-subfield-status">' ;
1098 echo '<div class="status-title">AVIF Support Status</div>' ;
1099 echo '<div class="status-body">' ;
1100 echo '<div class="status-item"><span class="status-item-title">PHP</span> : ' . wp_kses_post( phpversion() ) . '</div>' ;
1101 echo '<div class="status-item"><span class="status-item-title">GD</span> : ' . wp_kses_post( $gd_status ) . '</div>' ;
1102 echo '<div class="status-item"><span class="status-item-title">ImageMagick</span> : ' . wp_kses_post( $imagick_status ) . '</div>' ;
1103 echo '</div>' ;
1104 echo '<div class="status-footer">Full AVIF support requires that your server / hosting has <a href="https://php.watch/versions/8.1/gd-avif" target="_blank">GD extension</a> compiled with AVIF support in PHP 8.1 or greater, or, <a href="https://avif.io/blog/tutorials/imagemagick/" target="_blank">ImageMagick 7.0.25 or greater</a> installed. Without either, you can still upload AVIF files but without auto-generation of the smaller thumbnail sizes. A majority of <a href="https://avif.io/blog/articles/avif-browser-support/" target="_blank">modern desktop and mobile browsers</a> support the display of AVIF files.</div>' ;
1105 echo '</div>' ;
1106 }
1107
1108 }