Second commit
This commit is contained in:
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
/**
|
||||
* Main plugin bootstrap.
|
||||
*
|
||||
* @package TT5_Light_Dark_Toggle
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* TT5 Light/Dark Toggle plugin.
|
||||
*/
|
||||
class TT5_LDT {
|
||||
|
||||
/**
|
||||
* Initialize hooks.
|
||||
*/
|
||||
public static function init() {
|
||||
add_action( 'plugins_loaded', array( __CLASS__, 'bootstrap' ) );
|
||||
add_action( 'admin_notices', array( __CLASS__, 'admin_theme_notice' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load frontend assets when the active theme is Twenty Twenty-Five.
|
||||
*/
|
||||
public static function bootstrap() {
|
||||
if ( ! self::is_target_theme() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_assets' ) );
|
||||
add_action( 'wp_footer', array( __CLASS__, 'render_toggle' ), 5 );
|
||||
add_action( 'wp_head', array( __CLASS__, 'inline_preference_script' ), 0 );
|
||||
|
||||
add_action( 'wp_ajax_tt5_ldt_save_scheme', array( __CLASS__, 'ajax_save_scheme' ) );
|
||||
add_action( 'wp_ajax_nopriv_tt5_ldt_save_scheme', array( __CLASS__, 'ajax_save_scheme' ) );
|
||||
|
||||
add_action( 'show_user_profile', array( __CLASS__, 'render_profile_field' ) );
|
||||
add_action( 'edit_user_profile', array( __CLASS__, 'render_profile_field' ) );
|
||||
add_action( 'personal_options_update', array( __CLASS__, 'save_profile_field' ) );
|
||||
add_action( 'edit_user_profile_update', array( __CLASS__, 'save_profile_field' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether Twenty Twenty-Five (or a child of it) is active.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_target_theme() {
|
||||
$theme = wp_get_theme();
|
||||
return 'twentytwentyfive' === $theme->get_template();
|
||||
}
|
||||
|
||||
/**
|
||||
* Warn in admin if the theme is not supported.
|
||||
*/
|
||||
public static function admin_theme_notice() {
|
||||
if ( self::is_target_theme() || ! current_user_can( 'switch_themes' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
|
||||
if ( $screen && 'plugins' !== $screen->id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
echo '<div class="notice notice-warning"><p>';
|
||||
echo esc_html__(
|
||||
'TT5 Light/Dark Toggle is active but Twenty Twenty-Five is not the current theme. The toggle only appears with that theme.',
|
||||
'tt5-light-dark-toggle'
|
||||
);
|
||||
echo '</p></div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent flash of wrong theme by applying class before paint.
|
||||
*/
|
||||
public static function inline_preference_script() {
|
||||
$scheme = self::get_initial_scheme();
|
||||
$storage_key = esc_js( TT5_LDT_STORAGE );
|
||||
$cookie_name = esc_js( TT5_LDT_COOKIE );
|
||||
|
||||
?>
|
||||
<script id="tt5-ldt-init">
|
||||
(function () {
|
||||
var storageKey = <?php echo wp_json_encode( TT5_LDT_STORAGE ); ?>;
|
||||
var cookieName = <?php echo wp_json_encode( TT5_LDT_COOKIE ); ?>;
|
||||
var serverScheme = <?php echo wp_json_encode( $scheme ); ?>;
|
||||
var stored = '';
|
||||
try {
|
||||
stored = localStorage.getItem(storageKey) || '';
|
||||
} catch (e) {}
|
||||
if (!stored && document.cookie.indexOf(cookieName + '=') !== -1) {
|
||||
var match = document.cookie.match(new RegExp(cookieName + '=([^;]+)'));
|
||||
stored = match ? decodeURIComponent(match[1]) : '';
|
||||
}
|
||||
var scheme = stored === 'dark' || stored === 'light' ? stored : serverScheme;
|
||||
if (scheme === 'dark') {
|
||||
document.documentElement.classList.add('tt5-ldt-dark');
|
||||
}
|
||||
if (scheme === 'light' || scheme === 'dark') {
|
||||
document.documentElement.setAttribute('data-tt5-scheme', scheme);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve saved scheme for first paint (cookie or user meta only).
|
||||
*
|
||||
* @return string light|dark|empty string when none saved.
|
||||
*/
|
||||
public static function get_initial_scheme() {
|
||||
if ( isset( $_COOKIE[ TT5_LDT_COOKIE ] ) ) {
|
||||
$cookie = sanitize_key( wp_unslash( $_COOKIE[ TT5_LDT_COOKIE ] ) );
|
||||
if ( in_array( $cookie, array( 'light', 'dark' ), true ) ) {
|
||||
return $cookie;
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_user_logged_in() ) {
|
||||
$meta = get_user_meta( get_current_user_id(), TT5_LDT_STORAGE, true );
|
||||
if ( in_array( $meta, array( 'light', 'dark' ), true ) ) {
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue styles and toggle script.
|
||||
*/
|
||||
public static function enqueue_assets() {
|
||||
wp_enqueue_style(
|
||||
'tt5-ldt-dark',
|
||||
TT5_LDT_URL . 'assets/css/dark-theme.css',
|
||||
array(),
|
||||
TT5_LDT_VERSION
|
||||
);
|
||||
|
||||
wp_enqueue_style(
|
||||
'tt5-ldt-toggle',
|
||||
TT5_LDT_URL . 'assets/css/toggle.css',
|
||||
array(),
|
||||
TT5_LDT_VERSION
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'tt5-ldt-toggle',
|
||||
TT5_LDT_URL . 'assets/js/toggle.js',
|
||||
array(),
|
||||
TT5_LDT_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script(
|
||||
'tt5-ldt-toggle',
|
||||
'tt5Ldt',
|
||||
array(
|
||||
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
|
||||
'nonce' => wp_create_nonce( 'tt5_ldt_save' ),
|
||||
'storageKey' => TT5_LDT_STORAGE,
|
||||
'cookieName' => TT5_LDT_COOKIE,
|
||||
'cookiePath' => COOKIEPATH ? COOKIEPATH : '/',
|
||||
'cookieDomain' => COOKIE_DOMAIN,
|
||||
'isLoggedIn' => is_user_logged_in(),
|
||||
'i18n' => array(
|
||||
'light' => __( 'Switch to light mode', 'tt5-light-dark-toggle' ),
|
||||
'dark' => __( 'Switch to dark mode', 'tt5-light-dark-toggle' ),
|
||||
'lightLabel' => __( 'Light mode', 'tt5-light-dark-toggle' ),
|
||||
'darkLabel' => __( 'Dark mode', 'tt5-light-dark-toggle' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Output floating toggle button.
|
||||
*/
|
||||
public static function render_toggle() {
|
||||
$saved = self::get_initial_scheme();
|
||||
$is_dark = 'dark' === $saved;
|
||||
?>
|
||||
<button
|
||||
type="button"
|
||||
id="tt5-ldt-toggle"
|
||||
class="tt5-ldt-toggle"
|
||||
aria-pressed="<?php echo $is_dark ? 'true' : 'false'; ?>"
|
||||
aria-label="<?php echo esc_attr( $is_dark ? __( 'Switch to light mode', 'tt5-light-dark-toggle' ) : __( 'Switch to dark mode', 'tt5-light-dark-toggle' ) ); ?>"
|
||||
title="<?php echo esc_attr( $is_dark ? __( 'Light mode', 'tt5-light-dark-toggle' ) : __( 'Dark mode', 'tt5-light-dark-toggle' ) ); ?>"
|
||||
>
|
||||
<span class="tt5-ldt-toggle__icon tt5-ldt-toggle__icon--sun" aria-hidden="true">☀</span>
|
||||
<span class="tt5-ldt-toggle__icon tt5-ldt-toggle__icon--moon" aria-hidden="true">☾</span>
|
||||
<span class="tt5-ldt-toggle__label"><?php echo esc_html( $is_dark ? __( 'Light', 'tt5-light-dark-toggle' ) : __( 'Dark', 'tt5-light-dark-toggle' ) ); ?></span>
|
||||
</button>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist preference for logged-in users.
|
||||
*/
|
||||
public static function ajax_save_scheme() {
|
||||
check_ajax_referer( 'tt5_ldt_save', 'nonce' );
|
||||
|
||||
$scheme = isset( $_POST['scheme'] ) ? sanitize_key( wp_unslash( $_POST['scheme'] ) ) : '';
|
||||
if ( ! in_array( $scheme, array( 'light', 'dark' ), true ) ) {
|
||||
wp_send_json_error( array( 'message' => 'Invalid scheme' ), 400 );
|
||||
}
|
||||
|
||||
if ( is_user_logged_in() ) {
|
||||
update_user_meta( get_current_user_id(), TT5_LDT_STORAGE, $scheme );
|
||||
}
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional profile field (read-only info).
|
||||
*
|
||||
* @param WP_User $user User object.
|
||||
*/
|
||||
public static function render_profile_field( $user ) {
|
||||
$value = get_user_meta( $user->ID, TT5_LDT_STORAGE, true );
|
||||
if ( ! $value ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<h2><?php esc_html_e( 'Color scheme preference', 'tt5-light-dark-toggle' ); ?></h2>
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th><label><?php esc_html_e( 'Site appearance', 'tt5-light-dark-toggle' ); ?></label></th>
|
||||
<td>
|
||||
<?php echo esc_html( 'dark' === $value ? __( 'Dark mode', 'tt5-light-dark-toggle' ) : __( 'Light mode', 'tt5-light-dark-toggle' ) ); ?>
|
||||
<p class="description"><?php esc_html_e( 'Saved when you use the front-end light/dark toggle.', 'tt5-light-dark-toggle' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Profile save noop (preference saved via AJAX).
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
*/
|
||||
public static function save_profile_field( $user_id ) {
|
||||
if ( ! current_user_can( 'edit_user', $user_id ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user