PluginProbe ʕ •ᴥ•ʔ
Admin and Site Enhancements (ASE) / 8.7.2
Admin and Site Enhancements (ASE) v8.7.2
9.1.1 9.1.0 9.0.2 9.0.1 9.0.0 8.9.2 8.9.1 8.9.0 8.8.8 8.8.7 8.8.6 8.8.5 8.8.4 8.8.3 8.8.2 8.8.1 8.8.0 8.7.3 8.7.2 8.7.1 8.2.1 8.2.2 8.2.3 8.3.0 8.3.1 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 / settings.php
admin-site-enhancements Last commit date
assets 4 months ago classes 4 months ago includes 4 months ago languages 4 months ago vendor 4 months ago CHANGELOG.md 4 months ago LICENSE.md 4 months ago README.md 4 months ago admin-site-enhancements.php 4 months ago bootstrap.php 4 months ago functions.php 4 months ago settings.php 4 months ago
settings.php
1617 lines
1 <?php
2
3 /**
4 * Initialize options. [TODO] Move this into activation class at v7.
5 *
6 * @since 6.4.1
7 */
8 /**
9 * Get an ASE option as an array and normalize malformed values.
10 *
11 * Some sites may store malformed option payloads (e.g. strings), which can
12 * trigger fatal errors on PHP 8+ when string offsets are accessed as arrays.
13 *
14 * @since 8.4.2
15 *
16 * @param string $option_name Option name.
17 * @param bool|null $autoload Whether to autoload option.
18 * @return array
19 */
20 function asenha_get_option_array( $option_name, $autoload = null ) {
21 $option_value = get_option( $option_name, array() );
22 if ( is_array( $option_value ) ) {
23 return $option_value;
24 }
25 $normalized_value = array();
26 if ( is_object( $option_value ) ) {
27 $normalized_value = (array) $option_value;
28 } elseif ( is_string( $option_value ) && '' !== trim( $option_value ) ) {
29 $maybe_unserialized = maybe_unserialize( $option_value );
30 if ( is_array( $maybe_unserialized ) ) {
31 $normalized_value = $maybe_unserialized;
32 } elseif ( is_object( $maybe_unserialized ) ) {
33 $normalized_value = (array) $maybe_unserialized;
34 } elseif ( is_string( $maybe_unserialized ) && '' !== trim( $maybe_unserialized ) ) {
35 $maybe_json = json_decode( $maybe_unserialized, true );
36 if ( is_array( $maybe_json ) ) {
37 $normalized_value = $maybe_json;
38 }
39 }
40 }
41 if ( null === $autoload ) {
42 update_option( $option_name, $normalized_value );
43 } else {
44 update_option( $option_name, $normalized_value, $autoload );
45 }
46 return $normalized_value;
47 }
48
49 if ( false === get_option( ASENHA_SLUG_U ) ) {
50 global $wpdb;
51 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
52 $asenha_exists_in_db = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name = %s", ASENHA_SLUG_U ) );
53 if ( !$asenha_exists_in_db ) {
54 add_option(
55 ASENHA_SLUG_U,
56 array(),
57 '',
58 true
59 );
60 } else {
61 // Option exists in DB but cache returned false (stale persistent cache).
62 // Aggressively invalidate all cache layers including local in-process caches
63 // that some Redis/Memcached backends maintain separately from the external store.
64 wp_cache_delete( 'alloptions', 'options' );
65 wp_cache_delete( 'notoptions', 'options' );
66 if ( function_exists( 'wp_cache_flush' ) ) {
67 wp_cache_flush();
68 }
69 global $wp_object_cache;
70 if ( is_object( $wp_object_cache ) ) {
71 if ( property_exists( $wp_object_cache, 'local_cache' ) && is_array( $wp_object_cache->local_cache ) ) {
72 unset($wp_object_cache->local_cache['options']);
73 }
74 if ( property_exists( $wp_object_cache, 'cache' ) && is_array( $wp_object_cache->cache ) ) {
75 unset($wp_object_cache->cache['options']);
76 }
77 }
78 }
79 }
80 if ( false === get_option( ASENHA_SLUG_U . '_stats' ) ) {
81 global $wpdb;
82 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
83 $asenha_stats_exists_in_db = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name = %s", ASENHA_SLUG_U . '_stats' ) );
84 if ( !$asenha_stats_exists_in_db ) {
85 add_option(
86 ASENHA_SLUG_U . '_stats',
87 array(),
88 '',
89 false
90 );
91 } else {
92 // Option exists in DB but cache returned false (stale persistent cache).
93 // Aggressively invalidate all cache layers including local in-process caches.
94 wp_cache_delete( 'alloptions', 'options' );
95 wp_cache_delete( 'notoptions', 'options' );
96 if ( function_exists( 'wp_cache_flush' ) ) {
97 wp_cache_flush();
98 }
99 global $wp_object_cache;
100 if ( is_object( $wp_object_cache ) ) {
101 if ( property_exists( $wp_object_cache, 'local_cache' ) && is_array( $wp_object_cache->local_cache ) ) {
102 unset($wp_object_cache->local_cache['options']);
103 }
104 if ( property_exists( $wp_object_cache, 'cache' ) && is_array( $wp_object_cache->cache ) ) {
105 unset($wp_object_cache->cache['options']);
106 }
107 }
108 }
109 }
110 if ( false === get_option( ASENHA_SLUG_U . '_extra' ) ) {
111 global $wpdb;
112 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
113 $asenha_extra_exists_in_db = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name = %s", ASENHA_SLUG_U . '_extra' ) );
114 if ( !$asenha_extra_exists_in_db ) {
115 add_option(
116 ASENHA_SLUG_U . '_extra',
117 array(),
118 '',
119 true
120 );
121 } else {
122 // Option exists in DB but cache returned false (stale persistent cache).
123 // Aggressively invalidate all cache layers including local in-process caches.
124 wp_cache_delete( 'alloptions', 'options' );
125 wp_cache_delete( 'notoptions', 'options' );
126 if ( function_exists( 'wp_cache_flush' ) ) {
127 wp_cache_flush();
128 }
129 global $wp_object_cache;
130 if ( is_object( $wp_object_cache ) ) {
131 if ( property_exists( $wp_object_cache, 'local_cache' ) && is_array( $wp_object_cache->local_cache ) ) {
132 unset($wp_object_cache->local_cache['options']);
133 }
134 if ( property_exists( $wp_object_cache, 'cache' ) && is_array( $wp_object_cache->cache ) ) {
135 unset($wp_object_cache->cache['options']);
136 }
137 }
138 }
139 }
140 // Bugfix in v7.1.2 for Custom Content Type module
141 $options_extra = asenha_get_option_array( ASENHA_SLUG_U . '_extra', true );
142 if ( !isset( $options_extra['cfgroup_next_field_id'] ) ) {
143 $options_extra['cfgroup_next_field_id'] = 1;
144 update_option( ASENHA_SLUG_U . '_extra', $options_extra, true );
145 }
146 // Move Admin Menu Organizer options storage to extra table since v7.8.5
147 if ( !isset( $options_extra['admin_menu'] ) ) {
148 $options = asenha_get_option_array( ASENHA_SLUG_U, true );
149 $options_extra['admin_menu']['custom_menu_order'] = ( isset( $options['custom_menu_order'] ) ? $options['custom_menu_order'] : '' );
150 unset($options['custom_menu_order']);
151 $options_extra['admin_menu']['custom_menu_titles'] = ( isset( $options['custom_menu_titles'] ) ? $options['custom_menu_titles'] : '' );
152 unset($options['custom_menu_titles']);
153 $options_extra['admin_menu']['custom_menu_hidden'] = ( isset( $options['custom_menu_hidden'] ) ? trim( $options['custom_menu_hidden'], ',' ) : '' );
154 unset($options['custom_menu_hidden']);
155 update_option( ASENHA_SLUG_U . '_extra', $options_extra, true );
156 update_option( ASENHA_SLUG_U, $options, true );
157 }
158 /**
159 * Get the SMTP password storage status with backward-compatible fallbacks.
160 *
161 * This avoids fatal errors during mixed-version deployments where newer
162 * settings code may temporarily run against an older Email_Delivery class
163 * definition that does not yet provide the newer helper method/constants.
164 *
165 * @since 8.5.1
166 *
167 * @param string|null $stored_password Stored option value.
168 * @return string
169 */
170 function asenha_get_smtp_password_status_compat( $stored_password = null ) {
171 if ( null === $stored_password ) {
172 $options = asenha_get_option_array( ASENHA_SLUG_U, true );
173 $stored_password = ( isset( $options['smtp_password'] ) ? $options['smtp_password'] : '' );
174 }
175 $email_delivery = new \ASENHA\Classes\Email_Delivery();
176 if ( method_exists( $email_delivery, 'get_smtp_password_status' ) ) {
177 return $email_delivery->get_smtp_password_status( $stored_password );
178 }
179 if ( empty( $stored_password ) ) {
180 return 'empty';
181 }
182 if ( is_string( $stored_password ) && 0 === strpos( $stored_password, 'asenha_encrypted::smtp_password::v1::' ) ) {
183 return 'encrypted_valid';
184 }
185 return 'legacy_plaintext';
186 }
187
188 /**
189 * Encrypt the SMTP password when the runtime supports the newer helper.
190 *
191 * @since 8.5.1
192 *
193 * @param \ASENHA\Classes\Email_Delivery $email_delivery Email delivery instance.
194 * @param string $password Plaintext SMTP password.
195 * @return string Encrypted payload or empty string when unsupported.
196 */
197 function asenha_encrypt_smtp_password_compat( $email_delivery, $password ) {
198 if ( !method_exists( $email_delivery, 'encrypt_smtp_password' ) ) {
199 return '';
200 }
201 return $email_delivery->encrypt_smtp_password( $password );
202 }
203
204 /**
205 * Encrypt legacy SMTP password storage after pluggable functions are available.
206 *
207 * @since 8.5.1
208 */
209 function asenha_migrate_legacy_smtp_password_storage() {
210 $options = asenha_get_option_array( ASENHA_SLUG_U, true );
211 if ( empty( $options['smtp_password'] ) ) {
212 return;
213 }
214 $email_delivery = new \ASENHA\Classes\Email_Delivery();
215 if ( 'legacy_plaintext' !== asenha_get_smtp_password_status_compat( $options['smtp_password'] ) ) {
216 return;
217 }
218 $encrypted_smtp_password = asenha_encrypt_smtp_password_compat( $email_delivery, $options['smtp_password'] );
219 if ( !empty( $encrypted_smtp_password ) ) {
220 $options['smtp_password'] = $encrypted_smtp_password;
221 update_option( ASENHA_SLUG_U, $options, true );
222 }
223 }
224
225 if ( did_action( 'plugins_loaded' ) ) {
226 asenha_migrate_legacy_smtp_password_storage();
227 } else {
228 add_action( 'plugins_loaded', 'asenha_migrate_legacy_smtp_password_storage' );
229 }
230 /**
231 * Register admin menu
232 *
233 * @since 1.0.0
234 */
235 function asenha_register_admin_menu() {
236 add_submenu_page(
237 'tools.php',
238 // Parent page/menu
239 'Admin and Site Enhancements',
240 // Browser tab/window title
241 __( 'Enhancements', 'admin-site-enhancements' ),
242 // Sube menu title
243 'manage_options',
244 // Minimal user capabililty
245 ASENHA_SLUG,
246 // Page slug. Shows up in URL.
247 'asenha_add_settings_page'
248 );
249 }
250
251 /**
252 * Create the settings page of the plugin
253 *
254 * @since 1.0.0
255 */
256 function asenha_add_settings_page() {
257 $options = asenha_get_option_array( ASENHA_SLUG_U, true );
258 ?>
259 <div class="wrap asenha">
260
261 <div id="asenha-header" class="asenha-header">
262 <div class="asenha-header-left">
263 <img src="<?php
264 echo esc_html( ASENHA_URL ) . 'assets/img/ase_icon.png';
265 ?>" class="asenha-icon"/>
266 <h1 class="asenha-heading">
267 <?php
268 echo esc_html( get_admin_page_title() );
269 ?>
270 (ASE)
271 <?php
272 ?>
273 </h1>
274 <input id="module-search-input" type="search" placeholder="<?php
275 echo esc_attr__( 'Search...', 'admin-site-enhancements' );
276 ?>" />
277 <!-- <a href="https://wordpress.org/plugins/admin-site-enhancements/" target="_blank" class="asenha-header-action"><span>&#8505;</span> <?php
278 // esc_html_e( 'Info', 'admin-site-enhancements' );
279 ?></a> -->
280 </div>
281 <div class="asenha-header-right">
282 <?php
283 // https://icon-sets.iconify.design/iconamoon/star-bold/
284 $svg_star = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="2.5" d="m12 2l3.104 6.728l7.358.873l-5.44 5.03l1.444 7.268L12 18.28L5.534 21.9l1.444-7.268L1.538 9.6l7.359-.873L12 2Z"/></svg>';
285 // https://icon-sets.iconify.design/octicon/question-16/
286 $svg_support = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill="currentColor" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13a6.5 6.5 0 0 0 0-13ZM6.92 6.085h.001a.749.749 0 1 1-1.342-.67c.169-.339.436-.701.849-.977C6.845 4.16 7.369 4 8 4a2.756 2.756 0 0 1 1.637.525c.503.377.863.965.863 1.725c0 .448-.115.83-.329 1.15c-.205.307-.47.513-.692.662c-.109.072-.22.138-.313.195l-.006.004a6.24 6.24 0 0 0-.26.16a.952.952 0 0 0-.276.245a.75.75 0 0 1-1.248-.832c.184-.264.42-.489.692-.661c.103-.067.207-.132.313-.195l.007-.004c.1-.061.182-.11.258-.161a.969.969 0 0 0 .277-.245C8.96 6.514 9 6.427 9 6.25a.612.612 0 0 0-.262-.525A1.27 1.27 0 0 0 8 5.5c-.369 0-.595.09-.74.187a1.01 1.01 0 0 0-.34.398ZM9 11a1 1 0 1 1-2 0a1 1 0 0 1 2 0Z"/></svg>';
287 // https://icon-sets.iconify.design/octicon/comment-16/
288 $svg_feedback = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 16 16"><path fill="currentColor" d="M1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 13.25 12H9.06l-2.573 2.573A1.458 1.458 0 0 1 4 13.543V12H2.75A1.75 1.75 0 0 1 1 10.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h4.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"/></svg>';
289 // https://icon-sets.iconify.design/ic/baseline-translate/
290 $svg_translate = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path fill="currentColor" d="m12.87 15.07l-2.54-2.51l.03-.03A17.52 17.52 0 0 0 14.07 6H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35C8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5l3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7l1.62-4.33L19.12 17z"/></svg>';
291 // https://icon-sets.iconify.design/iconamoon/file-document/
292 $svg_docs = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="2"><path stroke-linecap="round" d="M7 21a2 2 0 0 1-2-2V3h9l5 5v11a2 2 0 0 1-2 2H7Z"/><path d="M13 3v6h6"/><path stroke-linecap="round" d="M9 13h6m-6 4h6"/></g></svg>';
293 // https://icon-sets.iconify.design/pajamas/heart/
294 $svg_sponsor = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 16 16"><path fill="currentColor" fill-rule="evenodd" d="M8.753 2.247L8 3l-.753-.753A4.243 4.243 0 0 0 1.25 8.25l5.69 5.69L8 15l1.06-1.06l5.69-5.69a4.243 4.243 0 0 0-5.997-6.003ZM8 12.879l5.69-5.69a2.743 2.743 0 0 0-3.877-3.881l-.752.753L8 5.12L6.94 4.06l-.753-.752v-.001A2.743 2.743 0 0 0 2.31 7.189L8 12.88Z" clip-rule="evenodd"/></svg>';
295 ?>
296 <a href="https://wordpress.org/plugins/admin-site-enhancements/#reviews" target="_blank" class="asenha-header-action review"><?php
297 echo wp_kses( $svg_star, get_kses_with_svg_ruleset() ) . esc_html__( 'Review', 'admin-site-enhancements' );
298 ?></a>
299 <a href="https://wordpress.org/support/plugin/admin-site-enhancements/" target="_blank" class="asenha-header-action feedback"><?php
300 echo wp_kses( $svg_feedback, get_kses_with_svg_ruleset() ) . esc_html__( 'Feedback', 'admin-site-enhancements' );
301 ?></a>
302 <a href="https://www.wpase.com/trnslt-plgnhdr" target="_blank" class="asenha-header-action translate"><?php
303 echo wp_kses( $svg_translate, get_kses_with_svg_ruleset() ) . esc_html__( 'Translate', 'admin-site-enhancements' );
304 ?></a>
305 <!--<a href="https://www.wpasenha.com/docs/" target="_blank" class="asenha-header-action docs"><?php
306 // echo $svg_docs . esc_html__( 'Docs', 'admin-site-enhancements' );
307 ?></a>-->
308 <!--<a id="plugin-sponsor" href="#" class="asenha-header-action sponsor"><?php
309 // echo $svg_sponsor . esc_html__( 'Sponsor', 'admin-site-enhancements' );
310 ?></a>-->
311 <a href="https://www.wpase.com/upgrade-btn" target="_blank" id="plugin-upgrade" class="button button-primary plugin-upgrade"><?php
312 echo esc_html__( 'Get ASE Pro', 'admin-site-enhancements' );
313 ?></a>
314 <?php
315 ?>
316 <a class="button button-primary asenha-save-button"><?php
317 echo esc_html__( 'Save Changes', 'admin-site-enhancements' );
318 ?></a>
319 <!-- https://icon-sets.iconify.design/svg-spinners/180-ring-with-bg/ -->
320 <div class="asenha-saving-changes" style="display:none;"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="#2271b1" d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z" opacity=".25"/><path fill="#2271b1" d="M12,4a8,8,0,0,1,7.89,6.7A1.53,1.53,0,0,0,21.38,12h0a1.5,1.5,0,0,0,1.48-1.75,11,11,0,0,0-21.72,0A1.5,1.5,0,0,0,2.62,12h0a1.53,1.53,0,0,0,1.49-1.3A8,8,0,0,1,12,4Z"><animateTransform attributeName="transform" dur="0.75s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path></svg></div>
321 <div class="asenha-changes-saved" style="display:none;"><svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24"><path fill="seagreen" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10s10-4.48 10-10S17.52 2 12 2zM9.29 16.29L5.7 12.7a.996.996 0 1 1 1.41-1.41L10 14.17l6.88-6.88a.996.996 0 1 1 1.41 1.41l-7.59 7.59a.996.996 0 0 1-1.41 0z"/></svg></div>
322 </div>
323 </div>
324
325 <div class="asenha-body">
326 <?php
327 $is_yearend_promo_period = is_yearend_promo_period();
328 ?>
329 <?php
330 if ( $is_yearend_promo_period ) {
331 ?>
332 <!-- <div class="asenha-upgrade-nudge" style="display: none;">
333 <div class="asenha-upgrade-nudge__message"><?php
334 // echo esc_html__( 'Lifetime Deal (LTD) is available for the Pro version of ASE.', 'admin-site-enhancements' );
335 ?></div>
336 <a href="https://www.wpase.com/upgrade-ndg" class="button asenha-upgrade-nudge__button" target="_blank"><?php
337 // echo esc_html__( 'Find Out More', 'admin-site-enhancements' );
338 ?></a>
339 <a href="#" id="dismiss-upgrade-nudge" class="asenha-upgrade-nudge__dismiss">
340 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24"><path fill="currentColor" 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>
341 </a>
342 </div> -->
343 <div class="asenha-promo-nudge" style="display: none;">
344 <div class="asenha-promo-nudge__message"><?php
345 echo esc_html__( 'ASE Pro YEAR-END SALE! 20% DISCOUNT. Lifetime Deal (LTD) available.', 'admin-site-enhancements' );
346 ?></div>
347 <a href="https://www.wpase.com/promo-ndg" class="button asenha-promo-nudge__button" target="_blank"><?php
348 echo esc_html__( 'Get It Now', 'admin-site-enhancements' );
349 ?></a>
350 <a href="#" id="dismiss-promo-nudge" class="asenha-promo-nudge__dismiss">
351 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24"><path fill="currentColor" 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>
352 </a>
353 </div>
354 <?php
355 } else {
356 ?>
357 <div class="asenha-upgrade-nudge" style="display: none;">
358 <div class="asenha-upgrade-nudge__message"><?php
359 echo esc_html__( 'Lifetime Deal (LTD) is available for the Pro version of ASE.', 'admin-site-enhancements' );
360 ?></div>
361 <a href="https://www.wpase.com/upgrade-ndg" class="button asenha-upgrade-nudge__button" target="_blank"><?php
362 echo esc_html__( 'Find Out More', 'admin-site-enhancements' );
363 ?></a>
364 <a href="#" id="dismiss-upgrade-nudge" class="asenha-upgrade-nudge__dismiss">
365 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24"><path fill="currentColor" 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>
366 </a>
367 </div>
368 <?php
369 }
370 ?>
371 <?php
372 ?>
373 <div class="asenha-support-nudge nudge-show-more is-enabled" style="display: none;">
374 <h3><?php
375 _e( 'Looks like some of these free enhancements have been useful for your site?', 'admin-site-enhancements' );
376 ?></h3>
377 <p class="nudge-description intro"><?php
378 _e( 'Please consider supporting ASE.', 'admin-site-enhancements' );
379 ?></p>
380 <div class="nudge-content">
381 <div class="nudge-primary">
382 <h4><?php
383 _e( 'Write a quick, 5-star review for ASE', 'admin-site-enhancements' );
384 ?></h4>
385 <div class="nudge-ctas">
386 <a href="https://wordpress.org/plugins/admin-site-enhancements/#reviews" target="_blank" class="button button-outline asenha-review-button"><?php
387 _e( 'Add Your Review', 'admin-site-enhancements' );
388 ?></a>
389 <a href="#" id="have-reviewed" class="asenha-have-supported"><?php
390 _e( 'I\'ve reviewed', 'admin-site-enhancements' );
391 ?></a>
392 </div>
393 <p class="nudge-description"><?php
394 _e( 'Or, help improve ASE by <a href="https://wordpress.org/support/plugin/admin-site-enhancements/" target="_blank">providing feedback</a>.', 'admin-site-enhancements' );
395 ?></p>
396 </div>
397 <div class="nudge-secondary">
398 <h4><?php
399 _e( 'Share about ASE on:', 'admin-site-enhancements' );
400 ?></h4>
401 <div class="nudge-ctas">
402 <a href="https://www.facebook.com/sharer.php?u=<?php
403 echo urlencode( 'https://www.wpase.com' );
404 ?>" target="_blank" class="button button-outline asenha-share-button"><?php
405 _e( 'Facebook', 'admin-site-enhancements' );
406 ?></a>
407 <a href="https://twitter.com/intent/post?url=<?php
408 echo urlencode( 'https://www.wpase.com' );
409 ?>&text=<?php
410 echo esc_attr( urlencode( 'Admin and Site Enhancements (ASE)' ) );
411 ?>" target="_blank" class="button button-outline asenha-share-button"><?php
412 _e( 'X / Twitter', 'admin-site-enhancements' );
413 ?></a>
414 <a href="https://www.wpase.com/video-reviews/" target="_blank" class="button button-outline asenha-share-button"><?php
415 _e( 'YouTube', 'admin-site-enhancements' );
416 ?></a>
417 <a href="#" id="have-shared" class="asenha-have-supported"><?php
418 _e( 'I\'ve shared', 'admin-site-enhancements' );
419 ?></a>
420 </div>
421 <div class="nudge-info">
422 <p class="nudge-description"><?php
423 _e( 'Help others discover ASE and maybe <a href="https://www.wpase.com/trnslt-plgnndg" target="_blank">translate</a> to your language.', 'admin-site-enhancements' );
424 ?></p>
425 </div>
426 </div>
427 </div>
428 <div class="dismiss-support-nudge"><a href="#" id="support-nudge-dismiss" class="asenha-support-nudge-dismiss"><?php
429 _e( 'Dismiss', 'admin-site-enhancements' );
430 ?></a></div>
431 </div>
432 <?php
433 ?>
434 <form action="options.php" method="post">
435 <div class="asenha-vertical-tabs">
436 <div class="asenha-tab-buttons">
437 <?php
438 // https://icon-sets.iconify.design/mdi/database-check-outline/ -- db check
439 // https://icon-sets.iconify.design/mdi/file-document-box-multiple-outline/ -- docs
440 // https://icon-sets.iconify.design/fluent/content-view-28-regular/ -- content
441 // https://icon-sets.iconify.design/lucide/shapes/ -- shapes
442 $icon_content_management = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M8.3 10a.7.7 0 0 1-.626-1.079L11.4 3a.7.7 0 0 1 1.198-.043L16.3 8.9a.7.7 0 0 1-.572 1.1Z"/><rect width="7" height="7" x="3" y="14" rx="1"/><circle cx="17.5" cy="17.5" r="3.5"/></g></svg>';
443 // https://icon-sets.iconify.design/mingcute/layout-line/
444 $icon_admin_interface = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="none" fill-rule="evenodd"><path d="M24 0v24H0V0h24ZM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035c-.01-.004-.019-.001-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427c-.002-.01-.009-.017-.017-.018Zm.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093c.012.004.023 0 .029-.008l.004-.014l-.034-.614c-.003-.012-.01-.02-.02-.022Zm-.715.002a.023.023 0 0 0-.027.006l-.006.014l-.034.614c0 .012.007.02.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01l-.184-.092Z"/><path fill="currentColor" d="M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5Zm16 0H5v3h14V5ZM5 19v-9h4v9H5Zm6 0h8v-9h-8v9Z"/></g></svg>';
445 // https://icon-sets.iconify.design/ri/login-circle-line/
446 $icon_login_logout = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="m10.998 16l5-4l-5-4v3h-9v2h9z"/><path fill="currentColor" d="M12.999 2.999a8.938 8.938 0 0 0-6.364 2.637L8.049 7.05c1.322-1.322 3.08-2.051 4.95-2.051s3.628.729 4.95 2.051S20 10.13 20 12s-.729 3.628-2.051 4.95s-3.08 2.051-4.95 2.051s-3.628-.729-4.95-2.051l-1.414 1.414c1.699 1.7 3.959 2.637 6.364 2.637s4.665-.937 6.364-2.637C21.063 16.665 22 14.405 22 12s-.937-4.665-2.637-6.364a8.938 8.938 0 0 0-6.364-2.637z"/></svg>';
447 // https://icon-sets.iconify.design/mingcute/code-line/
448 $icon_custom_code = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="none"><path d="M0 0h24v24H0z"/><path fill="currentColor" d="M14.486 3.143a1 1 0 0 1 .692 1.233l-4.43 15.788a1 1 0 0 1-1.926-.54l4.43-15.788a1 1 0 0 1 1.234-.693ZM7.207 7.05a1 1 0 0 1 0 1.414L3.672 12l3.535 3.535a1 1 0 1 1-1.414 1.415L1.55 12.707a1 1 0 0 1 0-1.414L5.793 7.05a1 1 0 0 1 1.414 0Zm9.586 1.414a1 1 0 1 1 1.414-1.414l4.243 4.243a1 1 0 0 1 0 1.414l-4.243 4.242a1 1 0 0 1-1.414-1.414L20.328 12l-3.535-3.536Z"/></g></svg>';
449 // https://icon-sets.iconify.design/mdi/forbid/
450 $icon_disable_components = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M12 2c5.5 0 10 4.5 10 10s-4.5 10-10 10S2 17.5 2 12S6.5 2 12 2m0 2c-1.9 0-3.6.6-4.9 1.7l11.2 11.2c1-1.4 1.7-3.1 1.7-4.9c0-4.4-3.6-8-8-8m4.9 14.3L5.7 7.1C4.6 8.4 4 10.1 4 12c0 4.4 3.6 8 8 8c1.9 0 3.6-.6 4.9-1.7Z"/></svg>';
451 // https://icon-sets.iconify.design/jam/shield-check/
452 $icon_security = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 16 16"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"><path d="m8 1.75l5.25 2v5c0 2.25-2 4.5-5.25 5.5c-3.25-1-5.25-3-5.25-5.5v-5z"/><path d="m5.75 7.75l1.5 1.5l3-3.5"/></g></svg>';
453 // https://icon-sets.iconify.design/streamline/image-flash-1-flash-power-connect-charge-electricity-lightning/
454 $icon_optimizations = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 14 14"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M4.25.5L2 5.81a.5.5 0 0 0 .46.69h2.79l-2 7l8.59-8.14a.5.5 0 0 0-.34-.86H7.75l2-4Z"/></svg>';
455 // https://icon-sets.iconify.design/iconoir/tools/
456 $icon_utilities = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"><path d="m10.05 10.607l-7.07 7.07a2 2 0 0 0 0 2.83v0a2 2 0 0 0 2.828 0l7.07-7.072m4.315.365l3.878 3.878a2 2 0 0 1 0 2.828v0a2 2 0 0 1-2.828 0l-6.209-6.208M6.733 5.904L4.61 6.61L2.49 3.075l1.414-1.414L7.44 3.782l-.707 2.122Zm0 0l2.83 2.83"/><path d="M10.05 10.607c-.844-2.153-.679-4.978 1.061-6.718c1.74-1.74 4.95-2.121 6.717-1.06l-3.04 3.04l-.283 3.111l3.111-.282l3.04-3.041c1.062 1.768.68 4.978-1.06 6.717c-1.74 1.74-4.564 1.905-6.717 1.061"/></g></svg>';
457 ?>
458 <input id="tab-content-management" type="radio" name="tabs" checked><label for="tab-content-management" class="modules-tab"><?php
459 echo wp_kses( $icon_content_management, get_kses_with_svg_ruleset() );
460 ?><span><?php
461 echo esc_html__( 'Content Management', 'admin-site-enhancements' );
462 ?></span></label>
463 <input id="tab-admin-interface" type="radio" name="tabs"><label for="tab-admin-interface" class="modules-tab"><?php
464 echo wp_kses( $icon_admin_interface, get_kses_with_svg_ruleset() );
465 ?><span><?php
466 echo esc_html__( 'Admin Interface', 'admin-site-enhancements' );
467 ?></span></label>
468 <input id="tab-login-logout" type="radio" name="tabs"><label for="tab-login-logout" class="modules-tab"><?php
469 echo wp_kses( $icon_login_logout, get_kses_with_svg_ruleset() );
470 ?><span><?php
471 echo esc_html__( 'Log In/Out | Register', 'admin-site-enhancements' );
472 ?></span></label>
473 <input id="tab-custom-code" type="radio" name="tabs"><label for="tab-custom-code" class="modules-tab"><?php
474 echo wp_kses( $icon_custom_code, get_kses_with_svg_ruleset() );
475 ?><span><?php
476 echo esc_html__( 'Custom Code', 'admin-site-enhancements' );
477 ?></span></label>
478 <input id="tab-disable-components" type="radio" name="tabs"><label for="tab-disable-components" class="modules-tab"><?php
479 echo wp_kses( $icon_disable_components, get_kses_with_svg_ruleset() );
480 ?><span><?php
481 echo esc_html__( 'Disable Components', 'admin-site-enhancements' );
482 ?></span></label>
483 <input id="tab-security" type="radio" name="tabs"><label for="tab-security" class="modules-tab"><?php
484 echo wp_kses( $icon_security, get_kses_with_svg_ruleset() );
485 ?><span><?php
486 echo esc_html__( 'Security', 'admin-site-enhancements' );
487 ?></span></label>
488 <input id="tab-optimizations" type="radio" name="tabs"><label for="tab-optimizations" class="modules-tab"><?php
489 echo wp_kses( $icon_optimizations, get_kses_with_svg_ruleset() );
490 ?><span><?php
491 echo esc_html__( 'Optimizations', 'admin-site-enhancements' );
492 ?></span></label>
493 <input id="tab-utilities" type="radio" name="tabs"><label for="tab-utilities" class="modules-tab"><?php
494 echo wp_kses( $icon_utilities, get_kses_with_svg_ruleset() );
495 ?><span><?php
496 echo esc_html__( 'Utilities', 'admin-site-enhancements' );
497 ?></span></label>
498 <label for="tab-search" class="search-tab" style="display:none;height:52px;"><span><?php
499 echo esc_html__( 'Search results:', 'admin-site-enhancements' );
500 ?></span></label>
501 </div>
502 <div class="asenha-tab-contents">
503 <section class="asenha-fields fields-content-management">
504 <table class="form-table" role="presentation">
505 <tbody></tbody>
506 </table>
507 </section>
508 <section class="asenha-fields fields-admin-interface">
509 <table class="form-table" role="presentation">
510 <tbody></tbody>
511 </table>
512 </section>
513 <section class="asenha-fields fields-login-logout">
514 <table class="form-table" role="presentation">
515 <tbody></tbody>
516 </table>
517 </section>
518 <section class="asenha-fields fields-custom-code">
519 <table class="form-table" role="presentation">
520 <tbody></tbody>
521 </table>
522 </section>
523 <section class="asenha-fields fields-disable-components">
524 <table class="form-table" role="presentation">
525 <tbody></tbody>
526 </table>
527 </section>
528 <section class="asenha-fields fields-security">
529 <table class="form-table" role="presentation">
530 <tbody></tbody>
531 </table>
532 </section>
533 <section class="asenha-fields fields-optimizations">
534 <table class="form-table" role="presentation">
535 <tbody></tbody>
536 </table>
537 </section>
538 <section class="asenha-fields fields-utilities">
539 <table class="form-table" role="presentation">
540 <tbody></tbody>
541 </table>
542 </section>
543 </div>
544 </div>
545 <div style="display:none;"><!-- Hide to prevent flash of fields appearing at the bottom of the page -->
546 <?php
547 settings_fields( ASENHA_ID );
548 ?>
549 <?php
550 do_settings_sections( ASENHA_SLUG );
551 ?>
552 <?php
553 submit_button(
554 __( 'Save Changes', 'admin-site-enhancements' ),
555 // Button copy
556 'primary',
557 // Type: 'primary', 'small', or 'large'
558 'submit',
559 // The 'name' attribute
560 true,
561 // Whether to wrap in <p> tag
562 array(
563 'id' => 'asenha-submit',
564 )
565 );
566 ?>
567 </div>
568 </form>
569 <?php
570 ?>
571 <div id="bottom-upgrade-nudge" class="asenha-upgrade-nudge-bottom" style="display:none;">
572 <div class="asenha-upgrade-nudge-bottom__message"><?php
573 echo __( 'Do more with <a href="https://www.wpase.com/upgrade-ndg-btm" target="_blank">ASE Pro</a>. Lifetime deal (LTD) <a href="https://www.wpase.com/upgrade-ndg-btm-prc" target="_blank">available</a>.', 'admin-site-enhancements' );
574 ?> <?php
575 if ( $is_yearend_promo_period ) {
576 echo __( 'Currently on YEAR-END SALE. <a href="https://www.wpase.com/promo-ndg" target="_blank">20% discount</a>.', 'admin-site-enhancements' );
577 }
578 ?></div>
579 </div>
580 <?php
581 ?>
582 </div>
583
584 <?php
585 ?>
586
587 </div>
588 <?php
589 // Record the number of times changes were saved as well as the date of last save
590 $asenha_stats = asenha_get_option_array( ASENHA_SLUG_U . '_stats', false );
591 $changes_saved = ( isset( $_GET['settings-updated'] ) && 'true' == $_GET['settings-updated'] ? true : false );
592 if ( $changes_saved ) {
593 $current_date = date( 'Y-m-d', time() );
594 if ( !isset( $asenha_stats['first_save_date'] ) ) {
595 $asenha_stats['first_save_date'] = $current_date;
596 $asenha_stats['last_save_date'] = $current_date;
597 $asenha_stats['save_count'] = 1;
598 $asenha_stats['have_supported'] = false;
599 $asenha_stats['support_nudge_dismissed'] = false;
600 $asenha_stats['support_nudge_last_shown_date'] = '';
601 $asenha_stats['support_nudge_last_shown_save_count'] = 0;
602 } else {
603 $asenha_stats['last_save_date'] = $current_date;
604 $save_count = $asenha_stats['save_count'];
605 $save_count++;
606 $asenha_stats['save_count'] = $save_count;
607 }
608 update_option( ASENHA_SLUG_U . '_stats', $asenha_stats, false );
609 }
610 }
611
612 /**
613 * Check whether it's the year-end promo period
614 *
615 * @since 7.8.11
616 */
617 function is_yearend_promo_period() {
618 // For year end promo between October 1 to December 31
619 $current_month = intval( date( 'n', time() ) );
620 // n is for numeric value of month, 1 to 12
621 if ( $current_month >= 10 ) {
622 $is_yearend_promo_period = true;
623 // Clear out last year's promo nudge dismissal data
624 $current_year = date( 'Y', time() );
625 $asenha_stats = asenha_get_option_array( ASENHA_SLUG_U . '_stats', false );
626 if ( isset( $asenha_stats['promo_nudge_dismissed'] ) && $asenha_stats['promo_nudge_dismissed'] ) {
627 $last_dismissed_year = date( 'Y', strtotime( $asenha_stats['promo_nudge_dismissed_date'] ) );
628 if ( $current_year > $last_dismissed_year ) {
629 $asenha_stats['promo_nudge_dismissed'] = false;
630 $asenha_stats['promo_nudge_dismissed_date'] = '';
631 update_option( ASENHA_SLUG_U . '_stats', $asenha_stats, false );
632 }
633 }
634 } else {
635 $is_yearend_promo_period = false;
636 }
637 // For year end promo between November 15 to December 31
638 // $tz = wp_timezone(); // WordPress timezone; or: new DateTimeZone('UTC')
639 // $current_date = new DateTimeImmutable('now', $tz);
640 // // $current_date = new DateTimeImmutable('2025-11-15', $tz); // For testing
641 // // $current_date = new DateTimeImmutable('2026-01-01', $tz); // For testing
642 // // $current_date = new DateTimeImmutable('2027-11-15', $tz); // For testing
643 // $year = (int) $current_date->format('Y');
644 // $start = new DateTimeImmutable("$year-11-15 00:00:00", $tz);
645 // $end = new DateTimeImmutable("$year-12-31 23:59:59", $tz);
646 // $is_between = ($current_date >= $start && $current_date <= $end);
647 // if ( $is_between ) {
648 // $is_yearend_promo_period = true;
649 // } else {
650 // $is_yearend_promo_period = false;
651 // }
652 // // Clear out last year's promo nudge dismissal data
653 // if ( $is_yearend_promo_period ) {
654 // $current_year = $year;
655 // $asenha_stats = get_option( ASENHA_SLUG_U . '_stats', array() );
656 // if ( isset( $asenha_stats['promo_nudge_dismissed'] ) && $asenha_stats['promo_nudge_dismissed'] ) {
657 // $last_dismissed_year = date( 'Y', strtotime( $asenha_stats['promo_nudge_dismissed_date'] ) );
658 // if ( $current_year > $last_dismissed_year ) {
659 // $asenha_stats['promo_nudge_dismissed'] = false;
660 // $asenha_stats['promo_nudge_dismissed_date'] = '';
661 // update_option( ASENHA_SLUG_U . '_stats', $asenha_stats, false );
662 // }
663 // }
664 // }
665 return $is_yearend_promo_period;
666 }
667
668 /**
669 * Suppress all notices, then add notice for successful settings update
670 *
671 * @since 1.1.0
672 */
673 function asenha_suppress_add_notices() {
674 global $plugin_page;
675 // Suppress all notices
676 if ( ASENHA_SLUG === $plugin_page ) {
677 remove_all_actions( 'admin_notices' );
678 }
679 // Add notice for successful settings update
680 if ( isset( $_GET['page'] ) && ASENHA_SLUG == $_GET['page'] && isset( $_GET['settings-updated'] ) && true == $_GET['settings-updated'] ) {
681 ?>
682 <script>
683 jQuery(document).ready( function() {
684 jQuery('.asenha-changes-saved').fadeIn(400).delay(2500).fadeOut(400);
685 });
686 </script>
687
688 <?php
689 }
690 }
691
692 /**
693 * Suppress all generic notices on the plugin settings page
694 *
695 * @since 2.7.0
696 */
697 function asenha_suppress_generic_notices() {
698 global $plugin_page;
699 // Suppress all notices
700 if ( ASENHA_SLUG === $plugin_page ) {
701 remove_all_actions( 'all_admin_notices' );
702 }
703 }
704
705 /**
706 * Enqueue admin scripts
707 *
708 * @since 1.0.0
709 */
710 function asenha_admin_scripts( $hook_suffix ) {
711 global
712 $wp_version,
713 $pagenow,
714 $typenow,
715 $taxnow,
716 $hook_suffix,
717 $current_user
718 ;
719 $current_screen = get_current_screen();
720 // Get all WP Enhancements options, default to empty array in case it's not been created yet
721 $options = asenha_get_option_array( 'admin_site_enhancements', true );
722 // For main page of this plugin
723 if ( is_asenha() ) {
724 wp_enqueue_style(
725 'asenha-jbox',
726 ASENHA_URL . 'assets/css/jBox.all.min.css',
727 array(),
728 ASENHA_VERSION
729 );
730 wp_enqueue_script(
731 'asenha-jbox',
732 ASENHA_URL . 'assets/js/jBox.all.min.js',
733 array(),
734 ASENHA_VERSION,
735 false
736 );
737 wp_enqueue_script(
738 'asenha-jsticky',
739 ASENHA_URL . 'assets/js/jquery.jsticky.mod.min.js',
740 array('jquery'),
741 ASENHA_VERSION,
742 false
743 );
744 wp_enqueue_script(
745 'asenha-js-cookie',
746 ASENHA_URL . 'assets/js/js.cookie.min.js',
747 array(),
748 ASENHA_VERSION,
749 false
750 );
751 // First, we unload the CodeMirror libraries included in WP core
752 wp_deregister_script( 'wp-codemirror' );
753 wp_deregister_script( 'code-editor' );
754 wp_deregister_script( 'htmlhint' );
755 wp_deregister_script( 'csslint' );
756 wp_deregister_script( 'esprima' );
757 wp_deregister_script( 'jshint' );
758 // Then, we load ASENHA's CodeMirror libraries. In use, e.g. for Utilities >> Enable Custom Admin / Frontend CSS / ads.txt / app-ads.txt
759 wp_enqueue_style(
760 'asenha-codemirror',
761 ASENHA_URL . 'assets/css/codemirror/codemirror.min.css',
762 array(),
763 ASENHA_VERSION
764 );
765 wp_enqueue_script(
766 'asenha-codemirror',
767 ASENHA_URL . 'assets/js/codemirror/codemirror.min.js',
768 array('jquery'),
769 ASENHA_VERSION,
770 true
771 );
772 wp_enqueue_script(
773 'asenha-codemirror-htmlmixed-mode',
774 ASENHA_URL . 'assets/js/codemirror/htmlmixed.js',
775 array('asenha-codemirror'),
776 ASENHA_VERSION,
777 true
778 );
779 wp_enqueue_script(
780 'asenha-codemirror-xml-mode',
781 ASENHA_URL . 'assets/js/codemirror/xml.js',
782 array('asenha-codemirror'),
783 ASENHA_VERSION,
784 true
785 );
786 wp_enqueue_script(
787 'asenha-codemirror-javascript-mode',
788 ASENHA_URL . 'assets/js/codemirror/javascript.js',
789 array('asenha-codemirror'),
790 ASENHA_VERSION,
791 true
792 );
793 wp_enqueue_script(
794 'asenha-codemirror-css-mode',
795 ASENHA_URL . 'assets/js/codemirror/css.js',
796 array('asenha-codemirror'),
797 ASENHA_VERSION,
798 true
799 );
800 wp_enqueue_script(
801 'asenha-codemirror-markdown-mode',
802 ASENHA_URL . 'assets/js/codemirror/markdown.js',
803 array('asenha-codemirror'),
804 ASENHA_VERSION,
805 true
806 );
807 // DataTables. In use, e.g. for Security >> Limit Login Attempts
808 wp_enqueue_style(
809 'asenha-datatables',
810 ASENHA_URL . 'assets/css/datatables/datatables.min.css',
811 array(),
812 ASENHA_VERSION
813 );
814 wp_enqueue_script(
815 'asenha-datatables',
816 ASENHA_URL . 'assets/js/datatables/datatables.min.js',
817 array('jquery'),
818 ASENHA_VERSION,
819 false
820 );
821 // Add WP media library assets
822 wp_enqueue_media();
823 // Add WP color picker assets
824 wp_enqueue_style( 'wp-color-picker' );
825 wp_enqueue_script( 'wp-color-picker' );
826 // We force loading the uncompressed version of TinyMCE. This ensures we load 'wp-tinymce-root' and then 'wp-tinymce',
827 // which prevents issue where the Visual tab is unusable in some scenarios
828 $wp_scripts = wp_scripts();
829 $wp_scripts->remove( 'wp-tinymce' );
830 wp_register_tinymce_scripts( $wp_scripts, true );
831 $admin_page_script_dependencies = array(
832 'asenha-jsticky',
833 'asenha-jbox',
834 'asenha-js-cookie',
835 'asenha-codemirror-htmlmixed-mode',
836 'asenha-codemirror-xml-mode',
837 'asenha-codemirror-javascript-mode',
838 'asenha-codemirror-css-mode',
839 'asenha-codemirror-markdown-mode',
840 'asenha-datatables',
841 'wp-color-picker',
842 'wp-mediaelement',
843 'wp-tinymce-root',
844 'wp-tinymce'
845 );
846 // Main style and script for the admin page
847 wp_enqueue_style(
848 'asenha-admin-page',
849 ASENHA_URL . 'assets/css/admin-page.css',
850 array(
851 'asenha-jbox',
852 'asenha-codemirror',
853 'asenha-datatables',
854 'wp-color-picker'
855 ),
856 ASENHA_VERSION
857 );
858 wp_enqueue_script(
859 'asenha-admin-page',
860 ASENHA_URL . 'assets/js/admin-page.js',
861 $admin_page_script_dependencies,
862 ASENHA_VERSION,
863 false
864 );
865 $jsvars = array(
866 'nonce' => wp_create_nonce( 'asenha-' . get_current_user_id() ),
867 'siteUrl' => get_site_url(),
868 'wpcontentUrl' => content_url(),
869 'mediaFrameTitle' => __( 'Select an Image', 'admin-site-enhancements' ),
870 'mediaFrameButtonText' => __( 'Use Selected Image', 'admin-site-enhancements' ),
871 'resetMenuNonce' => wp_create_nonce( 'reset-menu-nonce' ),
872 'sendTestEmailNonce' => wp_create_nonce( 'send-test-email-nonce_' . get_current_user_id() ),
873 'formBuilderSendTestEmailNonce' => wp_create_nonce( 'formbuilder_ajax' ),
874 'expandText' => __( 'Expand', 'admin-site-enhancements' ),
875 'collapseText' => __( 'Collapse', 'admin-site-enhancements' ),
876 'dataTable' => array(
877 'emptyTable' => __( 'No data available in table', 'admin-site-enhancements' ),
878 'info' => __( 'Showing _START_ to _END_ of _TOTAL_ entries', 'admin-site-enhancements' ),
879 'infoEmpty' => __( 'Showing 0 to 0 of 0 entries', 'admin-site-enhancements' ),
880 'infoFiltered' => __( '(filtered from _MAX_ total entries)', 'admin-site-enhancements' ),
881 'lengthMenu' => __( 'Show _MENU_ entries', 'admin-site-enhancements' ),
882 'search' => __( 'Search:', 'admin-site-enhancements' ),
883 'zeroRecords' => __( 'No matching records found', 'admin-site-enhancements' ),
884 'paginate' => array(
885 'first' => __( 'First', 'admin-site-enhancements' ),
886 'last' => __( 'Last', 'admin-site-enhancements' ),
887 'next' => __( 'Next', 'admin-site-enhancements' ),
888 'previous' => __( 'Previous', 'admin-site-enhancements' ),
889 ),
890 ),
891 'limitLoginAttempts' => array(
892 'releaseLockSuccess' => __( 'Lock released for %s.', 'admin-site-enhancements' ),
893 'releaseLockError' => __( 'Could not release lock. Please try again.', 'admin-site-enhancements' ),
894 ),
895 );
896 wp_localize_script( 'asenha-admin-page', 'adminPageVars', $jsvars );
897 }
898 // Enqueue on all wp-admin
899 wp_enqueue_style(
900 'asenha-wp-admin',
901 ASENHA_URL . 'assets/css/wp-admin.css',
902 array(),
903 ASENHA_VERSION
904 );
905 // Content Management >> Show IDs, for list tables in wp-admin, e.g. All Posts page
906 if ( false !== strpos( $current_screen->base, 'edit' ) || false !== strpos( $current_screen->base, 'users' ) || false !== strpos( $current_screen->base, 'upload' ) ) {
907 wp_enqueue_style(
908 'asenha-list-table',
909 ASENHA_URL . 'assets/css/list-table.css',
910 array(),
911 ASENHA_VERSION
912 );
913 }
914 // Content Management >> Enable Media Replacement
915 if ( $current_screen->base == 'upload' || $current_screen->id == 'attachment' ) {
916 // wp_enqueue_style( 'asenha-jbox', ASENHA_URL . 'assets/css/jBox.all.min.css', array(), ASENHA_VERSION );
917 // wp_enqueue_script( 'asenha-jbox', ASENHA_URL . 'assets/js/jBox.all.min.js', array(), ASENHA_VERSION, false );
918 wp_enqueue_style(
919 'asenha-media-replace',
920 ASENHA_URL . 'assets/css/media-replace.css',
921 array(),
922 ASENHA_VERSION
923 );
924 wp_enqueue_script(
925 'asenha-media-replace',
926 ASENHA_URL . 'assets/js/media-replace.js',
927 array(),
928 ASENHA_VERSION,
929 false
930 );
931 $media_replace = array(
932 'selectMediaText' => __( 'Select New Media File', 'admin-site-enhancements' ),
933 'performReplacementText' => __( 'Perform Replacement', 'admin-site-enhancements' ),
934 );
935 wp_localize_script( 'asenha-media-replace', 'mediaReplace', $media_replace );
936 }
937 // Admin Interface >> Admin Menu Organizer
938 if ( 'settings_page_admin-menu-organizer' == $current_screen->base ) {
939 // Re-register and re-enqueue jQuery UI Core and plugins required for sortable, draggable and droppable when ordering menu items
940 wp_deregister_script( 'jquery-ui-core' );
941 wp_register_script(
942 'jquery-ui-core',
943 get_site_url() . '/wp-includes/js/jquery/ui/core.min.js',
944 array('jquery'),
945 ASENHA_VERSION,
946 false
947 );
948 wp_enqueue_script( 'jquery-ui-core' );
949 if ( version_compare( $wp_version, '5.6.0', '>=' ) ) {
950 wp_deregister_script( 'jquery-ui-mouse' );
951 wp_register_script(
952 'jquery-ui-mouse',
953 get_site_url() . '/wp-includes/js/jquery/ui/mouse.min.js',
954 array('jquery-ui-core'),
955 ASENHA_VERSION,
956 false
957 );
958 wp_enqueue_script( 'jquery-ui-mouse' );
959 } else {
960 wp_deregister_script( 'jquery-ui-widget' );
961 wp_register_script(
962 'jquery-ui-widget',
963 get_site_url() . '/wp-includes/js/jquery/ui/widget.min.js',
964 array('jquery'),
965 ASENHA_VERSION,
966 false
967 );
968 wp_enqueue_script( 'jquery-ui-widget' );
969 wp_deregister_script( 'jquery-ui-mouse' );
970 wp_register_script(
971 'jquery-ui-mouse',
972 get_site_url() . '/wp-includes/js/jquery/ui/mouse.min.js',
973 array('jquery-ui-core', 'jquery-ui-widget'),
974 ASENHA_VERSION,
975 false
976 );
977 wp_enqueue_script( 'jquery-ui-mouse' );
978 }
979 wp_deregister_script( 'jquery-ui-sortable' );
980 wp_register_script(
981 'jquery-ui-sortable',
982 get_site_url() . '/wp-includes/js/jquery/ui/sortable.min.js',
983 array('jquery-ui-mouse'),
984 ASENHA_VERSION,
985 false
986 );
987 wp_enqueue_script( 'jquery-ui-sortable' );
988 wp_deregister_script( 'jquery-ui-draggable' );
989 wp_register_script(
990 'jquery-ui-draggable',
991 get_site_url() . '/wp-includes/js/jquery/ui/draggable.min.js',
992 array('jquery-ui-mouse'),
993 ASENHA_VERSION,
994 false
995 );
996 wp_enqueue_script( 'jquery-ui-draggable' );
997 wp_deregister_script( 'jquery-ui-droppable' );
998 wp_register_script(
999 'jquery-ui-droppable',
1000 get_site_url() . '/wp-includes/js/jquery/ui/droppable.min.js',
1001 array('jquery-ui-draggable'),
1002 ASENHA_VERSION,
1003 false
1004 );
1005 wp_enqueue_script( 'jquery-ui-droppable' );
1006 // Script to set behaviour and actions of the sortable menu
1007 wp_enqueue_script(
1008 'asenha-custom-admin-menu',
1009 ASENHA_URL . 'assets/js/custom-admin-menu.js',
1010 array('jquery-ui-draggable'),
1011 ASENHA_VERSION,
1012 false
1013 );
1014 wp_enqueue_style(
1015 'asenha-admin-menu-organizer',
1016 ASENHA_URL . 'assets/css/admin-menu-organizer.css',
1017 array(),
1018 ASENHA_VERSION
1019 );
1020 wp_enqueue_script(
1021 'asenha-admin-menu-organizer',
1022 ASENHA_URL . 'assets/js/admin-menu-organizer.js',
1023 array('asenha-custom-admin-menu'),
1024 ASENHA_VERSION,
1025 false
1026 );
1027 $amo_page_vars = array(
1028 'saveMenuNonce' => wp_create_nonce( 'save-menu-nonce' ),
1029 'strings' => array(
1030 'saveChangesError' => __( 'Unable to save changes. Please reload the page and try again.', 'admin-site-enhancements' ),
1031 ),
1032 );
1033 wp_localize_script( 'asenha-custom-admin-menu', 'amoPageVars', $amo_page_vars );
1034 }
1035 // Admin Interface >> Admin Bar Custom Elements (Pro)
1036 if ( $current_screen && 'settings_page_asenha-admin-bar' === $current_screen->base ) {
1037 wp_deregister_script( 'jquery-ui-core' );
1038 wp_register_script(
1039 'jquery-ui-core',
1040 get_site_url() . '/wp-includes/js/jquery/ui/core.min.js',
1041 array('jquery'),
1042 ASENHA_VERSION,
1043 false
1044 );
1045 wp_enqueue_script( 'jquery-ui-core' );
1046 if ( version_compare( $wp_version, '5.6.0', '>=' ) ) {
1047 wp_deregister_script( 'jquery-ui-mouse' );
1048 wp_register_script(
1049 'jquery-ui-mouse',
1050 get_site_url() . '/wp-includes/js/jquery/ui/mouse.min.js',
1051 array('jquery-ui-core'),
1052 ASENHA_VERSION,
1053 false
1054 );
1055 wp_enqueue_script( 'jquery-ui-mouse' );
1056 } else {
1057 wp_deregister_script( 'jquery-ui-widget' );
1058 wp_register_script(
1059 'jquery-ui-widget',
1060 get_site_url() . '/wp-includes/js/jquery/ui/widget.min.js',
1061 array('jquery'),
1062 ASENHA_VERSION,
1063 false
1064 );
1065 wp_enqueue_script( 'jquery-ui-widget' );
1066 wp_deregister_script( 'jquery-ui-mouse' );
1067 wp_register_script(
1068 'jquery-ui-mouse',
1069 get_site_url() . '/wp-includes/js/jquery/ui/mouse.min.js',
1070 array('jquery-ui-core', 'jquery-ui-widget'),
1071 ASENHA_VERSION,
1072 false
1073 );
1074 wp_enqueue_script( 'jquery-ui-mouse' );
1075 }
1076 wp_deregister_script( 'jquery-ui-sortable' );
1077 wp_register_script(
1078 'jquery-ui-sortable',
1079 get_site_url() . '/wp-includes/js/jquery/ui/sortable.min.js',
1080 array('jquery-ui-mouse'),
1081 ASENHA_VERSION,
1082 false
1083 );
1084 wp_enqueue_script( 'jquery-ui-sortable' );
1085 wp_enqueue_style(
1086 'asenha-admin-bar-custom-elements',
1087 ASENHA_URL . 'assets/premium/css/admin-bar-custom-elements.css',
1088 array(),
1089 ASENHA_VERSION
1090 );
1091 wp_enqueue_script(
1092 'asenha-admin-bar-custom-elements',
1093 ASENHA_URL . 'assets/premium/js/admin-bar-custom-elements.js',
1094 array('jquery-ui-sortable'),
1095 ASENHA_VERSION,
1096 false
1097 );
1098 }
1099 // Utilities >> Email Delivery Log
1100 if ( 'tools_page_email-delivery-log' == $hook_suffix ) {
1101 wp_enqueue_style( 'jquery-ui-css', ASENHA_URL . 'assets/premium/css/jquery-ui/jquery-ui.min.css' );
1102 wp_enqueue_style( 'asenha-email-delivery-log', ASENHA_URL . 'assets/premium/css/email-delivery-log.css' );
1103 wp_enqueue_script( 'jquery-ui' );
1104 // wp_enqueue_script( 'jquery-ui-datepicker' );
1105 wp_enqueue_script( 'jquery-ui-tabs' );
1106 wp_enqueue_script( 'asenha-email-delivery-log', ASENHA_URL . 'assets/premium/js/email-delivery-log.js' );
1107 $nonce = wp_create_nonce( 'email-delivery-log' . get_current_user_id() );
1108 wp_localize_script( 'asenha-email-delivery-log', 'emailLog', array(
1109 'nonce' => $nonce,
1110 ) );
1111 }
1112 // Utilities >> Image Sizes Panel∂
1113 if ( 'post' == $current_screen->base && 'attachment' == $current_screen->id ) {
1114 global $post;
1115 // Only enqueue if the attachment is an image
1116 if ( property_exists( $post, 'post_mime_type' ) && false !== strpos( $post->post_mime_type, 'image' ) ) {
1117 wp_enqueue_style( 'asenha-image-sizes-panel', ASENHA_URL . 'assets/css/image-sizes-panel.css' );
1118 }
1119 }
1120 // Code Snippets Manager
1121 if ( 'post' == $current_screen->base && 'asenha_code_snippet' == $current_screen->id || 'edit' == $current_screen->base && 'edit-asenha_code_snippet' == $current_screen->id ) {
1122 }
1123 // Content Management >> Hide Admin Notices
1124 if ( array_key_exists( 'hide_admin_notices', $options ) && $options['hide_admin_notices'] ) {
1125 $hide_for_nonadmins = ( isset( $options['hide_admin_notices_for_nonadmins'] ) ? $options['hide_admin_notices_for_nonadmins'] : false );
1126 $minimum_capability = 'manage_options';
1127 if ( current_user_can( $minimum_capability ) ) {
1128 wp_enqueue_style(
1129 'asenha-jbox',
1130 ASENHA_URL . 'assets/css/jBox.all.min.css',
1131 array(),
1132 ASENHA_VERSION
1133 );
1134 wp_enqueue_script(
1135 'asenha-jbox',
1136 ASENHA_URL . 'assets/js/jBox.all.min.js',
1137 array(),
1138 ASENHA_VERSION,
1139 false
1140 );
1141 wp_enqueue_style(
1142 'asenha-hide-admin-notices',
1143 ASENHA_URL . 'assets/css/hide-admin-notices.css',
1144 array(),
1145 ASENHA_VERSION
1146 );
1147 wp_enqueue_script(
1148 'asenha-hide-admin-notices',
1149 ASENHA_URL . 'assets/js/hide-admin-notices.js',
1150 array('asenha-jbox'),
1151 ASENHA_VERSION,
1152 false
1153 );
1154 }
1155 }
1156 // Utilities >> Multiple User Roles
1157 if ( array_key_exists( 'multiple_user_roles', $options ) && $options['multiple_user_roles'] ) {
1158 if ( 'user-edit.php' == $hook_suffix || 'user-new.php' == $hook_suffix ) {
1159 // Only replace roles dropdown with checkboxes for users that can assign roles to other users, e.g. administrators
1160 if ( current_user_can( 'promote_users', get_current_user_id() ) ) {
1161 wp_enqueue_script(
1162 'asenha-multiple-user-roles',
1163 ASENHA_URL . 'assets/js/multiple-user-roles.js',
1164 array('jquery'),
1165 ASENHA_VERSION,
1166 false
1167 );
1168 }
1169 }
1170 }
1171 $asenha_stats = asenha_get_option_array( ASENHA_SLUG_U . '_stats', false );
1172 $hide_promo_nudge = false;
1173 $is_yearend_promo_period = is_yearend_promo_period();
1174 // Pass on ASENHA stats to admin-page.js to determine whether to show support nudge
1175 $current_date = date( 'Y-m-d', time() );
1176 $show_support_nudge = false;
1177 $asenha_stats_localized = array(
1178 'firstSaveDate' => '',
1179 'lastSaveDate' => '',
1180 'saveCount' => 0,
1181 'hideUpgradeNudge' => false,
1182 'hidePromoNudge' => false,
1183 'showSupportNudge' => false,
1184 );
1185 if ( !empty( $asenha_stats ) ) {
1186 $hide_upgrade_nudge = ( isset( $asenha_stats['upgrade_nudge_dismissed'] ) ? $asenha_stats['upgrade_nudge_dismissed'] : false );
1187 $hide_promo_nudge = ( isset( $asenha_stats['promo_nudge_dismissed'] ) ? $asenha_stats['promo_nudge_dismissed'] : false );
1188 $have_supported = ( isset( $asenha_stats['have_supported'] ) ? $asenha_stats['have_supported'] : false );
1189 $changes_saved = ( isset( $_GET['settings-updated'] ) && 'true' == sanitize_text_field( $_GET['settings-updated'] ) ? true : false );
1190 $save_count = ( isset( $asenha_stats['save_count'] ) ? $asenha_stats['save_count'] : 0 );
1191 // Compensate for redirect from settings-updated=true URL
1192 if ( $changes_saved ) {
1193 $save_count = $save_count + 1;
1194 } else {
1195 $save_count = $save_count;
1196 }
1197 $saves_to_nudge_support = 10;
1198 if ( $save_count < $saves_to_nudge_support ) {
1199 $save_count_modulo = -1;
1200 } else {
1201 $save_count_modulo = $save_count % $saves_to_nudge_support;
1202 }
1203 // User have not supported ASE
1204 if ( false === $have_supported ) {
1205 // Support nudge have not been dismissed
1206 if ( isset( $asenha_stats['support_nudge_dismissed'] ) && false === $asenha_stats['support_nudge_dismissed'] ) {
1207 // Show support nudge after every x saves
1208 if ( $save_count_modulo >= 0 ) {
1209 $show_support_nudge = true;
1210 } else {
1211 $show_support_nudge = false;
1212 }
1213 if ( $show_support_nudge && $save_count_modulo >= 0 ) {
1214 $asenha_stats['support_nudge_last_shown_date'] = $current_date;
1215 $asenha_stats['support_nudge_last_shown_save_count'] = $save_count;
1216 update_option( ASENHA_SLUG_U . '_stats', $asenha_stats, false );
1217 }
1218 } else {
1219 if ( $save_count_modulo == 0 ) {
1220 $support_nudge_last_shown_save_count = ( isset( $asenha_stats['support_nudge_last_shown_save_count'] ) ? $asenha_stats['support_nudge_last_shown_save_count'] : 0 );
1221 if ( $save_count > $support_nudge_last_shown_save_count ) {
1222 $asenha_stats['support_nudge_dismissed'] = false;
1223 update_option( ASENHA_SLUG_U . '_stats', $asenha_stats, false );
1224 $show_support_nudge = true;
1225 } else {
1226 $show_support_nudge = false;
1227 }
1228 } else {
1229 $show_support_nudge = false;
1230 }
1231 }
1232 }
1233 $first_save_date = ( isset( $asenha_stats['first_save_date'] ) ? $asenha_stats['first_save_date'] : '' );
1234 $last_save_date = ( isset( $asenha_stats['last_save_date'] ) ? $asenha_stats['last_save_date'] : '' );
1235 $asenha_stats_localized = array(
1236 'firstSaveDate' => $first_save_date,
1237 'lastSaveDate' => $last_save_date,
1238 'saveCount' => $save_count,
1239 'isYearEndPromoPeriod' => $is_yearend_promo_period,
1240 'hideUpgradeNudge' => $hide_upgrade_nudge,
1241 'hidePromoNudge' => $hide_promo_nudge,
1242 'showSupportNudge' => $show_support_nudge,
1243 );
1244 }
1245 wp_localize_script( 'asenha-admin-page', 'asenhaStats', $asenha_stats_localized );
1246 }
1247
1248 /**
1249 * Enqueue block editor scripts and styles.
1250 *
1251 * Loaded via the `enqueue_block_editor_assets` hook so assets are scoped
1252 * strictly to block-editor post-edit screens (post.php / post-new.php).
1253 *
1254 * @since 7.11.0
1255 */
1256 function asenha_block_editor_scripts() {
1257 $current_screen = get_current_screen();
1258 // Only load on post edit / new post block editor screens.
1259 if ( !$current_screen instanceof \WP_Screen || 'post' !== $current_screen->base || !method_exists( $current_screen, 'is_block_editor' ) || !$current_screen->is_block_editor() ) {
1260 return;
1261 }
1262 wp_enqueue_style(
1263 'asenha-wp-block-editor',
1264 ASENHA_URL . 'assets/css/wp-block-editor.css',
1265 array(),
1266 ASENHA_VERSION
1267 );
1268 }
1269
1270 /**
1271 * Inline CSS for Admin Menu Organizer in all wp-admin pages. Previously loaded externally as part of wp-admin.css file
1272 *
1273 * @since 7.6.11
1274 */
1275 function asenha_admin_menu_organizer_css() {
1276 ?>
1277 <style type="text/css">
1278 /* Admin Interface >> Admin Menu Organizer */
1279 #adminmenuwrap {
1280 height: auto !important;
1281 }
1282
1283 .toplevel_page_wpide #adminmenuwrap {
1284 height: calc(100vh - var(--wpide-admin-bar-height)) !important;
1285 } /* Fix for when in WPIDE plugin's menu / admin page */
1286
1287 /* Hide "Show Less" toggle by default to avoid initial flash before JS runs. */
1288 #toplevel_page_asenha_hide_hidden_menu {
1289 display: none;
1290 }
1291
1292 .current.menu-top.hidden,
1293 .wp-has-current-submenu.hidden {
1294 display: list-item;
1295 }
1296
1297 #adminmenu a.menu-top.hidden,
1298 ul#adminmenu a.wp-has-current-submenu.hidden {
1299 display: block;
1300 }
1301
1302 /*! <fs_premium_only> */
1303 .always-hidden {
1304 display: none !important;
1305 }
1306
1307 #adminmenu .wp-submenu a.hidden {
1308 display: none;
1309 }
1310 /*! </fs_premium_only> */
1311 </style>
1312 <?php
1313 }
1314
1315 /**
1316 * Dequeue scripts that prevents ASE settings page from working properly. Usually from plugins.
1317 *
1318 * @since 6.3.3
1319 */
1320 function asenha_dequeue_scritps() {
1321 if ( is_asenha() ) {
1322 // https://wordpress.org/plugins/user-activity-log/
1323 wp_dequeue_script( 'chats-js' );
1324 wp_dequeue_script( 'custom_wp_admin_js' );
1325 // https://wordpress.org/plugins/print-invoices-packing-slip-labels-for-woocommerce/
1326 wp_dequeue_script( 'print-invoices-packing-slip-labels-for-woocommerce' );
1327 wp_dequeue_script( 'print-invoices-packing-slip-labels-for-woocommerce-form-wizard' );
1328 // https://wordpress.org/plugins/wp-reading-progress/
1329 wp_dequeue_script( 'ruigehond006_admin_javascript' );
1330 // WordPress Mentions Légales plugin v1.2.3 by Jean-Baptiste Aramendy - http://jba-development.fr/
1331 wp_dequeue_script( 'jquery-ui' );
1332 wp_dequeue_script( 'wordpress-mentions-legales' );
1333 // https://wordpress.org/plugins/us-weather-widget-willyweather/
1334 wp_dequeue_script( 'self' );
1335 // iThemes Security Pro / Solid Security Pro
1336 wp_dequeue_script( 'itsec-core-admin-notices' );
1337 // WPML
1338 wp_dequeue_script( 'wpml-ate-jobs-sync-ui' );
1339 wp_dequeue_script( 'wpml-purify' );
1340 wp_dequeue_script( 'sitepress-scripts' );
1341 wp_dequeue_script( 'sitepress' );
1342 wp_dequeue_script( 'wpml-dismiss-notice' );
1343 wp_dequeue_script( 'wpml-tm-scripts' );
1344 wp_dequeue_script( 'otgs-installer-components-save-setting' );
1345 wp_dequeue_script( 'installer-dismiss-nag' );
1346 wp_dequeue_script( 'install-recommended_plugin' );
1347 wp_dequeue_script( 'icl-admin-notifier' );
1348 wp_dequeue_script( 'otgsPopoverTooltip' );
1349 // WPML String Translation
1350 wp_dequeue_script( 'wpml-theme-plugin-localization-scan' );
1351 // Asset Cleanup
1352 wp_dequeue_script( 'wpassetcleanup-script' );
1353 }
1354 }
1355
1356 /**
1357 * Enqueue public scripts
1358 *
1359 * @since 3.9.0
1360 */
1361 function asenha_public_scripts( $hook_suffix ) {
1362 // Get all WP Enhancements options, default to empty array in case it's not been created yet
1363 $options = get_option( 'admin_site_enhancements', array() );
1364 // External Permalinks
1365 $enable_external_permalinks = ( array_key_exists( 'enable_external_permalinks', $options ) ? $options['enable_external_permalinks'] : false );
1366 if ( $enable_external_permalinks ) {
1367 wp_enqueue_script(
1368 'asenha-public',
1369 ASENHA_URL . 'assets/js/external-permalinks.js',
1370 array(),
1371 ASENHA_VERSION,
1372 false
1373 );
1374 wp_localize_script( 'asenha-public', 'phpVars', array(
1375 'externalPermalinksEnabled' => $enable_external_permalinks,
1376 ) );
1377 }
1378 // Media Categories
1379 $enable_media_categories = ( array_key_exists( 'enable_media_categories', $options ) ? $options['enable_media_categories'] : false );
1380 if ( $enable_media_categories && !is_admin() && is_user_logged_in() ) {
1381 wp_enqueue_style(
1382 'asenha-media-categories-frontend',
1383 ASENHA_URL . 'assets/css/media-categories-frontend.css',
1384 array(),
1385 ASENHA_VERSION
1386 );
1387 }
1388 // Media Replacement
1389 $enable_media_replacement = ( array_key_exists( 'enable_media_replacement', $options ) ? $options['enable_media_replacement'] : false );
1390 if ( $enable_media_replacement && !is_admin() && is_user_logged_in() ) {
1391 wp_enqueue_style(
1392 'asenha-media-replace-frontend',
1393 ASENHA_URL . 'assets/css/media-replace-frontend.css',
1394 array(),
1395 ASENHA_VERSION
1396 );
1397 }
1398 }
1399
1400 /**
1401 * Add admin bar styles for wp-admin and frontend
1402 *
1403 * @since 6.2.1
1404 */
1405 function asenha_admin_bar_item_js_css() {
1406 if ( is_user_logged_in() ) {
1407 ?>
1408 <!--<script></script>-->
1409 <style>
1410 #wp-admin-bar-user-info .avatar {
1411 object-fit: cover;
1412 }
1413 </style>
1414 <?php
1415 }
1416 }
1417
1418 /**
1419 * Add 'Access now' plugin action link.
1420 *
1421 * @since 1.0.0
1422 */
1423 function asenha_plugin_action_links( $links ) {
1424 $settings_link = '<a href="tools.php?page=' . ASENHA_SLUG . '">' . __( 'Configure', 'admin-site-enhancements' ) . '</a>';
1425 array_unshift( $links, $settings_link );
1426 return $links;
1427 }
1428
1429 /**
1430 * Modify footer text
1431 *
1432 * @since 1.0.0
1433 */
1434 function asenha_footer_text() {
1435 // Show nothing
1436 ?>
1437 <?php
1438 }
1439
1440 /**
1441 * Change WP version number text in footer
1442 *
1443 * @since 4.8.3
1444 */
1445 function asenha_footer_version_text() {
1446 ?>
1447 ASE <a href="https://www.wpase.com/documentation/changelog/" target="_blank">v<?php
1448 echo esc_html( ASENHA_VERSION );
1449 ?></a>
1450 <?php
1451 }
1452
1453 /**
1454 * Check if current screen is this plugin's main page
1455 *
1456 * @since 1.0.0
1457 */
1458 function is_asenha() {
1459 $request_uri = sanitize_text_field( $_SERVER['REQUEST_URI'] );
1460 // e.g. /wp-admin/index.php?page=page-slug
1461 if ( strpos( $request_uri, 'page=' . ASENHA_SLUG ) !== false ) {
1462 return true;
1463 // Yes, this is the plugin's main page
1464 } else {
1465 return false;
1466 // Nope, this is NOT the plugin's page
1467 }
1468 }
1469
1470 /**
1471 * Mark that user have supported ASE
1472 *
1473 * @since 5.2.7
1474 */
1475 function asenha_have_supported() {
1476 if ( isset( $_REQUEST ) && current_user_can( 'manage_options' ) ) {
1477 if ( wp_verify_nonce( sanitize_text_field( $_REQUEST['nonce'] ), 'asenha-' . get_current_user_id() ) ) {
1478 $asenha_stats = asenha_get_option_array( ASENHA_SLUG_U . '_stats', false );
1479 $asenha_stats['have_supported'] = true;
1480 $asenha_stats['support_nudge_dismissed'] = true;
1481 $success = update_option( ASENHA_SLUG_U . '_stats', $asenha_stats, false );
1482 if ( $success ) {
1483 echo json_encode( array(
1484 'success' => true,
1485 ) );
1486 } else {
1487 echo json_encode( array(
1488 'success' => false,
1489 ) );
1490 }
1491 }
1492 }
1493 }
1494
1495 /**
1496 * Dismiss support nudge
1497 *
1498 * @since 5.8.2
1499 */
1500 function asenha_dismiss_upgrade_nudge() {
1501 if ( isset( $_REQUEST ) && current_user_can( 'manage_options' ) ) {
1502 if ( wp_verify_nonce( sanitize_text_field( $_REQUEST['nonce'] ), 'asenha-' . get_current_user_id() ) ) {
1503 $current_date = date( 'Y-m-d', time() );
1504 $asenha_stats = asenha_get_option_array( ASENHA_SLUG_U . '_stats', false );
1505 $asenha_stats['upgrade_nudge_dismissed'] = true;
1506 $asenha_stats['upgrade_nudge_dismissed_date'] = $current_date;
1507 $success = update_option( ASENHA_SLUG_U . '_stats', $asenha_stats, false );
1508 if ( $success ) {
1509 echo json_encode( array(
1510 'success' => true,
1511 ) );
1512 } else {
1513 echo json_encode( array(
1514 'success' => false,
1515 ) );
1516 }
1517 }
1518 }
1519 }
1520
1521 /**
1522 * Dismiss promo nudge
1523 *
1524 * @since 7.5.1
1525 */
1526 function asenha_dismiss_promo_nudge() {
1527 if ( isset( $_REQUEST ) && current_user_can( 'manage_options' ) ) {
1528 if ( wp_verify_nonce( sanitize_text_field( $_REQUEST['nonce'] ), 'asenha-' . get_current_user_id() ) ) {
1529 $current_date = date( 'Y-m-d', time() );
1530 $asenha_stats = asenha_get_option_array( ASENHA_SLUG_U . '_stats', false );
1531 $asenha_stats['promo_nudge_dismissed'] = true;
1532 $asenha_stats['promo_nudge_dismissed_date'] = $current_date;
1533 $success = update_option( ASENHA_SLUG_U . '_stats', $asenha_stats, false );
1534 if ( $success ) {
1535 echo json_encode( array(
1536 'success' => true,
1537 ) );
1538 } else {
1539 echo json_encode( array(
1540 'success' => false,
1541 ) );
1542 }
1543 }
1544 }
1545 }
1546
1547 /**
1548 * Dismiss support nudge
1549 *
1550 * @since 5.2.7
1551 */
1552 function asenha_dismiss_support_nudge() {
1553 if ( isset( $_REQUEST ) && current_user_can( 'manage_options' ) ) {
1554 if ( wp_verify_nonce( sanitize_text_field( $_REQUEST['nonce'] ), 'asenha-' . get_current_user_id() ) ) {
1555 $asenha_stats = asenha_get_option_array( ASENHA_SLUG_U . '_stats', false );
1556 $asenha_stats['support_nudge_dismissed'] = true;
1557 $success = update_option( ASENHA_SLUG_U . '_stats', $asenha_stats, false );
1558 if ( $success ) {
1559 echo json_encode( array(
1560 'success' => true,
1561 ) );
1562 } else {
1563 echo json_encode( array(
1564 'success' => false,
1565 ) );
1566 }
1567 }
1568 }
1569 }
1570
1571 /**
1572 * Release lock for an IP address in Limit Login Attempts.
1573 *
1574 * Deletes the IP entry from the failed login attempts table, which immediately
1575 * releases the lockout for that IP address.
1576 *
1577 * @since 8.3.1
1578 */
1579 function asenha_release_login_lock() {
1580 if ( !current_user_can( 'manage_options' ) ) {
1581 wp_send_json_error( array(
1582 'message' => __( 'Insufficient permissions.', 'admin-site-enhancements' ),
1583 ) );
1584 }
1585 if ( !isset( $_REQUEST['nonce'] ) || !isset( $_REQUEST['ip_address'] ) ) {
1586 wp_send_json_error( array(
1587 'message' => __( 'Missing required data.', 'admin-site-enhancements' ),
1588 ) );
1589 }
1590 $nonce = sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) );
1591 if ( !wp_verify_nonce( $nonce, 'asenha-' . get_current_user_id() ) ) {
1592 wp_send_json_error( array(
1593 'message' => __( 'Invalid security token.', 'admin-site-enhancements' ),
1594 ) );
1595 }
1596 $ip_address = sanitize_text_field( wp_unslash( $_REQUEST['ip_address'] ) );
1597 $common_methods = new \ASENHA\Classes\Common_Methods();
1598 if ( !$common_methods->is_ip_valid( $ip_address ) ) {
1599 wp_send_json_error( array(
1600 'message' => __( 'Invalid IP address.', 'admin-site-enhancements' ),
1601 ) );
1602 }
1603 global $wpdb;
1604 $table_name = $wpdb->prefix . 'asenha_failed_logins';
1605 $deleted = $wpdb->delete( $table_name, array(
1606 'ip_address' => $ip_address,
1607 ), array('%s') );
1608 if ( false === $deleted ) {
1609 wp_send_json_error( array(
1610 'message' => __( 'Could not release lock.', 'admin-site-enhancements' ),
1611 ) );
1612 }
1613 wp_send_json_success( array(
1614 'deleted' => (int) $deleted,
1615 ) );
1616 }
1617