PluginProbe ʕ •ᴥ•ʔ
Admin and Site Enhancements (ASE) / 7.1.2
Admin and Site Enhancements (ASE) v7.1.2
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-columns-manager.php 2 years ago class-admin-menu-organizer.php 2 years ago class-auto-publish-posts-with-missed-schedule.php 2 years ago class-avif-upload.php 2 years ago class-change-login-url.php 2 years ago class-cleanup-admin-bar.php 2 years ago class-code-snippets-manager.php 2 years ago class-common-methods.php 2 years ago class-content-duplication.php 2 years ago class-content-order.php 2 years ago class-custom-admin-footer-text.php 2 years ago class-custom-body-class.php 2 years ago class-custom-content-types.php 2 years ago class-custom-css.php 2 years ago class-custom-nav-menu-items-in-new-tab.php 2 years ago class-deactivation.php 2 years ago class-disable-comments.php 2 years ago class-disable-dashboard-widgets.php 2 years ago class-disable-feeds.php 2 years ago class-disable-gutenberg.php 2 years ago class-disable-rest-api.php 2 years ago class-disable-smaller-components.php 2 years ago class-disable-updates.php 2 years ago class-disable-xml-rpc.php 2 years ago class-display-system-summary.php 2 years ago class-email-address-obfuscator.php 2 years ago class-email-delivery.php 2 years ago class-enhance-list-tables.php 2 years ago class-external-permalinks.php 2 years ago class-heartbeat-control.php 2 years ago class-hide-admin-bar.php 2 years ago class-hide-admin-notices.php 2 years ago class-image-sizes-panel.php 2 years ago class-image-upload-control.php 2 years ago class-insert-head-body-footer-code.php 2 years ago class-last-login-column.php 2 years ago class-limit-login-attempts.php 2 years ago class-login-id-type.php 2 years ago class-login-logout-menu.php 2 years ago class-maintenance-mode.php 2 years ago class-manage-ads-appads-txt.php 2 years ago class-manage-robots-txt.php 2 years ago class-media-replacement.php 2 years ago class-multiple-user-roles.php 2 years ago class-obfuscate-author-slugs.php 2 years ago class-open-external-links-in-new-tab.php 2 years ago class-password-protection.php 2 years ago class-redirect-after-login.php 2 years ago class-redirect-after-logout.php 2 years ago class-redirect-fourofour.php 2 years ago class-revisions-control.php 2 years ago class-search-engines-visibility.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-show-custom-taxonomy-filters.php 2 years ago class-site-identity-on-login-page.php 2 years ago class-svg-upload.php 2 years ago class-various-admin-ui-enhancements.php 2 years ago class-view-admin-as-role.php 2 years ago class-wider-admin-menu.php 2 years ago
class-settings-fields-render.php
1046 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 * Render checkbox field as a toggle/switcher
13 *
14 * @since 1.0.0
15 */
16 function render_checkbox_toggle( $args ) {
17 $option_name = $args['option_name'];
18 if ( !empty( $option_name ) ) {
19 $options = get_option( $option_name, array() );
20 } else {
21 $options = get_option( ASENHA_SLUG_U, array() );
22 }
23 $field_name = $args['field_name'];
24 $field_description = $args['field_description'];
25 $field_option_value = ( array_key_exists( $args['field_id'], $options ) ? $options[$args['field_id']] : false );
26 echo '<input type="checkbox" id="' . esc_attr( $field_name ) . '" class="asenha-field-checkbox" name="' . esc_attr( $field_name ) . '" ' . checked( $field_option_value, true, false ) . '>';
27 echo '<label for="' . esc_attr( $field_name ) . '"></label>';
28 // For field with additional options / sub-fields, we add a wrapper to enclose field descriptions
29 if ( array_key_exists( 'field_options_wrapper', $args ) && $args['field_options_wrapper'] ) {
30 // For when the options / sub-fields occupy lengthy vertical space, we add show all / less toggler
31 if ( array_key_exists( 'field_options_moreless', $args ) && $args['field_options_moreless'] ) {
32 echo '<div class="asenha-field-with-options field-show-more">';
33 echo '<a id="' . esc_attr( $args['field_slug'] ) . '-show-moreless" class="show-more-less show-more" href="#">' . __( 'Expand', 'admin-site-enhancements' ) . ' &#9660;</a>';
34 echo '<div class="asenha-field-options-wrapper wrapper-show-more">';
35 } else {
36 echo '<div class="asenha-field-with-options">';
37 echo '<div class="asenha-field-options-wrapper">';
38 }
39 }
40 echo '<div class="asenha-field-description">' . wp_kses_post( $field_description ) . '</div>';
41 // For field with additional options / sub-fields, we add wrapper for them
42 if ( array_key_exists( 'field_options_wrapper', $args ) && $args['field_options_wrapper'] ) {
43 echo '<div class="asenha-subfields" style="display:none"></div>';
44 }
45 // For field with additional options / sub-fields, we add a wrapper to enclose field descriptions
46 if ( array_key_exists( 'field_options_wrapper', $args ) && $args['field_options_wrapper'] ) {
47 echo '</div>';
48 echo '</div>';
49 }
50 }
51
52 /**
53 * Render checkbox field as sub-field of a toggle/switcher checkbox
54 *
55 * @since 1.9.0
56 */
57 function render_checkbox_plain( $args ) {
58 $option_name = $args['option_name'];
59 if ( !empty( $option_name ) ) {
60 $options = get_option( $option_name, array() );
61 } else {
62 $options = get_option( ASENHA_SLUG_U, array() );
63 }
64 $field_name = $args['field_name'];
65 $field_label = $args['field_label'];
66 $default_value = false;
67 switch ( $args['field_id'] ) {
68 case 'login_page_disable_registration':
69 $default_value = ( 1 == get_option( 'users_can_register' ) ? false : true );
70 break;
71 }
72 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : $default_value );
73 echo '<input type="checkbox" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox" name="' . esc_attr( $field_name ) . '" ' . checked( $field_option_value, true, false ) . '>';
74 echo '<label for="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox-label">' . wp_kses_post( $field_label ) . '</label>';
75 }
76
77 /**
78 * Render checkbox field as sub-field of a toggle/switcher checkbox
79 *
80 * @since 1.3.0
81 */
82 function render_checkbox_subfield( $args ) {
83 $option_name = $args['option_name'];
84 if ( !empty( $option_name ) ) {
85 $options = get_option( $option_name, array() );
86 } else {
87 $options = get_option( ASENHA_SLUG_U, array() );
88 }
89 $field_name = $args['field_name'];
90 $field_label = $args['field_label'];
91 if ( 'enable_duplication_for' == $args['parent_field_id'] ) {
92 // Default is true/enabled. Usually for options introduced at a later date where the previous default is true/enabled.
93 $default_value = true;
94 } else {
95 // Default is false / checked
96 $default_value = false;
97 }
98 $field_option_value = ( isset( $options[$args['parent_field_id']][$args['field_id']] ) ? $options[$args['parent_field_id']][$args['field_id']] : $default_value );
99 echo '<input type="checkbox" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox" name="' . esc_attr( $field_name ) . '" ' . checked( $field_option_value, true, false ) . '>';
100 echo '<label for="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox-label">' . wp_kses_post( $field_label ) . '</label>';
101 }
102
103 /**
104 * Render radio buttons field as sub-field of a toggle/switcher checkbox
105 *
106 * @since 1.3.0
107 */
108 function render_radio_buttons_subfield( $args ) {
109 $option_name = $args['option_name'];
110 if ( !empty( $option_name ) ) {
111 $options = get_option( $option_name, array() );
112 } else {
113 $options = get_option( ASENHA_SLUG_U, array() );
114 }
115 $field_id = $args['field_id'];
116 $field_name = $args['field_name'];
117 $field_radios = $args['field_radios'];
118 if ( !empty( $args['field_default'] ) ) {
119 $default_value = $args['field_default'];
120 } else {
121 $default_value = false;
122 }
123 $field_description = ( isset( $args['field_description'] ) ? $args['field_description'] : '' );
124 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : $default_value );
125 echo '<div class="asenha-subfield-radio-button-wrapper">';
126 foreach ( $field_radios as $radio_label => $radio_value ) {
127 echo '<input type="radio" id="' . esc_attr( $field_id . '_' . $radio_value ) . '" class="asenha-subfield-radio-button" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $radio_value ) . '" ' . checked( $radio_value, $field_option_value, false ) . '>';
128 echo '<label for="' . esc_attr( $field_id . '_' . $radio_value ) . '" class="asenha-subfield-radio-button-label">' . wp_kses_post( $radio_label ) . '</label>';
129 }
130 echo '</div>';
131 if ( !empty( $field_description ) ) {
132 echo '<div class="asenha-subfield-description">' . wp_kses_post( $field_description ) . '</div>';
133 }
134 }
135
136 /**
137 * Render checkboxes field as sub-field of a toggle/switcher checkbox
138 *
139 * @since 6.9.2
140 */
141 function render_checkboxes_subfield( $args ) {
142 $options = get_option( ASENHA_SLUG_U, array() );
143 $field_id = $args['field_id'];
144 $field_name = $args['field_name'];
145 $field_options = $args['field_options'];
146 $layout = ( !empty( $args['layout'] ) ? $args['layout'] : 'horizontal' );
147 $default_value = ( !empty( $args['field_default'] ) ? $args['field_default'] : array() );
148 $field_option_value = ( isset( $options[$field_id] ) ? (array) $options[$field_id] : $default_value );
149 echo '<div class="wrapper-for-checkboxes ' . esc_attr( $layout ) . '">';
150 foreach ( $field_options as $option_label => $option_value ) {
151 echo '<div>';
152 echo '<input type="checkbox" id="' . esc_attr( $field_id . '_' . $option_value ) . '" class="asenha-subfield-radio-button" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $option_value ) . '" ' . checked( in_array( $option_value, $field_option_value ), 1, false ) . '>';
153 echo '<label for="' . esc_attr( $field_id . '_' . $option_value ) . '" class="asenha-subfield-radio-button-label">' . wp_kses_post( $option_label ) . '</label>';
154 echo '</div>';
155 }
156 echo '</div>';
157 }
158
159 /**
160 * Render text field as sub-field of a toggle/switcher checkbox
161 *
162 * @since 1.4.0
163 */
164 function render_text_subfield( $args ) {
165 $option_name = $args['option_name'];
166 if ( !empty( $option_name ) ) {
167 $options = get_option( $option_name, array() );
168 } else {
169 $options = get_option( ASENHA_SLUG_U, array() );
170 }
171 $field_id = $args['field_id'];
172 $field_name = $args['field_name'];
173 $field_width_classname = ( isset( $args['field_width_classname'] ) ? $args['field_width_classname'] : '' );
174 $field_type = $args['field_type'];
175 $field_prefix = $args['field_prefix'];
176 $field_suffix = $args['field_suffix'];
177 $field_placeholder = ( isset( $args['field_placeholder'] ) ? $args['field_placeholder'] : '' );
178 $field_description = $args['field_description'];
179 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
180 if ( $field_id == 'live_site_url' ) {
181 $field_option_value = ( isset( $options[$args['field_id']] ) ? base64_decode( $options[$args['field_id']] ) : '' );
182 }
183 if ( !empty( $field_prefix ) && !empty( $field_suffix ) ) {
184 $field_classname = ' with-prefix with-suffix';
185 } elseif ( !empty( $field_prefix ) && empty( $field_suffix ) ) {
186 $field_classname = ' with-prefix';
187 } elseif ( empty( $field_prefix ) && !empty( $field_suffix ) ) {
188 $field_classname = ' with-suffix';
189 } else {
190 $field_classname = '';
191 }
192 if ( !empty( $field_width_classname ) ) {
193 $field_classname .= ' ' . $field_width_classname;
194 }
195 echo wp_kses_post( $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 ) . '">' . wp_kses_post( $field_suffix );
196 echo '<label for="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox-label">' . esc_html( $field_description ) . '</label>';
197 }
198
199 /**
200 * Render description field as sub-field of a toggle/switcher checkbox
201 *
202 * @since 4.6.0
203 */
204 function render_description_subfield( $args ) {
205 $field_description = $args['field_description'];
206 echo '<div class="asenha-subfield-description">' . wp_kses( $field_description, get_kses_with_custom_html_ruleset() ) . '</div>';
207 }
208
209 /**
210 * Render heading for sub-fields of a toggle/switcher checkbox
211 *
212 * @since 5.0.0
213 */
214 function render_subfields_heading( $args ) {
215 $subfields_heading = $args['subfields_heading'];
216 echo '<div class="asenha-subfields-heading">' . wp_kses_post( $subfields_heading ) . '</div>';
217 }
218
219 /**
220 * Render password field as sub-field of a toggle/switcher checkbox
221 *
222 * @since 4.1.0
223 */
224 function render_password_subfield( $args ) {
225 $option_name = $args['option_name'];
226 if ( !empty( $option_name ) ) {
227 $options = get_option( $option_name, array() );
228 } else {
229 $options = get_option( ASENHA_SLUG_U, array() );
230 }
231 $field_id = $args['field_id'];
232 $field_name = $args['field_name'];
233 $field_type = $args['field_type'];
234 $field_prefix = $args['field_prefix'];
235 $field_suffix = $args['field_suffix'];
236 $field_description = $args['field_description'];
237 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
238 if ( !empty( $field_prefix ) && !empty( $field_suffix ) ) {
239 $field_classname = ' with-prefix with-suffix';
240 } elseif ( !empty( $field_prefix ) && empty( $field_suffix ) ) {
241 $field_classname = ' with-prefix';
242 } elseif ( empty( $field_prefix ) && !empty( $field_suffix ) ) {
243 $field_classname = ' with-suffix';
244 } else {
245 $field_classname = '';
246 }
247 $placeholder = '';
248 echo wp_kses_post( $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="' . esc_attr( $field_option_value ) . '">' . wp_kses_post( $field_suffix );
249 echo '<label for="' . esc_attr( $field_name ) . '" class="asenha-subfield-checkbox-label">' . esc_html( $field_description ) . '</label>';
250 }
251
252 /**
253 * Render number field as sub-field of a toggle/switcher checkbox
254 *
255 * @since 1.4.0
256 */
257 function render_number_subfield( $args ) {
258 $option_name = $args['option_name'];
259 if ( !empty( $option_name ) ) {
260 $options = get_option( $option_name, array() );
261 } else {
262 $options = get_option( ASENHA_SLUG_U, array() );
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_placeholder = ( isset( $args['field_placeholder'] ) ? $args['field_placeholder'] : '' );
271 $field_description = ( isset( $args['field_description'] ) ? $args['field_description'] : '' );
272 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
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 echo '<div class="asenha-subfield-number-wrapper">';
283 if ( !empty( $field_intro ) ) {
284 echo '<div class="asenha-subfield-number-intro">' . wp_kses_post( $field_intro ) . '</div>';
285 }
286 echo '<div>' . wp_kses_post( $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( $field_placeholder ) . '" value="' . esc_attr( $field_option_value ) . '">' . wp_kses_post( $field_suffix ) . '</div>';
287 if ( !empty( $field_description ) ) {
288 echo '<div class="asenha-subfield-number-description">' . wp_kses_post( $field_description ) . '</div>';
289 }
290 echo '</div>';
291 }
292
293 /**
294 * Render select field as sub-field of a toggle/switcher checkbox
295 *
296 * @since 1.4.0
297 */
298 function render_select_subfield( $args ) {
299 $option_name = $args['option_name'];
300 if ( !empty( $option_name ) ) {
301 $options = get_option( $option_name, array() );
302 } else {
303 $options = get_option( ASENHA_SLUG_U, array() );
304 }
305 $field_id = $args['field_id'];
306 $field_name = $args['field_name'];
307 $field_type = $args['field_type'];
308 $field_prefix = $args['field_prefix'];
309 $field_suffix = $args['field_suffix'];
310 $field_select_options = $args['field_select_options'];
311 $field_select_default = $args['field_select_default'];
312 $field_intro = $args['field_intro'];
313 $field_description = $args['field_description'];
314 if ( !empty( $field_select_default ) ) {
315 $default_value = $field_select_default;
316 } else {
317 $default_value = false;
318 }
319 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : $default_value );
320 if ( !empty( $field_prefix ) && !empty( $field_suffix ) ) {
321 $field_classname = ' with-prefix with-suffix';
322 } elseif ( !empty( $field_prefix ) && empty( $field_suffix ) ) {
323 $field_classname = ' with-prefix';
324 } elseif ( empty( $field_prefix ) && !empty( $field_suffix ) ) {
325 $field_classname = ' with-suffix';
326 } else {
327 $field_classname = '';
328 }
329 if ( $args['display_none_on_load'] ) {
330 $inline_style = ' style="display:none;"';
331 } else {
332 $inline_style = '';
333 }
334 echo '<div class="asenha-subfield-select-wrapper">';
335 if ( !empty( $field_intro ) ) {
336 echo '<div class="asenha-subfield-select-intro">' . wp_kses_post( $field_intro ) . '</div>';
337 }
338 echo '<div' . esc_attr( $inline_style ) . ' class="asenha-subfield-select-inner">' . wp_kses_post( $field_prefix );
339 echo '<select name="' . esc_attr( $field_name ) . '" class="asenha-subfield-select' . esc_attr( $field_classname ) . '">';
340 foreach ( $field_select_options as $label => $value ) {
341 echo '<option value="' . esc_attr( $value ) . '" ' . selected( $value, $field_option_value, false ) . '>' . esc_html( $label ) . '</option>';
342 }
343 echo '</select>';
344 echo wp_kses_post( $field_suffix ) . '</div>';
345 if ( !empty( $field_description ) ) {
346 echo '<div class="asenha-subfield-select-description">' . wp_kses_post( $field_description ) . '</div>';
347 }
348 echo '</div>';
349 }
350
351 /**
352 * Render textarea field as sub-field of a toggle/switcher checkbox
353 *
354 * @since 2.3.0
355 */
356 function render_textarea_subfield( $args ) {
357 $option_name = $args['option_name'];
358 if ( !empty( $option_name ) ) {
359 $options = get_option( $option_name, array() );
360 } else {
361 $options = get_option( ASENHA_SLUG_U, array() );
362 }
363 $field_id = $args['field_id'];
364 $field_slug = $args['field_slug'];
365 $field_name = $args['field_name'];
366 $field_type = $args['field_type'];
367 $field_rows = $args['field_rows'];
368 $field_intro = $args['field_intro'];
369 $field_description = $args['field_description'];
370 $field_placeholder = ( isset( $args['field_placeholder'] ) ? $args['field_placeholder'] : '' );
371 // 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
372 if ( 'robots_txt_content' == $field_id ) {
373 if ( array_key_exists( 'manage_robots_txt', $options ) ) {
374 if ( !$options['manage_robots_txt'] ) {
375 // Manage robots.txt feature is NOT enabled
376 if ( array_key_exists( 'robots_txt_content', $options ) && $options['robots_txt_content'] ) {
377 $field_option_value = $options['robots_txt_content'];
378 } else {
379 $robots_txt_content = wp_remote_get( get_site_url() . '/robots.txt' );
380 $robots_txt_content = esc_textarea( trim( wp_remote_retrieve_body( $robots_txt_content ) ) );
381 $field_option_value = $robots_txt_content;
382 }
383 } else {
384 // Manage robots.txt feature is enabled
385 if ( array_key_exists( 'robots_txt_content', $options ) && $options['robots_txt_content'] ) {
386 $field_option_value = $options['robots_txt_content'];
387 } else {
388 $robots_txt_content = wp_remote_get( get_site_url() . '/robots.txt' );
389 $robots_txt_content = esc_textarea( trim( wp_remote_retrieve_body( $robots_txt_content ) ) );
390 $field_option_value = $robots_txt_content;
391 }
392 }
393 } else {
394 // Manage robots.txt feature has never been enabled yet
395 $robots_txt_content = wp_remote_get( get_site_url() . '/robots.txt' );
396 $robots_txt_content = esc_textarea( trim( wp_remote_retrieve_body( $robots_txt_content ) ) );
397 $field_option_value = $robots_txt_content;
398 }
399 } else {
400 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
401 }
402 echo '<div class="asenha-subfield-textarea-wrapper">';
403 if ( !empty( $field_intro ) ) {
404 echo '<div class="asenha-subfield-textarea-intro">' . wp_kses_post( $field_intro ) . '</div>';
405 }
406 echo '<textarea rows="' . esc_attr( $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>';
407 if ( !empty( $field_description ) ) {
408 echo '<div class="asenha-subfield-textarea-description">' . wp_kses_post( $field_description ) . '</div>';
409 }
410 echo '</div>';
411 }
412
413 /**
414 * Render textarea field as sub-field of a toggle/switcher checkbox
415 *
416 * @since 2.3.0
417 */
418 function render_wpeditor_subfield( $args ) {
419 $option_name = $args['option_name'];
420 if ( !empty( $option_name ) ) {
421 $options = get_option( $option_name, array() );
422 } else {
423 $options = get_option( ASENHA_SLUG_U, array() );
424 }
425 $field_id = $args['field_id'];
426 $field_slug = $args['field_slug'];
427 $field_name = $args['field_name'];
428 $field_type = $args['field_type'];
429 $field_intro = $args['field_intro'];
430 $field_description = $args['field_description'];
431 $field_placeholder = ( isset( $args['field_placeholder'] ) ? $args['field_placeholder'] : '' );
432 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
433 $editor_settings = $args['editor_settings'];
434 // https://developer.wordpress.org/reference/classes/_wp_editors/parse_settings/
435 echo '<div class="asenha-subfield-wpeditor-wrapper">';
436 if ( !empty( $field_intro ) ) {
437 echo '<div class="asenha-subfield-wpeditor-intro">' . wp_kses_post( $field_intro ) . '</div>';
438 }
439 $content = $field_option_value;
440 $editor_id = str_replace( array('[', ']'), array('--', ''), $field_name );
441 // vi( $editor_id, '', 'for ' . $field_name );
442 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
443 echo wp_editor( $content, $editor_id, $editor_settings );
444 if ( !empty( $field_description ) ) {
445 echo '<div class="asenha-subfield-wpeditor-description">' . wp_kses_post( $field_description ) . '</div>';
446 }
447 echo '</div>';
448 }
449
450 /**
451 * Render custom HTML subfield
452 *
453 * @since 5.3.0
454 */
455 function render_custom_html( $args ) {
456 echo wp_kses( $args['html'], get_kses_with_custom_html_ruleset() );
457 }
458
459 /**
460 * Render media subfield
461 *
462 * @since 6.2.2
463 */
464 function render_media_subfield( $args ) {
465 $field_id = $args['field_id'];
466 $field_slug = $args['field_slug'];
467 $field_name = $args['field_name'];
468 $field_media_frame_title = $args['field_media_frame_title'];
469 $field_media_frame_multiple = $args['field_media_frame_multiple'];
470 $field_media_frame_library_type = $args['field_media_frame_library_type'];
471 $field_media_frame_button_text = $args['field_media_frame_button_text'];
472 $field_intro = $args['field_intro'];
473 $field_description = $args['field_description'];
474 $options = get_option( $args['option_name'], array() );
475 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : '' );
476 ?>
477 <div class="media-subfield-wrapper">
478 <input id="<?php
479 echo esc_attr( $field_slug );
480 ?>" class="image-picker" type="text" size="40" name="<?php
481 echo esc_attr( $field_name );
482 ?>" value="<?php
483 echo esc_url( $field_option_value );
484 ?>" />
485 <button id="<?php
486 echo esc_attr( $field_slug );
487 ?>-button" class="image-picker-button button-secondary"><?php
488 echo __( 'Select an Image', 'admin-site-enhancements' );
489 ?></button>
490 <?php
491 if ( !empty( $field_description ) ) {
492 echo '<div class="asenha-subfield-description media-subfield">' . wp_kses_post( $field_description ) . '</div>';
493 }
494 ?>
495 </div>
496 <?php
497 }
498
499 /**
500 * Render media subfield
501 *
502 * @since 6.2.2
503 */
504 function render_color_picker_subfield( $args ) {
505 $common_methods = new Common_Methods();
506 $field_id = $args['field_id'];
507 $field_slug = $args['field_slug'];
508 $field_name = $args['field_name'];
509 $field_intro = $args['field_intro'];
510 $field_description = $args['field_description'];
511 $field_default_value = $args['field_default_value'];
512 $options = get_option( $args['option_name'], array() );
513 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : $field_default_value );
514 ?>
515 <div class="color-subfield-wrapper">
516 <input type="text" id="<?php
517 echo esc_attr( $field_slug );
518 ?>" name="<?php
519 echo esc_attr( $field_name );
520 ?>" value="<?php
521 echo esc_attr( $common_methods->sanitize_hex_color( $field_option_value ) );
522 ?>" data-default-color="<?php
523 echo esc_attr( $common_methods->sanitize_hex_color( $field_default_value ) );
524 ?>" class="color-picker"/>
525 </div>
526 <?php
527 }
528
529 /**
530 * Render sortable menu field
531 *
532 * @since 2.0.0
533 */
534 function render_sortable_menu( $args ) {
535 $triangle_right_icon = '<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 16 16"><path fill="currentColor" d="M14.222 6.687a1.5 1.5 0 0 1 0 2.629l-10 5.499A1.5 1.5 0 0 1 2 13.5V2.502a1.5 1.5 0 0 1 2.223-1.314z"/></svg>';
536 ?>
537 <div class="subfield-description"><?php
538 echo esc_html__( '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.', 'admin-site-enhancements' );
539 ?></div>
540 <?php
541 ?>
542 <ul id="custom-admin-menu" class="menu ui-sortable">
543 <?php
544 global $menu, $submenu;
545 $common_methods = new Common_Methods();
546 $option_name = $args['option_name'];
547 if ( !empty( $option_name ) ) {
548 $options = get_option( $option_name, array() );
549 } else {
550 $options = get_option( ASENHA_SLUG_U, array() );
551 }
552 // Set menu items to be excluded from title renaming. These are from WordPress core.
553 $renaming_not_allowed = array(
554 'menu-dashboard',
555 'menu-pages',
556 // 'menu-posts',
557 'menu-media',
558 'menu-comments',
559 'menu-appearance',
560 'menu-plugins',
561 'menu-users',
562 'menu-tools',
563 'menu-settings',
564 );
565 // Get custom menu item titles
566 if ( array_key_exists( 'custom_menu_titles', $options ) ) {
567 $custom_menu_titles = $options['custom_menu_titles'];
568 $custom_menu_titles = explode( ',', $custom_menu_titles );
569 } else {
570 $custom_menu_titles = array();
571 }
572 // Get menu items hidden by toggle
573 $menu_hidden_by_toggle = $common_methods->get_menu_hidden_by_toggle();
574 $i = 1;
575 // Check if there's an existing custom menu order data stored in options
576 if ( array_key_exists( 'custom_menu_order', $options ) ) {
577 $custom_menu = $options['custom_menu_order'];
578 $custom_menu = explode( ',', $custom_menu );
579 $menu_key_in_use = array();
580 // Render sortables with data in custom menu order
581 foreach ( $custom_menu as $custom_menu_item ) {
582 foreach ( $menu as $menu_key => $menu_info ) {
583 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
584 $menu_item_title = $menu_info[2];
585 $menu_item_id = $menu_info[2];
586 } else {
587 $menu_item_title = $menu_info[0];
588 $menu_item_id = $menu_info[5];
589 }
590 $menu_url_fragment = '';
591 if ( $custom_menu_item == $menu_item_id ) {
592 $menu_item_id_transformed = $common_methods->transform_menu_item_id( $menu_item_id );
593 $is_custom_menu = 'no';
594 ?>
595 <li id="<?php
596 echo esc_attr( $menu_item_id );
597 ?>" class="menu-item parent-menu-item menu-item-depth-0" data-custom-menu-item="<?php
598 echo esc_attr( $is_custom_menu );
599 ?>">
600 <div class="menu-item-bar">
601 <div class="menu-item-handle">
602 <span class="dashicons dashicons-menu"></span>
603 <div class="item-title">
604 <div class="title-wrapper">
605 <span class="menu-item-title">
606 <?php
607 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
608 $separator_name_ori = $menu_info[2];
609 $separator_name = str_replace( 'separator', 'Separator-', $separator_name_ori );
610 $separator_name = str_replace( '--last', '-Last', $separator_name );
611 $separator_name = str_replace( '--woocommerce', '--WooCommerce', $separator_name );
612 echo '~~ ' . esc_html( $separator_name ) . ' ~~';
613 } else {
614 if ( in_array( $menu_item_id, $renaming_not_allowed ) ) {
615 $menu_item_title = $menu_info[0];
616 echo wp_kses_post( $common_methods->strip_html_tags_and_content( $menu_item_title ) );
617 } else {
618 // Get defaul/custom menu item title
619 foreach ( $custom_menu_titles as $custom_menu_title ) {
620 // At this point, $custom_menu_title value looks like toplevel_page_snippets__Code Snippets
621 $custom_menu_title = explode( '__', $custom_menu_title );
622 if ( $custom_menu_title[0] == $menu_item_id ) {
623 $menu_item_title = $common_methods->strip_html_tags_and_content( $custom_menu_title[1] );
624 // e.g. Code Snippets
625 break;
626 // stop foreach loop so $menu_item_title is not overwritten in the next iteration
627 } else {
628 $menu_item_title = $common_methods->strip_html_tags_and_content( $menu_info[0] );
629 }
630 }
631 ?>
632 <input type="text" value="<?php
633 echo wp_kses_post( $menu_item_title );
634 ?>" class="menu-item-custom-title" data-menu-item-id="<?php
635 echo esc_attr( $menu_item_id );
636 ?>">
637 <?php
638 }
639 }
640 ?>
641 </span><!-- end of .menu-item-title -->
642 <?php
643 ?>
644 </div><!-- end of .title-wrapper -->
645 <div class="options-for-hiding">
646 <?php
647 $hide_text = __( 'Hide until toggled', 'admin-site-enhancements' );
648 $checkbox_class = 'parent-menu-hide-checkbox';
649 ?>
650 <label class="menu-item-checkbox-label">
651 <?php
652 if ( in_array( $custom_menu_item, $menu_hidden_by_toggle ) ) {
653 ?>
654 <input type="checkbox" id="hide-status-for-<?php
655 echo esc_attr( $menu_item_id_transformed );
656 ?>" class="<?php
657 echo esc_attr( $checkbox_class );
658 ?>" data-menu-item-title="<?php
659 echo esc_attr( $common_methods->strip_html_tags_and_content( $menu_item_title ) );
660 ?>" data-menu-item-id="<?php
661 echo esc_attr( $menu_item_id_transformed );
662 ?>" data-menu-item-id-ori="<?php
663 echo esc_attr( $menu_item_id );
664 ?>" data-menu-url-fragment="<?php
665 echo esc_attr( $menu_url_fragment );
666 ?>" checked>
667 <span><?php
668 echo esc_html( $hide_text );
669 ?></span>
670 <?php
671 } else {
672 ?>
673 <input type="checkbox" id="hide-status-for-<?php
674 echo esc_attr( $menu_item_id_transformed );
675 ?>" class="<?php
676 echo esc_attr( $checkbox_class );
677 ?>" data-menu-item-title="<?php
678 echo esc_attr( $common_methods->strip_html_tags_and_content( $menu_item_title ) );
679 ?>" data-menu-item-id="<?php
680 echo esc_attr( $menu_item_id_transformed );
681 ?>" data-menu-item-id-ori="<?php
682 echo esc_attr( $menu_item_id );
683 ?>" data-menu-url-fragment="<?php
684 echo esc_attr( $menu_url_fragment );
685 ?>">
686 <span><?php
687 echo esc_html( $hide_text );
688 ?></span>
689 <?php
690 }
691 ?>
692 </label>
693 <?php
694 ?>
695 </div><!-- end of .options-for-hiding -->
696 </div><!-- end of .item-title -->
697 </div><!-- end of .menu-item-handle -->
698 </div><!-- end of .menu-item-bar -->
699 <?php
700 $i = 1;
701 ?>
702 <div class="remove-menu-item"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path fill="#bbbbbb" d="M24 2.4L21.6 0L12 9.6L2.4 0L0 2.4L9.6 12L0 21.6L2.4 24l9.6-9.6l9.6 9.6l2.4-2.4l-9.6-9.6z"/></svg></div>
703 </li>
704 <?php
705 $menu_key_in_use[] = $menu_key;
706 }
707 }
708 }
709 // Render the rest of the current menu towards the end of the sortables
710 foreach ( $menu as $menu_key => $menu_info ) {
711 if ( !in_array( $menu_key, $menu_key_in_use ) ) {
712 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
713 $menu_item_id = $menu_info[2];
714 } else {
715 $menu_item_id = $menu_info[5];
716 }
717 $menu_item_title = $menu_info[0];
718 $menu_url_fragment = '';
719 // Strip tags
720 $menu_item_title = $common_methods->strip_html_tags_and_content( $menu_item_title );
721 // Exclude Show All/Less toggles
722 if ( false === strpos( $menu_item_id, 'toplevel_page_asenha_' ) ) {
723 $menu_item_id_transformed = $common_methods->transform_menu_item_id( $menu_item_id );
724 $is_custom_menu = 'no';
725 ?>
726 <li id="<?php
727 echo esc_attr( $menu_item_id );
728 ?>" class="menu-item parent-menu-item menu-item-depth-0" data-custom-menu-item="<?php
729 echo esc_attr( $is_custom_menu );
730 ?>">
731 <div class="menu-item-bar">
732 <div class="menu-item-handle">
733 <span class="dashicons dashicons-menu"></span>
734 <div class="item-title">
735 <div class="title-wrapper">
736 <span class="menu-item-title">
737 <?php
738 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
739 $separator_name_ori = $menu_info[2];
740 $separator_name = str_replace( 'separator', 'Separator-', $separator_name_ori );
741 $separator_name = str_replace( '--last', '-Last', $separator_name );
742 $separator_name = str_replace( '--woocommerce', '--WooCommerce', $separator_name );
743 echo '~~ ' . esc_html( $separator_name ) . ' ~~';
744 } else {
745 ?>
746 <input type="text" value="<?php
747 echo wp_kses_post( $menu_item_title );
748 ?>" class="menu-item-custom-title" data-menu-item-id="<?php
749 echo esc_attr( $menu_item_id );
750 ?>">
751 <?php
752 }
753 ?>
754 </span>
755 <?php
756 ?>
757 </div>
758 <div class="options-for-hiding">
759 <?php
760 $hide_text = __( 'Hide until toggled', 'admin-site-enhancements' );
761 $checkbox_class = 'parent-menu-hide-checkbox';
762 ?>
763 <label class="menu-item-checkbox-label">
764 <input type="checkbox" id="hide-status-for-<?php
765 echo esc_attr( $menu_item_id_transformed );
766 ?>" class="<?php
767 echo esc_attr( $checkbox_class );
768 ?>" data-menu-item-title="<?php
769 echo esc_attr( $common_methods->strip_html_tags_and_content( $menu_item_title ) );
770 ?>" data-menu-item-id="<?php
771 echo esc_attr( $menu_item_id_transformed );
772 ?>" data-menu-item-id-ori="<?php
773 echo esc_attr( $menu_item_id );
774 ?>" data-menu-url-fragment="<?php
775 echo esc_attr( $menu_url_fragment );
776 ?>">
777 <span><?php
778 echo esc_html( $hide_text );
779 ?></span>
780 </label>
781 <?php
782 ?>
783 </div><!-- end of .options-for-hiding -->
784 </div><!-- end of .item-title -->
785 </div><!-- end of .menu-item-handle -->
786 </div><!-- end of .menu-item-bar -->
787 <?php
788 $i = 1;
789 ?>
790 <div class="remove-menu-item"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path fill="#bbbbbb" d="M24 2.4L21.6 0L12 9.6L2.4 0L0 2.4L9.6 12L0 21.6L2.4 24l9.6-9.6l9.6 9.6l2.4-2.4l-9.6-9.6z"/></svg></div>
791 </li><!-- end of .menu-item -->
792 <?php
793 }
794 }
795 }
796 } else {
797 // No custom menu order has been saved yet
798 // Render sortables with existing items in the admin menu
799 foreach ( $menu as $menu_key => $menu_info ) {
800 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
801 $menu_item_id = $menu_info[2];
802 } else {
803 $menu_item_id = $menu_info[5];
804 }
805 $menu_url_fragment = '';
806 $menu_item_title = $menu_info[0];
807 $menu_item_id_transformed = $common_methods->transform_menu_item_id( $menu_item_id );
808 // Strip tags
809 $menu_item_title = $common_methods->strip_html_tags_and_content( $menu_item_title );
810 $is_custom_menu = 'no';
811 ?>
812 <li id="<?php
813 echo esc_attr( $menu_item_id );
814 ?>" class="menu-item parent-menu-item menu-item-depth-0" data-custom-menu-item="<?php
815 echo esc_attr( $is_custom_menu );
816 ?>">
817 <div class="menu-item-bar">
818 <div class="menu-item-handle">
819 <span class="dashicons dashicons-menu"></span>
820 <div class="item-title">
821 <div class="title-wrapper">
822 <span class="menu-item-title">
823 <?php
824 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
825 $separator_name_ori = $menu_info[2];
826 $separator_name = str_replace( 'separator', 'Separator-', $separator_name_ori );
827 $separator_name = str_replace( '--last', '-Last', $separator_name );
828 $separator_name = str_replace( '--woocommerce', '--WooCommerce', $separator_name );
829 echo '~~ ' . esc_html( $separator_name ) . ' ~~';
830 } else {
831 if ( in_array( $menu_item_id, $renaming_not_allowed ) ) {
832 echo wp_kses_post( $menu_item_title );
833 } else {
834 ?>
835 <input type="text" value="<?php
836 echo wp_kses_post( $menu_item_title );
837 ?>" class="menu-item-custom-title" data-menu-item-id="<?php
838 echo esc_attr( $menu_item_id );
839 ?>">
840 <?php
841 }
842 }
843 ?>
844 </span>
845 <?php
846 ?>
847 </div><!-- end of .title-wrapper -->
848 <div class="options-for-hiding">
849 <?php
850 $hide_text = __( 'Hide until toggled', 'admin-site-enhancements' );
851 $checkbox_class = 'parent-menu-hide-checkbox';
852 ?>
853 <label class="menu-item-checkbox-label">
854 <input type="checkbox" id="hide-status-for-<?php
855 echo esc_attr( $menu_item_id_transformed );
856 ?>" class="<?php
857 echo esc_attr( $checkbox_class );
858 ?>" data-menu-item-title="<?php
859 echo esc_attr( $common_methods->strip_html_tags_and_content( $menu_item_title ) );
860 ?>" data-menu-item-id="<?php
861 echo esc_attr( $menu_item_id_transformed );
862 ?>" data-menu-item-id-ori="<?php
863 echo esc_attr( $menu_item_id );
864 ?>" data-menu-url-fragment="<?php
865 echo esc_attr( $menu_url_fragment );
866 ?>">
867 <span><?php
868 echo esc_html( $hide_text );
869 ?></span>
870 </label>
871 <?php
872 ?>
873 </div><!-- end of .options-for-hiding -->
874 </div><!-- end of .item-title -->
875 </div><!-- end of .menu-item-handle -->
876 </div><!-- end of .menu-item-bar -->
877 <?php
878 $i = 1;
879 ?>
880 <div class="remove-menu-item"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path fill="#bbbbbb" d="M24 2.4L21.6 0L12 9.6L2.4 0L0 2.4L9.6 12L0 21.6L2.4 24l9.6-9.6l9.6 9.6l2.4-2.4l-9.6-9.6z"/></svg></div>
881 </li>
882 <?php
883 }
884 }
885 ?>
886 </ul>
887 <?php
888 // Hidden input field to store custom menu order (from options as is, or sortupdate) upon clicking Save Changes.
889 $field_id = $args['field_id'];
890 $field_name = $args['field_name'];
891 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
892 echo '<input type="hidden" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-text" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $field_option_value ) . '">';
893 // Hidden input field to store custom menu titles (from options as is, or custom values entered on each non-WP-default menu items.
894 $this->output_admin_menu_organizer_hidden_field( 'custom_menu_titles' );
895 // Hidden input field to store hidden menu items (from options as is, or 'Hide' checkbox clicks) upon clicking Save Changes.
896 $this->output_admin_menu_organizer_hidden_field( 'custom_menu_hidden' );
897 }
898
899 /**
900 * Output hidden field
901 *
902 * @since 6.9.13
903 */
904 public function output_admin_menu_organizer_hidden_field( $field_id ) {
905 $options = get_option( ASENHA_SLUG_U, array() );
906 $field_name = ASENHA_SLUG_U . '[' . $field_id . ']';
907 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : '' );
908 echo '<input type="hidden" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-text" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $field_option_value ) . '">';
909 }
910
911 /**
912 * Render textarea field as sub-field of a toggle/switcher checkbox
913 *
914 * @since 2.3.0
915 */
916 function render_datatable( $args ) {
917 global $wpdb;
918 $option_name = $args['option_name'];
919 if ( !empty( $option_name ) ) {
920 $options = get_option( $option_name, array() );
921 } else {
922 $options = get_option( ASENHA_SLUG_U, array() );
923 }
924 $field_id = $args['field_id'];
925 $field_slug = $args['field_slug'];
926 $field_name = $args['field_name'];
927 $field_type = $args['field_type'];
928 $field_description = $args['field_description'];
929 $table_title = $args['table_title'];
930 $table_name = $args['table_name'];
931 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
932 ?>
933 <table id="login-attempts-log" class="wp-list-table widefat striped datatable">
934 <thead>
935 <tr class="datatable-tr">
936 <th class="datatable-th"><?php
937 _e( 'IP Address<br />Last Username', 'admin-site-enhancements' );
938 ?></th>
939 <th class="datatable-th"><?php
940 _e( 'Attempts<br />Lockouts', 'admin-site-enhancements' );
941 ?></th>
942 <th class="datatable-th"><?php
943 _e( 'Last Attempt On', 'admin-site-enhancements' );
944 ?></th>
945 </tr>
946 </thead>
947 <tbody>
948 <?php
949 $limit = 1000;
950 $sql = $wpdb->prepare( "SELECT * FROM {$table_name} ORDER BY unixtime DESC LIMIT %d", array($limit) );
951 $entries = $wpdb->get_results( $sql, ARRAY_A );
952 foreach ( $entries as $entry ) {
953 $unixtime = $entry['unixtime'];
954 if ( function_exists( 'wp_date' ) ) {
955 $date = wp_date( 'F j, Y', $unixtime );
956 $time = wp_date( 'H:i:s', $unixtime );
957 } else {
958 $date = date_i18n( 'F j, Y', $unixtime );
959 $time = date_i18n( 'H:i:s', $unixtime );
960 }
961 ?>
962 <tr class="datatable-tr">
963 <td class="datatable-td"><?php
964 echo esc_html( $entry['ip_address'] );
965 ?><br /><?php
966 echo esc_html( $entry['username'] );
967 ?></td>
968 <td class="datatable-td"><?php
969 echo esc_html( $entry['fail_count'] );
970 ?><br /><?php
971 echo esc_html( $entry['lockout_count'] );
972 ?></td>
973 <td class="datatable-td"><span class="unixtime"><?php
974 echo esc_html( $entry['unixtime'] );
975 ?></span><?php
976 echo esc_html( $date );
977 ?><br /><?php
978 echo esc_html( $time );
979 ?></td>
980 </tr>
981 <?php
982 }
983 ?>
984 </tbody>
985 </table>
986 <?php
987 echo '<input type="hidden" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-datatable" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $field_option_value ) . '">';
988 }
989
990 /**
991 * Render checks and status for AVIF support
992 *
993 * @link https://php.watch/versions/8.1/gd-avif
994 * @since 5.7.0
995 */
996 public function render_avif_support_status() {
997 // Check status of GD extension and it's AVIF support
998 if ( extension_loaded( 'gd' ) && function_exists( 'gd_info' ) ) {
999 $is_gd_enabled = true;
1000 $gd_info = gd_info();
1001 $gd_version = $gd_info['GD Version'];
1002 $gd_avif_support = ( isset( $gd_info['AVIF Support'] ) ? isset( $gd_info['AVIF Support'] ) : false );
1003 if ( $gd_avif_support ) {
1004 $gd_status = $gd_version . ' <span class="supported">' . __( 'with AVIF support', 'admin-site-enhancements' ) . '</span>';
1005 } else {
1006 $gd_status = $gd_version . ' <span class="unsupported">' . __( 'without AVIF support', 'admin-site-enhancements' ) . '</span>';
1007 }
1008 } else {
1009 $is_gd_enabled = false;
1010 $gd_avif_support = false;
1011 $gd_status = __( 'Not available', 'admin-site-enhancements' );
1012 }
1013 // Check status of ImageMagick library and it's AVIF support
1014 if ( extension_loaded( 'imagick' ) && class_exists( 'Imagick' ) ) {
1015 $is_imagick_enabled = true;
1016 $imagick_version = \Imagick::getVersion();
1017 if ( preg_match( '/((?:[0-9]+\\.?)+)/', $imagick_version['versionString'], $matches ) ) {
1018 $imagick_version = $matches[0];
1019 } else {
1020 $imagick_version = $imagick_version['versionString'];
1021 }
1022 if ( version_compare( $imagick_version, '7.0.25', '>=' ) ) {
1023 $imagick_avif_support = true;
1024 $imagick_status = $imagick_version . ' <span class="supported">with AVIF support</span>';
1025 } else {
1026 $imagick_avif_support = false;
1027 $imagick_status = $imagick_version . ' <span class="unsupported">without AVIF support</span>';
1028 }
1029 } else {
1030 $is_imagick_enabled = false;
1031 $imagick_avif_support = false;
1032 $imagick_status = __( 'Not available', 'admin-site-enhancements' );
1033 }
1034 echo '<div class="asenha-subfield-status">';
1035 echo '<div class="status-title">' . __( 'AVIF Support Status', 'admin-site-enhancements' ) . '</div>';
1036 echo '<div class="status-body">';
1037 echo '<div class="status-item"><span class="status-item-title">PHP</span> : ' . wp_kses_post( phpversion() ) . '</div>';
1038 echo '<div class="status-item"><span class="status-item-title">GD</span> : ' . wp_kses_post( $gd_status ) . '</div>';
1039 echo '<div class="status-item"><span class="status-item-title">ImageMagick</span> : ' . wp_kses_post( $imagick_status ) . '</div>';
1040 echo '</div>';
1041 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://web.archive.org/web/20240104012918/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://web.archive.org/web/20231207174740/https://avif.io/blog/articles/avif-browser-support/" target="_blank">modern desktop and mobile browsers</a> support the display of AVIF files.', 'admin-site-enhancements' ) . '</div>';
1042 echo '</div>';
1043 }
1044
1045 }
1046