PluginProbe ʕ •ᴥ•ʔ
Admin and Site Enhancements (ASE) / 8.2.3
Admin and Site Enhancements (ASE) v8.2.3
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 7 months ago class-admin-menu-organizer.php 7 months ago class-admin-menu-svg-icon-mask.php 7 months ago class-auto-publish-posts-with-missed-schedule.php 7 months ago class-avif-upload.php 7 months ago class-captcha-protection.php 7 months ago class-change-login-url.php 7 months ago class-cleanup-admin-bar.php 7 months ago class-common-methods.php 7 months ago class-content-duplication.php 7 months ago class-content-order.php 7 months ago class-custom-admin-footer-text.php 7 months ago class-custom-body-class.php 7 months ago class-custom-css.php 7 months ago class-custom-nav-menu-items-in-new-tab.php 7 months ago class-deactivation.php 7 months ago class-disable-author-archives.php 7 months ago class-disable-comments.php 7 months ago class-disable-dashboard-widgets.php 7 months ago class-disable-embeds.php 7 months ago class-disable-feeds.php 7 months ago class-disable-gutenberg.php 7 months ago class-disable-rest-api.php 7 months ago class-disable-smaller-components.php 7 months ago class-disable-updates.php 7 months ago class-disable-xml-rpc.php 7 months ago class-display-system-summary.php 7 months ago class-email-address-obfuscator.php 7 months ago class-email-delivery.php 7 months ago class-enhance-list-tables.php 7 months ago class-external-permalinks.php 7 months ago class-heartbeat-control.php 7 months ago class-hide-admin-bar.php 7 months ago class-hide-admin-notices.php 7 months ago class-image-sizes-panel.php 7 months ago class-image-upload-control.php 7 months ago class-insert-head-body-footer-code.php 7 months ago class-last-login-column.php 7 months ago class-limit-login-attempts.php 7 months ago class-login-id-type.php 7 months ago class-login-logout-menu.php 7 months ago class-maintenance-mode.php 7 months ago class-manage-ads-appads-txt.php 7 months ago class-manage-robots-txt.php 7 months ago class-media-replacement.php 7 months ago class-multiple-user-roles.php 7 months ago class-obfuscate-author-slugs.php 7 months ago class-open-external-links-in-new-tab.php 7 months ago class-password-protection.php 7 months ago class-redirect-after-login.php 7 months ago class-redirect-after-logout.php 7 months ago class-redirect-fourofour.php 7 months ago class-registration-date-column.php 7 months ago class-revisions-control.php 7 months ago class-search-engines-visibility.php 7 months ago class-settings-fields-render.php 7 months ago class-settings-sanitization.php 7 months ago class-settings-sections-fields.php 7 months ago class-show-custom-taxonomy-filters.php 7 months ago class-site-identity-on-login-page.php 7 months ago class-svg-upload.php 7 months ago class-various-admin-ui-enhancements.php 7 months ago class-view-admin-as-role.php 7 months ago class-wider-admin-menu.php 7 months ago class-wp-config-transformer.php 7 months ago
class-settings-fields-render.php
1171 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 ( array_key_exists( 'field_hidden_inputs', $args ) && is_array( $args['field_hidden_inputs'] ) ) {
579 foreach ( $args['field_hidden_inputs'] as $hidden_input ) {
580 $hidden_option_key = ( isset( $hidden_input['option_key'] ) ? sanitize_key( $hidden_input['option_key'] ) : '' );
581 $hidden_id = ( isset( $hidden_input['field_id'] ) ? (string) $hidden_input['field_id'] : '' );
582 $hidden_name = ( isset( $hidden_input['field_name'] ) ? (string) $hidden_input['field_name'] : '' );
583 if ( empty( $hidden_option_key ) || empty( $hidden_id ) || empty( $hidden_name ) ) {
584 continue;
585 }
586 $hidden_value = ( isset( $options[$hidden_option_key] ) ? absint( $options[$hidden_option_key] ) : 0 );
587 echo '<input type="hidden" id="' . esc_attr( $hidden_id ) . '" class="asenha-hidden-media-dim" name="' . esc_attr( $hidden_name ) . '" value="' . esc_attr( $hidden_value ) . '" />';
588 }
589 }
590 ?>
591 <?php
592 if ( !empty( $field_description ) ) {
593 echo '<div class="asenha-subfield-description media-subfield">' . wp_kses_post( $field_description ) . '</div>';
594 }
595 ?>
596 </div>
597 <?php
598 }
599
600 /**
601 * Render media subfield
602 *
603 * @since 6.2.2
604 */
605 function render_color_picker_subfield( $args ) {
606 $common_methods = new Common_Methods();
607 $field_id = $args['field_id'];
608 $field_slug = $args['field_slug'];
609 $field_name = $args['field_name'];
610 $field_intro = $args['field_intro'];
611 $field_description = $args['field_description'];
612 $field_default_value = $args['field_default_value'];
613 $options = get_option( $args['option_name'], array() );
614 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : $field_default_value );
615 ?>
616 <div class="color-subfield-wrapper">
617 <input type="text" id="<?php
618 echo esc_attr( $field_slug );
619 ?>" name="<?php
620 echo esc_attr( $field_name );
621 ?>" value="<?php
622 echo esc_attr( $common_methods->sanitize_hex_color( $field_option_value ) );
623 ?>" data-default-color="<?php
624 echo esc_attr( $common_methods->sanitize_hex_color( $field_default_value ) );
625 ?>" class="color-picker"/>
626 </div>
627 <?php
628 }
629
630 /**
631 * Render text field as sub-field of a toggle/switcher checkbox
632 *
633 * @since 1.4.0
634 */
635 function render_content_toggler( $args ) {
636 $field_id = $args['field_id'];
637 $field_slug = $args['field_slug'];
638 $field_slug = str_replace( '_', '-', $field_id );
639 $show_text = ( isset( $args['show_text'] ) ? $args['show_text'] : '' );
640 $hide_text = ( isset( $args['hide_text'] ) ? $args['hide_text'] : '' );
641 $content_selector = ( isset( $args['content_selector'] ) ? $args['content_selector'] : '' );
642 ?>
643 <div class="subfield-content-toggler <?php
644 echo esc_attr( $field_slug );
645 ?>"><a href="#" data-show-text="<?php
646 echo esc_attr( $show_text );
647 ?>" data-hide-text="<?php
648 echo esc_attr( $hide_text );
649 ?>" data-target-selector="<?php
650 echo esc_attr( $content_selector );
651 ?>" class="asenha-content-toggler" data-expanded="no"><?php
652 echo esc_html( $show_text );
653 ?> <span></span></a></div>
654 <?php
655 }
656
657 /**
658 * Render sortable menu field
659 *
660 * @since 2.0.0
661 */
662 function render_sortable_menu() {
663 $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>';
664 ?>
665 <div class="module-description"><?php
666 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' );
667 ?></div>
668 <?php
669 ?>
670 <ul id="custom-admin-menu" class="menu ui-sortable">
671 <?php
672 global $menu, $submenu;
673 $common_methods = new Common_Methods();
674 $options_extra = get_option( ASENHA_SLUG_U . '_extra', array() );
675 $options = ( isset( $options_extra['admin_menu'] ) ? $options_extra['admin_menu'] : array() );
676 // Set menu items to be excluded from title renaming. These are from WordPress core.
677 $renaming_not_allowed = array(
678 'menu-dashboard',
679 'menu-pages',
680 // 'menu-posts',
681 'menu-media',
682 'menu-comments',
683 'menu-appearance',
684 'menu-plugins',
685 'menu-users',
686 'menu-tools',
687 'menu-settings',
688 );
689 // Get custom menu item titles
690 if ( array_key_exists( 'custom_menu_titles', $options ) ) {
691 $custom_menu_titles = $options['custom_menu_titles'];
692 $custom_menu_titles = explode( ',', $custom_menu_titles );
693 } else {
694 $custom_menu_titles = array();
695 }
696 // Get menu items hidden by toggle
697 $menu_hidden_by_toggle = $common_methods->get_menu_hidden_by_toggle();
698 $i = 1;
699 // Check if there's an existing custom menu order data stored in options
700 if ( array_key_exists( 'custom_menu_order', $options ) ) {
701 $custom_menu = $options['custom_menu_order'];
702 $custom_menu = explode( ',', $custom_menu );
703 $menu_key_in_use = array();
704 // Render sortables with data in custom menu order
705 foreach ( $custom_menu as $custom_menu_item ) {
706 foreach ( $menu as $menu_key => $menu_info ) {
707 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
708 $menu_item_title = $menu_info[2];
709 $menu_item_id = $menu_info[2];
710 } else {
711 $menu_item_title = $menu_info[0];
712 $menu_item_id = $menu_info[5];
713 }
714 $menu_url_fragment = '';
715 if ( $custom_menu_item == $menu_item_id ) {
716 $menu_item_id_transformed = $common_methods->transform_menu_item_id( $menu_item_id );
717 $is_custom_menu = 'no';
718 ?>
719 <li id="<?php
720 echo esc_attr( $menu_item_id );
721 ?>" class="menu-item parent-menu-item menu-item-depth-0" data-custom-menu-item="<?php
722 echo esc_attr( $is_custom_menu );
723 ?>">
724 <div class="menu-item-bar">
725 <div class="menu-item-handle">
726 <span class="dashicons dashicons-menu"></span>
727 <div class="item-title">
728 <div class="title-wrapper">
729 <span class="menu-item-title">
730 <?php
731 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
732 $separator_name_ori = $menu_info[2];
733 $separator_name = str_replace( 'separator', 'Separator-', $separator_name_ori );
734 $separator_name = str_replace( '--last', '-Last', $separator_name );
735 $separator_name = str_replace( '--woocommerce', '--WooCommerce', $separator_name );
736 echo '~~ ' . esc_html( $separator_name ) . ' ~~';
737 } else {
738 if ( in_array( $menu_item_id, $renaming_not_allowed ) ) {
739 $menu_item_title = $menu_info[0];
740 echo wp_kses_post( $common_methods->strip_html_tags_and_content( $menu_item_title ) );
741 } else {
742 // Get defaul/custom menu item title
743 foreach ( $custom_menu_titles as $custom_menu_title ) {
744 // At this point, $custom_menu_title value looks like toplevel_page_snippets__Code Snippets
745 $custom_menu_title = explode( '__', $custom_menu_title );
746 if ( $custom_menu_title[0] == $menu_item_id ) {
747 $menu_item_title = $common_methods->strip_html_tags_and_content( $custom_menu_title[1] );
748 // e.g. Code Snippets
749 break;
750 // stop foreach loop so $menu_item_title is not overwritten in the next iteration
751 } else {
752 $menu_item_title = $common_methods->strip_html_tags_and_content( $menu_info[0] );
753 }
754 }
755 ?>
756 <input type="text" value="<?php
757 echo wp_kses_post( wp_unslash( $menu_item_title ) );
758 ?>" class="menu-item-custom-title" data-menu-item-id="<?php
759 echo esc_attr( $menu_item_id );
760 ?>">
761 <?php
762 }
763 }
764 ?>
765 </span><!-- end of .menu-item-title -->
766 <?php
767 ?>
768 </div><!-- end of .title-wrapper -->
769 <div class="options-for-hiding">
770 <?php
771 $hide_text = __( 'Hide until toggled', 'admin-site-enhancements' );
772 $checkbox_class = 'parent-menu-hide-checkbox';
773 ?>
774 <label class="menu-item-checkbox-label">
775 <?php
776 if ( in_array( $custom_menu_item, $menu_hidden_by_toggle ) ) {
777 ?>
778 <input type="checkbox" id="hide-status-for-<?php
779 echo esc_attr( $menu_item_id_transformed );
780 ?>" class="<?php
781 echo esc_attr( $checkbox_class );
782 ?>" data-menu-item-title="<?php
783 echo esc_attr( $common_methods->strip_html_tags_and_content( $menu_item_title ) );
784 ?>" data-menu-item-id="<?php
785 echo esc_attr( $menu_item_id_transformed );
786 ?>" data-menu-item-id-ori="<?php
787 echo esc_attr( $menu_item_id );
788 ?>" data-menu-url-fragment="<?php
789 echo esc_attr( $menu_url_fragment );
790 ?>" checked>
791 <span><?php
792 echo esc_html( $hide_text );
793 ?></span>
794 <?php
795 } else {
796 ?>
797 <input type="checkbox" id="hide-status-for-<?php
798 echo esc_attr( $menu_item_id_transformed );
799 ?>" class="<?php
800 echo esc_attr( $checkbox_class );
801 ?>" data-menu-item-title="<?php
802 echo esc_attr( $common_methods->strip_html_tags_and_content( $menu_item_title ) );
803 ?>" data-menu-item-id="<?php
804 echo esc_attr( $menu_item_id_transformed );
805 ?>" data-menu-item-id-ori="<?php
806 echo esc_attr( $menu_item_id );
807 ?>" data-menu-url-fragment="<?php
808 echo esc_attr( $menu_url_fragment );
809 ?>">
810 <span><?php
811 echo esc_html( $hide_text );
812 ?></span>
813 <?php
814 }
815 ?>
816 </label>
817 <?php
818 ?>
819 </div><!-- end of .options-for-hiding -->
820 </div><!-- end of .item-title -->
821 </div><!-- end of .menu-item-handle -->
822 </div><!-- end of .menu-item-bar -->
823 <?php
824 $i = 1;
825 ?>
826 <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>
827 </li>
828 <?php
829 $menu_key_in_use[] = $menu_key;
830 }
831 }
832 }
833 // Render the rest of the current menu towards the end of the sortables
834 foreach ( $menu as $menu_key => $menu_info ) {
835 if ( !in_array( $menu_key, $menu_key_in_use ) ) {
836 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
837 $menu_item_id = $menu_info[2];
838 } else {
839 $menu_item_id = $menu_info[5];
840 }
841 $menu_item_title = $menu_info[0];
842 $menu_url_fragment = '';
843 // Strip tags
844 $menu_item_title = $common_methods->strip_html_tags_and_content( $menu_item_title );
845 // Exclude Show All/Less toggles
846 if ( false === strpos( $menu_item_id, 'toplevel_page_asenha_' ) ) {
847 $menu_item_id_transformed = $common_methods->transform_menu_item_id( $menu_item_id );
848 $is_custom_menu = 'no';
849 ?>
850 <li id="<?php
851 echo esc_attr( $menu_item_id );
852 ?>" class="menu-item parent-menu-item menu-item-depth-0" data-custom-menu-item="<?php
853 echo esc_attr( $is_custom_menu );
854 ?>">
855 <div class="menu-item-bar">
856 <div class="menu-item-handle">
857 <span class="dashicons dashicons-menu"></span>
858 <div class="item-title">
859 <div class="title-wrapper">
860 <span class="menu-item-title">
861 <?php
862 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
863 $separator_name_ori = $menu_info[2];
864 $separator_name = str_replace( 'separator', 'Separator-', $separator_name_ori );
865 $separator_name = str_replace( '--last', '-Last', $separator_name );
866 $separator_name = str_replace( '--woocommerce', '--WooCommerce', $separator_name );
867 echo '~~ ' . esc_html( $separator_name ) . ' ~~';
868 } else {
869 ?>
870 <input type="text" value="<?php
871 echo wp_kses_post( wp_unslash( $menu_item_title ) );
872 ?>" class="menu-item-custom-title" data-menu-item-id="<?php
873 echo esc_attr( $menu_item_id );
874 ?>">
875 <?php
876 }
877 ?>
878 </span>
879 <?php
880 ?>
881 </div>
882 <div class="options-for-hiding">
883 <?php
884 $hide_text = __( 'Hide until toggled', 'admin-site-enhancements' );
885 $checkbox_class = 'parent-menu-hide-checkbox';
886 ?>
887 <label class="menu-item-checkbox-label">
888 <input type="checkbox" id="hide-status-for-<?php
889 echo esc_attr( $menu_item_id_transformed );
890 ?>" class="<?php
891 echo esc_attr( $checkbox_class );
892 ?>" data-menu-item-title="<?php
893 echo esc_attr( $common_methods->strip_html_tags_and_content( $menu_item_title ) );
894 ?>" data-menu-item-id="<?php
895 echo esc_attr( $menu_item_id_transformed );
896 ?>" data-menu-item-id-ori="<?php
897 echo esc_attr( $menu_item_id );
898 ?>" data-menu-url-fragment="<?php
899 echo esc_attr( $menu_url_fragment );
900 ?>">
901 <span><?php
902 echo esc_html( $hide_text );
903 ?></span>
904 </label>
905 <?php
906 ?>
907 </div><!-- end of .options-for-hiding -->
908 </div><!-- end of .item-title -->
909 </div><!-- end of .menu-item-handle -->
910 </div><!-- end of .menu-item-bar -->
911 <?php
912 $i = 1;
913 ?>
914 <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>
915 </li><!-- end of .menu-item -->
916 <?php
917 }
918 }
919 }
920 } else {
921 // No custom menu order has been saved yet
922 // Render sortables with existing items in the admin menu
923 foreach ( $menu as $menu_key => $menu_info ) {
924 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
925 $menu_item_id = $menu_info[2];
926 } else {
927 $menu_item_id = $menu_info[5];
928 }
929 $menu_url_fragment = '';
930 $menu_item_title = $menu_info[0];
931 $menu_item_id_transformed = $common_methods->transform_menu_item_id( $menu_item_id );
932 // Strip tags
933 $menu_item_title = $common_methods->strip_html_tags_and_content( $menu_item_title );
934 $is_custom_menu = 'no';
935 ?>
936 <li id="<?php
937 echo esc_attr( $menu_item_id );
938 ?>" class="menu-item parent-menu-item menu-item-depth-0" data-custom-menu-item="<?php
939 echo esc_attr( $is_custom_menu );
940 ?>">
941 <div class="menu-item-bar">
942 <div class="menu-item-handle">
943 <span class="dashicons dashicons-menu"></span>
944 <div class="item-title">
945 <div class="title-wrapper">
946 <span class="menu-item-title">
947 <?php
948 if ( false !== strpos( $menu_info[4], 'wp-menu-separator' ) ) {
949 $separator_name_ori = $menu_info[2];
950 $separator_name = str_replace( 'separator', 'Separator-', $separator_name_ori );
951 $separator_name = str_replace( '--last', '-Last', $separator_name );
952 $separator_name = str_replace( '--woocommerce', '--WooCommerce', $separator_name );
953 echo '~~ ' . esc_html( $separator_name ) . ' ~~';
954 } else {
955 if ( in_array( $menu_item_id, $renaming_not_allowed ) ) {
956 echo wp_kses_post( $menu_item_title );
957 } else {
958 ?>
959 <input type="text" value="<?php
960 echo wp_kses_post( wp_unslash( $menu_item_title ) );
961 ?>" class="menu-item-custom-title" data-menu-item-id="<?php
962 echo esc_attr( $menu_item_id );
963 ?>">
964 <?php
965 }
966 }
967 ?>
968 </span>
969 <?php
970 ?>
971 </div><!-- end of .title-wrapper -->
972 <div class="options-for-hiding">
973 <?php
974 $hide_text = __( 'Hide until toggled', 'admin-site-enhancements' );
975 $checkbox_class = 'parent-menu-hide-checkbox';
976 ?>
977 <label class="menu-item-checkbox-label">
978 <input type="checkbox" id="hide-status-for-<?php
979 echo esc_attr( $menu_item_id_transformed );
980 ?>" class="<?php
981 echo esc_attr( $checkbox_class );
982 ?>" data-menu-item-title="<?php
983 echo esc_attr( $common_methods->strip_html_tags_and_content( $menu_item_title ) );
984 ?>" data-menu-item-id="<?php
985 echo esc_attr( $menu_item_id_transformed );
986 ?>" data-menu-item-id-ori="<?php
987 echo esc_attr( $menu_item_id );
988 ?>" data-menu-url-fragment="<?php
989 echo esc_attr( $menu_url_fragment );
990 ?>">
991 <span><?php
992 echo esc_html( $hide_text );
993 ?></span>
994 </label>
995 <?php
996 ?>
997 </div><!-- end of .options-for-hiding -->
998 </div><!-- end of .item-title -->
999 </div><!-- end of .menu-item-handle -->
1000 </div><!-- end of .menu-item-bar -->
1001 <?php
1002 $i = 1;
1003 ?>
1004 <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>
1005 </li>
1006 <?php
1007 }
1008 }
1009 ?>
1010 </ul>
1011 <?php
1012 // Hidden input field to store custom menu order (from options as is, or sortupdate) upon clicking Save Changes.
1013 $field_id = 'custom_menu_order';
1014 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : '' );
1015 echo '<input type="hidden" id="' . esc_attr( $field_id ) . '" class="asenha-subfield-text" name="' . esc_attr( $field_id ) . '" value="' . esc_attr( $field_option_value ) . '">';
1016 // Hidden input field to store hidden menu items (from options as is, or 'Hide' checkbox clicks) upon clicking Save Changes.
1017 $this->output_admin_menu_organizer_hidden_field( 'custom_menu_hidden' );
1018 // Hidden input field to store custom menu titles (from options as is, or custom values entered on each non-WP-default menu items.
1019 $this->output_admin_menu_organizer_hidden_field( 'custom_menu_titles' );
1020 }
1021
1022 /**
1023 * Output hidden field
1024 *
1025 * @since 6.9.13
1026 */
1027 public function output_admin_menu_organizer_hidden_field( $field_id ) {
1028 $options_extra = get_option( ASENHA_SLUG_U . '_extra', array() );
1029 $options = ( isset( $options_extra['admin_menu'] ) ? $options_extra['admin_menu'] : array() );
1030 $field_name = $field_id;
1031 $field_option_value = ( isset( $options[$field_id] ) ? $options[$field_id] : '' );
1032 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 ) ) . '">';
1033 }
1034
1035 /**
1036 * Render textarea field as sub-field of a toggle/switcher checkbox
1037 *
1038 * @since 2.3.0
1039 */
1040 function render_datatable( $args ) {
1041 global $wpdb;
1042 $option_name = $args['option_name'];
1043 if ( !empty( $option_name ) ) {
1044 $options = get_option( $option_name, array() );
1045 } else {
1046 $options = get_option( ASENHA_SLUG_U, array() );
1047 }
1048 $field_id = $args['field_id'];
1049 $field_slug = $args['field_slug'];
1050 $field_name = $args['field_name'];
1051 $field_type = $args['field_type'];
1052 $field_description = $args['field_description'];
1053 $table_title = $args['table_title'];
1054 $table_name = $args['table_name'];
1055 $field_option_value = ( isset( $options[$args['field_id']] ) ? $options[$args['field_id']] : '' );
1056 ?>
1057 <table id="login-attempts-log" class="wp-list-table widefat striped datatable">
1058 <thead>
1059 <tr class="datatable-tr">
1060 <th class="datatable-th"><?php
1061 _e( 'IP Address<br />Last Username', 'admin-site-enhancements' );
1062 ?></th>
1063 <th class="datatable-th"><?php
1064 _e( 'Attempts<br />Lockouts', 'admin-site-enhancements' );
1065 ?></th>
1066 <th class="datatable-th"><?php
1067 _e( 'Last Attempt On', 'admin-site-enhancements' );
1068 ?></th>
1069 </tr>
1070 </thead>
1071 <tbody>
1072 <?php
1073 $limit = 1000;
1074 $sql = $wpdb->prepare( "SELECT * FROM {$table_name} ORDER BY unixtime DESC LIMIT %d", array($limit) );
1075 $entries = $wpdb->get_results( $sql, ARRAY_A );
1076 foreach ( $entries as $entry ) {
1077 $unixtime = $entry['unixtime'];
1078 if ( function_exists( 'wp_date' ) ) {
1079 $date = wp_date( 'F j, Y', $unixtime );
1080 $time = wp_date( 'H:i:s', $unixtime );
1081 } else {
1082 $date = date_i18n( 'F j, Y', $unixtime );
1083 $time = date_i18n( 'H:i:s', $unixtime );
1084 }
1085 ?>
1086 <tr class="datatable-tr">
1087 <td class="datatable-td"><?php
1088 echo esc_html( $entry['ip_address'] );
1089 ?><br /><?php
1090 echo esc_html( $entry['username'] );
1091 ?></td>
1092 <td class="datatable-td"><?php
1093 echo esc_html( $entry['fail_count'] );
1094 ?><br /><?php
1095 echo esc_html( $entry['lockout_count'] );
1096 ?></td>
1097 <td class="datatable-td"><span class="unixtime"><?php
1098 echo esc_html( $entry['unixtime'] );
1099 ?></span><?php
1100 echo esc_html( $date );
1101 ?><br /><?php
1102 echo esc_html( $time );
1103 ?></td>
1104 </tr>
1105 <?php
1106 }
1107 ?>
1108 </tbody>
1109 </table>
1110 <?php
1111 echo '<div class="asenha-subfield-description">' . esc_html( $field_description ) . '</div>';
1112 echo '<input type="hidden" id="' . esc_attr( $field_name ) . '" class="asenha-subfield-datatable" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $field_option_value ) . '">';
1113 }
1114
1115 /**
1116 * Render checks and status for AVIF support
1117 *
1118 * @link https://php.watch/versions/8.1/gd-avif
1119 * @since 5.7.0
1120 */
1121 public function render_avif_support_status() {
1122 // Check status of GD extension and it's AVIF support
1123 if ( extension_loaded( 'gd' ) && function_exists( 'gd_info' ) ) {
1124 $is_gd_enabled = true;
1125 $gd_info = gd_info();
1126 $gd_version = $gd_info['GD Version'];
1127 $gd_avif_support = ( isset( $gd_info['AVIF Support'] ) ? isset( $gd_info['AVIF Support'] ) : false );
1128 if ( $gd_avif_support ) {
1129 $gd_status = $gd_version . ' <span class="supported">' . __( 'with AVIF support', 'admin-site-enhancements' ) . '</span>';
1130 } else {
1131 $gd_status = $gd_version . ' <span class="unsupported">' . __( 'without AVIF support', 'admin-site-enhancements' ) . '</span>';
1132 }
1133 } else {
1134 $is_gd_enabled = false;
1135 $gd_avif_support = false;
1136 $gd_status = __( 'Not available', 'admin-site-enhancements' );
1137 }
1138 // Check status of ImageMagick library and it's AVIF support
1139 if ( extension_loaded( 'imagick' ) && class_exists( 'Imagick' ) ) {
1140 $is_imagick_enabled = true;
1141 $imagick_version = \Imagick::getVersion();
1142 if ( preg_match( '/((?:[0-9]+\\.?)+)/', $imagick_version['versionString'], $matches ) ) {
1143 $imagick_version = $matches[0];
1144 } else {
1145 $imagick_version = $imagick_version['versionString'];
1146 }
1147 if ( version_compare( $imagick_version, '7.0.25', '>=' ) ) {
1148 $imagick_avif_support = true;
1149 $imagick_status = $imagick_version . ' <span class="supported">with AVIF support</span>';
1150 } else {
1151 $imagick_avif_support = false;
1152 $imagick_status = $imagick_version . ' <span class="unsupported">without AVIF support</span>';
1153 }
1154 } else {
1155 $is_imagick_enabled = false;
1156 $imagick_avif_support = false;
1157 $imagick_status = __( 'Not available', 'admin-site-enhancements' );
1158 }
1159 echo '<div class="asenha-subfield-status">';
1160 echo '<div class="status-title">' . __( 'AVIF Support Status', 'admin-site-enhancements' ) . '</div>';
1161 echo '<div class="status-body">';
1162 echo '<div class="status-item"><span class="status-item-title">PHP</span> : ' . wp_kses_post( phpversion() ) . '</div>';
1163 echo '<div class="status-item"><span class="status-item-title">GD</span> : ' . wp_kses_post( $gd_status ) . '</div>';
1164 echo '<div class="status-item"><span class="status-item-title">ImageMagick</span> : ' . wp_kses_post( $imagick_status ) . '</div>';
1165 echo '</div>';
1166 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>';
1167 echo '</div>';
1168 }
1169
1170 }
1171