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