PluginProbe
Admin and Site Enhancements (ASE) / 6.2.0
Admin and Site Enhancements (ASE) v6.2.0
9.1.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 All 273 releases
admin-site-enhancements / classes / class-settings-fields-render.php
class-settings-fields-render.php
981 lines 43.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 $field_option_value = ( isset( $options[$args['parent_field_id']][$args['field_id']] ) ? $options[$args['parent_field_id']][$args['field_id']] : false );
100 echo '<input type="checkbox" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox" name="' . esc_attr( $field_name ) . '" ' . checked( $field_option_value, true, false ) . '>' ;
101 echo '<label for="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox-label">' . wp_kses_post( $field_label ) . '</label>' ;
102 }
103
104 /**
105 * Render radio buttons field as sub-field of a toggle/switcher checkbox
106 *
107 * @since 1.3.0
108 */
109 function render_radio_buttons_subfield( $args )
110 {
111 $option_name = $args['option_name'];
112
113 if ( !empty($option_name) ) {
114 $options = get_option( $option_name, array() );
115 } else {
116 $options = get_option( ASENHA_SLUG_U, array() );
117 }
118
119 $field_id = $args['field_id'];
120 $field_name = $args['field_name'];
121 // $field_label = $args['field_label'];
122 $field_radios = $args['field_radios'];
123
124 if ( !empty($args['field_default']) ) {
125 $default_value = $args['field_default'];
126 } else {
127 $default_value = false;
128 }
129
130 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : $default_value );
131 foreach ( $field_radios as $radio_label => $radio_value ) {
132 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 ) . '>' ;
133 echo '<label for="' . esc_attr( $field_id . '_' . $radio_value ) . '" class="asenha-subfield-radio-button-label">' . wp_kses_post( $radio_label ) . '</label>' ;
134 }
135 }
136
137 /**
138 * Render text field as sub-field of a toggle/switcher checkbox
139 *
140 * @since 1.4.0
141 */
142 function render_text_subfield( $args )
143 {
144 $option_name = $args['option_name'];
145
146 if ( !empty($option_name) ) {
147 $options = get_option( $option_name, array() );
148 } else {
149 $options = get_option( ASENHA_SLUG_U, array() );
150 }
151
152 $field_id = $args['field_id'];
153 $field_name = $args['field_name'];
154 $field_type = $args['field_type'];
155 $field_prefix = $args['field_prefix'];
156 $field_suffix = $args['field_suffix'];
157 $field_description = $args['field_description'];
158 $field_placeholder = ( isset( $args['field_placeholder'] ) ? $args['field_placeholder'] : '' );
159 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
160
161 if ( !empty($field_prefix) && !empty($field_suffix) ) {
162 $field_classname = ' with-prefix with-suffix';
163 } elseif ( !empty($field_prefix) && empty($field_suffix) ) {
164 $field_classname = ' with-prefix';
165 } elseif ( empty($field_prefix) && !empty($field_suffix) ) {
166 $field_classname = ' with-suffix';
167 } else {
168 $field_classname = '';
169 }
170
171
172 if ( $field_id == 'custom_login_slug' ) {
173 $field_placeholder = 'e.g. backend';
174 } elseif ( $field_id == 'redirect_after_login_to_slug' ) {
175 $field_placeholder = 'e.g. my-account';
176 } elseif ( $field_id == 'redirect_after_logout_to_slug' ) {
177 $field_placeholder = 'e.g. come-visit-again';
178 } elseif ( $field_id == 'login_fails_allowed' ) {
179 $field_placeholder = '3';
180 } elseif ( $field_id == 'login_lockout_maxcount' ) {
181 $field_placeholder = '3';
182 } else {
183 }
184
185 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 ;
186 echo '<label for="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox-label">' . esc_html( $field_description ) . '</label>' ;
187 }
188
189 /**
190 * Render description field as sub-field of a toggle/switcher checkbox
191 *
192 * @since 4.6.0
193 */
194 function render_description_subfield( $args )
195 {
196 $field_description = $args['field_description'];
197 echo '<div class="asenha-subfield-description">' . $field_description . '</div>' ;
198 }
199
200 /**
201 * Render heading for sub-fields of a toggle/switcher checkbox
202 *
203 * @since 5.0.0
204 */
205 function render_subfields_heading( $args )
206 {
207 $subfields_heading = $args['subfields_heading'];
208 echo '<div class="asenha-subfields-heading">' . $subfields_heading . '</div>' ;
209 }
210
211 /**
212 * Render password field as sub-field of a toggle/switcher checkbox
213 *
214 * @since 4.1.0
215 */
216 function render_password_subfield( $args )
217 {
218 $option_name = $args['option_name'];
219
220 if ( !empty($option_name) ) {
221 $options = get_option( $option_name, array() );
222 } else {
223 $options = get_option( ASENHA_SLUG_U, array() );
224 }
225
226 $field_id = $args['field_id'];
227 $field_name = $args['field_name'];
228 $field_type = $args['field_type'];
229 $field_prefix = $args['field_prefix'];
230 $field_suffix = $args['field_suffix'];
231 $field_description = $args['field_description'];
232 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
233
234 if ( !empty($field_prefix) && !empty($field_suffix) ) {
235 $field_classname = ' with-prefix with-suffix';
236 } elseif ( !empty($field_prefix) && empty($field_suffix) ) {
237 $field_classname = ' with-prefix';
238 } elseif ( empty($field_prefix) && !empty($field_suffix) ) {
239 $field_classname = ' with-suffix';
240 } else {
241 $field_classname = '';
242 }
243
244 $placeholder = '';
245 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 ;
246 echo '<label for="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox-label">' . esc_html( $field_description ) . '</label>' ;
247 }
248
249 /**
250 * Render number field as sub-field of a toggle/switcher checkbox
251 *
252 * @since 1.4.0
253 */
254 function render_number_subfield( $args )
255 {
256 $option_name = $args['option_name'];
257
258 if ( !empty($option_name) ) {
259 $options = get_option( $option_name, array() );
260 } else {
261 $options = get_option( ASENHA_SLUG_U, array() );
262 }
263
264 $field_id = $args['field_id'];
265 $field_name = $args['field_name'];
266 $field_type = $args['field_type'];
267 $field_prefix = $args['field_prefix'];
268 $field_suffix = $args['field_suffix'];
269 $field_intro = $args['field_intro'];
270 $field_description = ( isset( $args['field_description'] ) ? $args['field_description'] : '' );
271 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
272
273 if ( !empty($field_prefix) && !empty($field_suffix) ) {
274 $field_classname = ' with-prefix with-suffix';
275 } elseif ( !empty($field_prefix) && empty($field_suffix) ) {
276 $field_classname = ' with-prefix';
277 } elseif ( empty($field_prefix) && !empty($field_suffix) ) {
278 $field_classname = ' with-suffix';
279 } else {
280 $field_classname = '';
281 }
282
283
284 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' ) {
285 $placeholder = '10';
286 } elseif ( $field_id == 'convert_to_webp_quality' ) {
287 $placeholder = '82';
288 } else {
289 $placeholder = '';
290 }
291
292 echo '<div class="asenha-subfield-number-wrapper">' ;
293 if ( !empty($field_intro) ) {
294 echo '<div class="asenha-subfield-number-intro">' . wp_kses_post( $field_intro ) . '</div>' ;
295 }
296 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>' ;
297 if ( !empty($field_description) ) {
298 echo '<div class="asenha-subfield-number-description">' . wp_kses_post( $field_description ) . '</div>' ;
299 }
300 echo '</div>' ;
301 }
302
303 /**
304 * Render select field as sub-field of a toggle/switcher checkbox
305 *
306 * @since 1.4.0
307 */
308 function render_select_subfield( $args )
309 {
310 $option_name = $args['option_name'];
311
312 if ( !empty($option_name) ) {
313 $options = get_option( $option_name, array() );
314 } else {
315 $options = get_option( ASENHA_SLUG_U, array() );
316 }
317
318 $field_id = $args['field_id'];
319 $field_name = $args['field_name'];
320 $field_type = $args['field_type'];
321 $field_prefix = $args['field_prefix'];
322 $field_suffix = $args['field_suffix'];
323 $field_select_options = $args['field_select_options'];
324 $field_select_default = $args['field_select_default'];
325 $field_intro = $args['field_intro'];
326 $field_description = $args['field_description'];
327
328 if ( !empty($args['field_select_default']) ) {
329 $default_value = $args['field_select_default'];
330 } else {
331 $default_value = false;
332 }
333
334 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : $default_value );
335
336 if ( !empty($field_prefix) && !empty($field_suffix) ) {
337 $field_classname = ' with-prefix with-suffix';
338 } elseif ( !empty($field_prefix) && empty($field_suffix) ) {
339 $field_classname = ' with-prefix';
340 } elseif ( empty($field_prefix) && !empty($field_suffix) ) {
341 $field_classname = ' with-suffix';
342 } else {
343 $field_classname = '';
344 }
345
346
347 if ( $args['display_none_on_load'] ) {
348 $inline_style = ' style="display:none;"';
349 } else {
350 $inline_style = '';
351 }
352
353 echo '<div class="asenha-subfield-select-wrapper">' ;
354 if ( !empty($field_intro) ) {
355 echo '<div class="asenha-subfield-select-intro">' . wp_kses_post( $field_intro ) . '</div>' ;
356 }
357 echo '<div' . $inline_style . ' class="asenha-subfield-select-inner">' . $field_prefix ;
358 echo '<select name="' . $field_name . '" class="asenha-subfield-select' . esc_attr( $field_classname ) . '">' ;
359 foreach ( $field_select_options as $label => $value ) {
360 echo '<option value="' . $value . '" ' . selected( $value, $field_option_value, false ) . '>' . $label . '</option>' ;
361 }
362 echo '</select>' ;
363 echo $field_suffix . '</div>' ;
364 if ( !empty($field_description) ) {
365 echo '<div class="asenha-subfield-select-description">' . wp_kses_post( $field_description ) . '</div>' ;
366 }
367 echo '</div>' ;
368 }
369
370 /**
371 * Render textarea field as sub-field of a toggle/switcher checkbox
372 *
373 * @since 2.3.0
374 */
375 function render_textarea_subfield( $args )
376 {
377 $option_name = $args['option_name'];
378
379 if ( !empty($option_name) ) {
380 $options = get_option( $option_name, array() );
381 } else {
382 $options = get_option( ASENHA_SLUG_U, array() );
383 }
384
385 $field_id = $args['field_id'];
386 $field_slug = $args['field_slug'];
387 $field_name = $args['field_name'];
388 $field_type = $args['field_type'];
389 $field_rows = $args['field_rows'];
390 $field_intro = $args['field_intro'];
391 $field_description = $args['field_description'];
392 $field_placeholder = ( isset( $args['field_placeholder'] ) ? $args['field_placeholder'] : '' );
393 // 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
394
395 if ( 'robots_txt_content' == $field_id ) {
396
397 if ( array_key_exists( 'manage_robots_txt', $options ) ) {
398
399 if ( !$options['manage_robots_txt'] ) {
400 // Manage robots.txt feature is NOT enabled
401
402 if ( array_key_exists( 'robots_txt_content', $options ) && $options['robots_txt_content'] ) {
403 $field_option_value = $options['robots_txt_content'];
404 } else {
405 $robots_txt_content = wp_remote_get( get_site_url() . '/robots.txt' );
406 $robots_txt_content = esc_textarea( trim( wp_remote_retrieve_body( $robots_txt_content ) ) );
407 $field_option_value = $robots_txt_content;
408 }
409
410 } else {
411 // Manage robots.txt feature is 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 }
422
423 } else {
424 // Manage robots.txt feature has never been enabled yet
425 $robots_txt_content = wp_remote_get( get_site_url() . '/robots.txt' );
426 $robots_txt_content = esc_textarea( trim( wp_remote_retrieve_body( $robots_txt_content ) ) );
427 $field_option_value = $robots_txt_content;
428 }
429
430 } else {
431 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
432 }
433
434 echo '<div class="asenha-subfield-textarea-wrapper">' ;
435 if ( !empty($field_intro) ) {
436 echo '<div class="asenha-subfield-textarea-intro">' . wp_kses_post( $field_intro ) . '</div>' ;
437 }
438 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>' ;
439 if ( !empty($field_description) ) {
440 echo '<div class="asenha-subfield-textarea-description">' . wp_kses_post( $field_description ) . '</div>' ;
441 }
442 echo '</div>' ;
443 }
444
445 /**
446 * Render test email subfield for Email Delivery module
447 *
448 * @since 5.3.0
449 */
450 function render_custom_html( $args )
451 {
452 // name attribute is emptied so this input will be excluded from saving into ASENHA option
453 echo $args['html'] ;
454 }
455
456 /**
457 * Render sortable menu field
458 *
459 * @since 2.0.0
460 */
461 function render_sortable_menu( $args )
462 {
463 ?>
464 <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>
465 <?php
466 ?>
467 <ul id="custom-admin-menu" class="menu ui-sortable">
468 <?php
469 global $menu, $submenu ;
470 $common_methods = new Common_Methods();
471 $option_name = $args['option_name'];
472
473 if ( !empty($option_name) ) {
474 $options = get_option( $option_name, array() );
475 } else {
476 $options = get_option( ASENHA_SLUG_U, array() );
477 }
478
479 // Set menu items to be excluded from title renaming. These are from WordPress core.
480 $renaming_not_allowed = array(
481 'menu-dashboard',
482 'menu-pages',
483 'menu-posts',
484 'menu-media',
485 'menu-comments',
486 'menu-appearance',
487 'menu-plugins',
488 'menu-users',
489 'menu-tools',
490 'menu-settings'
491 );
492 // Get custom menu item titles
493
494 if ( array_key_exists( 'custom_menu_titles', $options ) ) {
495 $custom_menu_titles = $options['custom_menu_titles'];
496 $custom_menu_titles = explode( ',', $custom_menu_titles );
497 } else {
498 $custom_menu_titles = array();
499 }
500
501 // Get menu items hidden by toggle
502 $menu_hidden_by_toggle = $common_methods->get_menu_hidden_by_toggle();
503 $i = 1;
504 // Check if there's an existing custom menu order data stored in options
505
506 if ( array_key_exists( 'custom_menu_order', $options ) ) {
507 $custom_menu = $options['custom_menu_order'];
508 $custom_menu = explode( ',', $custom_menu );
509 $menu_key_in_use = array();
510 // Render sortables with data in custom menu order
511 foreach ( $custom_menu as $custom_menu_item ) {
512 foreach ( $menu as $menu_key => $menu_info ) {
513
514 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
515 $menu_item_title = $menu_info[2];
516 $menu_item_id = $menu_info[2];
517 } else {
518 $menu_item_title = $menu_info[0];
519 $menu_item_id = $menu_info[5];
520 }
521
522 $menu_url_fragment = '';
523
524 if ( $custom_menu_item == $menu_item_id ) {
525 $menu_item_id_transformed = $common_methods->transform_menu_item_id( $menu_item_id );
526 ?>
527 <li id="<?php
528 echo esc_attr( $menu_item_id ) ;
529 ?>" class="menu-item parent-menu-item menu-item-depth-0">
530 <div class="menu-item-bar">
531 <div class="menu-item-handle">
532 <span class="dashicons dashicons-menu"></span>
533 <div class="item-title">
534 <div class="title-wrapper">
535 <span class="menu-item-title">
536 <?php
537
538 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
539 $separator_name_ori = $menu_info[2];
540 $separator_name = str_replace( 'separator', 'Separator-', $separator_name_ori );
541 $separator_name = str_replace( '--last', '-Last', $separator_name );
542 $separator_name = str_replace( '--woocommerce', '--WooCommerce', $separator_name );
543 echo '~~ ' . esc_html( $separator_name ) . ' ~~' ;
544 } else {
545
546 if ( in_array( $menu_item_id, $renaming_not_allowed ) ) {
547 $menu_item_title = $menu_info[0];
548 echo wp_kses_post( $common_methods->strip_html_tags_and_content( $menu_item_title ) ) ;
549 } else {
550 // Get defaul/custom menu item title
551 foreach ( $custom_menu_titles as $custom_menu_title ) {
552 // At this point, $custom_menu_title value looks like toplevel_page_snippets__Code Snippets
553 $custom_menu_title = explode( '__', $custom_menu_title );
554
555 if ( $custom_menu_title[0] == $menu_item_id ) {
556 $menu_item_title = $common_methods->strip_html_tags_and_content( $custom_menu_title[1] );
557 // e.g. Code Snippets
558 break;
559 // stop foreach loop so $menu_item_title is not overwritten in the next iteration
560 } else {
561 $menu_item_title = $common_methods->strip_html_tags_and_content( $menu_info[0] );
562 }
563
564 }
565 ?>
566 <input type="text" value="<?php
567 echo wp_kses_post( $menu_item_title ) ;
568 ?>" class="menu-item-custom-title" data-menu-item-id="<?php
569 echo esc_attr( $menu_item_id ) ;
570 ?>">
571 <?php
572 }
573
574 }
575
576 ?>
577 </span><!-- end of .menu-item-title -->
578 <?php
579 ?>
580 </div><!-- end of .title-wrapper -->
581 <div class="options-for-hiding">
582 <?php
583 $hide_text = 'Hide until toggled';
584 $checkbox_class = 'parent-menu-hide-checkbox';
585 ?>
586 <label class="menu-item-checkbox-label">
587 <?php
588
589 if ( in_array( $custom_menu_item, $menu_hidden_by_toggle ) ) {
590 ?>
591 <input type="checkbox" id="hide-status-for-<?php
592 echo esc_attr( $menu_item_id_transformed ) ;
593 ?>" class="<?php
594 echo esc_attr( $checkbox_class ) ;
595 ?>" data-menu-item-title="<?php
596 echo esc_attr( $common_methods->strip_html_tags_and_content( $menu_item_title ) ) ;
597 ?>" data-menu-item-id="<?php
598 echo esc_attr( $menu_item_id_transformed ) ;
599 ?>" data-menu-item-id-ori="<?php
600 echo esc_attr( $menu_item_id ) ;
601 ?>" data-menu-url-fragment="<?php
602 echo esc_attr( $menu_url_fragment ) ;
603 ?>" checked>
604 <span><?php
605 echo esc_html( $hide_text ) ;
606 ?></span>
607 <?php
608 } else {
609 ?>
610 <input type="checkbox" id="hide-status-for-<?php
611 echo esc_attr( $menu_item_id_transformed ) ;
612 ?>" class="<?php
613 echo esc_attr( $checkbox_class ) ;
614 ?>" data-menu-item-title="<?php
615 echo esc_attr( $common_methods->strip_html_tags_and_content( $menu_item_title ) ) ;
616 ?>" data-menu-item-id="<?php
617 echo esc_attr( $menu_item_id_transformed ) ;
618 ?>" data-menu-item-id-ori="<?php
619 echo esc_attr( $menu_item_id ) ;
620 ?>" data-menu-url-fragment="<?php
621 echo esc_attr( $menu_url_fragment ) ;
622 ?>">
623 <span><?php
624 echo esc_html( $hide_text ) ;
625 ?></span>
626 <?php
627 }
628
629 ?>
630 </label>
631 <?php
632 ?>
633 </div><!-- end of .options-for-hiding -->
634 </div><!-- end of .item-title -->
635 </div><!-- end of .menu-item-handle -->
636 </div><!-- end of .menu-item-bar -->
637 <?php
638 $i = 1;
639 ?>
640 </li>
641 <?php
642 $menu_key_in_use[] = $menu_key;
643 }
644
645 }
646 }
647 // Render the rest of the current menu towards the end of the sortables
648 foreach ( $menu as $menu_key => $menu_info ) {
649
650 if ( !in_array( $menu_key, $menu_key_in_use ) ) {
651
652 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
653 $menu_item_id = $menu_info[2];
654 } else {
655 $menu_item_id = $menu_info[5];
656 }
657
658 $menu_item_title = $menu_info[0];
659 $menu_url_fragment = '';
660 // Strip tags
661 $menu_item_title = $common_methods->strip_html_tags_and_content( $menu_item_title );
662 // Exclude Show All/Less toggles
663
664 if ( false === strpos( $menu_item_id, 'toplevel_page_asenha_' ) ) {
665 $menu_item_id_transformed = $common_methods->transform_menu_item_id( $menu_item_id );
666 ?>
667 <li id="<?php
668 echo esc_attr( $menu_item_id ) ;
669 ?>" class="menu-item parent-menu-item menu-item-depth-0">
670 <div class="menu-item-bar">
671 <div class="menu-item-handle">
672 <span class="dashicons dashicons-menu"></span>
673 <div class="item-title">
674 <div class="title-wrapper">
675 <span class="menu-item-title">
676 <?php
677
678 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
679 $separator_name_ori = $menu_info[2];
680 $separator_name = str_replace( 'separator', 'Separator-', $separator_name_ori );
681 $separator_name = str_replace( '--last', '-Last', $separator_name );
682 $separator_name = str_replace( '--woocommerce', '--WooCommerce', $separator_name );
683 echo '~~ ' . esc_html( $separator_name ) . ' ~~' ;
684 } else {
685 ?>
686 <input type="text" value="<?php
687 echo wp_kses_post( $menu_item_title ) ;
688 ?>" class="menu-item-custom-title" data-menu-item-id="<?php
689 echo esc_attr( $menu_item_id ) ;
690 ?>">
691 <?php
692 }
693
694 ?>
695 </span>
696 <?php
697 ?>
698 </div>
699 <div class="options-for-hiding">
700 <?php
701 $hide_text = 'Hide until toggled';
702 $checkbox_class = 'parent-menu-hide-checkbox';
703 ?>
704 <label class="menu-item-checkbox-label">
705 <input type="checkbox" id="hide-status-for-<?php
706 echo esc_attr( $menu_item_id_transformed ) ;
707 ?>" class="<?php
708 echo esc_attr( $checkbox_class ) ;
709 ?>" data-menu-item-id="<?php
710 echo esc_attr( $menu_item_id_transformed ) ;
711 ?>">
712 <span><?php
713 echo esc_html( $hide_text ) ;
714 ?></span>
715 </label>
716 <?php
717 ?>
718 </div><!-- end of .options-for-hiding -->
719 </div><!-- end of .item-title -->
720 </div><!-- end of .menu-item-handle -->
721 </div><!-- end of .menu-item-bar -->
722 <?php
723 $i = 1;
724 ?>
725 </li><!-- end of .menu-item -->
726 <?php
727 }
728
729 }
730
731 }
732 } else {
733 // No custom menu order has been saved yet
734 // Render sortables with existing items in the admin menu
735 foreach ( $menu as $menu_key => $menu_info ) {
736
737 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
738 $menu_item_id = $menu_info[2];
739 } else {
740 $menu_item_id = $menu_info[5];
741 }
742
743 $menu_url_fragment = '';
744 $menu_item_title = $menu_info[0];
745 $menu_item_id_transformed = $common_methods->transform_menu_item_id( $menu_item_id );
746 // Strip tags
747 $menu_item_title = $common_methods->strip_html_tags_and_content( $menu_item_title );
748 ?>
749 <li id="<?php
750 echo esc_attr( $menu_item_id ) ;
751 ?>" class="menu-item parent-menu-item menu-item-depth-0">
752 <div class="menu-item-bar">
753 <div class="menu-item-handle">
754 <span class="dashicons dashicons-menu"></span>
755 <div class="item-title">
756 <div class="title-wrapper">
757 <span class="menu-item-title">
758 <?php
759
760 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
761 $separator_name_ori = $menu_info[2];
762 $separator_name = str_replace( 'separator', 'Separator-', $separator_name_ori );
763 $separator_name = str_replace( '--last', '-Last', $separator_name );
764 $separator_name = str_replace( '--woocommerce', '--WooCommerce', $separator_name );
765 echo '~~ ' . esc_html( $separator_name ) . ' ~~' ;
766 } else {
767
768 if ( in_array( $menu_item_id, $renaming_not_allowed ) ) {
769 echo wp_kses_post( $menu_item_title ) ;
770 } else {
771 ?>
772 <input type="text" value="<?php
773 echo wp_kses_post( $menu_item_title ) ;
774 ?>" class="menu-item-custom-title" data-menu-item-id="<?php
775 echo esc_attr( $menu_item_id ) ;
776 ?>">
777 <?php
778 }
779
780 }
781
782 ?>
783 </span>
784 <?php
785 ?>
786 </div><!-- end of .title-wrapper -->
787 <div class="options-for-hiding">
788 <?php
789 $hide_text = 'Hide until toggled';
790 $checkbox_class = 'parent-menu-hide-checkbox';
791 ?>
792 <label class="menu-item-checkbox-label">
793 <input type="checkbox" id="hide-status-for-<?php
794 echo esc_attr( $menu_item_id_transformed ) ;
795 ?>" class="<?php
796 echo esc_attr( $checkbox_class ) ;
797 ?>" data-menu-item-id="<?php
798 echo esc_attr( $menu_item_id_transformed ) ;
799 ?>">
800 <span><?php
801 echo esc_html( $hide_text ) ;
802 ?></span>
803 </label>
804 <?php
805 ?>
806 </div><!-- end of .options-for-hiding -->
807 </div><!-- end of .item-title -->
808 </div><!-- end of .menu-item-handle -->
809 </div><!-- end of .menu-item-bar -->
810 <?php
811 $i = 1;
812 ?>
813 </li>
814 <?php
815 }
816 }
817
818 ?>
819 </ul>
820 <?php
821 // Hidden input field to store custom menu order (from options as is, or sortupdate) upon clicking Save Changes.
822 $field_id = $args['field_id'];
823 $field_name = $args['field_name'];
824 $field_description = $args['field_description'];
825 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
826 echo '<input type="hidden" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-text" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $field_option_value ) . '">' ;
827 // Hidden input field to store custom menu titles (from options as is, or custom values entered on each non-WP-default menu items.
828 $field_id = 'custom_menu_titles';
829 $field_name = ASENHA_SLUG_U . '[' . $field_id . ']';
830 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : '' );
831 echo '<input type="hidden" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-text" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $field_option_value ) . '">' ;
832 // Hidden input field to store hidden menu items (from options as is, or 'Hide' checkbox clicks) upon clicking Save Changes.
833 $field_id = 'custom_menu_hidden';
834 $field_name = ASENHA_SLUG_U . '[' . $field_id . ']';
835 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : '' );
836 echo '<input type="hidden" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-text" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $field_option_value ) . '">' ;
837 }
838
839 /**
840 * Render textarea field as sub-field of a toggle/switcher checkbox
841 *
842 * @since 2.3.0
843 */
844 function render_datatable( $args )
845 {
846 global $wpdb ;
847 $option_name = $args['option_name'];
848
849 if ( !empty($option_name) ) {
850 $options = get_option( $option_name, array() );
851 } else {
852 $options = get_option( ASENHA_SLUG_U, array() );
853 }
854
855 $field_id = $args['field_id'];
856 $field_slug = $args['field_slug'];
857 $field_name = $args['field_name'];
858 $field_type = $args['field_type'];
859 $field_description = $args['field_description'];
860 $table_title = $args['table_title'];
861 $table_name = $args['table_name'];
862 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
863 ?>
864 <table id="login-attempts-log" class="wp-list-table widefat striped datatable">
865 <thead>
866 <tr class="datatable-tr">
867 <th class="datatable-th">IP Address<br />Last Username</th>
868 <th class="datatable-th">Attempts<br />Lockouts</th>
869 <th class="datatable-th">Last Attempt On</th>
870 </tr>
871 </thead>
872 <tbody>
873 <?php
874 $limit = 1000;
875 $sql = $wpdb->prepare( "SELECT * FROM {$table_name} ORDER BY unixtime DESC LIMIT %d", array( $limit ) );
876 $entries = $wpdb->get_results( $sql, ARRAY_A );
877 foreach ( $entries as $entry ) {
878 $unixtime = $entry['unixtime'];
879
880 if ( function_exists( 'wp_date' ) ) {
881 $date = wp_date( 'F j, Y', $unixtime );
882 $time = wp_date( 'H:i:s', $unixtime );
883 } else {
884 $date = date_i18n( 'F j, Y', $unixtime );
885 $time = date_i18n( 'H:i:s', $unixtime );
886 }
887
888 ?>
889 <tr class="datatable-tr">
890 <td class="datatable-td"><?php
891 echo esc_html( $entry['ip_address'] ) ;
892 ?><br /><?php
893 echo esc_html( $entry['username'] ) ;
894 ?></td>
895 <td class="datatable-td"><?php
896 echo esc_html( $entry['fail_count'] ) ;
897 ?><br /><?php
898 echo esc_html( $entry['lockout_count'] ) ;
899 ?></td>
900 <td class="datatable-td"><?php
901 echo esc_html( $date ) ;
902 ?><br /><?php
903 echo esc_html( $time ) ;
904 ?></td>
905 </tr>
906 <?php
907 }
908 ?>
909 </tbody>
910 </table>
911 <?php
912 echo '<input type="hidden" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-datatable" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $field_option_value ) . '">' ;
913 }
914
915 /**
916 * Render checks and status for AVIF support
917 *
918 * @link https://php.watch/versions/8.1/gd-avif
919 * @since 5.7.0
920 */
921 public function render_avif_support_status()
922 {
923 // Check status of GD extension and it's AVIF support
924
925 if ( extension_loaded( 'gd' ) && function_exists( 'gd_info' ) ) {
926 $is_gd_enabled = true;
927 $gd_info = gd_info();
928 $gd_version = $gd_info['GD Version'];
929 $gd_avif_support = ( isset( $gd_info['AVIF Support'] ) ? isset( $gd_info['AVIF Support'] ) : false );
930
931 if ( $gd_avif_support ) {
932 $gd_status = $gd_version . ' <span class="supported">with AVIF support</span>';
933 } else {
934 $gd_status = $gd_version . ' <span class="unsupported">without AVIF support</span>';
935 }
936
937 } else {
938 $is_gd_enabled = false;
939 $gd_avif_support = false;
940 $gd_status = 'Not available';
941 }
942
943 // Check status of ImageMagick library and it's AVIF support
944
945 if ( extension_loaded( 'imagick' ) && class_exists( 'Imagick' ) ) {
946 $is_imagick_enabled = true;
947 $imagick_version = \Imagick::getVersion();
948
949 if ( preg_match( '/((?:[0-9]+\\.?)+)/', $imagick_version['versionString'], $matches ) ) {
950 $imagick_version = $matches[0];
951 } else {
952 $imagick_version = $imagick_version['versionString'];
953 }
954
955
956 if ( version_compare( $imagick_version, '7.0.25', '>=' ) ) {
957 $imagick_avif_support = true;
958 $imagick_status = $imagick_version . ' <span class="supported">with AVIF support</span>';
959 } else {
960 $imagick_avif_support = false;
961 $imagick_status = $imagick_version . ' <span class="unsupported">without AVIF support</span>';
962 }
963
964 } else {
965 $is_imagick_enabled = false;
966 $imagick_avif_support = false;
967 $imagick_status = 'Not available';
968 }
969
970 echo '<div class="asenha-subfield-status">' ;
971 echo '<div class="status-title">AVIF Support Status</div>' ;
972 echo '<div class="status-body">' ;
973 echo '<div class="status-item"><span class="status-item-title">PHP</span> : ' . wp_kses_post( phpversion() ) . '</div>' ;
974 echo '<div class="status-item"><span class="status-item-title">GD</span> : ' . wp_kses_post( $gd_status ) . '</div>' ;
975 echo '<div class="status-item"><span class="status-item-title">ImageMagick</span> : ' . wp_kses_post( $imagick_status ) . '</div>' ;
976 echo '</div>' ;
977 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>' ;
978 echo '</div>' ;
979 }
980
981 }