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