12 Commits

21 changed files with 2005 additions and 1142 deletions

View File

@ -1,8 +0,0 @@
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"

9
.woodpecker.yml Normal file
View File

@ -0,0 +1,9 @@
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"

111
DEVELOPMENT.md Normal file
View File

@ -0,0 +1,111 @@
# WP Allstars Plugin Development Workflow
This document outlines the development workflow for the WP Allstars Plugin to ensure stable and reliable feature implementation.
## Development Principles
1. **Stability First**: The primary goal is maintaining a stable plugin that works reliably
2. **Incremental Changes**: Implement changes in small, manageable increments
3. **Complete Testing**: Every change must be thoroughly tested before integration
4. **Documentation**: All features and changes must be well-documented
## Branch Structure
- `main` - Production-ready code, always stable
- `v0.2.3-stable` - Our current stable development branch
- `feature/v0.2.3-stable/{feature-name}` - Feature branches for new development
## Development Workflow
### 1. Feature Planning
1. Identify a feature from the ROADMAP.md file to implement
2. Review any existing implementation in unstable versions
3. Document the implementation plan in ROADMAP.md
4. Create a new feature branch from the stable base
```bash
git checkout v0.2.3-stable
git checkout -b feature/v0.2.3-stable/sync-guard
```
### 2. Feature Implementation
1. Start with the smallest possible functional change
2. Commit frequently with descriptive commit messages including stability classification
3. Example commit message format:
```
[EXPERIMENTAL] Add basic sync guard detection functionality
- Adds file existence check for .syncing flag
- Implements conditional loading based on flag
- Does not yet handle admin notices
```
4. Reference the ROADMAP.md and TESTING.md documents while implementing
### 3. Testing
1. Complete all relevant tests from TESTING.md
2. Add feature-specific tests if needed
3. Test in a clean WordPress environment
4. Test with WP_DEBUG enabled
5. Document any issues found and fix them
### 4. Code Review
1. Self-review code for:
- PHP best practices
- WordPress coding standards
- Security considerations
- Performance implications
- Error handling
2. Consider peer review if possible
### 5. Integration
1. Create a pull request to merge into the stable branch
2. Summarize changes, testing performed, and any caveats
3. Once approved, merge using `--no-ff` to preserve feature history
```bash
git checkout v0.2.3-stable
git merge --no-ff feature/v0.2.3-stable/sync-guard
```
4. Tag new version if appropriate:
```bash
git tag v0.2.3.1-stable
git push origin v0.2.3.1-stable
```
5. Update STABILITY.md with the new version information
### 6. Post-Integration
1. Deploy to test environment and confirm functionality
2. Update ROADMAP.md to reflect the implemented feature
3. Clean up feature branch if no longer needed
## Handling Unstable Code References
When examining code from unstable versions:
1. **Never copy-paste directly** - Understand the approach and reimplement
2. **Isolate problematic code** - Identify why it might have failed
3. **Take the best ideas** - Implement the concept, not the exact implementation
4. **Document the reference** - Note which version inspired each implementation
## Versioning Scheme
- `vX.Y.Z` - Major.Minor.Patch
- `vX.Y.Z-stable` - Stable development branches
- `vX.Y.Z.N-stable` - Minor updates to stable branches
## Continuous Improvement
- Regularly review and update these development procedures
- Document lessons learned
- Improve testing procedures based on discoveries

View File

@ -1,6 +1,7 @@
# WP Allstars
A WordPress plugin that enhances your WordPress experience with curated plugins, themes, and optimization tools.
Current version: v0.2.3.3 (stable)
## Description
@ -8,6 +9,8 @@ WP Allstars is a powerful WordPress plugin designed to help site owners and deve
## Features
- **Modern Admin UI**: Enhanced admin interface with responsive design and interactive components.
- **Admin Color Schemes**: Switch between default and modern admin color schemes.
- **Curated Plugin Recommendations**: Browse and install recommended free plugins organized by category.
- **Pro Plugin Showcase**: Discover premium plugins with direct links to purchase.
- **Theme Integration**: Easily install and activate the Kadence theme.
@ -28,6 +31,8 @@ After activation, you'll find the WP Allstars menu in your WordPress admin sideb
### General
Basic settings for the plugin, including:
- Admin UI Enhancements
- Admin Color Schemes
- Auto Upload Images
- Image Optimization
- Cache Management
@ -77,6 +82,15 @@ Discover premium plugins with direct links to purchase.
Easily install and activate the Kadence theme.
## UI Components
The plugin includes several enhanced UI components:
- **Cards**: Flexible containers for displaying content with optional headers and footers
- **Accordions**: Collapsible content panels for presenting information in a limited space
- **Notifications**: Stylish notifications for providing user feedback
- **Enhanced Form Elements**: Improved styling for inputs, buttons, and toggles
## Development
### Requirements

139
ROADMAP.md Normal file
View File

@ -0,0 +1,139 @@
# WP Allstars Plugin Development Roadmap
This document outlines features from later versions that we plan to integrate into our stable development branch. The goal is to incrementally implement these features in a stable manner, without introducing critical errors.
## Feature Backlog
| Feature | Source Version | Priority | Complexity | Risk | Status |
|---------|----------------|----------|------------|------|--------|
| Multisite Category | v0.2.6 | High | Low | Low | ✅ Implemented in v0.2.3-stable |
| Sync Guard | v0.2.6-fix | High | Low | Low | ✅ Implemented in v0.2.3.1-stable |
| More Robust File Loading | v0.2.6-fix | High | Low | Low | ✅ Implemented in v0.2.3-stable |
| Admin Colors Feature | v0.2.4 | High | Low | Low | ✅ Implemented in v0.2.3.2-stable |
| Basic Admin UI Enhancements | v0.2.5 | High | Medium | Medium | ✅ Implemented in v0.2.3.3-stable |
| Advanced Admin UI Components | v0.2.5 | Medium | Medium | Medium | 🔄 To be implemented |
| Access Manager Improvements | v0.2.5 | Medium | Medium | Medium | 🔄 To be implemented |
| Role-Based Access Controls | v0.2.5.1 | High | Medium | Medium | 🔄 To be implemented |
| Improved Plugin Structure | v0.2.5 | Medium | Medium | High | 🔄 To be implemented |
| Performance Optimizations | v0.2.6 | Medium | Medium | Medium | 🔄 To be implemented |
| Enhanced Plugin Filtering | v0.2.6 | Medium | Medium | Low | 🔄 To be implemented |
| Plugin Settings Export/Import | v0.2.6 | Low | High | Medium | 🔄 To be implemented |
| Plugin Dashboard | v0.2.6-fix | Medium | Medium | Medium | 🔄 To be implemented |
| New Category Pages | v0.2.4+ | Medium | Low | Low | 🔄 To be implemented |
## Implementation Strategy
### Multisite Category with Network Plugin Auditor
- **Description**: Add a "Multisite" filter after Advanced and include network-plugin-auditor
- **Why it failed before**: Didn't properly update all required files for the feature
- **Implementation plan**: Add to free-plugins.php and update class-free-plugins-manager.php to display the category correctly
- **Testing criteria**: Verify category appears in UI and plugin can be installed
### Sync Guard
- **Description**: Prevent plugin loading during rsync operations to avoid partial file loading
- **Why it failed before**: Added to wrong location, dependent on missing files
- **Implementation plan**:
1. Create a simpler version of the sync guard
2. Update post-commit hook to handle sync operations better
3. Use file flag to signal when sync is in progress
- **Testing criteria**: Verify plugin doesn't attempt to load during sync operations
### Admin Colors Feature
- **Description**: Allow users to switch between default and modern admin color schemes
- **Why it's valuable**: Provides visual distinction and improves user experience
- **Implementation plan**:
1. Create class-wp-allstars-admin-colors.php
2. Add toggle in settings to switch color schemes
3. Register the feature in the main plugin file
- **Testing criteria**: Verify color scheme changes when toggled
### Basic Admin UI Enhancements
- **Description**: Improve the basic styling of admin interfaces
- **Why it's valuable**: Better user experience and modern look
- **Implementation plan**:
1. Create class-wp-allstars-ui-enhancements.php
2. Implement UI components like cards, accordions, and notifications
3. Add responsive design improvements
- **Testing criteria**: Verify UI components work correctly across different screen sizes
- **Status**: ✅ Implemented in v0.2.3.3-stable
### Advanced Admin UI Components
- **Description**: Add more sophisticated UI elements and interactions
- **Why it's valuable**: Enhanced usability and professional appearance
- **Implementation plan**:
1. Implement enhanced toggles and accordions
2. Add notification styling
3. Improve plugin cards and layouts
- **Testing criteria**: Verify all UI components work correctly across browsers
### Access Manager Improvements
- **Description**: Enhance user role and permission management
- **Why it's valuable**: More granular control over plugin features
- **Implementation plan**:
1. Update class-access-manager.php
2. Add role checkboxes in UI
3. Implement proper access restriction handling
- **Testing criteria**: Verify correct permissions are applied based on user roles
### Role-Based Access Controls
- **Description**: Implement fine-grained access controls for different user roles
- **Why it's valuable**: Allows administrators to restrict access to specific plugin features
- **Implementation plan**:
1. Create role capability mapping system
2. Add permission checks throughout the plugin
3. Create UI for managing role permissions
- **Testing criteria**: Verify users can only access features appropriate to their role
### Improved Plugin Structure
- **Description**: Better organization of code with clearer separation of concerns
- **Why it's valuable**: More maintainable codebase and fewer dependency issues
- **Implementation plan**:
1. Reorganize class loading order
2. Improve dependency management
3. Enhance error handling for API calls
- **Testing criteria**: Verify plugin loads correctly with no dependency errors
### Performance Optimizations
- **Description**: Improve plugin performance and resource usage
- **Why it's valuable**: Better user experience and lower server load
- **Implementation plan**:
1. Optimize asset loading (CSS/JS)
2. Reduce database queries
3. Implement caching for external API requests
- **Testing criteria**: Verify reduced page load times and server resource usage
### Enhanced Plugin Filtering
- **Description**: More advanced filtering options for the plugins section
- **Why it's valuable**: Makes it easier for users to find relevant plugins
- **Implementation plan**:
1. Add category-specific icons and metadata
2. Implement more filtering options
3. Improve search functionality
- **Testing criteria**: Verify filtering works correctly and improves plugin discovery
### Plugin Settings Export/Import
- **Description**: Allow users to backup and restore plugin settings
- **Why it's valuable**: Easier migration between environments and configuration backup
- **Implementation plan**:
1. Create export functionality for settings
2. Implement import/restore capability
3. Add settings profiles for different use cases
- **Testing criteria**: Verify settings can be exported and successfully imported on another site
## Development Order
The suggested implementation order is:
1. ✅ Admin Colors Feature (low complexity, enhances UI)
2. ✅ Basic Admin UI Enhancements (foundation for other UI improvements)
3. Role-Based Access Controls (security-related, high priority)
4. Advanced Admin UI Components (builds on basic UI)
5. Access Manager Improvements (depends on UI components and role controls)
6. Performance Optimizations (improves user experience)
7. Enhanced Plugin Filtering (better usability)
8. Improved Plugin Structure (code quality)
9. Plugin Dashboard improvements (adds functionality)
10. New Category Pages (content enhancement)
11. Plugin Settings Export/Import (advanced functionality)
Each feature should be developed in its own branch and only merged after thorough testing.

41
STABILITY.md Normal file
View File

@ -0,0 +1,41 @@
# WP Allstars Plugin Stability Status
This document tracks the stability status of different versions of the WP Allstars Plugin.
## Stability Classification
- **[STABLE]**: Thoroughly tested, works as expected in production environments
- **[FUNCTIONAL]**: Works but may have minor issues or incomplete features
- **[EXPERIMENTAL]**: Contains new features that are not fully tested
- **[UNSTABLE]**: Known to have critical issues that affect functionality
## Version Status
| Version | Status | Notes |
|---------|--------|-------|
| v0.2.3.3 | **[FUNCTIONAL]** | Stable version with Basic Admin UI Enhancements - adds improved components and responsive design. |
| v0.2.3.2 | **[STABLE]** | Stable version with Admin Colors feature properly implemented. |
| v0.2.3.1 | **[STABLE]** | Stable version with Sync Guard feature implemented. |
| v0.2.3-stable-base | **[STABLE]** | Base stable version with robust file loading. All core functionality works properly. |
| v0.2.4 | **[UNSTABLE]** | Contains critical errors - reference only for feature ideas. |
| v0.2.6 | **[UNSTABLE]** | Contains file structure issues and critical errors - reference only for feature ideas. |
| v0.2.6-fix | **[UNSTABLE]** | Attempted fixes but still has issues - reference only. |
| v0.2.6-revert | **[UNSTABLE]** | Failed attempt to revert to stable version - do not use. |
## Current Development
Current development is based on the v0.2.3-stable-base version with incremental feature additions. We're implementing features from the roadmap while maintaining stability.
## Implemented Features
1. Robust File Loading (v0.2.3-stable-base)
2. Sync Guard (v0.2.3.1)
3. Admin Colors Feature (v0.2.3.2)
4. Basic Admin UI Enhancements (v0.2.3.3)
## Stability Guidelines
1. All new features must be developed in isolated feature branches
2. Comprehensive testing is required before merging
3. Each feature should be implemented as a series of small, atomic commits
4. All commits should include a stability classification in commit messages: [STABLE], [FUNCTIONAL], etc.
5. Full testing checklist must be completed before marking a version as [STABLE]

163
TESTING.md Normal file
View File

@ -0,0 +1,163 @@
# WP Allstars Plugin Testing Guide
This document provides testing checklist for the WP Allstars Plugin to ensure stability and functionality.
## General Testing Guidelines
1. Test each feature in isolation before testing integrated functionality
2. Test on multiple WordPress versions (5.8+)
3. Test with different themes activated
4. Test with and without other plugins activated
5. Test on different screen sizes (desktop, tablet, mobile)
## Feature-Specific Testing
### Multisite Category
- [ ] Verify "Multisite" category appears in plugin list filters
- [ ] Verify plugins in the multisite category appear when the filter is selected
- [ ] Verify network-plugin-auditor appears in multisite category
- [ ] Test installation of network-plugin-auditor via the plugin interface
### Sync Guard
- [ ] Create a .syncing file in the plugin root directory
- [ ] Verify plugin displays "syncing" notice instead of loading
- [ ] Remove .syncing file
- [ ] Verify plugin loads normally after removing .syncing file
### Admin Colors Feature
- [ ] Verify Admin Colors toggle appears in settings
- [ ] Toggle the admin colors option to "Modern"
- [ ] Verify admin UI updates with modern colors
- [ ] Toggle back to "Default"
- [ ] Verify admin UI returns to default colors
- [ ] Test color switching on different pages of the admin
- [ ] Verify setting is saved when toggling
### Basic Admin UI Enhancements
- [ ] Verify basic UI components are properly styled (buttons, forms, etc.)
- [ ] Test responsive behavior on different screen sizes
- [ ] Verify card components display properly with headers and footers
- [ ] Test accordion functionality (expand/collapse)
- [ ] Verify notification components display properly with different types (success, error, warning)
- [ ] Test dismissible notifications
- [ ] Verify that UI components are properly styled across different WordPress admin pages
- [ ] Test keyboard accessibility for interactive components
## Integration Testing
- [ ] Verify all features work together without conflicts
- [ ] Test performance impact with all features enabled
- [ ] Verify plugin loads without errors on plugin activation
- [ ] Test deactivation and reactivation
## Browser Compatibility
Test on the following browsers:
- [ ] Chrome (latest)
- [ ] Firefox (latest)
- [ ] Safari (latest)
- [ ] Edge (latest)
## Performance Testing
- [ ] Measure page load time before and after enabling the plugin
- [ ] Check for any JavaScript errors in browser console
- [ ] Verify CSS is properly cached
- [ ] Ensure assets are properly minified
## Version Upgrade Testing
When testing a new version:
- [ ] Test upgrading from previous version
- [ ] Verify settings are preserved during upgrade
- [ ] Check for any deprecation warnings or errors
## Security Testing
- [ ] Verify all admin pages are properly secured
- [ ] Check for proper escaping of output
- [ ] Verify nonce checks on form submissions
- [ ] Test with user roles other than administrator
## Final Pre-Release Checklist
- [ ] All tests passed on multiple environments
- [ ] Version numbers updated in all files
- [ ] Changelog updated
- [ ] Documentation reflects new features
- [ ] All scripts and styles properly enqueued
## Regression Testing
After implementing new features, perform regression testing on previously implemented features to ensure they still function correctly.
## Pre-Merge Testing Checklist
### Basic Functionality Tests
- [ ] Plugin activates without errors
- [ ] Plugin deactivates without errors
- [ ] Admin menu appears correctly
- [ ] All submenu items load without errors
- [ ] Settings can be saved without errors
- [ ] Plugin works with WordPress debug mode enabled
### Feature-Specific Tests
Each new feature should have its own testing checklist added here.
#### Multisite Category Feature
- [ ] "Multisite" category appears in the correct location in the UI
- [ ] Network Plugin Auditor appears in the Multisite category
- [ ] Category filter works when clicked
- [ ] Plugin can be installed from the category
#### Sync Guard Feature
- [ ] Plugin doesn't load when .syncing file is present
- [ ] .syncing file is created during sync operations
- [ ] .syncing file is removed after sync completes
- [ ] User is notified when plugin is in sync mode
### Compatibility Tests
- [ ] Plugin works with latest WordPress version
- [ ] Plugin works with PHP 7.4+
- [ ] Plugin works with common themes (Twenty Twenty-Three, Kadence)
- [ ] Plugin co-exists with other popular plugins without conflicts
### Browser Compatibility
- [ ] UI works correctly in Chrome
- [ ] UI works correctly in Firefox
- [ ] UI works correctly in Safari
- [ ] UI works correctly in Edge
### Mobile Responsiveness
- [ ] Admin interface is usable on mobile devices
- [ ] No layout issues on small screens
## Testing Process
1. Create a clean WordPress installation for testing
2. Install and activate the plugin
3. Enable WordPress debug mode (WP_DEBUG = true)
4. Complete all tests in the checklist
5. Document any issues found
6. Fix issues and retest
7. Only mark as [STABLE] when all tests pass
## Continuous Integration
For future implementation:
- [ ] Automated unit tests
- [ ] Integration tests
- [ ] End-to-end tests
- [ ] Code quality checks

View File

@ -109,25 +109,50 @@
}
}
/* Base Toggle Switch Component */
/* Setting notification */
.wp-setting-notification {
display: inline-flex;
align-items: center;
margin-left: 10px;
background: #00a32a;
color: white;
padding: 3px 10px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
animation: fadeIn 0.3s ease-in-out;
height: 20px;
box-sizing: border-box;
position: relative;
transform: translateY(-3px);
white-space: nowrap;
min-width: 60px;
justify-content: center;
}
.wp-setting-notification.error {
background: #d63638;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
/* Toggle Switch */
.wp-toggle-switch {
position: relative;
display: inline-block;
width: 36px;
width: 40px;
height: 20px;
flex-shrink: 0;
cursor: pointer;
pointer-events: all;
z-index: 2;
vertical-align: middle;
margin-right: 8px;
}
.wp-toggle-switch input {
opacity: 0;
width: 0;
height: 0;
margin: 0;
padding: 0;
position: absolute;
}
.wp-toggle-slider {
@ -139,7 +164,7 @@
bottom: 0;
background-color: #ccc;
transition: .3s;
border-radius: 20px;
border-radius: 34px;
}
.wp-toggle-slider:before {
@ -152,15 +177,55 @@
background-color: white;
transition: .3s;
border-radius: 50%;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
input:checked + .wp-toggle-slider {
background-color: #00a32a; /* WordPress standard green color */
background-color: #2271b1;
}
input:focus + .wp-toggle-slider {
box-shadow: 0 0 1px #2271b1;
}
input:checked + .wp-toggle-slider:before {
transform: translateX(16px);
transform: translateX(20px);
}
/* Settings layout */
.wp-setting-row {
background: #fff;
border: 1px solid #e5e5e5;
box-shadow: 0 1px 1px rgba(0,0,0,.04);
padding: 20px;
margin-bottom: 20px;
border-radius: 3px;
}
.wp-setting-header {
position: relative;
}
.wp-setting-main {
display: flex;
justify-content: space-between;
align-items: center;
}
.wp-setting-left {
display: flex;
align-items: center;
}
.wp-setting-label {
font-weight: 600;
margin: 0;
font-size: 14px;
}
.wp-setting-description {
margin: 10px 0 0;
color: #666;
font-size: 13px;
}
/* Tab Content Area - GLOBAL SETTINGS - All tab spacing should inherit from here */
@ -209,7 +274,7 @@ input:checked + .wp-toggle-slider:before {
.wp-setting-base:hover,
.wp-setting-row:hover,
.wp-allstars-toggle:hover {
border-color: #00a32a;
border-color: #2271b1;
box-shadow: 0 2px 6px rgba(0,0,0,0.15);
}
@ -333,8 +398,8 @@ input:checked + .wp-toggle-slider:before {
.wp-allstars-setting-row input[type="text"]:focus,
.wp-allstars-setting-row input[type="number"]:focus,
.wp-allstars-setting-row textarea:focus {
border-color: #00a32a;
box-shadow: 0 0 0 1px #00a32a;
border-color: #2271b1;
box-shadow: 0 0 0 1px #2271b1;
outline: 2px solid transparent;
}
@ -717,31 +782,6 @@ input:checked + .wp-toggle-slider:before {
}
}
/* Settings Notification */
.wp-setting-notification {
display: inline-flex;
align-items: center;
margin-left: 10px;
background: #00a32a;
color: white;
padding: 3px 10px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
animation: fadeIn 0.3s ease-in-out;
height: 20px;
box-sizing: border-box;
position: relative;
transform: translateY(-3px);
white-space: nowrap;
min-width: 60px;
justify-content: center;
}
.wp-setting-notification.error {
background: #d63638;
}
/* Add space for notification to prevent layout shifts */
.wp-setting-left label,
.wp-allstars-toggle-left label,
@ -761,110 +801,6 @@ input:checked + .wp-toggle-slider:before {
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 {
from { opacity: 0; }
to { opacity: 1; }
}
.wpa-loading-overlay {
position: absolute;
top: 0;

View File

@ -0,0 +1,463 @@
/**
* WP Allstars UI Enhancements
*
* Provides enhanced UI components for the WP Allstars plugin
* Building on the foundation of wp-allstars-admin.css
*/
/*
* Enhanced UI Base Styles
* These styles apply to the entire admin area when the enhanced UI is activated
*/
.wp-allstars-enhanced-ui #wpcontent {
padding-left: 0;
}
.wp-allstars-enhanced-ui .wp-allstars-wrap {
padding: 0 20px 20px;
max-width: 1200px;
margin: 0 auto;
}
/*
* Cards Component
* A flexible container for displaying content with an optional header and footer
*/
.wp-allstars-card {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
margin-bottom: 20px;
transition: box-shadow 0.3s ease, transform 0.2s ease;
overflow: hidden;
border: 1px solid #e5e5e5;
}
.wp-allstars-card:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
transform: translateY(-2px);
}
.wp-allstars-card-header {
padding: 15px 20px;
border-bottom: 1px solid #f0f0f0;
display: flex;
align-items: center;
background: #fbfbfb;
}
.wp-allstars-card-icon {
margin-right: 12px;
color: #2271b1;
flex-shrink: 0;
}
.wp-allstars-card-title {
font-size: 16px;
font-weight: 600;
color: #1d2327;
flex-grow: 1;
}
.wp-allstars-card-content {
padding: 20px;
}
.wp-allstars-card-footer {
padding: 12px 20px;
border-top: 1px solid #f0f0f0;
background: #fbfbfb;
}
/*
* Accordion Component
* Collapsible content panels for presenting information in a limited space
*/
.wp-allstars-accordion {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
margin-bottom: 15px;
overflow: hidden;
border: 1px solid #e5e5e5;
}
.wp-allstars-accordion-header {
padding: 15px 20px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
background: #fbfbfb;
transition: background-color 0.2s ease;
user-select: none;
}
.wp-allstars-accordion-header:hover {
background: #f6f7f7;
}
.wp-allstars-accordion-title {
font-size: 15px;
font-weight: 600;
color: #1d2327;
}
.wp-allstars-accordion-icon {
width: 20px;
height: 20px;
position: relative;
transition: transform 0.3s ease;
}
.wp-allstars-accordion-icon::before,
.wp-allstars-accordion-icon::after {
content: '';
position: absolute;
background-color: #2271b1;
transition: transform 0.3s ease;
}
.wp-allstars-accordion-icon::before {
top: 9px;
left: 0;
width: 20px;
height: 2px;
}
.wp-allstars-accordion-icon::after {
top: 0;
left: 9px;
width: 2px;
height: 20px;
}
.wp-allstars-accordion-header[aria-expanded="true"] .wp-allstars-accordion-icon::after {
transform: rotate(90deg);
}
.wp-allstars-accordion-content {
display: none;
border-top: 1px solid #f0f0f0;
}
.wp-allstars-accordion-inner {
padding: 20px;
}
/*
* Enhanced Button Styles
* Improved button appearance and interactions
*/
.wp-allstars-enhanced-ui .button {
border-radius: 4px;
transition: all 0.2s ease;
border-color: #c3c4c7;
padding: 0 12px;
height: 36px;
line-height: 34px;
box-shadow: none;
}
.wp-allstars-enhanced-ui .button:hover,
.wp-allstars-enhanced-ui .button:focus {
background: #f6f7f7;
border-color: #8c8f94;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
outline: none;
}
.wp-allstars-enhanced-ui .button-primary {
background: #2271b1;
border-color: #2271b1;
color: #fff;
}
.wp-allstars-enhanced-ui .button-primary:hover,
.wp-allstars-enhanced-ui .button-primary:focus {
background: #135e96;
border-color: #135e96;
color: #fff;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
.wp-allstars-enhanced-ui .button-large {
height: 40px;
line-height: 38px;
padding: 0 16px;
font-size: 14px;
}
.wp-allstars-enhanced-ui .button-small {
height: 28px;
line-height: 26px;
padding: 0 8px;
font-size: 12px;
}
/*
* Enhanced Toggle Styles
*/
/* Base toggle styles that apply even without enhanced UI */
.wp-toggle-switch {
position: relative;
display: inline-block;
width: 40px;
height: 20px;
vertical-align: middle;
margin-right: 8px;
}
.wp-toggle-switch input[type="checkbox"] {
opacity: 0;
width: 100%;
height: 100%;
position: absolute;
z-index: 2;
cursor: pointer;
margin: 0;
padding: 0;
top: 0;
left: 0;
}
.wp-toggle-slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: .3s;
border-radius: 34px;
z-index: 1;
}
.wp-toggle-slider:before {
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 2px;
bottom: 2px;
background-color: white;
transition: .3s;
border-radius: 50%;
}
input:checked + .wp-toggle-slider {
background-color: #2271b1;
}
input:focus + .wp-toggle-slider {
box-shadow: 0 0 1px #2271b1;
}
input:checked + .wp-toggle-slider:before {
transform: translateX(20px);
}
/* Enhanced UI specific toggle styles - only apply additional styling */
.wp-allstars-enhanced-ui .wp-toggle-switch {
width: 46px;
height: 24px;
}
.wp-allstars-enhanced-ui .wp-toggle-slider {
border-radius: 24px;
background-color: #ccc;
}
.wp-allstars-enhanced-ui .wp-toggle-slider:before {
height: 18px;
width: 18px;
left: 3px;
bottom: 3px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}
.wp-allstars-enhanced-ui input:checked + .wp-toggle-slider {
background-color: #2271b1;
}
.wp-allstars-enhanced-ui input:checked + .wp-toggle-slider:before {
transform: translateX(22px);
}
/*
* Notification Component
* Stylish notifications for providing user feedback
*/
.wp-allstars-notification {
display: flex;
align-items: center;
padding: 12px 15px;
border-radius: 6px;
margin-bottom: 15px;
border-left: 4px solid #2271b1;
background: #f0f6fc;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.07);
position: relative;
animation: wpaNotificationSlideIn 0.3s ease forwards;
}
.wp-allstars-notification-success {
background: #edfaef;
border-left-color: #00a32a;
}
.wp-allstars-notification-warning {
background: #fcf9e8;
border-left-color: #dba617;
}
.wp-allstars-notification-error {
background: #fcf0f1;
border-left-color: #d63638;
}
.wp-allstars-notification-icon {
margin-right: 12px;
width: 20px;
height: 20px;
background-repeat: no-repeat;
background-position: center;
flex-shrink: 0;
}
.wp-allstars-notification-content {
flex-grow: 1;
padding-right: 30px;
}
.wp-allstars-notification-title {
font-weight: 600;
margin-bottom: 3px;
}
.wp-allstars-notification-message {
font-size: 13px;
line-height: 1.5;
}
.wp-allstars-notification-dismiss {
position: absolute;
top: 12px;
right: 12px;
width: 20px;
height: 20px;
cursor: pointer;
opacity: 0.6;
transition: opacity 0.2s ease;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 8.586l3.293-3.293a1 1 0 0 1 1.414 1.414L11.414 10l3.293 3.293a1 1 0 0 1-1.414 1.414L10 11.414l-3.293 3.293a1 1 0 0 1-1.414-1.414L8.586 10 5.293 6.707a1 1 0 0 1 1.414-1.414L10 8.586z"/></svg>') no-repeat center;
}
.wp-allstars-notification-dismiss:hover {
opacity: 1;
}
@keyframes wpaNotificationSlideIn {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/*
* Form Enhancements
*/
.wp-allstars-enhanced-ui input[type="text"],
.wp-allstars-enhanced-ui input[type="number"],
.wp-allstars-enhanced-ui input[type="password"],
.wp-allstars-enhanced-ui input[type="email"],
.wp-allstars-enhanced-ui input[type="url"],
.wp-allstars-enhanced-ui select,
.wp-allstars-enhanced-ui textarea {
border-radius: 4px;
border: 1px solid #8c8f94;
padding: 8px 12px;
box-shadow: none;
transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.wp-allstars-enhanced-ui input[type="text"]:focus,
.wp-allstars-enhanced-ui input[type="number"]:focus,
.wp-allstars-enhanced-ui input[type="password"]:focus,
.wp-allstars-enhanced-ui input[type="email"]:focus,
.wp-allstars-enhanced-ui input[type="url"]:focus,
.wp-allstars-enhanced-ui select:focus,
.wp-allstars-enhanced-ui textarea:focus {
border-color: #2271b1;
box-shadow: 0 0 0 1px #2271b1;
outline: none;
}
/*
* Responsive Enhancements
*/
@media screen and (max-width: 960px) {
.wp-allstars-enhanced-ui .wp-setting-main,
.wp-allstars-enhanced-ui .wp-allstars-toggle-main {
flex-direction: column;
align-items: flex-start;
}
.wp-allstars-enhanced-ui .wp-setting-left,
.wp-allstars-enhanced-ui .wp-allstars-toggle-left {
margin-bottom: 15px;
}
}
@media screen and (max-width: 782px) {
.wp-allstars-enhanced-ui .wp-setting-row,
.wp-allstars-enhanced-ui .wp-allstars-toggle {
padding: 15px;
}
.wp-allstars-enhanced-ui .wp-toggle-switch {
margin-bottom: 10px;
}
.wp-allstars-enhanced-ui .button {
font-size: 13px;
}
.wp-allstars-card-header,
.wp-allstars-card-content,
.wp-allstars-card-footer {
padding: 15px;
}
.wp-allstars-accordion-header {
padding: 12px 15px;
}
.wp-allstars-accordion-inner {
padding: 15px;
}
}
@media screen and (max-width: 600px) {
.wp-allstars-enhanced-ui .wp-allstars-wrap {
padding: 0 10px 10px;
}
.wp-allstars-card-header,
.wp-allstars-card-content,
.wp-allstars-card-footer {
padding: 12px;
}
.wp-allstars-card-title {
font-size: 15px;
}
.wp-allstars-notification {
padding: 10px 12px;
}
}

View File

@ -1,450 +0,0 @@
<?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

@ -109,13 +109,12 @@ class WP_Allstars_Admin_Manager {
$allowed_options = array(
'wp_allstars_simple_setting',
'wp_allstars_auto_upload_images',
'wp_allstars_admin_color_scheme',
'wp_allstars_max_width',
'wp_allstars_max_height',
'wp_allstars_exclude_urls',
'wp_allstars_image_name_pattern',
'wp_allstars_image_alt_pattern',
'wp_allstars_hide_admin_bar',
'wp_allstars_restrict_dashboard'
'wp_allstars_image_alt_pattern'
);
if (!in_array($option, $allowed_options)) {

View File

@ -29,6 +29,7 @@ class WP_Allstars_Settings_Manager {
public static function register_settings() {
// General settings
register_setting('wp_allstars_settings', 'wp_allstars_simple_setting');
register_setting('wp_allstars_settings', 'wp_allstars_admin_color_scheme');
// Advanced settings
register_setting('wp_allstars_settings', 'wp_allstars_auto_upload_images');
@ -71,7 +72,32 @@ class WP_Allstars_Settings_Manager {
?>
<div class="wp-allstars-settings-section">
<div class="wp-allstars-settings-grid">
<!-- Modern Admin Colors Setting -->
<!-- Admin Color Scheme Setting -->
<div class="wp-setting-row">
<div class="wp-setting-header">
<div class="wp-setting-main">
<div class="wp-setting-left">
<div class="wp-toggle-switch">
<input type="checkbox"
id="wp_allstars_admin_color_scheme"
name="wp_allstars_admin_color_scheme"
value="1"
<?php checked(get_option('wp_allstars_admin_color_scheme', false)); ?>
/>
<span class="wp-toggle-slider"></span>
</div>
<label for="wp_allstars_admin_color_scheme" class="wp-setting-label">
<?php esc_html_e('Modern Admin Colors', 'wp-allstars'); ?>
</label>
</div>
</div>
<p class="wp-setting-description">
<?php esc_html_e('Switch to the Modern Admin colors, to remind that you\'re using WP Allstars.', 'wp-allstars'); ?>
</p>
</div>
</div>
<!-- Example of a simple toggle setting (no panel) -->
<div class="wp-setting-row">
<div class="wp-setting-header">
<div class="wp-setting-main">
@ -86,12 +112,12 @@ class WP_Allstars_Settings_Manager {
<span class="wp-toggle-slider"></span>
</div>
<label for="wp_allstars_simple_setting" class="wp-setting-label">
<?php esc_html_e('Modern Admin Colors', 'wp-allstars'); ?>
<?php esc_html_e('Example: Simple Toggle', 'wp-allstars'); ?>
</label>
</div>
</div>
<p class="wp-setting-description">
<?php esc_html_e('Switch to the Modern Admin colours, to remind that you\'re using an SEO Pro Stack :)', 'wp-allstars'); ?>
<?php esc_html_e('This is an example of a simple toggle setting without an expandable panel. Currently for demonstration purposes only.', 'wp-allstars'); ?>
</p>
</div>
</div>
@ -107,10 +133,41 @@ class WP_Allstars_Settings_Manager {
?>
<div class="wp-allstars-settings-section">
<div class="wp-allstars-settings-grid">
<?php
// Display access control settings
WP_Allstars_Access_Manager::display_access_settings();
?>
<!-- Example of an expandable panel setting -->
<div class="wp-allstars-toggle">
<div class="wp-allstars-toggle-header" aria-expanded="false">
<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>
<?php
@ -127,6 +184,7 @@ class WP_Allstars_Settings_Manager {
// Save general settings
update_option('wp_allstars_simple_setting', isset($_POST['wp_allstars_simple_setting']) ? 1 : 0);
update_option('wp_allstars_admin_color_scheme', isset($_POST['wp_allstars_admin_color_scheme']) ? 1 : 0);
// Save advanced settings
update_option('wp_allstars_auto_upload_images', isset($_POST['wp_allstars_auto_upload_images']) ? 1 : 0);

View File

@ -0,0 +1,74 @@
/**
* WP Allstars Admin Colors Script
*
* Handles toggling the admin color scheme
*/
(function($) {
'use strict';
// Once the DOM is ready
$(document).ready(function() {
// Find the color scheme toggle
var $toggle = $('#wp_allstars_admin_color_scheme');
if (!$toggle.length) {
return;
}
// Listen for changes to the toggle
$toggle.on('change', function() {
var $this = $(this);
var enabled = $this.is(':checked');
var $notification = $this.closest('label').find('.wp-setting-notification');
// Show loading notification
if ($notification.length) {
$notification.text('Saving...').show();
} else {
$notification = $('<span class="wp-setting-notification">Saving...</span>');
$this.closest('label').append($notification);
}
// Send AJAX request
$.ajax({
url: wpAllstarsColors.ajax_url,
type: 'POST',
data: {
action: 'wp_allstars_update_color_scheme',
nonce: wpAllstarsColors.nonce,
enabled: enabled ? 1 : 0
},
success: function(response) {
if (response.success) {
// Show success notification
$notification.text('Saved!').removeClass('error');
// Reload page after a short delay to apply new color scheme
setTimeout(function() {
window.location.reload();
}, 1000);
} else {
// Show error notification
$notification.text('Error').addClass('error');
// Revert toggle
$this.prop('checked', !enabled);
// Log error
console.error('Error updating color scheme:', response.data);
}
},
error: function(xhr, status, error) {
// Show error notification
$notification.text('Error').addClass('error');
// Revert toggle
$this.prop('checked', !enabled);
// Log error
console.error('AJAX error:', error);
}
});
});
});
})(jQuery);

View File

@ -1,387 +1,72 @@
// Define loadTheme in the global scope so it can be called from inline scripts
var loadTheme;
/**
* WP Allstars Admin Script
*
* Handles UI interactions in the admin settings
*/
(function($) {
'use strict';
jQuery(document).ready(function($) {
// Function to show notification
function showNotification(message, $element, isError = false) {
// Remove any existing notifications
$('.wp-setting-notification').remove();
// Document ready handler
$(document).ready(function() {
// Handle toggle switches
$('.wp-toggle-switch input[type="checkbox"]').on('change', function() {
var $this = $(this);
var option = $this.attr('id');
var value = $this.is(':checked') ? 1 : 0;
// Create notification element
var $notification = $('<span class="wp-setting-notification' + (isError ? ' error' : '') + '">' + message + '</span>');
// If element is provided, show notification next to it
if ($element && $element.length) {
$element.after($notification);
} else {
// Fallback to header if no element provided
$('.wp-allstars-header h1').after($notification);
}
// Fade out after delay
setTimeout(function() {
$notification.fadeOut(300, function() {
$(this).remove();
});
}, 2000);
}
// Handle option updates
function updateOption(option, value) {
return $.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'wp_allstars_update_option',
option: option,
value: value,
nonce: wpAllstars.nonce
// Don't handle the admin color scheme toggle here - it has its own handler
if (option === 'wp_allstars_admin_color_scheme') {
return;
}
}).then(function(response) {
if (!response.success) {
throw new Error(response.data || 'Error saving setting');
// Show update notification
var $notification = $this.closest('label').find('.wp-setting-notification');
if ($notification.length === 0) {
$notification = $('<span class="wp-setting-notification">Saving...</span>');
$this.closest('label').append($notification);
} else {
$notification.text('Saving...').removeClass('error').show();
}
return response;
});
}
// Handle toggle switch clicks
$('.wp-toggle-switch').on('click', function(e) {
e.stopPropagation();
var $checkbox = $(this).find('input[type="checkbox"]');
var isChecked = $checkbox.is(':checked');
$checkbox.prop('checked', !isChecked).trigger('change');
});
// Prevent label clicks from toggling the checkbox directly
$('.wp-setting-label, .wp-allstars-toggle-left label').on('click', function(e) {
e.preventDefault();
e.stopPropagation();
});
// Handle checkbox changes
$('.wp-toggle-switch input[type="checkbox"]').on('change', function(e) {
e.stopPropagation();
var $input = $(this);
var option = $input.attr('name');
var value = $input.is(':checked') ? 1 : 0;
var $label = $input.closest('.wp-setting-left, .wp-allstars-toggle-left').find('label');
updateOption(option, value)
.then(function() {
showNotification('Saved', $label);
})
.catch(function() {
showNotification('Error saving settings', $label, true);
});
});
// Handle text input changes
$('.wp-allstars-setting-row input[type="text"], .wp-allstars-setting-row input[type="number"], .wp-allstars-setting-row textarea').on('blur change', function() {
var $input = $(this);
var option = $input.attr('name');
var value = $input.val();
var $label = $input.closest('.wp-allstars-setting-row').find('label').first();
updateOption(option, value)
.then(function() {
showNotification('Saved', $label);
})
.catch(function(error) {
console.error('Error:', error);
showNotification('Error saving setting', $label, true);
});
});
// Toggle expandable panels
$('.wp-allstars-toggle-header').on('click', function(e) {
if (!$(e.target).closest('.wp-toggle-switch').length &&
!$(e.target).closest('label').length) {
var $settings = $(this).closest('.wp-allstars-toggle').find('.wp-allstars-toggle-settings');
var isExpanded = $(this).attr('aria-expanded') === 'true';
$(this).attr('aria-expanded', !isExpanded);
$settings.slideToggle(200);
}
});
// Set initial panel states
$('.wp-allstars-toggle-header').each(function() {
var $settings = $(this).closest('.wp-allstars-toggle').find('.wp-allstars-toggle-settings');
var isExpanded = $(this).attr('aria-expanded') === 'true';
if (!isExpanded) {
$settings.hide();
}
});
// Remove JavaScript-based tab switching - let the native WordPress tab links work
// Plugin category filters
if ($('#wpa-plugin-filters').length) {
$('#wpa-plugin-filters a').on('click', function(e) {
e.preventDefault();
var category = $(this).data('category');
// Update active filter
$('#wpa-plugin-filters a').removeClass('current');
$(this).addClass('current');
// Load plugins for the selected category
loadPlugins(category);
});
// Load initial plugins if we're on the recommended tab
if ($('#recommended').is(':visible') && $('#wpa-plugin-list').is(':empty')) {
loadPlugins('minimal');
}
}
// Load theme tab content if we're on the theme tab
if ($('#theme').is(':visible') && $('#wpa-theme-list').length && $('#wpa-theme-list').is(':empty')) {
loadTheme();
}
// Function to load plugins
function loadPlugins(category) {
var $container = $('#wpa-plugin-list');
var $loadingOverlay = $('<div class="wp-allstars-loading-overlay"><span class="spinner is-active"></span></div>');
// Show loading overlay
$container.css('position', 'relative').append($loadingOverlay);
// Clear existing plugins
$container.empty().append($loadingOverlay);
// AJAX request to get plugins
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'wp_allstars_get_plugins',
category: category,
_wpnonce: wpAllstars.nonce
},
success: function(response) {
// Remove loading overlay
$loadingOverlay.remove();
if (response.success) {
// Append plugins HTML
$container.html(response.data);
// Initialize plugin action buttons
initPluginActions();
// Individual plugin card spinners have been removed
} else {
// Show error message
$container.html('<div class="notice notice-error"><p>' + response.data + '</p></div>');
}
},
error: function(xhr, status, error) {
// Remove loading overlay
$loadingOverlay.remove();
// Show error message
$container.html('<div class="notice notice-error"><p>Failed to load plugins. Please try again. Error: ' + error + '</p></div>');
console.error('AJAX Error:', xhr.responseText);
}
});
}
// Theme handlers are initialized directly from the inline script
// We don't need a separate loadTheme function anymore
// Initialize plugin action buttons
function initPluginActions() {
// Remove any existing event handlers to prevent duplicates
$('.plugin-card .install-now').off('click');
$('.plugin-card .update-now').off('click');
$('.plugin-card .activate-now').off('click');
// Install plugin
$('.plugin-card .install-now').on('click', function(e) {
e.preventDefault();
var $button = $(this);
var slug = $button.data('slug');
$button.addClass('updating-message').text('Installing...');
wp.updates.installPlugin({
slug: slug,
success: function(response) {
$button.removeClass('updating-message').addClass('updated-message').text('Installed!');
setTimeout(function() {
// Replace the button with an activate button
var $parent = $button.parent();
$button.remove();
$parent.html('<a class="button activate-now" href="' + response.activateUrl + '" data-slug="' + slug + '" aria-label="Activate ' + slug + '">Activate</a>');
// Re-initialize the event handlers
initPluginActions();
}, 1000);
},
error: function(response) {
$button.removeClass('updating-message').text('Install Now');
alert(response.errorMessage);
}
});
});
// Update plugin
$('.plugin-card .update-now').on('click', function(e) {
e.preventDefault();
var $button = $(this);
var slug = $button.data('slug');
$button.addClass('updating-message').text('Updating...');
wp.updates.updatePlugin({
slug: slug,
success: function() {
$button.removeClass('updating-message').addClass('updated-message').text('Updated!');
setTimeout(function() {
$button.removeClass('update-now updated-message')
.addClass('button-disabled')
.text('Active');
}, 1000);
},
error: function(response) {
$button.removeClass('updating-message').text('Update Now');
alert(response.errorMessage);
}
});
});
// Activate plugin
$('.plugin-card .activate-now').on('click', function(e) {
e.preventDefault();
var $button = $(this);
var url = $button.attr('href');
var slug = $button.data('slug');
$button.addClass('updating-message').text('Activating...');
// Save the option via AJAX
$.ajax({
url: url,
dataType: 'html',
success: function() {
$button.removeClass('updating-message').addClass('updated-message').text('Activated!');
setTimeout(function() {
// Replace the button with an active button
var $parent = $button.parent();
$button.remove();
$parent.html('<button type="button" class="button button-disabled" disabled="disabled">Active</button>');
}, 1000);
},
error: function() {
$button.removeClass('updating-message').text('Activate');
alert('Failed to activate plugin. Please try again or activate from the Plugins page.');
}
});
});
}
// Expose initPluginActions to global scope for use in other scripts
window.initPluginActions = initPluginActions;
// Initialize theme handlers
function initThemeHandlers() {
console.log('Initializing theme handlers');
// Remove any existing event handlers to prevent duplicates
$('.theme-actions .install-now').off('click');
$('.theme-actions .activate-now').off('click');
// Install theme - use wp.updates.installTheme AJAX method
$('.theme-actions .install-now').on('click', function(e) {
e.preventDefault();
var $button = $(this);
var slug = $button.data('slug');
var buttonText = $button.text();
$button.addClass('updating-message').attr('aria-label', wp.updates.l10n.installing);
wp.updates.installTheme({
slug: slug,
success: function(response) {
$button.removeClass('updating-message').addClass('updated-message').attr('aria-label', wp.updates.l10n.installed);
setTimeout(function() {
// Replace the button with an activate button
var $parent = $button.parent();
$button.remove();
// Create activate URL with nonce
var activateUrl = ajaxurl + '?action=wp_allstars_activate_theme&theme=' + slug + '&_wpnonce=' + wpAllstars.nonce;
$parent.prepend('<a href="' + activateUrl + '" class="button button-primary activate-now" data-slug="' + slug + '" data-name="Kadence" data-nonce="' + wpAllstars.nonce + '">Activate</a>');
// Re-initialize the event handlers
initThemeHandlers();
}, 1000);
},
error: function(response) {
$button.removeClass('updating-message').text(buttonText);
alert(response.errorMessage || 'Error installing theme');
}
});
});
// Activate theme - use AJAX
$('.theme-actions .activate-now').on('click', function(e) {
e.preventDefault();
var $button = $(this);
var slug = $button.data('slug');
var nonce = $button.data('nonce');
var buttonText = $button.text();
$button.addClass('updating-message').attr('aria-label', 'Activating...');
$.ajax({
url: ajaxurl,
url: wpAllstars.ajaxurl,
type: 'POST',
data: {
action: 'wp_allstars_activate_theme',
theme: slug,
_wpnonce: wpAllstars.nonce
action: 'wp_allstars_update_option',
nonce: wpAllstars.nonce,
option: option,
value: value
},
success: function(response) {
if (response.success) {
$button.removeClass('updating-message').addClass('updated-message').attr('aria-label', 'Activated');
$notification.text('Saved!');
setTimeout(function() {
// Replace the button with an active button
var $parent = $button.parent();
$button.remove();
$parent.prepend('<button type="button" class="button button-disabled" disabled="disabled">Active</button>');
// Optionally reload the page to show the activated theme
// window.location.reload();
}, 1000);
$notification.fadeOut(300);
}, 2000);
} else {
$button.removeClass('updating-message').text(buttonText);
alert(response.data || 'Error activating theme');
$notification.text('Error').addClass('error');
console.error('Error saving option:', response.data);
}
},
error: function(xhr, status, error) {
$button.removeClass('updating-message').text(buttonText);
alert('Failed to activate theme. Please try again or activate from the Themes page. Error: ' + error);
$notification.text('Error').addClass('error');
console.error('AJAX error:', error);
}
});
});
}
// Expose initThemeHandlers to global scope for use in other scripts
window.initThemeHandlers = initThemeHandlers;
});
// Toggle expandable panels
$('.wp-allstars-toggle-header').on('click', function() {
var $this = $(this);
var $settings = $this.next('.wp-allstars-toggle-settings');
var isExpanded = $this.attr('aria-expanded') === 'true';
// Toggle aria-expanded attribute
$this.attr('aria-expanded', !isExpanded);
// Toggle settings visibility
$settings.slideToggle(200);
});
});
})(jQuery);

View File

@ -0,0 +1,184 @@
/**
* WP Allstars UI Enhancements
*
* Handles interactions for enhanced UI components
*/
(function($) {
'use strict';
// UI Components Object
var WPAallstarsUI = {
/**
* Initialize all UI components
*/
init: function() {
this.initAccordions();
this.initNotifications();
this.initCards();
// Initialize templates
this.initTemplates();
},
/**
* Initialize accordion functionality
*/
initAccordions: function() {
// Handle accordion toggle
$(document).on('click', '.wp-allstars-accordion-header', function() {
var $header = $(this);
var $content = $header.next('.wp-allstars-accordion-content');
var isExpanded = $header.attr('aria-expanded') === 'true';
// Toggle aria-expanded attribute
$header.attr('aria-expanded', !isExpanded);
// Toggle content visibility with animation
$content.slideToggle(200);
});
},
/**
* Initialize notification system
*/
initNotifications: function() {
// Handle notification dismissal
$(document).on('click', '.wp-allstars-notification-dismiss', function() {
$(this).closest('.wp-allstars-notification').fadeOut(200, function() {
$(this).remove();
});
});
// Auto-dismiss success notifications after 5 seconds
setTimeout(function() {
$('.wp-allstars-notification-success').fadeOut(300, function() {
$(this).remove();
});
}, 5000);
},
/**
* Initialize card components
*/
initCards: function() {
// Add any card-specific interactions here
$('.wp-allstars-card').on('mouseenter', function() {
$(this).addClass('wp-allstars-card-hover');
}).on('mouseleave', function() {
$(this).removeClass('wp-allstars-card-hover');
});
},
/**
* Initialize Underscore.js templates
*/
initTemplates: function() {
// Only proceed if wp.template is available (WordPress admin)
if (typeof wp !== 'undefined' && wp.template) {
// Store template functions for easy access
this.templates = {
accordion: wp.template('wp-allstars-accordion'),
card: wp.template('wp-allstars-card'),
notification: wp.template('wp-allstars-notification')
};
}
},
/**
* Create an accordion
*
* @param {Object} data Accordion data with id, title, and content
* @param {jQuery|String} target Where to append the accordion
* @return {jQuery} The created accordion element
*/
createAccordion: function(data, target) {
if (!this.templates || !this.templates.accordion) {
return $('<div>').text('Template not available');
}
var $accordion = $(this.templates.accordion(data));
if (target) {
if (typeof target === 'string') {
$(target).append($accordion);
} else {
target.append($accordion);
}
}
return $accordion;
},
/**
* Create a card
*
* @param {Object} data Card data with header, content, footer, and icon
* @param {jQuery|String} target Where to append the card
* @return {jQuery} The created card element
*/
createCard: function(data, target) {
if (!this.templates || !this.templates.card) {
return $('<div>').text('Template not available');
}
var $card = $(this.templates.card(data));
if (target) {
if (typeof target === 'string') {
$(target).append($card);
} else {
target.append($card);
}
}
return $card;
},
/**
* Create a notification
*
* @param {Object} data Notification data with type, title, and message
* @param {jQuery|String} target Where to append the notification
* @return {jQuery} The created notification element
*/
createNotification: function(data, target) {
if (!this.templates || !this.templates.notification) {
return $('<div>').text('Template not available');
}
// Set default type if not provided
data.type = data.type || 'info';
var $notification = $(this.templates.notification(data));
if (target) {
if (typeof target === 'string') {
$(target).prepend($notification);
} else {
target.prepend($notification);
}
// Auto-dismiss success notifications
if (data.type === 'success') {
setTimeout(function() {
$notification.fadeOut(300, function() {
$(this).remove();
});
}, 5000);
}
}
return $notification;
}
};
// Initialize on document ready
$(document).ready(function() {
// Initialize UI components
WPAallstarsUI.init();
// Make UI components available globally for use elsewhere
window.WPAallstarsUI = WPAallstarsUI;
});
})(jQuery);

34
debug.php Normal file
View File

@ -0,0 +1,34 @@
<?php
// Debug file to identify WordPress plugin errors
error_reporting(E_ALL);
ini_set('display_errors', 1);
echo "Starting debug process<br>";
// First check free-plugins.php syntax
$output = shell_exec('php -l admin/data/free-plugins.php');
echo "Syntax check for free-plugins.php: " . $output . "<br>";
// Then check class-free-plugins-manager.php syntax
$output = shell_exec('php -l admin/includes/class-free-plugins-manager.php');
echo "Syntax check for class-free-plugins-manager.php: " . $output . "<br>";
// Try including the files
echo "Attempting to include free-plugins.php<br>";
include_once 'admin/data/free-plugins.php';
echo "Successfully included free-plugins.php<br>";
echo "Attempting to include class-free-plugins-manager.php<br>";
include_once 'admin/includes/class-free-plugins-manager.php';
echo "Successfully included class-free-plugins-manager.php<br>";
// Check the function output
if (function_exists('wp_allstars_get_free_plugins')) {
$plugins = wp_allstars_get_free_plugins();
echo "Function wp_allstars_get_free_plugins() exists and returned:<br>";
echo "<pre>";
print_r($plugins);
echo "</pre>";
} else {
echo "Function wp_allstars_get_free_plugins() is not defined<br>";
}

30
debug2.php Normal file
View File

@ -0,0 +1,30 @@
<?php
// Debug file to read and analyze class-free-plugins-manager.php
error_reporting(E_ALL);
ini_set('display_errors', 1);
echo "Reading class-free-plugins-manager.php content:<br>";
$content = file_get_contents('admin/includes/class-free-plugins-manager.php');
if ($content === false) {
echo "Failed to read file<br>";
} else {
// Count how many times 'multisite' appears in the file
$multisite_count = substr_count($content, 'multisite');
echo "Found 'multisite' {$multisite_count} times in the file<br>";
// Line-by-line analysis to find issues around the multisite references
$lines = explode("\n", $content);
for ($i = 0; $i < count($lines); $i++) {
if (strpos($lines[$i], 'multisite') !== false) {
echo "Line " . ($i+1) . ": " . htmlspecialchars($lines[$i]) . "<br>";
// Check a few lines before and after for context
for ($j = max(0, $i-3); $j <= min(count($lines)-1, $i+3); $j++) {
if ($j != $i) {
echo "Context Line " . ($j+1) . ": " . htmlspecialchars($lines[$j]) . "<br>";
}
}
echo "<br>";
}
}
}

View File

@ -5,7 +5,7 @@
* Handles setting the admin color scheme based on user preferences
*
* @package WP_ALLSTARS
* @since 0.2.4
* @since 0.2.3.1
*/
if (!defined('ABSPATH')) {
@ -22,7 +22,7 @@ class WP_Allstars_Admin_Colors {
*
* @var string
*/
private $option_name = 'wp_allstars_simple_setting';
private $option_name = 'wp_allstars_admin_color_scheme';
/**
* Modern color scheme key
@ -44,156 +44,126 @@ class WP_Allstars_Admin_Colors {
public function __construct() {
// Set up hooks
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_color_scheme', array($this, 'handle_color_scheme_update'));
// Add script to handle the toggle
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'));
}
/**
* Add script to show saved notification after page refresh
* Enqueue scripts and styles for the color scheme toggle
*/
public function add_saved_notification_script() {
// Only add on our settings page
public function enqueue_color_scripts() {
// Only enqueue on our plugin pages
$screen = get_current_screen();
if (!$screen || strpos($screen->id, 'wp-allstars') === false) {
if (!isset($screen->id) || 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;
wp_enqueue_script(
'wp-allstars-color-toggle',
plugin_dir_url(dirname(__FILE__)) . 'admin/js/wp-allstars-admin-colors.js',
array('jquery'),
WP_ALLSTARS_VERSION,
true
);
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);
}
wp_localize_script('wp-allstars-color-toggle', 'wpAllstarsColors', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wp_allstars_color_nonce'),
'option_name' => $this->option_name,
));
}
/**
* Enqueue JavaScript to handle toggle and page refresh
*/
public function enqueue_color_scripts($hook) {
// Only load on the plugin settings page
if (strpos($hook, 'wp-allstars') === false) {
return;
}
// Add inline JS for handling toggle and refresh
$color_js = '
jQuery(document).ready(function($) {
// Special handler for admin color scheme toggle
$("#wp_allstars_simple_setting").on("change", function() {
var isEnabled = $(this).is(":checked");
// Save setting via AJAX and refresh page
$.ajax({
url: ajaxurl,
type: "POST",
data: {
action: "wp_allstars_update_option",
option: "wp_allstars_simple_setting",
value: isEnabled ? 1 : 0,
nonce: "' . wp_create_nonce('wp-allstars-nonce') . '"
},
success: function() {
// Refresh the page after successful update
window.location.reload();
}
});
});
});
';
wp_add_inline_script('wp-allstars-admin', $color_js);
}
/**
* Set the admin color scheme based on the setting value
* Set the admin color scheme based on user preference
*/
public function set_admin_color_scheme() {
// Only apply for administrators
if (!current_user_can('manage_options')) {
return;
}
// Get current user
$user_id = get_current_user_id();
if (!$user_id) {
return;
}
// Check if our setting is enabled
$modern_colors_enabled = get_option($this->option_name, false);
// Check if our option is enabled
$enable_modern = get_option($this->option_name, false);
// Get the scheme to set
$scheme = $modern_colors_enabled ? $this->modern_scheme : $this->default_scheme;
// Set the appropriate color scheme
if ($enable_modern) {
// Use modern scheme if available, otherwise use default
$this->set_user_color_scheme($user_id, $this->modern_scheme);
}
}
// Update user meta to set the color scheme
/**
* Set a user's color scheme
*
* @param int $user_id The user ID
* @param string $scheme The color scheme to set
*/
private function set_user_color_scheme($user_id, $scheme) {
// Check if the scheme exists
global $_wp_admin_css_colors;
// If the scheme doesn't exist, use the default
if (!isset($_wp_admin_css_colors[$scheme])) {
$scheme = $this->default_scheme;
}
// Update the user's color scheme
update_user_meta($user_id, 'admin_color', $scheme);
}
/**
* Handle color scheme update via AJAX
* Handle AJAX request to update color scheme
*/
public function handle_color_scheme_update() {
// Check for required params
if (!isset($_POST['option']) || !isset($_POST['value']) || !isset($_POST['nonce'])) {
return;
}
// Verify nonce
check_ajax_referer('wp-allstars-nonce', 'nonce');
// Only process our specific option
if ($_POST['option'] !== $this->option_name) {
return;
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'wp_allstars_color_nonce')) {
wp_send_json_error('Invalid nonce');
}
// Get the current user ID
$user_id = get_current_user_id();
if (!$user_id) {
return;
// Verify user can manage options
if (!current_user_can('manage_options')) {
wp_send_json_error('Insufficient permissions');
}
// Determine which scheme to set based on the value
$value = (bool) $_POST['value'];
$scheme = $value ? $this->modern_scheme : $this->default_scheme;
// Update the user's color scheme
update_user_meta($user_id, 'admin_color', $scheme);
// Get the new value
$enabled = isset($_POST['enabled']) ? (bool) $_POST['enabled'] : false;
// Update the option
update_option($this->option_name, $value ? 1 : 0);
update_option($this->option_name, $enabled);
// Set a transient to show the saved notice
set_transient('wp_allstars_colors_updated_' . $user_id, true, 30);
// Get current user
$user_id = get_current_user_id();
// Return success
wp_send_json_success();
// Set the color scheme
if ($enabled) {
$this->set_user_color_scheme($user_id, $this->modern_scheme);
$message = 'Modern admin colors enabled';
} else {
$this->set_user_color_scheme($user_id, $this->default_scheme);
$message = 'Default admin colors restored';
}
// Send success response
wp_send_json_success(array(
'message' => $message,
'enabled' => $enabled,
));
}
/**
* Check if modern color scheme is enabled
*
* @return bool Whether modern color scheme is enabled
*/
public function is_modern_color_scheme_enabled() {
return (bool) get_option($this->option_name, false);
}
}

View File

@ -0,0 +1,60 @@
<?php
/**
* WP ALLSTARS Sync Guard
*
* Prevents plugin loading during sync operations to avoid fatal errors.
*
* @package WP_ALLSTARS
* @since 0.2.3.1
*/
if (!defined('ABSPATH')) {
exit;
}
/**
* Class responsible for detecting sync operations and preventing plugin loading
*/
class WP_Allstars_Sync_Guard {
/**
* Flag file name for sync operations
*/
const SYNC_FLAG_FILE = '.syncing';
/**
* Check if sync is in progress
*
* @return bool Whether sync is in progress
*/
public static function is_sync_in_progress() {
$flag_file = plugin_dir_path(dirname(__FILE__)) . self::SYNC_FLAG_FILE;
return file_exists($flag_file);
}
/**
* Handle sync mode by showing admin notice and preventing plugin loading
*
* @return bool True if sync is in progress, false otherwise
*/
public static function handle_sync_mode() {
if (self::is_sync_in_progress()) {
// Add admin notice
add_action('admin_notices', array(__CLASS__, 'display_sync_notice'));
// Return true to indicate plugin should not continue loading
return true;
}
return false;
}
/**
* Display sync in progress notice
*/
public static function display_sync_notice() {
echo '<div class="notice notice-warning is-dismissible">';
echo '<p><strong>WP Allstars:</strong> Plugin files are currently syncing. The plugin functionality is temporarily disabled to prevent errors. Please try again in a moment.</p>';
echo '</div>';
}
}

View File

@ -0,0 +1,330 @@
<?php
/**
* WP Allstars UI Enhancements
*
* Responsible for enhancing the WordPress admin interface with improved UI components
* like cards, panels, buttons, and responsive design elements.
*
* @package WP_ALLSTARS
* @version v0.2.3.3
*/
if (!defined('WPINC')) {
exit;
}
class WP_Allstars_UI_Enhancements {
/**
* Constructor
* Initialize hooks and settings
*/
public function __construct() {
// Register scripts and styles
add_action('admin_enqueue_scripts', array($this, 'enqueue_assets'));
// Add body class for enhanced UI
add_filter('admin_body_class', array($this, 'add_body_class'));
// Initialize UI components
$this->init_components();
// Ensure toggle functionality works
add_action('admin_footer', array($this, 'ensure_toggle_functionality'), 99);
}
/**
* Enqueue CSS and JavaScript assets
*/
public function enqueue_assets($hook) {
// Only load on WP Allstars pages
if (strpos($hook, 'wp-allstars') === false) {
return;
}
// Already registered in main plugin file, but ensure they're enqueued
wp_enqueue_style('wp-allstars-admin');
wp_enqueue_script('wp-allstars-admin');
// Add UI enhancements script
wp_enqueue_script(
'wp-allstars-ui-enhancements',
plugin_dir_url(dirname(__FILE__)) . 'admin/js/wp-allstars-ui-enhancements.js',
array('jquery', 'wp-allstars-admin'),
WP_ALLSTARS_VERSION,
true
);
// Add enhanced UI styles
wp_enqueue_style(
'wp-allstars-ui-enhancements',
plugin_dir_url(dirname(__FILE__)) . 'admin/css/wp-allstars-ui-enhancements.css',
array('wp-allstars-admin'),
WP_ALLSTARS_VERSION
);
// Localize script with settings
wp_localize_script('wp-allstars-ui-enhancements', 'wpAllstarsUI', array(
'ajaxurl' => admin_url('ajax.php'),
'nonce' => wp_create_nonce('wp_allstars_ui_nonce'),
));
}
/**
* Add body class for enhanced UI
*/
public function add_body_class($classes) {
if (isset($_GET['page']) && strpos($_GET['page'], 'wp-allstars') !== false) {
$classes .= ' wp-allstars-enhanced-ui';
}
return $classes;
}
/**
* Initialize UI components
*/
private function init_components() {
// Add accordion functionality
add_action('admin_footer', array($this, 'render_accordion_template'));
// Add card component
add_action('admin_footer', array($this, 'render_card_template'));
// Add notification system
add_action('admin_footer', array($this, 'render_notification_template'));
}
/**
* Ensure toggle switch functionality
* This adds JS to reinitialize toggle switch handlers after our enhanced UI is applied
*/
public function ensure_toggle_functionality() {
// Only on WP Allstars pages
if (!isset($_GET['page']) || strpos($_GET['page'], 'wp-allstars') === false) {
return;
}
// Get the nonce value
$nonce = wp_create_nonce('wp-allstars-nonce');
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
// Make sure the wpAllstars object is available
if (typeof wpAllstars === 'undefined') {
window.wpAllstars = {
ajaxurl: '<?php echo esc_url(admin_url('admin-ajax.php')); ?>',
nonce: '<?php echo esc_js($nonce); ?>'
};
}
// Remove any existing handlers first to prevent duplicates
$('.wp-toggle-switch input[type="checkbox"]').off('change');
$('.wp-allstars-toggle-header').off('click');
// Re-bind toggle switch handlers
$('.wp-toggle-switch input[type="checkbox"]').on('change', function() {
console.log('Toggle switch changed:', this.id);
var $this = $(this);
var option = $this.attr('id');
var value = $this.is(':checked') ? 1 : 0;
// Don't handle the admin color scheme toggle here - it has its own handler
if (option === 'wp_allstars_admin_color_scheme') {
return;
}
// Show update notification
var $notification = $this.closest('.wp-setting-left').find('.wp-setting-notification');
if ($notification.length === 0) {
$notification = $('<span class="wp-setting-notification">Saving...</span>');
$this.closest('.wp-setting-left').append($notification);
} else {
$notification.text('Saving...').removeClass('error').show();
}
// Save the option via AJAX
$.ajax({
url: wpAllstars.ajaxurl,
type: 'POST',
data: {
action: 'wp_allstars_update_option',
nonce: wpAllstars.nonce,
option: option,
value: value
},
success: function(response) {
if (response.success) {
$notification.text('Saved!');
setTimeout(function() {
$notification.fadeOut(300);
}, 2000);
} else {
$notification.text('Error').addClass('error');
console.error('Error saving option:', response.data);
}
},
error: function(xhr, status, error) {
$notification.text('Error').addClass('error');
console.error('AJAX error:', error);
}
});
});
// Re-bind expandable panels
$('.wp-allstars-toggle-header').on('click', function() {
var $this = $(this);
var $settings = $this.next('.wp-allstars-toggle-settings');
var isExpanded = $this.attr('aria-expanded') === 'true';
// Toggle aria-expanded attribute
$this.attr('aria-expanded', !isExpanded);
// Toggle settings visibility
$settings.slideToggle(200);
});
// Special handling for admin color scheme toggle if exists
if (typeof wpAllstarsColors !== 'undefined') {
var $colorToggle = $('#wp_allstars_admin_color_scheme');
if ($colorToggle.length) {
$colorToggle.off('change').on('change', function() {
var isModern = $(this).is(':checked');
// Show saving notification
var $notification = $colorToggle.closest('.wp-setting-left').find('.wp-setting-notification');
if ($notification.length === 0) {
$notification = $('<span class="wp-setting-notification">Saving...</span>');
$colorToggle.closest('.wp-setting-left').append($notification);
} else {
$notification.text('Saving...').removeClass('error').show();
}
// Save the option via AJAX
$.ajax({
url: wpAllstarsColors.ajaxurl,
type: 'POST',
data: {
action: 'wp_allstars_update_color_scheme',
nonce: wpAllstarsColors.nonce,
is_modern: isModern ? 1 : 0
},
success: function(response) {
if (response.success) {
if (isModern) {
$('body').addClass('wp-allstars-modern-admin');
} else {
$('body').removeClass('wp-allstars-modern-admin');
}
$notification.text('Saved!');
setTimeout(function() {
$notification.fadeOut(300);
}, 2000);
} else {
$notification.text('Error').addClass('error');
console.error('Error updating color scheme:', response.data);
// Revert toggle
$colorToggle.prop('checked', !isModern);
}
},
error: function(xhr, status, error) {
$notification.text('Error').addClass('error');
console.error('AJAX error:', error);
// Revert toggle
$colorToggle.prop('checked', !isModern);
}
});
});
}
}
});
</script>
<?php
}
/**
* Render accordion template
*/
public function render_accordion_template() {
// Only on WP Allstars pages
if (!isset($_GET['page']) || strpos($_GET['page'], 'wp-allstars') === false) {
return;
}
?>
<script type="text/html" id="tmpl-wp-allstars-accordion">
<div class="wp-allstars-accordion" role="tablist">
<div class="wp-allstars-accordion-header" role="tab" id="accordion-header-{{data.id}}" aria-expanded="false">
<div class="wp-allstars-accordion-title">{{data.title}}</div>
<div class="wp-allstars-accordion-icon"></div>
</div>
<div class="wp-allstars-accordion-content" role="tabpanel" aria-labelledby="accordion-header-{{data.id}}">
<div class="wp-allstars-accordion-inner">
{{{data.content}}}
</div>
</div>
</div>
</script>
<?php
}
/**
* Render card template
*/
public function render_card_template() {
// Only on WP Allstars pages
if (!isset($_GET['page']) || strpos($_GET['page'], 'wp-allstars') === false) {
return;
}
?>
<script type="text/html" id="tmpl-wp-allstars-card">
<div class="wp-allstars-card">
<# if (data.header) { #>
<div class="wp-allstars-card-header">
<# if (data.icon) { #>
<div class="wp-allstars-card-icon">{{{data.icon}}}</div>
<# } #>
<div class="wp-allstars-card-title">{{data.header}}</div>
</div>
<# } #>
<div class="wp-allstars-card-content">
{{{data.content}}}
</div>
<# if (data.footer) { #>
<div class="wp-allstars-card-footer">
{{{data.footer}}}
</div>
<# } #>
</div>
</script>
<?php
}
/**
* Render notification template
*/
public function render_notification_template() {
// Only on WP Allstars pages
if (!isset($_GET['page']) || strpos($_GET['page'], 'wp-allstars') === false) {
return;
}
?>
<script type="text/html" id="tmpl-wp-allstars-notification">
<div class="wp-allstars-notification wp-allstars-notification-{{data.type}}">
<div class="wp-allstars-notification-icon"></div>
<div class="wp-allstars-notification-content">
<# if (data.title) { #>
<div class="wp-allstars-notification-title">{{data.title}}</div>
<# } #>
<div class="wp-allstars-notification-message">{{data.message}}</div>
</div>
<div class="wp-allstars-notification-dismiss"></div>
</div>
</script>
<?php
}
}

View File

@ -6,7 +6,7 @@
* site performance, improve workflow, and provide recommendations for plugins and hosting.
*
* @package WP_ALLSTARS
* @version v0.2.4
* @version v0.2.3.3
*
* Plugin Name: WP Allstars
* Plugin URI: https://wpallstars.com
@ -15,13 +15,13 @@
* Author URI: https://wpallstars.com
* Text Domain: wp-allstars
* Domain Path: /languages
* @version v0.2.4
* @version v0.2.3.3
*
* 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)
* Version: v0.2.3.3 (Beta)
*
* WP Allstars is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -30,61 +30,83 @@
*
* 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 PHP: 7.2
*/
if (!defined('WPINC')) {
exit;
}
// Define plugin version from the file header
if (!function_exists('get_plugin_data')) {
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
define('WP_ALLSTARS_VERSION', 'v0.2.3.3');
/**
* Load files safely by checking if they exist first
*/
function wp_allstars_require_if_exists($file) {
if (file_exists($file)) {
require_once $file;
return true;
}
return false;
}
$plugin_data = get_plugin_data(__FILE__, false, false);
define('WP_ALLSTARS_VERSION', $plugin_data['Version']);
/**
* Check for sync operations before loading the plugin
*/
// Simple sync detection - check for .syncing file
if (file_exists(__DIR__ . '/.syncing')) {
// Only load the minimal code needed for admin notice
if (is_admin()) {
add_action('admin_notices', function() {
echo '<div class="notice notice-warning is-dismissible">';
echo '<p><strong>WP Allstars:</strong> Plugin files are currently syncing. The plugin functionality is temporarily disabled to prevent errors. Please try again in a moment.</p>';
echo '</div>';
});
}
// Exit early to prevent loading other files
return;
}
// Load the sync guard for future use and more advanced sync detection
wp_allstars_require_if_exists(plugin_dir_path(__FILE__) . 'includes/class-wp-allstars-sync-guard.php');
/**
* Plugin activation hook
*/
function wp_allstars_activate() {
// Setup initial configuration when needed
// Setup initial config
}
register_activation_hook(__FILE__, 'wp_allstars_activate');
/**
* Load core plugin components
*/
require_once plugin_dir_path(__FILE__) . 'includes/class-wp-allstars-auto-upload.php';
require_once plugin_dir_path(__FILE__) . 'includes/class-wp-allstars-admin-colors.php';
// Core includes
wp_allstars_require_if_exists(plugin_dir_path(__FILE__) . 'includes/class-wp-allstars-auto-upload.php');
wp_allstars_require_if_exists(plugin_dir_path(__FILE__) . 'includes/class-wp-allstars-admin-colors.php');
wp_allstars_require_if_exists(plugin_dir_path(__FILE__) . 'includes/class-wp-allstars-ui-enhancements.php');
// Load admin-specific components
// Admin includes
if (is_admin()) {
// Include manager classes
require_once plugin_dir_path(__FILE__) . 'admin/includes/class-admin-manager.php';
require_once plugin_dir_path(__FILE__) . 'admin/includes/class-settings-manager.php';
require_once plugin_dir_path(__FILE__) . 'admin/includes/class-theme-manager.php';
require_once plugin_dir_path(__FILE__) . 'admin/includes/class-workflow-manager.php';
require_once plugin_dir_path(__FILE__) . 'admin/includes/class-tools-manager.php';
require_once plugin_dir_path(__FILE__) . 'admin/includes/class-hosting-manager.php';
require_once plugin_dir_path(__FILE__) . 'admin/includes/class-pro-plugins-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-readme-manager.php';
require_once plugin_dir_path(__FILE__) . 'admin/includes/class-access-manager.php';
$admin_includes = array(
'admin/includes/class-admin-manager.php',
'admin/includes/class-settings-manager.php',
'admin/includes/class-theme-manager.php',
'admin/includes/class-workflow-manager.php',
'admin/includes/class-tools-manager.php',
'admin/includes/class-hosting-manager.php',
'admin/includes/class-pro-plugins-manager.php',
'admin/includes/class-plugin-manager.php',
'admin/includes/class-free-plugins-manager.php',
'admin/includes/class-readme-manager.php'
);
// Initialize the admin manager
add_action('plugins_loaded', array('WP_Allstars_Admin_Manager', 'init'));
foreach ($admin_includes as $file) {
wp_allstars_require_if_exists(plugin_dir_path(__FILE__) . $file);
}
// Data files
require_once plugin_dir_path(__FILE__) . 'admin/data/pro-plugins.php';
require_once plugin_dir_path(__FILE__) . 'admin/data/readme.php';
// Settings and data
wp_allstars_require_if_exists(plugin_dir_path(__FILE__) . 'admin/data/pro-plugins.php');
wp_allstars_require_if_exists(plugin_dir_path(__FILE__) . 'admin/data/readme.php');
// Legacy files (for backward compatibility)
require_once plugin_dir_path(__FILE__) . 'admin/settings.php';
// Admin settings
wp_allstars_require_if_exists(plugin_dir_path(__FILE__) . 'admin/settings.php');
}
/**
@ -104,15 +126,14 @@ add_action('init', 'wp_allstars_init_auto_upload');
* Initialize core features
*/
function wp_allstars_init_features() {
// Initialize the Admin Colors feature
new WP_Allstars_Admin_Colors();
// Initialize Admin Colors feature if the class exists
if (class_exists('WP_Allstars_Admin_Colors')) {
new WP_Allstars_Admin_Colors();
}
// Initialize the Access Manager
WP_Allstars_Access_Manager::init();
// Initialize UI Enhancements if the class exists
if (class_exists('WP_Allstars_UI_Enhancements')) {
new WP_Allstars_UI_Enhancements();
}
}
add_action('plugins_loaded', 'wp_allstars_init_features');
/**
* Initialize core plugin classes
*/
$wp_allstars_auto_upload = new WP_Allstars_Auto_Upload();