12 Commits

Author SHA1 Message Date
7e806ab5ed woodpecker test workflow updated
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2025-06-02 16:58:15 +04:00
33ef75695c woodpecker pipeline file renamed 2025-06-02 16:48:28 +04:00
0fc2009391 fix: Standardize toggle switch behavior across plugin - Standardize the Access Manager toggle switches to match working implementations - Use the standard update_option AJAX handler for main toggles - Add new toggle settings to allowed options in Admin Manager - Ensure accordion panels stay open/closed and show saved settings correctly - Implement consistent notification display with proper placement - Synchronize role checkboxes with main toggle switches - Fix the Settings UI with improved styling and behavior 2025-03-25 18:10:54 +00:00
3426a5f4ae fix: Accordion and toggle switch behavior - Fix accordion panels to stay open when clicked - Prevent toggle switch from reverting back to 'on' state - Ensure consistent 'Error Saving' message - Fix event propagation issues causing double triggers - Remove redundant event handlers causing yo-yo effect 2025-03-25 18:01:48 +00:00
bd3a19b04a refactor: Improve access control settings UI and functionality - Fix double notification issue when toggling feature - Improve AJAX handling with better error handling - Create consistent component design for role checkboxes - Improve notification display and positioning - Enhance toggle component with better header/content styling - Add responsive design for all screen sizes - Ensure expansion/collapse works correctly 2025-03-25 17:29:08 +00:00
e794126197 fix: Access control settings improvements - Revert role checkboxes layout to previous styling - Fix settings saving functionality with proper result checking - Update error message to 'Error Saving' - Only load functionality when settings are enabled - Use empty arrays as defaults for role settings 2025-03-25 17:13:53 +00:00
00134f8ffc fix: Improve access control settings UI and functionality - Add AJAX saving for toggle switches and role checkboxes - Fix notification styling and layout issues - Shorten error message to 'Error Saving' - Add proper spacing for notifications to prevent layout shifts - Ensure labels have minimum width to prevent wrapping - Add success/error notifications for all setting changes 2025-03-25 13:21:10 +00:00
57398ea7b4 feat: Add Admin Bar & Dashboard Control functionality - Add new Access Manager class for handling admin bar and dashboard access control - Implement role-based admin bar visibility control - Implement role-based dashboard access restrictions - Add expandable settings panels for role selection - Add responsive grid layout for role checkboxes - Set Guest, Subscriber, and Customer roles as default restricted roles - Update Settings Manager to display access control settings in advanced tab 2025-03-25 12:42:28 +00:00
0693b438ed Update toggle switches and UI elements to use WordPress standard green color 2025-03-25 03:36:00 +00:00
23364d40fc Update version to v0.2.4 2025-03-25 03:27:38 +00:00
d146721f3a Use inline saved lozenge instead of admin notice for color scheme toggle 2025-03-25 03:20:54 +00:00
39c8560f1e Fix admin color scheme toggle to refresh page and show success notification 2025-03-25 03:18:53 +00:00
8 changed files with 669 additions and 246 deletions

8
.woodpecker.yaml Normal file
View File

@ -0,0 +1,8 @@
steps:
- name: test
image: php:7.4-cli
commands:
- apt-get update && apt-get install -y git
- php -l wp-allstars-plugin.php # Syntax check
- find . -name *.php -exec php -l {} \;
- echo "Basic linting passed"

View File

@ -1,9 +0,0 @@
pipeline:
test:
image: php:7.4-cli
commands:
- apt-get update && apt-get install -y git
- php -l wpa-superstar-plugin.php # Syntax check
- php -l admin/settings.php
- php -l includes/speed-functions.php
- echo "Basic linting passed"

View File

@ -156,7 +156,7 @@
} }
input:checked + .wp-toggle-slider { input:checked + .wp-toggle-slider {
background-color: #2271b1; background-color: #00a32a; /* WordPress standard green color */
} }
input:checked + .wp-toggle-slider:before { input:checked + .wp-toggle-slider:before {
@ -209,7 +209,7 @@ input:checked + .wp-toggle-slider:before {
.wp-setting-base:hover, .wp-setting-base:hover,
.wp-setting-row:hover, .wp-setting-row:hover,
.wp-allstars-toggle:hover { .wp-allstars-toggle:hover {
border-color: #2271b1; border-color: #00a32a;
box-shadow: 0 2px 6px rgba(0,0,0,0.15); box-shadow: 0 2px 6px rgba(0,0,0,0.15);
} }
@ -333,8 +333,8 @@ input:checked + .wp-toggle-slider:before {
.wp-allstars-setting-row input[type="text"]:focus, .wp-allstars-setting-row input[type="text"]:focus,
.wp-allstars-setting-row input[type="number"]:focus, .wp-allstars-setting-row input[type="number"]:focus,
.wp-allstars-setting-row textarea:focus { .wp-allstars-setting-row textarea:focus {
border-color: #2271b1; border-color: #00a32a;
box-shadow: 0 0 0 1px #2271b1; box-shadow: 0 0 0 1px #00a32a;
outline: 2px solid transparent; outline: 2px solid transparent;
} }
@ -733,6 +733,9 @@ input:checked + .wp-toggle-slider:before {
box-sizing: border-box; box-sizing: border-box;
position: relative; position: relative;
transform: translateY(-3px); transform: translateY(-3px);
white-space: nowrap;
min-width: 60px;
justify-content: center;
} }
.wp-setting-notification.error { .wp-setting-notification.error {
@ -758,6 +761,105 @@ input:checked + .wp-toggle-slider:before {
line-height: 1.4; line-height: 1.4;
} }
/* Role Checkboxes - Consistent component design */
.wp-allstars-role-checkboxes {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 10px;
}
.wp-allstars-role-checkbox {
flex: 0 0 calc(33.333% - 10px);
max-width: calc(33.333% - 10px);
display: flex;
align-items: center;
gap: 8px;
padding: 8px 10px;
background: #f8f9fa;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s ease;
}
.wp-allstars-role-checkbox:hover {
background: #f0f0f1;
border-color: #2271b1;
}
.wp-allstars-role-checkbox input[type="checkbox"] {
margin: 0;
}
.wp-allstars-role-checkbox span {
font-size: 13px;
color: #50575e;
}
/* Responsive adjustments */
@media screen and (max-width: 992px) {
.wp-allstars-role-checkbox {
flex: 0 0 calc(50% - 10px);
max-width: calc(50% - 10px);
}
}
@media screen and (max-width: 782px) {
.wp-allstars-role-checkbox {
flex: 0 0 calc(50% - 8px);
max-width: calc(50% - 8px);
padding: 6px 8px;
}
.wp-allstars-role-checkbox span {
font-size: 12px;
}
}
@media screen and (max-width: 480px) {
.wp-allstars-role-checkbox {
flex: 0 0 100%;
max-width: 100%;
}
}
/* Enhanced toggle component */
.wp-allstars-toggle {
position: relative;
overflow: hidden;
}
.wp-allstars-toggle-header[aria-expanded="true"] {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
/* Better settings panel styling */
.wp-allstars-toggle-settings {
padding: 20px;
background: #f8f9fa;
border-top: 1px solid #ddd;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
}
.wp-allstars-setting-row {
margin-bottom: 20px;
}
.wp-allstars-setting-row:last-child {
margin-bottom: 0;
}
.wp-allstars-setting-row label {
display: block;
margin-bottom: 8px;
font-size: 14px;
font-weight: 600;
color: #1d2327;
}
@keyframes fadeIn { @keyframes fadeIn {
from { opacity: 0; } from { opacity: 0; }
to { opacity: 1; } to { opacity: 1; }

View File

@ -0,0 +1,450 @@
<?php
/**
* WP ALLSTARS Access Manager
*
* Handles access control features like admin bar and dashboard access
*
* @package WP_ALLSTARS
* @since 0.2.5
*/
if (!defined('ABSPATH')) {
exit; // Exit if accessed directly
}
class WP_Allstars_Access_Manager {
/**
* Initialize the class
*/
public static function init() {
add_action('admin_init', array(__CLASS__, 'register_settings'));
add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueue_scripts'));
// Add hooks for admin bar and dashboard access control
add_action('init', array(__CLASS__, 'setup_access_control'));
// Add AJAX handlers
add_action('wp_ajax_wp_allstars_update_access_setting', array(__CLASS__, 'handle_access_setting_update'));
}
/**
* Register settings for access control
*/
public static function register_settings() {
register_setting('wp_allstars_access', 'wp_allstars_hide_admin_bar_roles');
register_setting('wp_allstars_access', 'wp_allstars_restrict_dashboard_roles');
}
/**
* Enqueue scripts for the access control settings
*
* @param string $hook Current admin page hook
*/
public static function enqueue_scripts($hook) {
if ('settings_page_wp-allstars' !== $hook) {
return;
}
wp_enqueue_style(
'wp-allstars-admin',
plugins_url('css/wp-allstars-admin.css', dirname(__FILE__)),
array(),
WP_ALLSTARS_VERSION
);
// Add inline JS for handling settings updates
$access_js = '
jQuery(document).ready(function($) {
// Handle main toggle switches using the standard update_option AJAX call
$("#wp_allstars_hide_admin_bar, #wp_allstars_restrict_dashboard").on("change", function(e) {
e.stopPropagation();
var $this = $(this);
var setting = $this.attr("id");
var value = $this.is(":checked") ? 1 : 0;
// Clear any existing notifications
$(".wp-setting-notification").remove();
$.ajax({
url: ajaxurl,
type: "POST",
data: {
action: "wp_allstars_update_option",
option: setting,
value: value,
nonce: wpAllstars.nonce
},
success: function(response) {
if (response.success) {
// Show success notification
showNotification("Saved", $this);
// Update UI based on toggle state
var $container = $this.closest(".wp-allstars-toggle");
var $settingsArea = $container.find(".wp-allstars-toggle-settings");
var $header = $container.find(".wp-allstars-toggle-header");
if (value) {
// Set default roles (subscriber, customer) as checked when enabled
$settingsArea.find("input[value=\'subscriber\'], input[value=\'customer\']").prop("checked", true);
// Update role settings via AJAX
var setting_key = setting === "wp_allstars_hide_admin_bar" ?
"wp_allstars_hide_admin_bar_roles" :
"wp_allstars_restrict_dashboard_roles";
$.ajax({
url: ajaxurl,
type: "POST",
data: {
action: "wp_allstars_update_access_setting",
setting: setting_key,
value: ["subscriber", "customer"],
nonce: wpAllstars.nonce
}
});
// Expand the section if it was toggled on
if ($header.attr("aria-expanded") === "false") {
$header.attr("aria-expanded", "true");
$settingsArea.slideDown(200);
}
} else {
// Clear all role checkboxes when disabled
$settingsArea.find("input[type=checkbox]").prop("checked", false);
// Update role settings via AJAX
var setting_key = setting === "wp_allstars_hide_admin_bar" ?
"wp_allstars_hide_admin_bar_roles" :
"wp_allstars_restrict_dashboard_roles";
$.ajax({
url: ajaxurl,
type: "POST",
data: {
action: "wp_allstars_update_access_setting",
setting: setting_key,
value: [],
nonce: wpAllstars.nonce
}
});
}
} else {
// Show error notification
showNotification("Error Saving", $this, "error");
// Revert the toggle to its previous state
$this.prop("checked", !$this.is(":checked"));
}
},
error: function() {
// Show error notification
showNotification("Error Saving", $this, "error");
// Revert the toggle to its previous state
$this.prop("checked", !$this.is(":checked"));
}
});
});
// Handle role checkbox changes
$(".wp-allstars-role-checkbox input").on("change", function(e) {
e.stopPropagation();
var $this = $(this);
var $container = $this.closest(".wp-allstars-role-checkboxes");
var settingName = $container.find("input").first().attr("name");
var settingKey = settingName.replace("[]", "");
var selectedRoles = [];
// Get all checked roles
$container.find("input:checked").each(function() {
selectedRoles.push($(this).val());
});
// Clear any existing notifications
$(".wp-setting-notification").remove();
// Find the main toggle for this section
var $mainToggle = $this.closest(".wp-allstars-toggle").find(".wp-toggle-switch input");
// Update the setting via AJAX
$.ajax({
url: ajaxurl,
type: "POST",
data: {
action: "wp_allstars_update_access_setting",
setting: settingKey,
value: selectedRoles,
nonce: wpAllstars.nonce
},
success: function(response) {
if (response.success) {
// Update the main toggle based on role selection
$mainToggle.prop("checked", selectedRoles.length > 0);
// Show success notification
showNotification("Saved", $mainToggle);
} else {
// Show error notification
showNotification("Error Saving", $mainToggle, "error");
// Revert the checkbox to its previous state
$this.prop("checked", !$this.prop("checked"));
}
},
error: function() {
// Show error notification
showNotification("Error Saving", $mainToggle, "error");
// Revert the checkbox to its previous state
$this.prop("checked", !$this.prop("checked"));
}
});
});
// Utility function to show notifications
function showNotification(message, $element, type) {
type = type || "success"; // Default to success
// Find the nearest toggle header for notification placement
var $toggleHeader = $element.closest(".wp-allstars-toggle").find(".wp-allstars-toggle-header");
var $label = $toggleHeader.find("label");
var $notification = $("<span>").addClass("wp-setting-notification " + type).text(message);
// Remove any existing notifications
$toggleHeader.find(".wp-setting-notification").remove();
// Add the notification
$label.append($notification);
// Remove notification after delay
setTimeout(function() {
$notification.fadeOut(300, function() {
$(this).remove();
});
}, 2000);
}
});
';
wp_add_inline_script('wp-allstars-admin', $access_js);
}
/**
* Handle AJAX updates for access settings
*/
public static function handle_access_setting_update() {
// Verify nonce
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'wp-allstars-nonce')) {
wp_send_json_error(array('message' => 'Invalid nonce'));
return;
}
// Check user capabilities
if (!current_user_can('manage_options')) {
wp_send_json_error(array('message' => 'Insufficient permissions'));
return;
}
// Get and validate setting
$setting = isset($_POST['setting']) ? sanitize_text_field($_POST['setting']) : '';
$value = isset($_POST['value']) ? $_POST['value'] : '';
if (empty($setting)) {
wp_send_json_error(array('message' => 'Invalid setting'));
return;
}
// Handle the role settings update
if ($setting === 'wp_allstars_hide_admin_bar_roles' || $setting === 'wp_allstars_restrict_dashboard_roles') {
// Sanitize the array of roles
if (is_array($value)) {
$value = array_map('sanitize_text_field', $value);
} else {
$value = array();
}
// Update the option
$result = update_option($setting, $value);
if ($result) {
// Also update the corresponding toggle setting for consistency
if ($setting === 'wp_allstars_hide_admin_bar_roles') {
update_option('wp_allstars_hide_admin_bar', !empty($value) ? 1 : 0);
} else if ($setting === 'wp_allstars_restrict_dashboard_roles') {
update_option('wp_allstars_restrict_dashboard', !empty($value) ? 1 : 0);
}
wp_send_json_success(array('message' => 'Setting updated successfully'));
} else {
wp_send_json_error(array('message' => 'Error Saving'));
}
} else {
wp_send_json_error(array('message' => 'Invalid setting name'));
}
}
/**
* Set up access control hooks
*/
public static function setup_access_control() {
// Get current user
$user = wp_get_current_user();
if (!$user->exists()) {
return;
}
// Get user roles
$user_roles = $user->roles;
// Get restricted roles from settings
$hide_admin_bar_roles = get_option('wp_allstars_hide_admin_bar_roles', array());
$restrict_dashboard_roles = get_option('wp_allstars_restrict_dashboard_roles', array());
// Check if user's role is in restricted roles
$should_hide_admin_bar = array_intersect($user_roles, $hide_admin_bar_roles);
$should_restrict_dashboard = array_intersect($user_roles, $restrict_dashboard_roles);
// Hide admin bar if needed
if (!empty($should_hide_admin_bar)) {
add_filter('show_admin_bar', '__return_false');
}
// Restrict dashboard access if needed
if (!empty($should_restrict_dashboard) && is_admin() && !wp_doing_ajax()) {
// Allow access to profile page
if (isset($_GET['page']) && $_GET['page'] === 'profile.php') {
return;
}
// Redirect to home page
wp_redirect(home_url());
exit;
}
}
/**
* Display the access control settings in the advanced tab
*/
public static function display_access_settings() {
// Register the additional toggle settings (matching the working toggle switches format)
register_setting('wp_allstars_access', 'wp_allstars_hide_admin_bar');
register_setting('wp_allstars_access', 'wp_allstars_restrict_dashboard');
// Get current settings
$hide_admin_bar = get_option('wp_allstars_hide_admin_bar', 0);
$restrict_dashboard = get_option('wp_allstars_restrict_dashboard', 0);
$hide_admin_bar_roles = get_option('wp_allstars_hide_admin_bar_roles', array());
$restrict_dashboard_roles = get_option('wp_allstars_restrict_dashboard_roles', array());
// Ensure the toggle state matches the role array
if (!empty($hide_admin_bar_roles) && !$hide_admin_bar) {
update_option('wp_allstars_hide_admin_bar', 1);
$hide_admin_bar = 1;
} else if (empty($hide_admin_bar_roles) && $hide_admin_bar) {
update_option('wp_allstars_hide_admin_bar', 0);
$hide_admin_bar = 0;
}
if (!empty($restrict_dashboard_roles) && !$restrict_dashboard) {
update_option('wp_allstars_restrict_dashboard', 1);
$restrict_dashboard = 1;
} else if (empty($restrict_dashboard_roles) && $restrict_dashboard) {
update_option('wp_allstars_restrict_dashboard', 0);
$restrict_dashboard = 0;
}
// Get all available roles
$roles = wp_roles()->get_names();
?>
<!-- Admin Bar Control -->
<div class="wp-allstars-toggle">
<div class="wp-allstars-toggle-header" aria-expanded="<?php echo !empty($hide_admin_bar_roles) ? 'true' : 'false'; ?>">
<div class="wp-allstars-toggle-main">
<div class="wp-allstars-toggle-left">
<div class="wp-toggle-switch">
<input type="checkbox"
id="wp_allstars_hide_admin_bar"
name="wp_allstars_hide_admin_bar"
value="1"
<?php checked($hide_admin_bar); ?>
/>
<span class="wp-toggle-slider"></span>
</div>
<label for="wp_allstars_hide_admin_bar">
<?php esc_html_e('Admin Bar: Remove for these User Roles', 'wp-allstars'); ?>
</label>
</div>
</div>
<p class="wp-setting-description">
<?php esc_html_e('Remove the Admin Bar from showing for logged-in Users that have consumer Roles, where Admin is not relevant to.', 'wp-allstars'); ?>
</p>
</div>
<div class="wp-allstars-toggle-settings" style="<?php echo !empty($hide_admin_bar_roles) ? 'display: block;' : 'display: none;'; ?>">
<div class="wp-allstars-setting-row">
<label><?php esc_html_e('Select User Roles', 'wp-allstars'); ?></label>
<div class="wp-allstars-role-checkboxes">
<?php foreach ($roles as $role_key => $role_name): ?>
<label class="wp-allstars-role-checkbox">
<input type="checkbox"
name="wp_allstars_hide_admin_bar_roles[]"
value="<?php echo esc_attr($role_key); ?>"
<?php checked(in_array($role_key, $hide_admin_bar_roles)); ?>
/>
<?php echo esc_html($role_name); ?>
</label>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
<!-- Dashboard Access Control -->
<div class="wp-allstars-toggle">
<div class="wp-allstars-toggle-header" aria-expanded="<?php echo !empty($restrict_dashboard_roles) ? 'true' : 'false'; ?>">
<div class="wp-allstars-toggle-main">
<div class="wp-allstars-toggle-left">
<div class="wp-toggle-switch">
<input type="checkbox"
id="wp_allstars_restrict_dashboard"
name="wp_allstars_restrict_dashboard"
value="1"
<?php checked($restrict_dashboard); ?>
/>
<span class="wp-toggle-slider"></span>
</div>
<label for="wp_allstars_restrict_dashboard">
<?php esc_html_e('Dashboard: Prevent access for these User Roles', 'wp-allstars'); ?>
</label>
</div>
</div>
<p class="wp-setting-description">
<?php esc_html_e('Prevent the Admin Dashboard from being accessed by consumer Roles, where WP Admin is not relevant.', 'wp-allstars'); ?>
</p>
</div>
<div class="wp-allstars-toggle-settings" style="<?php echo !empty($restrict_dashboard_roles) ? 'display: block;' : 'display: none;'; ?>">
<div class="wp-allstars-setting-row">
<label><?php esc_html_e('Select User Roles', 'wp-allstars'); ?></label>
<div class="wp-allstars-role-checkboxes">
<?php foreach ($roles as $role_key => $role_name): ?>
<label class="wp-allstars-role-checkbox">
<input type="checkbox"
name="wp_allstars_restrict_dashboard_roles[]"
value="<?php echo esc_attr($role_key); ?>"
<?php checked(in_array($role_key, $restrict_dashboard_roles)); ?>
/>
<?php echo esc_html($role_name); ?>
</label>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
<?php
}
}

View File

@ -113,7 +113,9 @@ class WP_Allstars_Admin_Manager {
'wp_allstars_max_height', 'wp_allstars_max_height',
'wp_allstars_exclude_urls', 'wp_allstars_exclude_urls',
'wp_allstars_image_name_pattern', 'wp_allstars_image_name_pattern',
'wp_allstars_image_alt_pattern' 'wp_allstars_image_alt_pattern',
'wp_allstars_hide_admin_bar',
'wp_allstars_restrict_dashboard'
); );
if (!in_array($option, $allowed_options)) { if (!in_array($option, $allowed_options)) {

View File

@ -107,41 +107,10 @@ class WP_Allstars_Settings_Manager {
?> ?>
<div class="wp-allstars-settings-section"> <div class="wp-allstars-settings-section">
<div class="wp-allstars-settings-grid"> <div class="wp-allstars-settings-grid">
<!-- Example of an expandable panel setting --> <?php
<div class="wp-allstars-toggle"> // Display access control settings
<div class="wp-allstars-toggle-header" aria-expanded="false"> WP_Allstars_Access_Manager::display_access_settings();
<div class="wp-allstars-toggle-main"> ?>
<div class="wp-allstars-toggle-left">
<div class="wp-toggle-switch">
<input type="checkbox"
id="wp_allstars_auto_upload_images"
name="wp_allstars_auto_upload_images"
value="1"
<?php checked(get_option('wp_allstars_auto_upload_images', false)); ?>
/>
<span class="wp-toggle-slider"></span>
</div>
<label for="wp_allstars_auto_upload_images">
<?php esc_html_e('Example: Expandable Panel', 'wp-allstars'); ?>
</label>
</div>
</div>
<p class="wp-setting-description">
<?php esc_html_e('This is an example of an expandable panel setting. Currently for demonstration purposes only - no actual functionality.', 'wp-allstars'); ?>
</p>
</div>
<div class="wp-allstars-toggle-settings">
<div class="wp-allstars-setting-row">
<label for="example_text"><?php esc_html_e('Example Text Field', 'wp-allstars'); ?></label>
<input type="text"
id="example_text"
name="example_text"
value="Example value"
/>
<p class="description"><?php esc_html_e('This is an example text field for demonstration purposes.', 'wp-allstars'); ?></p>
</div>
</div>
</div>
</div> </div>
</div> </div>
<?php <?php

View File

@ -5,7 +5,7 @@
* Handles setting the admin color scheme based on user preferences * Handles setting the admin color scheme based on user preferences
* *
* @package WP_ALLSTARS * @package WP_ALLSTARS
* @since 0.2.3 * @since 0.2.4
*/ */
if (!defined('ABSPATH')) { if (!defined('ABSPATH')) {
@ -45,14 +45,62 @@ class WP_Allstars_Admin_Colors {
// Set up hooks // Set up hooks
add_action('admin_init', array($this, 'set_admin_color_scheme')); add_action('admin_init', array($this, 'set_admin_color_scheme'));
add_action('wp_ajax_wp_allstars_update_option', array($this, 'handle_color_scheme_update'), 5); add_action('wp_ajax_wp_allstars_update_option', array($this, 'handle_color_scheme_update'), 5);
add_action('wp_ajax_wp_allstars_get_admin_colors', array($this, 'get_admin_colors_ajax'));
// Add script to handle dynamic color changes // Add script to handle the toggle
add_action('admin_enqueue_scripts', array($this, 'enqueue_color_scripts')); add_action('admin_enqueue_scripts', array($this, 'enqueue_color_scripts'));
// Add script for showing saved notification
add_action('admin_footer', array($this, 'add_saved_notification_script'));
} }
/** /**
* Enqueue JavaScript to handle dynamic color scheme changes * Add script to show saved notification after page refresh
*/
public function add_saved_notification_script() {
// Only add on our settings page
$screen = get_current_screen();
if (!$screen || strpos($screen->id, 'wp-allstars') === false) {
return;
}
// Check if we have a transient indicating a recent save
$user_id = get_current_user_id();
$transient_name = 'wp_allstars_colors_updated_' . $user_id;
if (get_transient($transient_name)) {
// Add inline script to show the notification
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
// Get the label element
var $label = $('label[for="wp_allstars_simple_setting"]');
// Show notification using the plugin's existing showNotification function
if (typeof showNotification === 'function') {
showNotification('Saved', $label);
} else {
// Fallback implementation if showNotification isn't available
$('.wp-setting-notification').remove();
var $notification = $('<span class="wp-setting-notification">Saved</span>');
$label.after($notification);
setTimeout(function() {
$notification.fadeOut(300, function() {
$(this).remove();
});
}, 2000);
}
});
</script>
<?php
// Delete the transient so it only shows once
delete_transient($transient_name);
}
}
/**
* Enqueue JavaScript to handle toggle and page refresh
*/ */
public function enqueue_color_scripts($hook) { public function enqueue_color_scripts($hook) {
// Only load on the plugin settings page // Only load on the plugin settings page
@ -60,157 +108,29 @@ class WP_Allstars_Admin_Colors {
return; return;
} }
// Get the available color schemes // Add inline JS for handling toggle and refresh
global $_wp_admin_css_colors;
// Get URLs for the fresh and modern schemes
$fresh_url = '';
$modern_url = '';
if (isset($_wp_admin_css_colors['fresh'])) {
$fresh_url = $_wp_admin_css_colors['fresh']->url;
}
if (isset($_wp_admin_css_colors['modern'])) {
$modern_url = $_wp_admin_css_colors['modern']->url;
}
// Add inline JS for handling dynamic color scheme changes
$color_js = ' $color_js = '
jQuery(document).ready(function($) { jQuery(document).ready(function($) {
// Store color scheme URLs for direct access
var colorSchemes = {
"fresh": "' . esc_js($fresh_url) . '",
"modern": "' . esc_js($modern_url) . '"
};
// Special handler for admin color scheme toggle // Special handler for admin color scheme toggle
$("#wp_allstars_simple_setting").on("change", function() { $("#wp_allstars_simple_setting").on("change", function() {
var isEnabled = $(this).is(":checked"); var isEnabled = $(this).is(":checked");
// Apply the color scheme dynamically // Save setting via AJAX and refresh page
if (isEnabled) {
switchColorScheme("modern");
} else {
switchColorScheme("fresh");
}
});
// Function to switch admin color scheme without page reload
function switchColorScheme(newScheme) {
console.log("Switching to color scheme:", newScheme);
// Exit if we dont have URL for this scheme
if (!colorSchemes[newScheme]) {
console.error("No URL found for color scheme:", newScheme);
return;
}
try {
// 1. Update the body class first
var $body = $("body");
$body.removeClass(function(index, className) {
return (className.match(/(^|\s)admin-color-\S+/g) || []).join(" ");
});
$body.addClass("admin-color-" + newScheme);
// 2. Directly replace color stylesheet URLs
var baseUrl = colorSchemes[newScheme];
if (!baseUrl) return;
// Force cache-busting
var cacheBuster = "?_=" + new Date().getTime();
// Replace all stylesheets with colors in their URL
var $adminColorLinks = $("link[href*=\'colors-\'], link[href*=\'/colors.\'], link#colors, link#colors-css, link#admin-colors-css");
// Log what we found
console.log("Found admin color links:", $adminColorLinks.length);
$adminColorLinks.each(function() {
console.log(" - Link:", $(this).attr("href"));
});
// For each stylesheet, create and inject a new one with the correct scheme
$adminColorLinks.each(function() {
var $oldLink = $(this);
var oldHref = $oldLink.attr("href");
var id = $oldLink.attr("id") || "";
// Skip if not a stylesheet
if (!oldHref || $oldLink.attr("rel") !== "stylesheet") return;
// Determine what file is being loaded
var fileType = "";
if (oldHref.indexOf("colors-rtl") !== -1) {
fileType = "colors-rtl.min.css";
} else if (oldHref.indexOf("colors.min") !== -1) {
fileType = "colors.min.css";
} else {
fileType = "colors.css";
}
// Create the new URL
var newUrl = baseUrl + fileType + cacheBuster;
console.log("Replacing", oldHref, "with", newUrl);
// Create a new stylesheet element
var $newLink = $("<link />", {
rel: "stylesheet",
type: "text/css",
id: id,
href: newUrl
});
// Insert new stylesheet and remove old one
$oldLink.after($newLink);
setTimeout(function() {
$oldLink.remove();
}, 100);
});
// If we found no stylesheets, inject the main one
if ($adminColorLinks.length === 0) {
console.log("No admin color stylesheets found, injecting new one");
$("head").append(
$("<link />", {
rel: "stylesheet",
type: "text/css",
id: "colors-css",
href: baseUrl + "colors.min.css" + cacheBuster
})
);
}
// 3. Save the setting via AJAX
saveColorScheme(newScheme);
} catch (e) {
console.error("Error switching color scheme:", e);
}
}
function saveColorScheme(scheme) {
// AJAX request to save the color scheme setting
$.ajax({ $.ajax({
url: ajaxurl, url: ajaxurl,
type: "POST", type: "POST",
data: { data: {
action: "wp_allstars_update_admin_colors", action: "wp_allstars_update_option",
scheme: scheme, option: "wp_allstars_simple_setting",
_wpnonce: wpAllstars.nonce value: isEnabled ? 1 : 0,
nonce: "' . wp_create_nonce('wp-allstars-nonce') . '"
}, },
success: function(response) { success: function() {
if (response.success) { // Refresh the page after successful update
console.log("Color scheme updated successfully"); window.location.reload();
} else {
console.error("Error updating color scheme:", response);
}
},
error: function(xhr, status, error) {
console.error("AJAX error:", error);
} }
}); });
} });
}); });
'; ';
@ -239,14 +159,16 @@ class WP_Allstars_Admin_Colors {
/** /**
* Handle color scheme update via AJAX * Handle color scheme update via AJAX
* Runs early to apply the color scheme change before the general option update handler
*/ */
public function handle_color_scheme_update() { public function handle_color_scheme_update() {
// Check for required params // Check for required params
if (!isset($_POST['option']) || !isset($_POST['value'])) { if (!isset($_POST['option']) || !isset($_POST['value']) || !isset($_POST['nonce'])) {
return; return;
} }
// Verify nonce
check_ajax_referer('wp-allstars-nonce', 'nonce');
// Only process our specific option // Only process our specific option
if ($_POST['option'] !== $this->option_name) { if ($_POST['option'] !== $this->option_name) {
return; return;
@ -264,52 +186,14 @@ class WP_Allstars_Admin_Colors {
// Update the user's color scheme // Update the user's color scheme
update_user_meta($user_id, 'admin_color', $scheme); update_user_meta($user_id, 'admin_color', $scheme);
}
/**
* AJAX handler to update and get admin color schemes - similar to WordPress core
*/
public function get_admin_colors_ajax() {
// Register handler for our new AJAX action
add_action('wp_ajax_wp_allstars_update_admin_colors', array($this, 'update_admin_colors_ajax'));
}
/**
* AJAX handler to update admin color scheme and return class names
*/
public function update_admin_colors_ajax() {
check_ajax_referer('wp-allstars-nonce', '_wpnonce');
$user_id = get_current_user_id(); // Update the option
if (!$user_id) { update_option($this->option_name, $value ? 1 : 0);
wp_send_json_error('Not logged in');
}
// Get the old scheme // Set a transient to show the saved notice
$old_scheme = get_user_meta($user_id, 'admin_color', true); set_transient('wp_allstars_colors_updated_' . $user_id, true, 30);
if (!$old_scheme) {
$old_scheme = 'fresh'; // Default WordPress admin color scheme
}
// Get the new scheme // Return success
$scheme = isset($_POST['scheme']) ? sanitize_text_field($_POST['scheme']) : 'fresh'; wp_send_json_success();
// Validate scheme
global $_wp_admin_css_colors;
if (!isset($_wp_admin_css_colors[$scheme])) {
wp_send_json_error('Invalid color scheme');
}
// Update user meta
update_user_meta($user_id, 'admin_color', $scheme);
// Also update our plugin option
update_option($this->option_name, $scheme === $this->modern_scheme ? 1 : 0);
// Return success with old and new scheme names for CSS class updates
wp_send_json_success(array(
'previousScheme' => 'admin-color-' . $old_scheme,
'currentScheme' => 'admin-color-' . $scheme
));
} }
} }

View File

@ -6,18 +6,31 @@
* site performance, improve workflow, and provide recommendations for plugins and hosting. * site performance, improve workflow, and provide recommendations for plugins and hosting.
* *
* @package WP_ALLSTARS * @package WP_ALLSTARS
* @version v0.2.3 * @version v0.2.4
* *
* Plugin Name: WP ALLSTARS Plugin * Plugin Name: WP Allstars
* Plugin URI: https://www.wpallstars.com * Plugin URI: https://wpallstars.com
* Description: WP ALLSTARS Plugin for WordPress. Speed Matters. * Description: A superstar stack of premium WordPress functionality, designed for SEO pros.
* Version: v0.2.3 (Beta) * Author: Marcus Quinn
* Author: WP ALLSTARS * Author URI: https://wpallstars.com
* Author URI: https://www.wpallstars.com
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
* Text Domain: wp-allstars * Text Domain: wp-allstars
* Domain Path: /languages * Domain Path: /languages
* @version v0.2.4
*
* WP Allstars is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* any later version.
* Version: v0.2.4 (Beta)
*
* WP Allstars is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WP Allstars. If not, see https://www.gnu.org/licenses/gpl-2.0.html.
*
* Requires at least: 5.0 * Requires at least: 5.0
* Requires PHP: 7.2 * Requires PHP: 7.2
*/ */
@ -61,6 +74,7 @@ if (is_admin()) {
require_once plugin_dir_path(__FILE__) . 'admin/includes/class-plugin-manager.php'; require_once plugin_dir_path(__FILE__) . 'admin/includes/class-plugin-manager.php';
require_once plugin_dir_path(__FILE__) . 'admin/includes/class-free-plugins-manager.php'; require_once plugin_dir_path(__FILE__) . 'admin/includes/class-free-plugins-manager.php';
require_once plugin_dir_path(__FILE__) . 'admin/includes/class-readme-manager.php'; require_once plugin_dir_path(__FILE__) . 'admin/includes/class-readme-manager.php';
require_once plugin_dir_path(__FILE__) . 'admin/includes/class-access-manager.php';
// Initialize the admin manager // Initialize the admin manager
add_action('plugins_loaded', array('WP_Allstars_Admin_Manager', 'init')); add_action('plugins_loaded', array('WP_Allstars_Admin_Manager', 'init'));
@ -92,6 +106,9 @@ add_action('init', 'wp_allstars_init_auto_upload');
function wp_allstars_init_features() { function wp_allstars_init_features() {
// Initialize the Admin Colors feature // Initialize the Admin Colors feature
new WP_Allstars_Admin_Colors(); new WP_Allstars_Admin_Colors();
// Initialize the Access Manager
WP_Allstars_Access_Manager::init();
} }
add_action('plugins_loaded', 'wp_allstars_init_features'); add_action('plugins_loaded', 'wp_allstars_init_features');