Compare commits
155 Commits
main
...
feature/v0
Author | SHA1 | Date | |
---|---|---|---|
478be700fc | |||
b5aeeaf2c4 | |||
a4c69999f6 | |||
cd48fcada2 | |||
6daba67a6d | |||
5242d2c20c | |||
994977970b | |||
d490604513 | |||
e57f22f277 | |||
bae13ca936 | |||
c597f21818 | |||
0fdb2a60e2 | |||
b74d8112ca | |||
05ff272b51 | |||
e19dfecd6c | |||
ff306ed32c | |||
bcb4a7e05b | |||
0d3c497b23 | |||
e2bfefc6f6 | |||
5652ae2ad3 | |||
394cefa3cf | |||
d9a06e3813 | |||
f5a17e343e | |||
63c2b7231a | |||
e1e8e19946 | |||
291cbe34f5 | |||
62f368756a | |||
4153564acb | |||
7eef6caab8 | |||
d464d4cbe8 | |||
817b564813 | |||
4f88de74f6 | |||
2998604468 | |||
d89ecc5548 | |||
89009dca92 | |||
a374f26e34 | |||
d9b136f925 | |||
576d79b1e7 | |||
a467a6aa10 | |||
1f885f1745 | |||
2158855a1a | |||
233006f155 | |||
4e951f1fb7 | |||
fd78d35186 | |||
fba03d6e43 | |||
9b307f1b9d | |||
894a31d5b6 | |||
01740ed72c | |||
bbb0dc377a | |||
8e6371fe9d | |||
d9413aff1c | |||
f1c3087900 | |||
2d644e9c37 | |||
fbb4cb69ba | |||
7a3b8a948f | |||
d8130b1e19 | |||
b069bf3f3c | |||
ba0878b230 | |||
4f391f0cda | |||
d5a4a29ae9 | |||
daccb54342 | |||
90f6969e1b | |||
f7b8629926 | |||
aac7ac1195 | |||
6528d8e79a | |||
21b0ef599d | |||
5f45ea85fa | |||
c3d1aff49f | |||
d389f92bd6 | |||
23c5d0adce | |||
1384145138 | |||
169b226a39 | |||
69ad1d55a7 | |||
42150fe694 | |||
6040c1b5bd | |||
1224937955 | |||
34b09de04e | |||
41adfb56e4 | |||
f03da91142 | |||
69623d2660 | |||
e90f6168ed | |||
eb768d9090 | |||
1b548a59e2 | |||
03d9511f4b | |||
2b01f3523f | |||
016f6000a6 | |||
1cf243d5e1 | |||
09aebfcc98 | |||
e00c627410 | |||
c16e1d62fd | |||
ad2aba88a3 | |||
4de39fbd85 | |||
ea881f7691 | |||
19cd4d3355 | |||
5a28089043 | |||
9cd079206f | |||
a82bd8b3f4 | |||
7c6afdc8c7 | |||
f8c098b5a1 | |||
1eb732684b | |||
a4b594c0e2 | |||
5f90586044 | |||
a2b7ba6d72 | |||
e83dbcfff7 | |||
28f87f689e | |||
5f195f8cfb | |||
d2e8cc858c | |||
dc6b1a046f | |||
221eefab9e | |||
a81b6ac5a7 | |||
634f29eee7 | |||
e94a1d902d | |||
1c477aa0f2 | |||
9108a5345c | |||
16d0d5e2ef | |||
8fa4b67da9 | |||
673d4a60fd | |||
4d671d5901 | |||
0c96faaf60 | |||
83d7debe54 | |||
ccc57dc72b | |||
f0d00accaf | |||
19e6455abb | |||
f7fb0c6545 | |||
9e1c077080 | |||
4bbcbe3d12 | |||
46696eff87 | |||
8cef4c8868 | |||
da5d08587c | |||
c2276f4ebd | |||
b267156b68 | |||
ddd64643c4 | |||
ddd2846171 | |||
4fe9d45eba | |||
ad489bddb5 | |||
5fdc3e277c | |||
096c9be284 | |||
2b4e3cecd3 | |||
d280ec197b | |||
5352b38348 | |||
2405f98eb8 | |||
24ffdf8950 | |||
93c3290b63 | |||
436a829646 | |||
20fb06a29e | |||
8fa2b00d7a | |||
f0ffa7e552 | |||
55d092d568 | |||
1b02e8eb24 | |||
c8835de92f | |||
d9c710969b | |||
2c68b66dbc | |||
9b0e7acd2d | |||
930530cc96 | |||
ecd3887bb9 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -38,7 +38,7 @@ $RECYCLE.BIN/
|
||||
.git_status_temp.txt
|
||||
project-documents/
|
||||
reference-plugins/
|
||||
*.bak
|
||||
*.bak*
|
||||
node_modules/
|
||||
composer.lock
|
||||
package-lock.json
|
||||
|
111
DEVELOPMENT.md
Normal file
111
DEVELOPMENT.md
Normal 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
|
14
README.md
14
README.md
@ -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
139
ROADMAP.md
Normal 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
41
STABILITY.md
Normal 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
163
TESTING.md
Normal 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
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
/* Plugin Browser Styles */
|
||||
.wp-allstars-wrap .wp-allstars-plugin-browser {
|
||||
margin: 0 -8px !important;
|
||||
padding: 0 8px !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
@ -9,37 +9,57 @@
|
||||
/* Plugin List Container */
|
||||
.wp-allstars-wrap #wpa-plugin-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Filter Bar */
|
||||
/* Filter Bar - Full Width */
|
||||
.wp-allstars-wrap #wpa-plugin-filters.wp-filter {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
width: 100%;
|
||||
margin: 0 0 11px 0 !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Standard WordPress Plugin Grid Layout - exactly matching core */
|
||||
.wp-allstars-wrap .wp-list-table.plugin-install {
|
||||
margin-top: 20px;
|
||||
clear: both;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.wp-allstars-wrap #the-list {
|
||||
margin: 0;
|
||||
/* Center filter links */
|
||||
.wp-filter .filter-links {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 0;
|
||||
justify-content: center;
|
||||
float: none !important;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Plugin Cards - essential layout only */
|
||||
.wp-filter .filter-links li {
|
||||
float: none;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* Responsive filters */
|
||||
@media screen and (max-width: 782px) {
|
||||
.wp-filter .filter-links li > a {
|
||||
padding: 12px 8px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.wp-filter .filter-links li > a {
|
||||
padding: 10px 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Plugin Cards - Use consistent layout similar to 768px width for all screens */
|
||||
.plugin-card {
|
||||
margin: 0 8px 16px;
|
||||
width: calc(50% - 16px);
|
||||
margin: 0 0 24px 0 !important;
|
||||
width: 100% !important;
|
||||
background-color: #fff;
|
||||
border: 1px solid #dcdcde;
|
||||
border-radius: 8px;
|
||||
@ -47,6 +67,13 @@
|
||||
box-sizing: border-box;
|
||||
transition: all 0.2s ease;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
.plugin-card:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.plugin-card:hover {
|
||||
@ -54,23 +81,123 @@
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* Ensure the right edge aligns with the navigation above */
|
||||
.plugin-card:nth-child(even) {
|
||||
margin-right: 0;
|
||||
/* Card Content */
|
||||
.plugin-card-top {
|
||||
padding: 24px !important;
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.plugin-card:nth-child(odd) {
|
||||
margin-left: 0;
|
||||
.plugin-icon {
|
||||
position: relative !important;
|
||||
float: left !important;
|
||||
width: 64px !important;
|
||||
height: 64px !important;
|
||||
margin: 0 20px 15px 0 !important;
|
||||
}
|
||||
|
||||
/* Consistent styling for all widths */
|
||||
/* Force equal spacing between all cards */
|
||||
.plugin-card:nth-child(odd) {
|
||||
margin-right: 8px;
|
||||
/* Name and description positioning - 768px style */
|
||||
.name.column-name {
|
||||
margin: 0 0 12px 84px !important;
|
||||
margin-right: 0 !important; /* Full width content */
|
||||
}
|
||||
|
||||
.plugin-card:nth-child(even) {
|
||||
margin-left: 8px;
|
||||
.name.column-name h3 {
|
||||
font-size: 16px !important;
|
||||
font-weight: 600 !important;
|
||||
line-height: 1.4 !important;
|
||||
margin: 0 0 12px !important;
|
||||
color: #1d2327 !important;
|
||||
word-wrap: break-word !important;
|
||||
}
|
||||
|
||||
.desc.column-description {
|
||||
margin: 0 0 20px 84px !important;
|
||||
margin-right: 0 !important; /* Full width content */
|
||||
font-size: 14px !important;
|
||||
line-height: 1.6 !important;
|
||||
color: #50575e !important;
|
||||
}
|
||||
|
||||
/* Action Links - Position below content */
|
||||
.action-links {
|
||||
position: relative !important;
|
||||
width: 100% !important;
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
align-items: center !important;
|
||||
justify-content: flex-end !important;
|
||||
gap: 8px !important;
|
||||
padding: 0 !important;
|
||||
margin-top: 10px !important;
|
||||
}
|
||||
|
||||
.plugin-action-buttons {
|
||||
margin: 0 !important;
|
||||
float: none !important;
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
.plugin-action-buttons .button {
|
||||
width: auto !important;
|
||||
min-width: 120px !important;
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
/* Card Bottom - Right aligned compatibility text */
|
||||
.plugin-card-bottom {
|
||||
background: #f6f7f7 !important;
|
||||
padding: 15px 20px !important;
|
||||
border-top: 1px solid #ddd !important;
|
||||
text-align: right !important;
|
||||
margin-top: auto !important;
|
||||
}
|
||||
|
||||
/* Loading Overlay without white background */
|
||||
.wp-allstars-loading-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: transparent !important;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
/* Extra small screens only */
|
||||
@media screen and (max-width: 480px) {
|
||||
.plugin-card {
|
||||
padding-top: 80px !important; /* Space for icon at top */
|
||||
}
|
||||
|
||||
.name.column-name,
|
||||
.desc.column-description {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
.plugin-icon {
|
||||
position: absolute !important;
|
||||
top: 16px !important;
|
||||
left: 16px !important;
|
||||
float: none !important;
|
||||
}
|
||||
|
||||
.action-links {
|
||||
flex-direction: column !important;
|
||||
align-items: stretch !important;
|
||||
}
|
||||
|
||||
.plugin-action-buttons {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.plugin-action-buttons .button {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Global plugin icon positioning that applies to all viewport sizes */
|
||||
@ -144,7 +271,7 @@ body.wp-admin .wp-list-table.plugin-install #the-list .plugin-card .plugin-card-
|
||||
min-height: 100px !important;
|
||||
position: relative !important;
|
||||
padding: 20px !important;
|
||||
padding-top: 20px !important; /* Force top padding to stay at 20px */
|
||||
padding-top: 22px !important; /* Force top padding to stay at 22px */
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
@ -152,7 +279,7 @@ body.wp-admin .wp-list-table.plugin-install #the-list .plugin-card .plugin-card-
|
||||
@supports (display: flex) {
|
||||
body.wp-admin .wp-list-table.plugin-install #the-list .plugin-card .plugin-card-top {
|
||||
padding: 20px !important;
|
||||
padding-top: 20px !important;
|
||||
padding-top: 22px !important;
|
||||
min-height: 100px !important;
|
||||
}
|
||||
}
|
||||
@ -236,13 +363,6 @@ body.wp-admin .plugin-card-bottom {
|
||||
margin-top: 0 !important;
|
||||
text-align: left !important;
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
max-width: none !important;
|
||||
clear: both !important;
|
||||
width: 100% !important;
|
||||
box-sizing: border-box !important;
|
||||
border-bottom-left-radius: 8px !important;
|
||||
border-bottom-right-radius: 8px !important;
|
||||
}
|
||||
|
||||
/* Remove excessive spacing between elements */
|
||||
@ -329,6 +449,40 @@ body.wp-admin .wp-list-table.plugin-install #the-list .plugin-card .action-links
|
||||
line-height: 28px !important;
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
background-color: #d35400 !important;
|
||||
color: #fff !important;
|
||||
border-color: #c24e00 !important;
|
||||
transition: all 0.3s ease !important;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2) !important;
|
||||
position: relative !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
body.wp-admin .wp-list-table.plugin-install #the-list .plugin-card .action-links .button.go-pro::before {
|
||||
content: '' !important;
|
||||
position: absolute !important;
|
||||
top: 0 !important;
|
||||
left: -100% !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent) !important;
|
||||
transition: all 0.5s ease !important;
|
||||
}
|
||||
|
||||
body.wp-admin .wp-list-table.plugin-install #the-list .plugin-card .action-links .button.go-pro:hover {
|
||||
background-color: #aa4300 !important;
|
||||
border-color: #953b00 !important;
|
||||
transform: translateY(-2px) !important;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3) !important;
|
||||
}
|
||||
|
||||
body.wp-admin .wp-list-table.plugin-install #the-list .plugin-card .action-links .button.go-pro:hover::before {
|
||||
left: 100% !important;
|
||||
}
|
||||
|
||||
body.wp-admin .wp-list-table.plugin-install #the-list .plugin-card .action-links .button.go-pro:active {
|
||||
transform: translateY(0) !important;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3) !important;
|
||||
}
|
||||
|
||||
/* Ensure consistent layout for action buttons */
|
||||
@ -370,7 +524,6 @@ body.wp-admin .plugin-card-bottom .compatibility-untested *,
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
.plugin-card:hover {
|
||||
border-color: #999;
|
||||
}
|
||||
@ -523,7 +676,7 @@ body.wp-admin .plugin-card-bottom .compatibility-untested *,
|
||||
.wp-filter {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 12px 0 25px;
|
||||
margin: 12px 0 0;
|
||||
padding: 0 10px;
|
||||
background: #fff;
|
||||
border: 1px solid #dcdcde;
|
||||
@ -617,6 +770,12 @@ body.wp-admin .plugin-card-bottom .compatibility-untested *,
|
||||
}
|
||||
|
||||
/* Theme Browser */
|
||||
.theme-browser {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.theme-browser .theme {
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
@ -750,4 +909,11 @@ body.wp-admin .plugin-card-bottom .compatibility-untested *,
|
||||
|
||||
.theme-browser .theme:nth-child(2n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Theme browser proper layout */
|
||||
.theme-browser .theme:nth-child(2n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
/* Remove media query for wider screens since we're using consistent layout */
|
463
admin/css/wp-allstars-ui-enhancements.css
Normal file
463
admin/css/wp-allstars-ui-enhancements.css
Normal 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;
|
||||
}
|
||||
}
|
161
admin/data/free-plugins.php
Normal file
161
admin/data/free-plugins.php
Normal file
@ -0,0 +1,161 @@
|
||||
<?php
|
||||
/**
|
||||
* Recommended plugins data for WP ALLSTARS plugin
|
||||
*/
|
||||
|
||||
// Define recommended plugins
|
||||
function wp_allstars_get_free_plugins() {
|
||||
return array(
|
||||
'minimal' => array(
|
||||
'antispam-bee',
|
||||
'compressx',
|
||||
'fluent-smtp',
|
||||
'kadence-blocks',
|
||||
'simple-cloudflare-turnstile'
|
||||
),
|
||||
'admin' => array(
|
||||
'admin-bar-dashboard-control',
|
||||
'codepress-admin-columns',
|
||||
'admin-menu-editor',
|
||||
'hide-admin-notices',
|
||||
'mainwp-child',
|
||||
'mainwp-child-reports',
|
||||
'magic-login',
|
||||
'manage-notification-emails',
|
||||
'plugin-groups',
|
||||
'plugin-toggle'
|
||||
),
|
||||
'affiliates' => array(
|
||||
'pretty-links',
|
||||
'simple-urls',
|
||||
'slicewp'
|
||||
),
|
||||
'ai' => array(
|
||||
'ai-engine',
|
||||
),
|
||||
'cms' => array(
|
||||
'auto-post-scheduler',
|
||||
'block-options',
|
||||
'bookmark-card',
|
||||
'browser-shots',
|
||||
'bulk-actions-select-all',
|
||||
'bulk-edit-categories-tags',
|
||||
'bulk-edit-user-profiles-in-spreadsheet',
|
||||
'carbon-copy',
|
||||
'code-block-pro',
|
||||
'iframe-block',
|
||||
'ics-calendar',
|
||||
'mammoth-docx-converter',
|
||||
'nav-menu-roles',
|
||||
'ninja-tables',
|
||||
'post-draft-preview',
|
||||
'post-type-switcher',
|
||||
'simple-custom-post-order',
|
||||
'simple-icons',
|
||||
'sticky-posts-switch',
|
||||
'term-management-tools',
|
||||
'the-paste',
|
||||
'ultimate-addons-for-gutenberg',
|
||||
'wikipedia-preview',
|
||||
'wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages'
|
||||
),
|
||||
'compliance' => array(
|
||||
'avatar-privacy',
|
||||
'complianz-gdpr',
|
||||
'complianz-terms-conditions',
|
||||
'really-simple-ssl'
|
||||
),
|
||||
'crm' => array(
|
||||
'fluent-boards',
|
||||
'fluent-booking',
|
||||
'fluent-community',
|
||||
'fluent-crm',
|
||||
'fluentform',
|
||||
'fluentforms-pdf',
|
||||
'fluentform-block',
|
||||
'fluent-support'
|
||||
),
|
||||
'ecommerce' => array(
|
||||
'woocommerce',
|
||||
'woo-bulk-edit-products',
|
||||
'woo-coupons-bulk-editor',
|
||||
'woocommerce-gateway-gocardless',
|
||||
'kadence-woocommerce-email-designer',
|
||||
'pymntpl-paypal-woocommerce',
|
||||
'woo-stripe-payment'
|
||||
),
|
||||
'lms' => array(
|
||||
'fluent-community',
|
||||
'masterstudy-lms-learning-management-system',
|
||||
'tutor'
|
||||
),
|
||||
'media' => array(
|
||||
'easy-watermark',
|
||||
'enable-media-replace',
|
||||
'image-copytrack',
|
||||
'imsanity',
|
||||
'media-file-renamer',
|
||||
'safe-svg'
|
||||
),
|
||||
'seo' => array(
|
||||
'burst-statistics',
|
||||
'pretty-link',
|
||||
'revive-so',
|
||||
'seo-by-rank-math',
|
||||
'syndication-links',
|
||||
'ultimate-410',
|
||||
'webmention'
|
||||
),
|
||||
'setup' => array(
|
||||
'kadence-starter-templates',
|
||||
'wordpress-importer'
|
||||
),
|
||||
'social' => array(
|
||||
'bit-social',
|
||||
'easy-video-reviews',
|
||||
'social-engine',
|
||||
'wp-social-ninja',
|
||||
'wp-social-reviews'
|
||||
),
|
||||
'speed' => array(
|
||||
'disable-wordpress-updates',
|
||||
'flying-analytics',
|
||||
'flying-pages',
|
||||
'flying-scripts',
|
||||
'freesoul-deactivate-plugins',
|
||||
'index-wp-mysql-for-speed',
|
||||
'litespeed-cache',
|
||||
'performant-translations',
|
||||
'wp-optimize',
|
||||
'wp-widget-disable'
|
||||
),
|
||||
'translation' => array(
|
||||
'hreflang-manager-lite',
|
||||
'performant-translations',
|
||||
'translatepress-multilingual'
|
||||
),
|
||||
'advanced' => array(
|
||||
'acf-better-search',
|
||||
'advanced-custom-fields',
|
||||
'automatorwp',
|
||||
'bit-pi',
|
||||
'bit-integrations',
|
||||
'code-snippets',
|
||||
'easy-code-manager',
|
||||
'favorites',
|
||||
'remove-cpt-base',
|
||||
'remove-old-slugspermalinks',
|
||||
'secure-custom-fields',
|
||||
'yellow-pencil-visual-theme-customizer'
|
||||
),
|
||||
'debug' => array(
|
||||
'advanced-database-cleaner',
|
||||
'debug-log-manager',
|
||||
'gotmls',
|
||||
'query-monitor',
|
||||
'string-locator',
|
||||
'user-switching',
|
||||
'wp-crontrol'
|
||||
)
|
||||
);
|
||||
}
|
167
admin/data/hosting-providers.php
Normal file
167
admin/data/hosting-providers.php
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
/**
|
||||
* Hosting providers data for WP ALLSTARS plugin
|
||||
*/
|
||||
|
||||
// Define hosting providers
|
||||
function wp_allstars_get_hosting_providers() {
|
||||
return array(
|
||||
'closte' => array(
|
||||
'name' => 'Closte',
|
||||
'description' => 'Managed WordPress hosting with advanced performance optimization and auto-scaling.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://closte.com/',
|
||||
'primary' => true
|
||||
),
|
||||
array(
|
||||
'text' => 'Pricing',
|
||||
'url' => 'https://closte.com/pricing'
|
||||
)
|
||||
)
|
||||
),
|
||||
'cloudron' => array(
|
||||
'name' => 'Cloudron',
|
||||
'description' => 'Self-hosted platform that makes it easy to run web applications like WordPress on your server.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.cloudron.io/',
|
||||
'primary' => true
|
||||
),
|
||||
array(
|
||||
'text' => 'Pricing',
|
||||
'url' => 'https://www.cloudron.io/pricing.html'
|
||||
)
|
||||
)
|
||||
),
|
||||
'hostinger' => array(
|
||||
'name' => 'Hostinger',
|
||||
'description' => 'Affordable WordPress hosting with good performance and user-friendly management tools.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.hostinger.com/',
|
||||
'primary' => true
|
||||
),
|
||||
array(
|
||||
'text' => 'Pricing',
|
||||
'url' => 'https://www.hostinger.com/wordpress-hosting'
|
||||
)
|
||||
)
|
||||
),
|
||||
'hetzner' => array(
|
||||
'name' => 'Hetzner Cloud',
|
||||
'description' => 'High-performance cloud servers with excellent price-to-performance ratio for self-managed WordPress hosting.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.hetzner.com/cloud/',
|
||||
'primary' => true
|
||||
),
|
||||
array(
|
||||
'text' => 'Pricing',
|
||||
'url' => 'https://www.hetzner.com/cloud#pricing'
|
||||
)
|
||||
)
|
||||
),
|
||||
'simplehost' => array(
|
||||
'name' => 'SimpleHost',
|
||||
'description' => 'Streamlined WordPress hosting with a focus on simplicity and performance.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://simplehost.so/',
|
||||
'primary' => true
|
||||
),
|
||||
array(
|
||||
'text' => 'Pricing',
|
||||
'url' => 'https://simplehost.so/#pricing'
|
||||
)
|
||||
)
|
||||
),
|
||||
'cloudflare' => array(
|
||||
'name' => 'Cloudflare',
|
||||
'description' => 'Global cloud platform that provides CDN, security, and performance optimization services.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.cloudflare.com/en-gb/',
|
||||
'primary' => true
|
||||
),
|
||||
array(
|
||||
'text' => 'Pricing',
|
||||
'url' => 'https://www.cloudflare.com/en-gb/plans/'
|
||||
)
|
||||
)
|
||||
),
|
||||
'spaceship' => array(
|
||||
'name' => 'Spaceship',
|
||||
'description' => 'Modern hosting platform with advanced features for WordPress sites.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.spaceship.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'101domain' => array(
|
||||
'name' => '101Domain',
|
||||
'description' => 'Domain registration and management service with support for hundreds of TLDs.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.101domain.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'namecheap' => array(
|
||||
'name' => 'Namecheap',
|
||||
'description' => 'Domain registrar and web hosting provider with competitive pricing and good support.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.namecheap.com/',
|
||||
'primary' => true
|
||||
),
|
||||
array(
|
||||
'text' => 'Pricing',
|
||||
'url' => 'https://www.namecheap.com/hosting/shared/'
|
||||
)
|
||||
)
|
||||
),
|
||||
'updownio' => array(
|
||||
'name' => 'Updown.io',
|
||||
'description' => 'Simple and affordable website monitoring service with uptime checks and performance metrics.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://updown.io/',
|
||||
'primary' => true
|
||||
),
|
||||
array(
|
||||
'text' => 'Pricing',
|
||||
'url' => 'https://updown.io/pricing'
|
||||
)
|
||||
)
|
||||
),
|
||||
'coolify' => array(
|
||||
'name' => 'Coolify',
|
||||
'description' => 'Self-hostable Heroku & Netlify alternative for developers. Deploy your apps, databases, and services with ease.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://coolify.io/',
|
||||
'primary' => true
|
||||
),
|
||||
array(
|
||||
'text' => 'Pricing',
|
||||
'url' => 'https://coolify.io/pricing/'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
* Pro Plugins Configuration
|
||||
*/
|
||||
|
||||
function wp_allstars_get_pro_plugins_config() {
|
||||
function wp_allstars_get_pro_plugins() {
|
||||
return array(
|
||||
'magic-login-pro' => array(
|
||||
'name' => 'Magic Login Pro',
|
46
admin/data/readme.php
Normal file
46
admin/data/readme.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* Read Me data for WP ALLSTARS plugin
|
||||
* Content is pulled from the README.md file
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Define readme content
|
||||
function wp_allstars_get_readme_content() {
|
||||
// Get README.md content
|
||||
$readme_path = WP_PLUGIN_DIR . '/wpa-superstar-plugin/README.md';
|
||||
$readme_content = '';
|
||||
|
||||
if (file_exists($readme_path)) {
|
||||
$readme_content = file_get_contents($readme_path);
|
||||
} else {
|
||||
// Fallback content if README.md is not found
|
||||
$readme_content = <<<MARKDOWN
|
||||
# WP Allstars
|
||||
|
||||
A WordPress plugin that enhances your WordPress experience with curated plugins, themes, and optimization tools.
|
||||
|
||||
## Description
|
||||
|
||||
WP Allstars is a powerful WordPress plugin designed to help site owners and developers optimize their WordPress installations. It provides a curated collection of recommended plugins, themes, and optimization tools all in one place.
|
||||
|
||||
## Features
|
||||
|
||||
- **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.
|
||||
- **Workflow Optimization**: Tools to streamline your WordPress workflow.
|
||||
- **Advanced Settings**: Fine-tune your WordPress installation with advanced configuration options.
|
||||
|
||||
Version: {WP_ALLSTARS_VERSION}
|
||||
MARKDOWN;
|
||||
}
|
||||
|
||||
return [
|
||||
'title' => 'Read Me',
|
||||
'content' => $readme_content
|
||||
];
|
||||
}
|
161
admin/data/recommended-plugins.php
Normal file
161
admin/data/recommended-plugins.php
Normal file
@ -0,0 +1,161 @@
|
||||
<?php
|
||||
/**
|
||||
* Recommended plugins data for WP ALLSTARS plugin
|
||||
*/
|
||||
|
||||
// Define recommended plugins
|
||||
function wp_allstars_get_recommended_plugins() {
|
||||
return array(
|
||||
'minimal' => array(
|
||||
'antispam-bee',
|
||||
'compressx',
|
||||
'fluent-smtp',
|
||||
'kadence-blocks',
|
||||
'simple-cloudflare-turnstile'
|
||||
),
|
||||
'admin' => array(
|
||||
'admin-bar-dashboard-control',
|
||||
'codepress-admin-columns',
|
||||
'admin-menu-editor',
|
||||
'hide-admin-notices',
|
||||
'mainwp-child',
|
||||
'mainwp-child-reports',
|
||||
'magic-login',
|
||||
'manage-notification-emails',
|
||||
'plugin-groups',
|
||||
'plugin-toggle'
|
||||
),
|
||||
'affiliates' => array(
|
||||
'pretty-links',
|
||||
'simple-urls',
|
||||
'slicewp'
|
||||
),
|
||||
'ai' => array(
|
||||
'ai-engine',
|
||||
),
|
||||
'cms' => array(
|
||||
'auto-post-scheduler',
|
||||
'block-options',
|
||||
'bookmark-card',
|
||||
'browser-shots',
|
||||
'bulk-actions-select-all',
|
||||
'bulk-edit-categories-tags',
|
||||
'bulk-edit-user-profiles-in-spreadsheet',
|
||||
'carbon-copy',
|
||||
'code-block-pro',
|
||||
'iframe-block',
|
||||
'ics-calendar',
|
||||
'mammoth-docx-converter',
|
||||
'nav-menu-roles',
|
||||
'ninja-tables',
|
||||
'post-draft-preview',
|
||||
'post-type-switcher',
|
||||
'simple-custom-post-order',
|
||||
'simple-icons',
|
||||
'sticky-posts-switch',
|
||||
'term-management-tools',
|
||||
'the-paste',
|
||||
'ultimate-addons-for-gutenberg',
|
||||
'wikipedia-preview',
|
||||
'wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages'
|
||||
),
|
||||
'compliance' => array(
|
||||
'avatar-privacy',
|
||||
'complianz-gdpr',
|
||||
'complianz-terms-conditions',
|
||||
'really-simple-ssl'
|
||||
),
|
||||
'crm' => array(
|
||||
'fluent-boards',
|
||||
'fluent-booking',
|
||||
'fluent-community',
|
||||
'fluent-crm',
|
||||
'fluentform',
|
||||
'fluentforms-pdf',
|
||||
'fluentform-block',
|
||||
'fluent-support'
|
||||
),
|
||||
'ecommerce' => array(
|
||||
'woocommerce',
|
||||
'woo-bulk-edit-products',
|
||||
'woo-coupons-bulk-editor',
|
||||
'woocommerce-gateway-gocardless',
|
||||
'kadence-woocommerce-email-designer',
|
||||
'pymntpl-paypal-woocommerce',
|
||||
'woo-stripe-payment'
|
||||
),
|
||||
'lms' => array(
|
||||
'fluent-community',
|
||||
'masterstudy-lms-learning-management-system',
|
||||
'tutor'
|
||||
),
|
||||
'media' => array(
|
||||
'easy-watermark',
|
||||
'enable-media-replace',
|
||||
'image-copytrack',
|
||||
'imsanity',
|
||||
'media-file-renamer',
|
||||
'safe-svg'
|
||||
),
|
||||
'seo' => array(
|
||||
'burst-statistics',
|
||||
'pretty-link',
|
||||
'revive-so',
|
||||
'seo-by-rank-math',
|
||||
'syndication-links',
|
||||
'ultimate-410',
|
||||
'webmention'
|
||||
),
|
||||
'setup' => array(
|
||||
'kadence-starter-templates',
|
||||
'wordpress-importer'
|
||||
),
|
||||
'social' => array(
|
||||
'bit-social',
|
||||
'easy-video-reviews',
|
||||
'social-engine',
|
||||
'wp-social-ninja',
|
||||
'wp-social-reviews'
|
||||
),
|
||||
'speed' => array(
|
||||
'disable-wordpress-updates',
|
||||
'flying-analytics',
|
||||
'flying-pages',
|
||||
'flying-scripts',
|
||||
'freesoul-deactivate-plugins',
|
||||
'index-wp-mysql-for-speed',
|
||||
'litespeed-cache',
|
||||
'performant-translations',
|
||||
'wp-optimize',
|
||||
'wp-widget-disable'
|
||||
),
|
||||
'translation' => array(
|
||||
'hreflang-manager-lite',
|
||||
'performant-translations',
|
||||
'translatepress-multilingual'
|
||||
),
|
||||
'advanced' => array(
|
||||
'acf-better-search',
|
||||
'advanced-custom-fields',
|
||||
'automatorwp',
|
||||
'bit-pi',
|
||||
'bit-integrations',
|
||||
'code-snippets',
|
||||
'easy-code-manager',
|
||||
'favorites',
|
||||
'remove-cpt-base',
|
||||
'remove-old-slugspermalinks',
|
||||
'secure-custom-fields',
|
||||
'yellow-pencil-visual-theme-customizer'
|
||||
),
|
||||
'debug' => array(
|
||||
'advanced-database-cleaner',
|
||||
'debug-log-manager',
|
||||
'gotmls',
|
||||
'query-monitor',
|
||||
'string-locator',
|
||||
'user-switching',
|
||||
'wp-crontrol'
|
||||
)
|
||||
);
|
||||
}
|
543
admin/data/tools.php
Normal file
543
admin/data/tools.php
Normal file
@ -0,0 +1,543 @@
|
||||
<?php
|
||||
/**
|
||||
* Tools data for WP ALLSTARS plugin
|
||||
*/
|
||||
|
||||
// Define tools
|
||||
function wp_allstars_get_tools() {
|
||||
return array(
|
||||
'advise' => array(
|
||||
'name' => 'Advise.so',
|
||||
'description' => 'Website analytics and optimization tool for improving user experience and conversion rates.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://advise.so/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'seoutils' => array(
|
||||
'name' => 'SEO Utils',
|
||||
'description' => 'Collection of SEO tools to analyze and improve website search engine optimization.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://seoutils.app/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'dataforseo' => array(
|
||||
'name' => 'DataForSEO',
|
||||
'description' => 'API-based SEO data provider for rank tracking, keyword research and competitive analysis.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://dataforseo.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'ahrefs' => array(
|
||||
'name' => 'Ahrefs',
|
||||
'description' => 'Comprehensive SEO toolset for backlink analysis, keyword research, and competitor research.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://ahrefs.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'localrank' => array(
|
||||
'name' => 'LocalRank.so',
|
||||
'description' => 'Local SEO tool for tracking and improving local search rankings for businesses.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://localrank.so/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'turnithuman' => array(
|
||||
'name' => 'Turn It Human',
|
||||
'description' => 'AI content humanizer that makes AI-generated content sound more natural and authentic.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://turnithuman.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'searchconsole' => array(
|
||||
'name' => 'Google Search Console',
|
||||
'description' => 'Free tool from Google to monitor and troubleshoot your site\'s presence in Google Search results.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://search.google.com/search-console/about',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'bingwebmaster' => array(
|
||||
'name' => 'Bing Webmaster Tools',
|
||||
'description' => 'Free tool from Microsoft to help optimize your website for Bing search engine.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.bing.com/webmasters/about',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'fiverr' => array(
|
||||
'name' => 'Fiverr',
|
||||
'description' => 'Freelance services marketplace for businesses to find digital services including web development.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.fiverr.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'legiit' => array(
|
||||
'name' => 'Legiit',
|
||||
'description' => 'Marketplace for digital marketing services including SEO, content writing, and web design.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://legiit.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'openwebui' => array(
|
||||
'name' => 'Open WebUI',
|
||||
'description' => 'Open-source web interface for interacting with AI models and chatbots.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://openwebui.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'nextcloud' => array(
|
||||
'name' => 'Nextcloud',
|
||||
'description' => 'Self-hosted productivity platform and file sync solution for secure collaboration.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://nextcloud.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'enpass' => array(
|
||||
'name' => 'Enpass',
|
||||
'description' => 'Password manager that stores sensitive information locally on your device.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.enpass.io/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'pdfstudio' => array(
|
||||
'name' => 'PDF Studio',
|
||||
'description' => 'Professional PDF editor with advanced features for creating and modifying PDF documents.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.qoppa.com/pdfstudio/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'affinity' => array(
|
||||
'name' => 'Affinity',
|
||||
'description' => 'Professional creative software suite including Photo, Designer, and Publisher applications.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://affinity.serif.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'pixelmator' => array(
|
||||
'name' => 'Pixelmator Pro',
|
||||
'description' => 'Professional image editing software for Mac with powerful tools and an intuitive interface.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.pixelmator.com/pro/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'upscayl' => array(
|
||||
'name' => 'Upscayl',
|
||||
'description' => 'Open-source AI image upscaler that enhances and enlarges images with improved quality.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://upscayl.org/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'sitesucker' => array(
|
||||
'name' => 'SiteSucker',
|
||||
'description' => 'Website downloading tool that allows you to save entire websites for offline viewing.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://ricks-apps.com/osx/sitesucker/index.html',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'virustotal' => array(
|
||||
'name' => 'VirusTotal',
|
||||
'description' => 'Free service that analyzes files and URLs for viruses, worms, trojans, and other malicious content.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.virustotal.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'transmit' => array(
|
||||
'name' => 'Transmit',
|
||||
'description' => 'File transfer client for macOS with support for FTP, SFTP, WebDAV, and cloud services.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://panic.com/transmit/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'iterm2' => array(
|
||||
'name' => 'iTerm2',
|
||||
'description' => 'Terminal emulator for macOS with advanced features beyond the default Terminal app.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://iterm2.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'cloudron' => array(
|
||||
'name' => 'Cloudron',
|
||||
'description' => 'Self-hosted platform that makes it easy to run web applications like WordPress on your server.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.cloudron.io/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'urlmonitor' => array(
|
||||
'name' => 'URL Monitor',
|
||||
'description' => 'Website monitoring service that tracks uptime, performance, and alerts you to issues.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://urlmonitor.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'speedyindex' => array(
|
||||
'name' => 'Speedy Index',
|
||||
'description' => 'Tool for monitoring website indexing speed and performance in search engines.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://en.speedyindex.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'pagespeed' => array(
|
||||
'name' => 'PageSpeed Insights',
|
||||
'description' => 'Google tool that analyzes web page performance on mobile and desktop devices.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://pagespeed.web.dev/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'windsurf' => array(
|
||||
'name' => 'Codeium Windsurf',
|
||||
'description' => 'AI-powered IDE with advanced code completion and generation capabilities.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://codeium.com/windsurf',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'lowfruits' => array(
|
||||
'name' => 'Low Fruits',
|
||||
'description' => 'SEO tool for finding low-competition keywords to target for faster ranking.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://lowfruits.io/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'keysearch' => array(
|
||||
'name' => 'Keysearch',
|
||||
'description' => 'Affordable keyword research tool for finding valuable keywords for SEO.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.keysearch.co/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'smartlead' => array(
|
||||
'name' => 'SmartLead',
|
||||
'description' => 'Email outreach platform for cold email campaigns and lead generation.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.smartlead.ai/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'muraena' => array(
|
||||
'name' => 'Muraena AI',
|
||||
'description' => 'AI-powered writing assistant for creating and optimizing content.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://muraena.ai/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'googlebusiness' => array(
|
||||
'name' => 'Google Business Profile',
|
||||
'description' => 'Free tool to manage your business presence on Google Search and Maps.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://business.google.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'chatgptdetector' => array(
|
||||
'name' => 'ChatGPT Detector',
|
||||
'description' => 'Tool to detect AI-generated content from models like ChatGPT.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://textvisualization.app/chatgpt-detector/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'zerogpt' => array(
|
||||
'name' => 'ZeroGPT',
|
||||
'description' => 'AI content detector that identifies text generated by AI models.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://zerogpt.tools/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'zerogptplus' => array(
|
||||
'name' => 'ZeroGPT Plus',
|
||||
'description' => 'Advanced AI content detector with improved accuracy and additional features.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.zerogpt.plus/en',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'neuronwriter' => array(
|
||||
'name' => 'NeuronWriter',
|
||||
'description' => 'AI-powered SEO content optimization tool for creating high-ranking content.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.neuronwriter.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'serposcope' => array(
|
||||
'name' => 'Serposcope',
|
||||
'description' => 'Open-source rank tracker to monitor website positions in search engines.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.serposcope.com/en/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'searchatlas' => array(
|
||||
'name' => 'Search Atlas',
|
||||
'description' => 'Comprehensive SEO platform with keyword research, rank tracking, and content optimization tools.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://searchatlas.com/',
|
||||
'primary' => true
|
||||
),
|
||||
array(
|
||||
'text' => 'Pricing',
|
||||
'url' => 'https://searchatlas.com/pricing/',
|
||||
'primary' => false
|
||||
)
|
||||
)
|
||||
),
|
||||
'seoptimer' => array(
|
||||
'name' => 'SEOptimer',
|
||||
'description' => 'Website audit tool that provides SEO, usability, and performance recommendations.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.seoptimer.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'jitsi' => array(
|
||||
'name' => 'Jitsi Meet',
|
||||
'description' => 'Free, open-source video conferencing platform with no account required.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://meet.jit.si/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'appsumo' => array(
|
||||
'name' => 'AppSumo',
|
||||
'description' => 'Marketplace for discounted digital products and services for entrepreneurs.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://appsumo.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'screenstudio' => array(
|
||||
'name' => 'Screen Studio',
|
||||
'description' => 'Screen recording software with automatic editing and professional results.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://screen.studio/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'screenflow' => array(
|
||||
'name' => 'ScreenFlow',
|
||||
'description' => 'Professional screen recording and video editing software for macOS.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.telestream.net/screenflow/overview.htm',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'acronis' => array(
|
||||
'name' => 'Acronis Cyber Protect Connect',
|
||||
'description' => 'Remote desktop and support solution for secure access to remote computers.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.acronis.com/en-us/products/cyber-protect-connect/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'espocrm' => array(
|
||||
'name' => 'EspoCRM',
|
||||
'description' => 'Open-source customer relationship management (CRM) application.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.espocrm.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'libreoffice' => array(
|
||||
'name' => 'LibreOffice',
|
||||
'description' => 'Free and open-source office suite compatible with Microsoft Office formats.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://www.libreoffice.org/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'localwp' => array(
|
||||
'name' => 'Local',
|
||||
'description' => 'Local WordPress development tool for creating WordPress sites locally.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://localwp.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'notability' => array(
|
||||
'name' => 'Notability',
|
||||
'description' => 'Note-taking app for iPad and Mac with handwriting and PDF annotation features.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://notability.com/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
'ulysses' => array(
|
||||
'name' => 'Ulysses',
|
||||
'description' => 'Writing app for Mac, iPad, and iPhone with a clean interface and powerful features.',
|
||||
'button_group' => array(
|
||||
array(
|
||||
'text' => 'Home Page',
|
||||
'url' => 'https://ulysses.app/',
|
||||
'primary' => true
|
||||
)
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
314
admin/includes/class-admin-manager.php
Normal file
314
admin/includes/class-admin-manager.php
Normal file
@ -0,0 +1,314 @@
|
||||
<?php
|
||||
/**
|
||||
* WP ALLSTARS Admin Manager
|
||||
*
|
||||
* @package WP_ALLSTARS
|
||||
* @since 0.2.0
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class WP_Allstars_Admin_Manager {
|
||||
|
||||
/**
|
||||
* Initialize the class and register hooks
|
||||
*/
|
||||
public static function init() {
|
||||
add_action('admin_menu', array(__CLASS__, 'register_admin_menu'));
|
||||
add_action('wp_ajax_wp_allstars_update_option', array(__CLASS__, 'update_option'));
|
||||
add_action('admin_init', array(__CLASS__, 'register_settings'));
|
||||
add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueue_admin_scripts'));
|
||||
|
||||
// Initialize all manager classes
|
||||
WP_Allstars_Settings_Manager::init();
|
||||
WP_Allstars_Theme_Manager::init();
|
||||
WP_Allstars_Workflow_Manager::init();
|
||||
WP_Allstars_Pro_Plugins_Manager::init();
|
||||
WP_Allstars_Tools_Manager::init();
|
||||
WP_Allstars_Hosting_Manager::init();
|
||||
WP_Allstars_Free_Plugins_Manager::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue admin scripts and styles
|
||||
*
|
||||
* @param string $hook The current admin page hook
|
||||
*/
|
||||
public static function enqueue_admin_scripts($hook) {
|
||||
if ('settings_page_wp-allstars' !== $hook) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Enqueue admin stylesheet
|
||||
wp_enqueue_style(
|
||||
'wp-allstars-admin',
|
||||
plugins_url('css/wp-allstars-admin.css', dirname(__FILE__)),
|
||||
array(),
|
||||
WP_ALLSTARS_VERSION
|
||||
);
|
||||
|
||||
// Enqueue admin JavaScript
|
||||
wp_enqueue_script(
|
||||
'wp-allstars-admin',
|
||||
plugins_url('js/wp-allstars-admin.js', dirname(__FILE__)),
|
||||
array('jquery'),
|
||||
WP_ALLSTARS_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
// Localize the script with necessary data for AJAX
|
||||
wp_localize_script('wp-allstars-admin', 'wpAllstars', array(
|
||||
'nonce' => wp_create_nonce('wp-allstars-nonce'),
|
||||
'ajaxurl' => admin_url('admin-ajax.php')
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register core plugin settings
|
||||
*/
|
||||
public static function register_settings() {
|
||||
// Core settings groups - tab-specific settings are registered in their respective manager classes
|
||||
register_setting('wp_allstars_general', 'wp_allstars_general_settings');
|
||||
register_setting('wp_allstars_advanced', 'wp_allstars_advanced_settings');
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler for updating options
|
||||
*/
|
||||
public static function update_option() {
|
||||
// Verify nonce for security
|
||||
check_ajax_referer('wp-allstars-nonce', 'nonce');
|
||||
|
||||
// Check if user has proper permissions
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error('Insufficient permissions');
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate and sanitize input
|
||||
if (!isset($_POST['option']) || !isset($_POST['value'])) {
|
||||
wp_send_json_error('Missing required parameters');
|
||||
return;
|
||||
}
|
||||
|
||||
$option = sanitize_text_field($_POST['option']);
|
||||
|
||||
// Different sanitization based on expected value type
|
||||
$value = $_POST['value'];
|
||||
if (is_numeric($value)) {
|
||||
$value = intval($value);
|
||||
} elseif (is_string($value)) {
|
||||
$value = sanitize_text_field($value);
|
||||
} elseif (is_array($value)) {
|
||||
$value = array_map('sanitize_text_field', $value);
|
||||
}
|
||||
|
||||
// Whitelist of allowed options to update for security
|
||||
$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'
|
||||
);
|
||||
|
||||
if (!in_array($option, $allowed_options)) {
|
||||
wp_send_json_error('Invalid option');
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the option
|
||||
$result = update_option($option, $value);
|
||||
|
||||
if ($result) {
|
||||
wp_send_json_success(array(
|
||||
'message' => 'Option updated successfully',
|
||||
'option' => $option,
|
||||
'value' => $value
|
||||
));
|
||||
} else {
|
||||
wp_send_json_success(array(
|
||||
'message' => 'No changes made to option',
|
||||
'option' => $option
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the admin menu item
|
||||
*/
|
||||
public static function register_admin_menu() {
|
||||
add_options_page(
|
||||
'WP ALLSTARS Settings',
|
||||
'WP ALLSTARS',
|
||||
'manage_options',
|
||||
'wp-allstars',
|
||||
array(__CLASS__, 'render_settings_page')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the settings page
|
||||
*/
|
||||
public static function render_settings_page() {
|
||||
global $tabs;
|
||||
|
||||
$active_tab = isset($_GET['tab']) ? $_GET['tab'] : 'general';
|
||||
$active_category = isset($_GET['category']) ? $_GET['category'] : 'minimal';
|
||||
|
||||
// Tab-specific resources
|
||||
if ($active_tab === 'recommended') {
|
||||
WP_Allstars_Plugin_Manager::clear_plugin_cache();
|
||||
wp_enqueue_script('plugin-install');
|
||||
wp_enqueue_script('updates');
|
||||
add_thickbox();
|
||||
wp_enqueue_style('wp-allstars-plugins', plugins_url('css/wp-allstars-plugins.css', dirname(__FILE__)));
|
||||
|
||||
// Add inline script to load plugins on page load
|
||||
wp_add_inline_script('wp-allstars-admin', '
|
||||
jQuery(document).ready(function($) {
|
||||
if ($("#wpa-plugin-list").length && $("#wpa-plugin-list").is(":empty")) {
|
||||
var category = "' . esc_js($active_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);
|
||||
|
||||
// AJAX request to get plugins
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
type: "POST",
|
||||
data: {
|
||||
action: "wp_allstars_get_plugins",
|
||||
category: category,
|
||||
_wpnonce: wpAllstars.nonce
|
||||
},
|
||||
success: function(response) {
|
||||
$loadingOverlay.remove();
|
||||
if (response.success) {
|
||||
$container.html(response.data);
|
||||
// Initialize plugin action buttons
|
||||
if (typeof initPluginActions === "function") {
|
||||
initPluginActions();
|
||||
}
|
||||
|
||||
// Spinners have been removed from individual cards
|
||||
} else {
|
||||
$container.html("<div class=\"notice notice-error\"><p>" + response.data + "</p></div>");
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
$loadingOverlay.remove();
|
||||
$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);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
');
|
||||
}
|
||||
?>
|
||||
<div class="wrap wp-allstars-wrap">
|
||||
<div class="wp-allstars-header">
|
||||
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
|
||||
<div class="wp-allstars-header-actions">
|
||||
<span class="wp-allstars-version"><?php echo esc_html(WP_ALLSTARS_VERSION); ?></span>
|
||||
<a href="https://www.wpallstars.com/" target="_blank" class="button button-secondary green-button-secondary green-visit-website">
|
||||
<?php esc_html_e('Visit Website', 'wp-allstars'); ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wp-allstars-tabs-wrapper">
|
||||
<h2 class="nav-tab-wrapper">
|
||||
<a href="?page=wp-allstars&tab=general" class="nav-tab <?php echo $active_tab === 'general' ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e('General', 'wp-allstars'); ?>
|
||||
</a>
|
||||
<a href="?page=wp-allstars&tab=advanced" class="nav-tab <?php echo $active_tab === 'advanced' ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e('Advanced', 'wp-allstars'); ?>
|
||||
</a>
|
||||
<a href="?page=wp-allstars&tab=workflow" class="nav-tab <?php echo $active_tab === 'workflow' ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e('Workflow', 'wp-allstars'); ?>
|
||||
</a>
|
||||
<a href="?page=wp-allstars&tab=theme" class="nav-tab <?php echo $active_tab === 'theme' ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e('Theme', 'wp-allstars'); ?>
|
||||
</a>
|
||||
<a href="?page=wp-allstars&tab=recommended" class="nav-tab <?php echo $active_tab === 'recommended' ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e('Free Plugins', 'wp-allstars'); ?>
|
||||
</a>
|
||||
<a href="?page=wp-allstars&tab=pro" class="nav-tab <?php echo $active_tab === 'pro' ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e('Pro Plugins', 'wp-allstars'); ?>
|
||||
</a>
|
||||
<a href="?page=wp-allstars&tab=hosting" class="nav-tab <?php echo $active_tab === 'hosting' ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e('Hosting', 'wp-allstars'); ?>
|
||||
</a>
|
||||
<a href="?page=wp-allstars&tab=tools" class="nav-tab <?php echo $active_tab === 'tools' ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e('Tools', 'wp-allstars'); ?>
|
||||
</a>
|
||||
<a href="?page=wp-allstars&tab=readme" class="nav-tab <?php echo $active_tab === 'readme' ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e('Read Me', 'wp-allstars'); ?>
|
||||
</a>
|
||||
</h2>
|
||||
|
||||
<div class="wp-allstars-tab-content">
|
||||
<?php
|
||||
// Each tab's content is handled by its respective manager class
|
||||
switch ($active_tab) {
|
||||
case 'general':
|
||||
WP_Allstars_Settings_Manager::display_general_tab();
|
||||
break;
|
||||
|
||||
case 'advanced':
|
||||
WP_Allstars_Settings_Manager::display_advanced_tab();
|
||||
break;
|
||||
|
||||
case 'workflow':
|
||||
WP_Allstars_Workflow_Manager::display_tab_content();
|
||||
break;
|
||||
|
||||
case 'theme':
|
||||
WP_Allstars_Theme_Manager::display_tab_content();
|
||||
break;
|
||||
|
||||
case 'recommended':
|
||||
WP_Allstars_Free_Plugins_Manager::display_tab_content();
|
||||
break;
|
||||
|
||||
case 'pro':
|
||||
WP_Allstars_Pro_Plugins_Manager::display_tab_content();
|
||||
break;
|
||||
|
||||
case 'hosting':
|
||||
WP_Allstars_Hosting_Manager::display_tab_content();
|
||||
break;
|
||||
|
||||
case 'tools':
|
||||
WP_Allstars_Tools_Manager::display_tab_content();
|
||||
break;
|
||||
|
||||
case 'readme':
|
||||
WP_Allstars_Readme_Manager::display_tab_content();
|
||||
break;
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for enqueue_admin_scripts to maintain compatibility with settings.php
|
||||
*
|
||||
* @param string $hook The current admin page hook
|
||||
*/
|
||||
public static function enqueue_scripts($hook) {
|
||||
self::enqueue_admin_scripts($hook);
|
||||
}
|
||||
}
|
186
admin/includes/class-free-plugins-manager.php
Normal file
186
admin/includes/class-free-plugins-manager.php
Normal file
@ -0,0 +1,186 @@
|
||||
<?php
|
||||
/**
|
||||
* WP ALLSTARS Free Plugins Manager
|
||||
*
|
||||
* Manages the Free Plugins tab including:
|
||||
* - Category filtering system
|
||||
* - Plugin recommendations by use case
|
||||
* - Plugin installation functionality
|
||||
*
|
||||
* @package WP_ALLSTARS
|
||||
* @since 0.2.0
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
/**
|
||||
* WP_Allstars_Free_Plugins_Manager class
|
||||
*
|
||||
* Provides categorized plugin recommendations based on website needs
|
||||
*/
|
||||
class WP_Allstars_Free_Plugins_Manager {
|
||||
|
||||
/**
|
||||
* Initialize the class and register hooks if needed
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function init() {
|
||||
// We'll implement AJAX handlers in a future update if needed
|
||||
// add_action('wp_ajax_wp_allstars_load_free_plugins', array(self::class, 'ajax_load_free_plugins'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the free plugins tab content
|
||||
*
|
||||
* Renders the category filter bar and plugin list container.
|
||||
* Initial view shows 'minimal' category plugins by default.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function display_tab_content() {
|
||||
// Get the active category from query params or use default
|
||||
$active_category = isset($_GET['category']) ? sanitize_text_field($_GET['category']) : 'minimal';
|
||||
|
||||
// Get all available plugin categories from the data file
|
||||
$plugin_categories = wp_allstars_get_free_plugins();
|
||||
|
||||
// Define all categories in the desired display order
|
||||
$priority_categories = array(
|
||||
'minimal', 'admin', 'affiliates', 'ai', 'cms',
|
||||
'compliance', 'crm', 'ecommerce', 'lms', 'media',
|
||||
'seo', 'setup', 'social', 'speed', 'translation',
|
||||
'advanced', 'debug'
|
||||
);
|
||||
|
||||
// Start HTML output
|
||||
?>
|
||||
<div class="wp-allstars-settings-content tab-content" id="recommended">
|
||||
<div id="wpa-plugin-filters" class="wp-filter">
|
||||
<ul class="filter-links">
|
||||
<?php
|
||||
// First output priority categories
|
||||
foreach ($priority_categories as $category) {
|
||||
if (isset($plugin_categories[$category])) {
|
||||
$category_name = ucfirst($category);
|
||||
if ($category == 'cms') $category_name = 'CMS';
|
||||
if ($category == 'crm') $category_name = 'CRM';
|
||||
if ($category == 'ecommerce') $category_name = 'eCommerce';
|
||||
if ($category == 'lms') $category_name = 'LMS';
|
||||
if ($category == 'seo') $category_name = 'SEO';
|
||||
?>
|
||||
<li><a href="#" data-category="<?php echo esc_attr($category); ?>" class="<?php echo $active_category == $category ? 'current' : ''; ?>">
|
||||
<?php echo esc_html($category_name); ?>
|
||||
</a></li>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
// Add any new categories that might have been added to the data file but aren't in our priority list
|
||||
$remaining_categories = array_diff(array_keys($plugin_categories), $priority_categories);
|
||||
sort($remaining_categories);
|
||||
|
||||
foreach ($remaining_categories as $category) {
|
||||
$category_name = ucfirst($category);
|
||||
if ($category == 'cms') $category_name = 'CMS';
|
||||
if ($category == 'crm') $category_name = 'CRM';
|
||||
if ($category == 'ecommerce') $category_name = 'eCommerce';
|
||||
if ($category == 'lms') $category_name = 'LMS';
|
||||
if ($category == 'seo') $category_name = 'SEO';
|
||||
?>
|
||||
<li><a href="#" data-category="<?php echo esc_attr($category); ?>" class="<?php echo $active_category == $category ? 'current' : ''; ?>">
|
||||
<?php echo esc_html($category_name); ?>
|
||||
</a></li>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="wp-allstars-plugin-browser" style="margin-top: 22px;">
|
||||
<div id="wpa-plugin-list" class="wpa-plugin-container" style="position: relative; min-height: 200px;">
|
||||
<!-- Plugin content will be loaded via AJAX -->
|
||||
<div class="wp-allstars-loading-overlay">
|
||||
<span class="spinner is-active"></span>
|
||||
<p>Loading plugin data...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
// Filter tab click handler
|
||||
$('#wpa-plugin-filters .filter-links a').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var category = $(this).data('category');
|
||||
var $container = $('#wpa-plugin-list');
|
||||
|
||||
// Update filter UI
|
||||
$('#wpa-plugin-filters .filter-links a').removeClass('current');
|
||||
$(this).addClass('current');
|
||||
|
||||
// Create new loading overlay
|
||||
$container.empty();
|
||||
var $loadingOverlay = $('<div class="wp-allstars-loading-overlay"><span class="spinner is-active"></span><p>Loading plugin data...</p></div>');
|
||||
$container.append($loadingOverlay);
|
||||
|
||||
// Load plugins in selected category
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'wp_allstars_get_plugins',
|
||||
category: category,
|
||||
_wpnonce: '<?php echo wp_create_nonce('wp-allstars-nonce'); ?>'
|
||||
},
|
||||
success: function(response) {
|
||||
$loadingOverlay.remove();
|
||||
|
||||
if (response.success) {
|
||||
// Add plugins to the container
|
||||
$container.html(response.data);
|
||||
|
||||
// Initialize plugin action buttons (fix for AJAX install/activate functionality)
|
||||
if (typeof initPluginActions === "function") {
|
||||
initPluginActions();
|
||||
} else if (typeof window.initPluginActions === "function") {
|
||||
window.initPluginActions();
|
||||
}
|
||||
} else {
|
||||
$container.html('<div class="notice notice-error"><p>' + response.data + '</p></div>');
|
||||
console.error('Error loading plugins:', response.data);
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
$loadingOverlay.remove();
|
||||
$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);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Load initial category (minimal or from URL)
|
||||
$('#wpa-plugin-filters .filter-links a.current').trigger('click');
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the recommended plugins data
|
||||
*
|
||||
* @return array Array of recommended plugins by category
|
||||
*/
|
||||
public static function get_recommended_plugins() {
|
||||
// Define the plugins data if it hasn't been included yet
|
||||
if (!function_exists('wp_allstars_get_free_plugins')) {
|
||||
require_once dirname(dirname(__FILE__)) . '/data/free-plugins.php';
|
||||
}
|
||||
|
||||
return wp_allstars_get_free_plugins();
|
||||
}
|
||||
}
|
138
admin/includes/class-hosting-manager.php
Normal file
138
admin/includes/class-hosting-manager.php
Normal file
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
/**
|
||||
* WP ALLSTARS Hosting Manager
|
||||
*
|
||||
* Manages the hosting providers tab and functionality
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class WP_Allstars_Hosting_Manager {
|
||||
|
||||
/**
|
||||
* Initialize the class
|
||||
*/
|
||||
public static function init() {
|
||||
add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueue_styles'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the hosting tab content
|
||||
*/
|
||||
public static function display_tab_content() {
|
||||
?>
|
||||
<div class="wp-allstars-settings-content tab-content" id="hosting">
|
||||
<div class="wpa-pro-plugins">
|
||||
<?php
|
||||
$hosting_providers = self::get_hosting_providers();
|
||||
// Sort providers alphabetically by name
|
||||
uasort($hosting_providers, function($a, $b) {
|
||||
return strcasecmp($a['name'], $b['name']);
|
||||
});
|
||||
foreach ($hosting_providers as $provider) {
|
||||
?>
|
||||
<div class="wpa-pro-plugin">
|
||||
<h3><?php echo esc_html($provider['name']); ?></h3>
|
||||
<p><?php echo esc_html($provider['description']); ?></p>
|
||||
<?php if (isset($provider['button_group'])): ?>
|
||||
<div class="button-group">
|
||||
<?php foreach ($provider['button_group'] as $button): ?>
|
||||
<?php
|
||||
$button_class = 'button';
|
||||
if (isset($button['primary']) && $button['primary']) {
|
||||
$button_class .= ' button-primary go-pro-button';
|
||||
} else {
|
||||
// Add green styling to secondary buttons
|
||||
$button_class .= ' green-button-secondary';
|
||||
// Special handling for Pricing buttons
|
||||
if ($button['text'] === 'Pricing') {
|
||||
$button_class .= ' pricing-button';
|
||||
}
|
||||
}
|
||||
?>
|
||||
<a href="<?php echo esc_url($button['url']); ?>" target="_blank" class="<?php echo esc_attr($button_class); ?>">
|
||||
<?php echo esc_html($button['text']); ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of hosting providers
|
||||
*
|
||||
* @return array Array of hosting providers
|
||||
*/
|
||||
public static function get_hosting_providers() {
|
||||
// Define the providers data if it hasn't been included yet
|
||||
if (!function_exists('wp_allstars_get_hosting_providers')) {
|
||||
require_once dirname(dirname(__FILE__)) . '/data/hosting-providers.php';
|
||||
}
|
||||
|
||||
return wp_allstars_get_hosting_providers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue styles for the hosting tab
|
||||
*
|
||||
* @param string $hook Current admin page hook
|
||||
*/
|
||||
public static function enqueue_styles($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 CSS for hosting to match the single column layout
|
||||
$custom_css = '
|
||||
#hosting .wpa-pro-plugins {
|
||||
padding: 15px 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
#hosting .wpa-pro-plugin {
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
padding: 24px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
width: 100%;
|
||||
margin-bottom: 24px;
|
||||
max-width: 100%;
|
||||
}
|
||||
#hosting .wpa-pro-plugin:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
#hosting .wpa-pro-plugin:hover {
|
||||
border-color: #2271b1;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.15);
|
||||
}
|
||||
#hosting .wpa-pro-plugin .button-group {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
';
|
||||
|
||||
wp_add_inline_style('wp-allstars-admin', $custom_css);
|
||||
}
|
||||
}
|
363
admin/includes/class-plugin-manager.php
Normal file
363
admin/includes/class-plugin-manager.php
Normal file
@ -0,0 +1,363 @@
|
||||
<?php
|
||||
/**
|
||||
* WP ALLSTARS Plugin Manager
|
||||
*
|
||||
* Core class for handling WordPress plugin data and operations:
|
||||
* - Plugin data retrieval and caching mechanism
|
||||
* - AJAX handlers for asynchronous plugin data loading
|
||||
* - Plugin card UI generation with install/update actions
|
||||
* - Cache clearing on plugin changes
|
||||
*
|
||||
* @package WP_ALLSTARS
|
||||
* @since 0.2.0
|
||||
*/
|
||||
|
||||
// Exit if accessed directly
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* WP_Allstars_Plugin_Manager class
|
||||
*
|
||||
* Manages the Free Plugins tab and provides core plugin functionality
|
||||
* for other plugin-related managers.
|
||||
*/
|
||||
class WP_Allstars_Plugin_Manager {
|
||||
/**
|
||||
* Initialize the class and register all action hooks
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function init() {
|
||||
// Register AJAX handler for plugin data retrieval
|
||||
add_action('wp_ajax_wp_allstars_get_plugins', [self::class, 'ajax_get_plugins']);
|
||||
|
||||
// Register hooks for automatic cache clearing when plugins change
|
||||
add_action('upgrader_process_complete', [self::class, 'clear_plugin_cache'], 10, 0);
|
||||
add_action('activated_plugin', [self::class, 'clear_plugin_cache']);
|
||||
add_action('deactivated_plugin', [self::class, 'clear_plugin_cache']);
|
||||
add_action('deleted_plugin', [self::class, 'clear_plugin_cache']);
|
||||
add_action('update_option_active_plugins', [self::class, 'clear_plugin_cache']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cached plugin data for a specific category
|
||||
*
|
||||
* Uses the WordPress transients API to store plugin data
|
||||
* for improved performance and reduced API calls.
|
||||
*
|
||||
* @param string $category The plugin category to retrieve (e.g., 'featured', 'popular')
|
||||
* @return mixed Array of plugin data if cache exists, false otherwise
|
||||
*/
|
||||
public static function get_cached_plugins($category) {
|
||||
$cache_key = 'wp_allstars_plugins_' . sanitize_key($category);
|
||||
$cached_data = get_transient($cache_key);
|
||||
|
||||
if ($cached_data !== false) {
|
||||
return $cached_data;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cached plugin data for a category
|
||||
*
|
||||
* @param string $category The plugin category
|
||||
* @param mixed $data The data to cache
|
||||
*/
|
||||
public static function set_cached_plugins($category, $data) {
|
||||
$cache_key = 'wp_allstars_plugins_' . $category;
|
||||
set_transient($cache_key, $data, 12 * HOUR_IN_SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler for getting plugin data
|
||||
*/
|
||||
public static function ajax_get_plugins() {
|
||||
// Check nonce with the correct action name
|
||||
if (!check_ajax_referer('wp-allstars-nonce', false, false)) {
|
||||
wp_send_json_error('Invalid security token sent.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!current_user_can('install_plugins')) {
|
||||
wp_die(-1);
|
||||
}
|
||||
|
||||
$category = isset($_POST['category']) ? sanitize_key($_POST['category']) : 'minimal';
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
|
||||
|
||||
// Get our recommended plugins for this category
|
||||
$recommended_plugins = wp_allstars_get_free_plugins();
|
||||
if (!isset($recommended_plugins[$category])) {
|
||||
wp_send_json_error('Invalid category: ' . $category);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to get cached data first
|
||||
$cached_data = self::get_cached_plugins($category);
|
||||
if ($cached_data !== false) {
|
||||
error_log('Using cached data for category: ' . $category);
|
||||
try {
|
||||
// Generate plugin cards HTML
|
||||
$html = self::generate_plugin_cards($cached_data->plugins);
|
||||
wp_send_json_success($html);
|
||||
return;
|
||||
} catch (Exception $e) {
|
||||
error_log('Error displaying cached plugins: ' . $e->getMessage());
|
||||
// Fall through to fetch fresh data
|
||||
}
|
||||
}
|
||||
|
||||
error_log('Fetching fresh data for category: ' . $category);
|
||||
error_log('Plugins to fetch: ' . implode(', ', $recommended_plugins[$category]));
|
||||
|
||||
try {
|
||||
$plugins = array();
|
||||
|
||||
// Only fetch plugins that are in our recommended list for this category
|
||||
foreach ($recommended_plugins[$category] as $slug) {
|
||||
try {
|
||||
error_log('Fetching plugin data for: ' . $slug);
|
||||
$plugin_data = plugins_api('plugin_information', array(
|
||||
'slug' => $slug,
|
||||
'fields' => array(
|
||||
'short_description' => true,
|
||||
'sections' => false,
|
||||
'requires' => true,
|
||||
'rating' => true,
|
||||
'ratings' => false,
|
||||
'downloaded' => true,
|
||||
'last_updated' => true,
|
||||
'added' => false,
|
||||
'tags' => false,
|
||||
'compatibility' => false,
|
||||
'homepage' => true,
|
||||
'versions' => false,
|
||||
'donate_link' => false,
|
||||
'reviews' => false,
|
||||
'banners' => false,
|
||||
'icons' => true,
|
||||
'active_installs' => true,
|
||||
'group' => false,
|
||||
'contributors' => false,
|
||||
)
|
||||
));
|
||||
|
||||
if (is_wp_error($plugin_data)) {
|
||||
error_log('Error fetching plugin data for ' . $slug . ': ' . $plugin_data->get_error_message());
|
||||
} else {
|
||||
$plugins[] = $plugin_data;
|
||||
error_log('Successfully fetched data for: ' . $slug);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log('Exception fetching plugin data for ' . $slug . ': ' . $e->getMessage());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($plugins)) {
|
||||
wp_send_json_error('No plugin data could be retrieved for category: ' . $category);
|
||||
return;
|
||||
}
|
||||
|
||||
error_log('Total plugins fetched: ' . count($plugins));
|
||||
|
||||
// Create response object
|
||||
$res = (object) array(
|
||||
'info' => array(
|
||||
'page' => 1,
|
||||
'pages' => 1,
|
||||
'results' => count($plugins),
|
||||
),
|
||||
'plugins' => $plugins
|
||||
);
|
||||
|
||||
// Cache the results
|
||||
self::set_cached_plugins($category, $res);
|
||||
|
||||
// Generate plugin cards HTML
|
||||
$html = self::generate_plugin_cards($plugins);
|
||||
wp_send_json_success($html);
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log('Failed to fetch plugin data: ' . $e->getMessage());
|
||||
wp_send_json_error('Failed to fetch plugin data: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate HTML for plugin cards
|
||||
*
|
||||
* @param array $plugins Array of plugin data
|
||||
* @return string HTML for the plugin cards
|
||||
*/
|
||||
public static function generate_plugin_cards($plugins) {
|
||||
if (empty($plugins)) {
|
||||
return '<div class="notice notice-error"><p>No plugins found.</p></div>';
|
||||
}
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="wp-list-table widefat plugin-install">
|
||||
<div id="the-list">
|
||||
<?php foreach ($plugins as $plugin): ?>
|
||||
<div class="plugin-card plugin-card-<?php echo esc_attr($plugin->slug); ?>">
|
||||
<div class="plugin-card-top">
|
||||
<div class="name column-name">
|
||||
<h3>
|
||||
<?php echo esc_html($plugin->name); ?>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="action-links">
|
||||
<ul class="plugin-action-buttons">
|
||||
<?php
|
||||
$status = install_plugin_install_status($plugin);
|
||||
switch ($status['status']) {
|
||||
case 'install':
|
||||
echo '<li><a class="button install-now" data-slug="' . esc_attr($plugin->slug) . '" href="' . esc_url($status['url']) . '" aria-label="' . esc_attr(sprintf(__('Install %s now'), $plugin->name)) . '">' . __('Install now') . '</a></li>';
|
||||
break;
|
||||
case 'update_available':
|
||||
echo '<li><a class="button button-primary update-now" data-plugin="' . esc_attr($status['file']) . '" data-slug="' . esc_attr($plugin->slug) . '" href="' . esc_url($status['url']) . '" aria-label="' . esc_attr(sprintf(__('Update %s now'), $plugin->name)) . '">' . __('Update Now') . '</a></li>';
|
||||
break;
|
||||
case 'latest_installed':
|
||||
case 'newer_installed':
|
||||
if (is_plugin_active($status['file'])) {
|
||||
echo '<li><button type="button" class="button button-disabled" disabled="disabled">' . __('Active') . '</button></li>';
|
||||
} else {
|
||||
echo '<li><a class="button button-primary activate-now" href="' . esc_url(wp_nonce_url('plugins.php?action=activate&plugin=' . $status['file'], 'activate-plugin_' . $status['file'])) . '" aria-label="' . esc_attr(sprintf(__('Activate %s'), $plugin->name)) . '">' . __('Activate') . '</a></li>';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Add PRO button if available
|
||||
self::add_pro_button($plugin);
|
||||
|
||||
// Add "More Details" link
|
||||
echo '<li><a class="thickbox open-plugin-details-modal" href="' . esc_url(admin_url('plugin-install.php?tab=plugin-information&plugin=' . $plugin->slug . '&TB_iframe=true&width=600&height=550')) . '" aria-label="' . esc_attr(sprintf(__('More information about %s'), $plugin->name)) . '">' . __('More Details') . '</a></li>';
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php if (!empty($plugin->icons) && !empty($plugin->icons['1x'])): ?>
|
||||
<div class="plugin-icon">
|
||||
<img src="<?php echo esc_url($plugin->icons['1x']); ?>" alt="">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="desc column-description">
|
||||
<p><?php echo esc_html($plugin->short_description); ?></p>
|
||||
<p class="authors">
|
||||
<cite><?php printf(__('By %s'), $plugin->author); ?></cite>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="plugin-card-bottom">
|
||||
<div class="vers column-rating">
|
||||
<?php wp_star_rating(array('rating' => $plugin->rating, 'type' => 'percent', 'number' => $plugin->num_ratings)); ?>
|
||||
<span class="num-ratings" aria-hidden="true">(<?php echo number_format_i18n($plugin->num_ratings); ?>)</span>
|
||||
</div>
|
||||
<div class="column-updated">
|
||||
<strong><?php _e('Last Updated:'); ?></strong>
|
||||
<?php printf(__('%s ago'), human_time_diff(strtotime($plugin->last_updated))); ?>
|
||||
</div>
|
||||
<div class="column-downloaded">
|
||||
<?php
|
||||
if ($plugin->active_installs >= 1000000) {
|
||||
$active_installs_millions = floor($plugin->active_installs / 1000000);
|
||||
$active_installs_text = sprintf(
|
||||
_n('%s+ Million Active Installations', '%s+ Million Active Installations', $active_installs_millions),
|
||||
number_format_i18n($active_installs_millions)
|
||||
);
|
||||
} elseif (0 == $plugin->active_installs) {
|
||||
$active_installs_text = _x('Less Than 10 Active Installations', 'Active plugin installations');
|
||||
} else {
|
||||
$active_installs_text = sprintf(
|
||||
_n('%s+ Active Installation', '%s+ Active Installations', $plugin->active_installs),
|
||||
number_format_i18n($plugin->active_installs)
|
||||
);
|
||||
}
|
||||
/* translators: %s: number of active installations */
|
||||
echo esc_html($active_installs_text);
|
||||
?>
|
||||
</div>
|
||||
<div class="column-compatibility">
|
||||
<?php
|
||||
$version = get_bloginfo('version');
|
||||
if (!empty($plugin->tested) && version_compare($version, $plugin->tested, '>')) {
|
||||
echo '<span class="compatibility-untested">' . __('Untested with your version of WordPress') . '</span>';
|
||||
} elseif (!empty($plugin->requires) && version_compare($version, $plugin->requires, '<')) {
|
||||
echo '<span class="compatibility-incompatible">' . __('Incompatible with your version of WordPress') . '</span>';
|
||||
} else {
|
||||
echo '<span class="compatibility-compatible">' . __('Compatible with your version of WordPress') . '</span>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add PRO button to plugin cards if a pro version exists
|
||||
*
|
||||
* @param object $plugin The plugin object
|
||||
*/
|
||||
public static function add_pro_button($plugin) {
|
||||
$pro_plugins = wp_allstars_get_pro_plugins();
|
||||
|
||||
if (isset($pro_plugins[$plugin->slug])) {
|
||||
$pro_plugin = $pro_plugins[$plugin->slug];
|
||||
$pro_url = self::get_pro_plugin_url($pro_plugin);
|
||||
|
||||
if (!empty($pro_url)) {
|
||||
echo '<li><a href="' . esc_url($pro_url) . '" target="_blank" class="button button-primary go-pro-button">' . esc_html__('Go Pro', 'wp-allstars') . '</a></li>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL for a pro plugin from its config
|
||||
*
|
||||
* @param array $pro_plugin The pro plugin configuration array
|
||||
* @return string The URL for the pro plugin
|
||||
*/
|
||||
public static function get_pro_plugin_url($pro_plugin) {
|
||||
// First check if there's a button_group defined
|
||||
if (isset($pro_plugin['button_group']) && is_array($pro_plugin['button_group'])) {
|
||||
foreach ($pro_plugin['button_group'] as $button) {
|
||||
// Return the URL for the primary button if available
|
||||
if (isset($button['primary']) && $button['primary'] && !empty($button['url'])) {
|
||||
return $button['url'];
|
||||
}
|
||||
}
|
||||
|
||||
// If no primary button found, return the first button URL
|
||||
if (!empty($pro_plugin['button_group'][0]['url'])) {
|
||||
return $pro_plugin['button_group'][0]['url'];
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to the main URL if available
|
||||
if (!empty($pro_plugin['url'])) {
|
||||
return $pro_plugin['url'];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear plugin cache when plugins are updated, activated, or deactivated
|
||||
*/
|
||||
public static function clear_plugin_cache() {
|
||||
$recommended_plugins = wp_allstars_get_free_plugins();
|
||||
foreach (array_keys($recommended_plugins) as $category) {
|
||||
delete_transient('wp_allstars_plugins_' . $category);
|
||||
}
|
||||
}
|
||||
}
|
227
admin/includes/class-pro-plugins-manager.php
Normal file
227
admin/includes/class-pro-plugins-manager.php
Normal file
@ -0,0 +1,227 @@
|
||||
<?php
|
||||
/**
|
||||
* WP ALLSTARS Pro Plugins Manager
|
||||
*
|
||||
* Handles premium plugin recommendations including:
|
||||
* - Premium plugin information display
|
||||
* - Purchase links and affiliate management
|
||||
* - Plugin feature highlighting
|
||||
* - Price and promotion display
|
||||
*
|
||||
* @package WP_ALLSTARS
|
||||
* @since 0.2.0
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('WPINC')) {
|
||||
die;
|
||||
}
|
||||
|
||||
/**
|
||||
* WP_Allstars_Pro_Plugins_Manager class
|
||||
*
|
||||
* Responsible for the Pro Plugins tab in the plugin interface.
|
||||
*/
|
||||
class WP_Allstars_Pro_Plugins_Manager {
|
||||
|
||||
/**
|
||||
* Initialize the class and register required hooks
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function init() {
|
||||
// Enqueue pro plugins specific styles
|
||||
add_action('admin_enqueue_scripts', array(self::class, 'enqueue_styles'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all pro plugin configurations
|
||||
*
|
||||
* Retrieves premium plugin information from configuration,
|
||||
* including pricing, features, and purchase links.
|
||||
*
|
||||
* @return array Array of premium plugin data
|
||||
*/
|
||||
public static function get_pro_plugins() {
|
||||
// Load pro plugin configuration from the data file
|
||||
return wp_allstars_get_pro_plugins();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the pro plugins tab content
|
||||
*
|
||||
* Renders the premium plugins tab with plugin cards
|
||||
* in alphabetical order by name.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function display_tab_content() {
|
||||
// Get premium plugin data
|
||||
$pro_plugins = self::get_pro_plugins();
|
||||
|
||||
// Sort plugins alphabetically by name for consistent display
|
||||
uasort($pro_plugins, function($a, $b) {
|
||||
return strcasecmp($a['name'], $b['name']);
|
||||
});
|
||||
|
||||
// Start the tab content container
|
||||
echo '<div class="wp-allstars-settings-content tab-content" id="pro"><div class="wpa-pro-plugins">';
|
||||
|
||||
// Render each plugin card
|
||||
foreach ($pro_plugins as $plugin) {
|
||||
self::display_plugin_card($plugin);
|
||||
}
|
||||
|
||||
// Close the container
|
||||
echo '</div></div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a single plugin card
|
||||
*
|
||||
* @param array $plugin Plugin configuration
|
||||
*/
|
||||
public static function display_plugin_card($plugin) {
|
||||
?>
|
||||
<div class="wpa-pro-plugin">
|
||||
<h3><?php echo esc_html($plugin['name']); ?></h3>
|
||||
<p><?php echo esc_html($plugin['description']); ?></p>
|
||||
<?php if (isset($plugin['button_group'])): ?>
|
||||
<div class="button-group">
|
||||
<?php foreach ($plugin['button_group'] as $button): ?>
|
||||
<?php
|
||||
$button_class = 'button';
|
||||
if (isset($button['primary']) && $button['primary']) {
|
||||
$button_class .= ' button-primary';
|
||||
// Add green color to 'Go Pro' buttons
|
||||
if ($button['text'] === 'Go Pro') {
|
||||
$button_class .= ' go-pro-button';
|
||||
}
|
||||
} else {
|
||||
// Add green styling to secondary buttons
|
||||
$button_class .= ' green-button-secondary';
|
||||
// Special handling for Pricing buttons
|
||||
if ($button['text'] === 'Pricing') {
|
||||
$button_class .= ' pricing-button';
|
||||
}
|
||||
}
|
||||
?>
|
||||
<a href="<?php echo esc_url($button['url']); ?>" target="_blank" class="<?php echo esc_attr($button_class); ?>">
|
||||
<?php echo esc_html($button['text']); ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="button-group">
|
||||
<?php if (!empty($plugin['demo_url'])): ?>
|
||||
<a href="<?php echo esc_url($plugin['demo_url']); ?>" class="button green-button-secondary" target="_blank">
|
||||
<?php esc_html_e('View Demo', 'wp-allstars'); ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<a href="<?php echo esc_url($plugin['url']); ?>" class="button button-primary go-pro-button" target="_blank">
|
||||
<?php esc_html_e('Learn More', 'wp-allstars'); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue styles specific to pro plugins
|
||||
*/
|
||||
public static function enqueue_styles($hook) {
|
||||
// Only load on the plugin settings page
|
||||
if (strpos($hook, 'wp-allstars') === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add inline CSS for pro plugins
|
||||
$custom_css = '
|
||||
.wpa-pro-plugins {
|
||||
padding: 15px 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.wpa-pro-plugin {
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
padding: 24px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
width: 100%;
|
||||
margin-bottom: 24px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.wpa-pro-plugin:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.wpa-pro-plugin:hover {
|
||||
border-color: #2271b1;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.15);
|
||||
}
|
||||
.wpa-pro-plugin h3 {
|
||||
margin: 0 0 12px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #1d2327;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.wpa-pro-plugin p {
|
||||
margin: 0 0 16px;
|
||||
color: #50575e;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.wpa-pro-plugin .button-group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-top: auto;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.wpa-pro-plugin .button {
|
||||
text-decoration: none;
|
||||
min-width: 120px;
|
||||
text-align: center;
|
||||
height: 30px;
|
||||
line-height: 28px;
|
||||
padding: 0 12px;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
border: 1px solid #0071a1 !important;
|
||||
border-radius: 3px !important;
|
||||
background: #f6f7f7;
|
||||
color: #0071a1;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
box-shadow: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.wpa-pro-plugin .button:hover {
|
||||
background: #f0f0f1;
|
||||
border-color: #0071a1;
|
||||
color: #0071a1;
|
||||
}
|
||||
.wpa-pro-plugin .button-primary {
|
||||
background: #0071a1;
|
||||
border-color: #0071a1;
|
||||
color: #fff;
|
||||
}
|
||||
.wpa-pro-plugin .button-primary:hover {
|
||||
background: #006291;
|
||||
border-color: #006291;
|
||||
color: #fff;
|
||||
}
|
||||
';
|
||||
|
||||
wp_add_inline_style('wp-allstars-admin', $custom_css);
|
||||
}
|
||||
}
|
126
admin/includes/class-readme-manager.php
Normal file
126
admin/includes/class-readme-manager.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* Read Me Manager Class
|
||||
*
|
||||
* @package WP_ALLSTARS
|
||||
* @since 0.2.0
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class WP_Allstars_Readme_Manager {
|
||||
|
||||
/**
|
||||
* Initialize the class
|
||||
*/
|
||||
public static function init() {
|
||||
add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueue_styles'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue styles for the readme tab
|
||||
*
|
||||
* @param string $hook Current admin page hook
|
||||
*/
|
||||
public static function enqueue_styles($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
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the readme content
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_readme_content() {
|
||||
return wp_allstars_get_readme_content();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the readme tab content
|
||||
*/
|
||||
public static function display_tab_content() {
|
||||
$readme = self::get_readme_content();
|
||||
|
||||
?>
|
||||
<div class="wp-allstars-settings-content tab-content" id="readme">
|
||||
<div class="wpa-pro-plugins">
|
||||
<div class="wpa-pro-plugin">
|
||||
<div class="wp-allstars-markdown-content">
|
||||
<?php echo self::parse_markdown($readme['content']); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse markdown content to HTML
|
||||
*
|
||||
* A simple markdown parser for basic formatting
|
||||
*
|
||||
* @param string $markdown The markdown content
|
||||
* @return string The HTML content
|
||||
*/
|
||||
private static function parse_markdown($markdown) {
|
||||
// Replace version placeholder with actual version
|
||||
$markdown = str_replace('{WP_ALLSTARS_VERSION}', WP_ALLSTARS_VERSION, $markdown);
|
||||
|
||||
// Headers
|
||||
$markdown = preg_replace('/^### (.*?)$/m', '<h3>$1</h3>', $markdown);
|
||||
$markdown = preg_replace('/^## (.*?)$/m', '<h2>$1</h2>', $markdown);
|
||||
$markdown = preg_replace('/^# (.*?)$/m', '<h1>$1</h1>', $markdown);
|
||||
|
||||
// Bold and Italic
|
||||
$markdown = preg_replace('/\*\*(.*?)\*\*/s', '<strong>$1</strong>', $markdown);
|
||||
$markdown = preg_replace('/\*(.*?)\*/s', '<em>$1</em>', $markdown);
|
||||
|
||||
// Process lists first - identify all list items
|
||||
$markdown = preg_replace('/^- (.*?)$/m', '<li class="bullet-item">$1</li>', $markdown);
|
||||
$markdown = preg_replace('/^\* (.*?)$/m', '<li class="bullet-item">$1</li>', $markdown);
|
||||
$markdown = preg_replace('/^\d+\. (.*?)$/m', '<li class="number-item">$1</li>', $markdown);
|
||||
|
||||
// Group consecutive list items into appropriate list types
|
||||
// First group bullet items into unordered lists
|
||||
$markdown = preg_replace('/((?:<li class="bullet-item">.*?<\/li>\n)+)/s', '<ul class="wp-allstars-ul">$1</ul>', $markdown);
|
||||
|
||||
// Then group numbered items into ordered lists with a special class for indentation
|
||||
$markdown = preg_replace('/((?:<li class="number-item">.*?<\/li>\n)+)/s', '<ol class="wp-allstars-ol numbered-list">$1</ol>', $markdown);
|
||||
|
||||
// Clean up the classes from the final output
|
||||
$markdown = str_replace('class="bullet-item"', '', $markdown);
|
||||
$markdown = str_replace('class="number-item"', '', $markdown);
|
||||
$markdown = str_replace('class="wp-allstars-ul"', 'class="wp-allstars-list"', $markdown);
|
||||
$markdown = str_replace('class="wp-allstars-ol numbered-list"', 'class="wp-allstars-list numbered-list"', $markdown);
|
||||
|
||||
// Links
|
||||
$markdown = preg_replace('/\[(.*?)\]\((.*?)\)/s', '<a href="$2" target="_blank">$1</a>', $markdown);
|
||||
|
||||
// Paragraphs
|
||||
$markdown = preg_replace('/^(?!<[a-z]).+$/m', '<p>$0</p>', $markdown);
|
||||
|
||||
// Fix multiple paragraph tags
|
||||
$markdown = str_replace('<p><p>', '<p>', $markdown);
|
||||
$markdown = str_replace('</p></p>', '</p>', $markdown);
|
||||
|
||||
// Fix lists within paragraphs
|
||||
$markdown = str_replace('<p><ul>', '<ul>', $markdown);
|
||||
$markdown = str_replace('</ul></p>', '</ul>', $markdown);
|
||||
|
||||
return $markdown;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the class
|
||||
WP_Allstars_Readme_Manager::init();
|
195
admin/includes/class-settings-manager.php
Normal file
195
admin/includes/class-settings-manager.php
Normal file
@ -0,0 +1,195 @@
|
||||
<?php
|
||||
/**
|
||||
* Settings Manager Class
|
||||
*
|
||||
* Handles the display and management of plugin settings tabs (General and Advanced).
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if ( ! defined( 'WPINC' ) ) {
|
||||
die;
|
||||
}
|
||||
|
||||
class WP_Allstars_Settings_Manager {
|
||||
|
||||
/**
|
||||
* Initialize the class
|
||||
*/
|
||||
public static function init() {
|
||||
// Register settings
|
||||
add_action('admin_init', array(self::class, 'register_settings'));
|
||||
|
||||
// Enqueue scripts and styles if needed
|
||||
add_action('admin_enqueue_scripts', array(self::class, 'enqueue_scripts'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register plugin settings
|
||||
*/
|
||||
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');
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue scripts and styles needed for settings
|
||||
*/
|
||||
public static function enqueue_scripts($hook) {
|
||||
// Only load on the plugin settings page
|
||||
if (strpos($hook, 'wp-allstars') === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add inline JS for toggle functionality
|
||||
$toggle_js = '
|
||||
jQuery(document).ready(function($) {
|
||||
// Toggle expandable settings 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);
|
||||
});
|
||||
});
|
||||
';
|
||||
|
||||
wp_add_inline_script('wp-allstars-admin', $toggle_js);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the general tab content
|
||||
*/
|
||||
public static function display_general_tab() {
|
||||
?>
|
||||
<div class="wp-allstars-settings-section">
|
||||
<div class="wp-allstars-settings-grid">
|
||||
<!-- 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">
|
||||
<div class="wp-setting-left">
|
||||
<div class="wp-toggle-switch">
|
||||
<input type="checkbox"
|
||||
id="wp_allstars_simple_setting"
|
||||
name="wp_allstars_simple_setting"
|
||||
value="1"
|
||||
<?php checked(get_option('wp_allstars_simple_setting', false)); ?>
|
||||
/>
|
||||
<span class="wp-toggle-slider"></span>
|
||||
</div>
|
||||
<label for="wp_allstars_simple_setting" class="wp-setting-label">
|
||||
<?php esc_html_e('Example: Simple Toggle', 'wp-allstars'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<p class="wp-setting-description">
|
||||
<?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>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the advanced tab content
|
||||
*/
|
||||
public static function display_advanced_tab() {
|
||||
?>
|
||||
<div class="wp-allstars-settings-section">
|
||||
<div class="wp-allstars-settings-grid">
|
||||
<!-- 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
|
||||
}
|
||||
|
||||
/**
|
||||
* Save settings
|
||||
*/
|
||||
public static function save_settings() {
|
||||
// Check for nonce
|
||||
if (!isset($_POST['wp_allstars_settings_nonce']) || !wp_verify_nonce($_POST['wp_allstars_settings_nonce'], 'wp_allstars_save_settings')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// Add settings saved notice
|
||||
add_settings_error('wp_allstars_settings', 'settings_updated', __('Settings saved.', 'wp-allstars'), 'updated');
|
||||
}
|
||||
}
|
329
admin/includes/class-theme-manager.php
Normal file
329
admin/includes/class-theme-manager.php
Normal file
@ -0,0 +1,329 @@
|
||||
<?php
|
||||
/**
|
||||
* WP ALLSTARS Theme Manager
|
||||
*
|
||||
* Manages the Theme tab functionality including:
|
||||
* - Theme data retrieval and caching
|
||||
* - AJAX handlers for theme browsing
|
||||
* - Theme activation and installation
|
||||
* - Theme UI rendering
|
||||
*
|
||||
* @package WP_ALLSTARS
|
||||
* @since 0.2.0
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('WPINC')) {
|
||||
die;
|
||||
}
|
||||
|
||||
/**
|
||||
* WP_Allstars_Theme_Manager class
|
||||
*
|
||||
* Provides theme discovery and management functionality
|
||||
*/
|
||||
class WP_Allstars_Theme_Manager {
|
||||
|
||||
/**
|
||||
* Initialize the class and register all action hooks
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function init() {
|
||||
// Register AJAX handlers for theme operations
|
||||
add_action('wp_ajax_wp_allstars_get_themes', array(self::class, 'ajax_get_themes'));
|
||||
add_action('wp_ajax_wp_allstars_activate_theme', array(self::class, 'activate_theme'));
|
||||
|
||||
// Register hooks for automatic cache clearing when themes change
|
||||
add_action('upgrader_process_complete', array(self::class, 'clear_theme_cache'), 10, 0);
|
||||
add_action('switch_theme', array(self::class, 'clear_theme_cache'));
|
||||
|
||||
// Enqueue theme-specific assets when needed
|
||||
add_action('admin_enqueue_scripts', array(self::class, 'enqueue_scripts'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue scripts and styles for the theme tab
|
||||
*
|
||||
* Loads necessary WordPress core scripts and stylesheets
|
||||
* required for theme browsing and installation.
|
||||
*
|
||||
* @param string $hook The current admin page hook
|
||||
* @return void
|
||||
*/
|
||||
public static function enqueue_scripts($hook) {
|
||||
// Only load on plugin pages
|
||||
if (strpos($hook, 'wp-allstars') === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only load when theme tab is active
|
||||
if (!isset($_GET['tab']) || $_GET['tab'] !== 'theme') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load WordPress core theme functionality
|
||||
require_once ABSPATH . 'wp-admin/includes/theme.php';
|
||||
|
||||
// Enqueue core WordPress scripts for theme operations
|
||||
wp_enqueue_script('theme-install');
|
||||
wp_enqueue_script('updates');
|
||||
add_thickbox();
|
||||
|
||||
// Enqueue theme tab specific styles
|
||||
wp_enqueue_style(
|
||||
'wp-allstars-admin',
|
||||
plugins_url('css/wp-allstars-admin.css', dirname(__FILE__)),
|
||||
array(),
|
||||
WP_ALLSTARS_VERSION
|
||||
);
|
||||
wp_enqueue_style('wp-allstars-plugins', plugins_url('css/wp-allstars-plugins.css', dirname(__FILE__)));
|
||||
|
||||
// Enqueue the main admin script before adding inline script
|
||||
wp_enqueue_script('wp-allstars-admin', plugins_url('js/wp-allstars-admin.js', dirname(__FILE__)), array('jquery'), '1.0.0', true);
|
||||
|
||||
// Localize the script with nonce data
|
||||
wp_localize_script('wp-allstars-admin', 'wpAllstars', array(
|
||||
'nonce' => wp_create_nonce('wp-allstars-nonce'),
|
||||
'ajaxurl' => admin_url('admin-ajax.php')
|
||||
));
|
||||
|
||||
// Add inline script for theme loading and interaction
|
||||
wp_add_inline_script('wp-allstars-admin', self::get_theme_scripts());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get theme scripts for inline inclusion
|
||||
*/
|
||||
private static function get_theme_scripts() {
|
||||
return '
|
||||
jQuery(document).ready(function($) {
|
||||
if ($("#wpa-theme-list").length) {
|
||||
var $container = $("#wpa-theme-list");
|
||||
var $loadingOverlay = $container.find(".wp-allstars-loading-overlay");
|
||||
|
||||
// AJAX request to get themes
|
||||
$.ajax({
|
||||
url: wpAllstars.ajaxurl,
|
||||
type: "POST",
|
||||
data: {
|
||||
action: "wp_allstars_get_themes",
|
||||
_wpnonce: wpAllstars.nonce
|
||||
},
|
||||
success: function(response) {
|
||||
$loadingOverlay.remove();
|
||||
if (response.success) {
|
||||
$container.html(response.data);
|
||||
// Initialize theme handlers - use the global function from admin.js
|
||||
if (typeof window.initThemeHandlers === "function") {
|
||||
window.initThemeHandlers();
|
||||
}
|
||||
} else {
|
||||
$container.html("<div class=\"notice notice-error\"><p>" + response.data + "</p></div>");
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
$loadingOverlay.remove();
|
||||
$container.html("<div class=\"notice notice-error\"><p>Failed to load themes. Please try again. Error: " + error + "</p></div>");
|
||||
console.error("AJAX Error:", xhr.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the theme tab content
|
||||
*/
|
||||
public static function display_tab_content() {
|
||||
?>
|
||||
<div class="wp-allstars-settings-content tab-content" id="theme">
|
||||
<div id="wpa-theme-list" class="wpa-theme-container">
|
||||
<!-- Theme content will be loaded via AJAX -->
|
||||
<div class="wp-allstars-loading-overlay">
|
||||
<span class="spinner is-active"></span>
|
||||
<p>Loading theme data...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cached theme
|
||||
*/
|
||||
public static function get_cached_theme() {
|
||||
$cache_key = 'wp_allstars_theme_kadence';
|
||||
return get_transient($cache_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cached theme
|
||||
*/
|
||||
public static function set_cached_theme($data) {
|
||||
$cache_key = 'wp_allstars_theme_kadence';
|
||||
set_transient($cache_key, $data, 12 * HOUR_IN_SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear theme cache
|
||||
*/
|
||||
public static function clear_theme_cache() {
|
||||
delete_transient('wp_allstars_theme_kadence');
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX endpoint for getting themes
|
||||
*/
|
||||
public static function ajax_get_themes() {
|
||||
error_log('WP ALLSTARS: Theme AJAX handler started');
|
||||
|
||||
// Check nonce with the correct action name
|
||||
if (!isset($_POST['_wpnonce'])) {
|
||||
error_log('WP ALLSTARS: No nonce provided');
|
||||
wp_send_json_error('No security token provided.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Use verify_nonce instead of check_ajax_referer for more reliable verification
|
||||
if (!wp_verify_nonce($_POST['_wpnonce'], 'wp-allstars-nonce')) {
|
||||
error_log('WP ALLSTARS: Invalid nonce: ' . sanitize_text_field($_POST['_wpnonce']));
|
||||
wp_send_json_error('Invalid security token sent.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!current_user_can('install_themes')) {
|
||||
error_log('WP ALLSTARS: User does not have permission to install themes');
|
||||
wp_send_json_error('Permission denied');
|
||||
return;
|
||||
}
|
||||
|
||||
error_log('WP ALLSTARS: Starting theme fetch process');
|
||||
|
||||
try {
|
||||
error_log('WP ALLSTARS: Fetching theme data for kadence');
|
||||
|
||||
// Check if we have cached data first
|
||||
$theme_data = self::get_cached_theme();
|
||||
|
||||
// If no cached data, fetch from API
|
||||
if (empty($theme_data)) {
|
||||
error_log('WP ALLSTARS: No cached theme data, fetching from API');
|
||||
|
||||
// Get theme data with minimal fields
|
||||
$theme_data = themes_api('theme_information', array(
|
||||
'slug' => 'kadence',
|
||||
'fields' => array(
|
||||
'sections' => false,
|
||||
'description' => true,
|
||||
'rating' => true,
|
||||
'ratings' => false,
|
||||
'downloaded' => true,
|
||||
'download_link' => true,
|
||||
'last_updated' => true,
|
||||
'homepage' => true,
|
||||
'tags' => false,
|
||||
'screenshot_url' => true,
|
||||
'version' => true,
|
||||
'requires' => true,
|
||||
'requires_php' => true,
|
||||
'active_installs' => true,
|
||||
'author' => true,
|
||||
'preview_url' => true,
|
||||
)
|
||||
));
|
||||
|
||||
// Cache the result if successful
|
||||
if (!is_wp_error($theme_data)) {
|
||||
self::set_cached_theme($theme_data);
|
||||
}
|
||||
} else {
|
||||
error_log('WP ALLSTARS: Using cached theme data');
|
||||
}
|
||||
|
||||
if (is_wp_error($theme_data)) {
|
||||
error_log('WP ALLSTARS Theme API Error: ' . $theme_data->get_error_message());
|
||||
wp_send_json_error('Theme API Error: ' . $theme_data->get_error_message());
|
||||
return;
|
||||
}
|
||||
|
||||
error_log('WP ALLSTARS: Successfully fetched theme data');
|
||||
|
||||
// Format author data
|
||||
$author = '';
|
||||
if (is_string($theme_data->author)) {
|
||||
$author = $theme_data->author;
|
||||
} elseif (is_array($theme_data->author)) {
|
||||
$author = isset($theme_data->author['display_name']) ? $theme_data->author['display_name'] : '';
|
||||
}
|
||||
|
||||
error_log('WP ALLSTARS: Theme data retrieved, generating HTML');
|
||||
|
||||
// Generate custom HTML for the theme using our template partial
|
||||
ob_start();
|
||||
include(plugin_dir_path(dirname(__FILE__)) . 'partials/theme-panel.php');
|
||||
$html = ob_get_clean();
|
||||
|
||||
if (empty($html)) {
|
||||
error_log('WP ALLSTARS: Empty HTML generated');
|
||||
wp_send_json_error('Failed to generate theme display');
|
||||
return;
|
||||
}
|
||||
|
||||
error_log('WP ALLSTARS: Successfully generated theme display, HTML length: ' . strlen($html));
|
||||
wp_send_json_success($html);
|
||||
exit; // Ensure we exit after sending the JSON response
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log('WP ALLSTARS Theme loading exception: ' . $e->getMessage());
|
||||
error_log('WP ALLSTARS Theme loading exception trace: ' . $e->getTraceAsString());
|
||||
wp_send_json_error('Theme loading error: ' . $e->getMessage());
|
||||
} catch (Error $e) {
|
||||
error_log('WP ALLSTARS Theme loading error: ' . $e->getMessage());
|
||||
error_log('WP ALLSTARS Theme loading error trace: ' . $e->getTraceAsString());
|
||||
wp_send_json_error('Theme loading error: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler for theme activation
|
||||
*/
|
||||
public static function activate_theme() {
|
||||
// Debug information
|
||||
error_log('Theme activation AJAX request received: ' . print_r($_POST, true));
|
||||
|
||||
// Check nonce with the correct action name
|
||||
if (!check_ajax_referer('wp-allstars-nonce', '_wpnonce', false)) {
|
||||
error_log('Theme activation failed: Invalid nonce');
|
||||
wp_send_json_error('Invalid security token sent.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!current_user_can('switch_themes')) {
|
||||
error_log('Theme activation failed: Permission denied');
|
||||
wp_send_json_error('Permission denied');
|
||||
return;
|
||||
}
|
||||
|
||||
$theme = isset($_POST['theme']) ? sanitize_text_field($_POST['theme']) : '';
|
||||
if (empty($theme)) {
|
||||
error_log('Theme activation failed: No theme specified');
|
||||
wp_send_json_error('No theme specified');
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the theme object
|
||||
$theme_obj = wp_get_theme($theme);
|
||||
if (!$theme_obj->exists()) {
|
||||
error_log('Theme activation failed: Theme does not exist - ' . $theme);
|
||||
wp_send_json_error('Theme does not exist');
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the new theme
|
||||
switch_theme($theme);
|
||||
error_log('Theme activation success - ' . $theme);
|
||||
wp_send_json_success();
|
||||
}
|
||||
}
|
168
admin/includes/class-tools-manager.php
Normal file
168
admin/includes/class-tools-manager.php
Normal file
@ -0,0 +1,168 @@
|
||||
<?php
|
||||
/**
|
||||
* Tools Manager Class
|
||||
*
|
||||
* @package WP_ALLSTARS
|
||||
* @since 0.2.0
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class WP_Allstars_Tools_Manager {
|
||||
|
||||
/**
|
||||
* Initialize the class
|
||||
*/
|
||||
public static function init() {
|
||||
add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueue_styles'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue styles for the tools tab
|
||||
*
|
||||
* @param string $hook Current admin page hook
|
||||
*/
|
||||
public static function enqueue_styles($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 CSS for tools to match the single column layout
|
||||
$custom_css = '
|
||||
#tools .wpa-pro-plugins {
|
||||
padding: 15px 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
#tools .wpa-pro-plugin {
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
padding: 24px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
width: 100%;
|
||||
margin-bottom: 24px;
|
||||
max-width: 100%;
|
||||
}
|
||||
#tools .wpa-pro-plugin:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
#tools .wpa-pro-plugin:hover {
|
||||
border-color: #2271b1;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.15);
|
||||
}
|
||||
#tools .wpa-pro-plugin .button-group {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
';
|
||||
|
||||
wp_add_inline_style('wp-allstars-admin', $custom_css);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all tools
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_tools() {
|
||||
return wp_allstars_get_tools();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the tools tab content
|
||||
*/
|
||||
public static function display_tab_content() {
|
||||
$tools = self::get_tools();
|
||||
|
||||
// Sort tools alphabetically by name
|
||||
uasort($tools, function($a, $b) {
|
||||
return strcasecmp($a['name'], $b['name']);
|
||||
});
|
||||
|
||||
?>
|
||||
<div class="wp-allstars-settings-content tab-content" id="tools">
|
||||
<div class="wpa-pro-plugins">
|
||||
<?php
|
||||
foreach ($tools as $tool) {
|
||||
self::display_tool_card(self::sanitize_tool_data($tool));
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a single tool card
|
||||
*
|
||||
* @param array $tool Sanitized tool configuration
|
||||
*/
|
||||
private static function display_tool_card($tool) {
|
||||
// Ensure we have the required fields
|
||||
if (empty($tool['name'])) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div class="wpa-pro-plugin">
|
||||
<h3><?php echo esc_html($tool['name']); ?></h3>
|
||||
|
||||
<?php if (!empty($tool['description'])): ?>
|
||||
<p><?php echo esc_html($tool['description']); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($tool['button_group']) && is_array($tool['button_group'])): ?>
|
||||
<div class="button-group">
|
||||
<?php foreach ($tool['button_group'] as $button): ?>
|
||||
<?php if (!empty($button['url']) && !empty($button['text'])): ?>
|
||||
<?php
|
||||
$button_class = 'button';
|
||||
if (!empty($button['primary'])) {
|
||||
$button_class .= ' button-primary go-pro-button';
|
||||
} else {
|
||||
$button_class .= ' green-button-secondary';
|
||||
}
|
||||
?>
|
||||
<a
|
||||
href="<?php echo esc_url($button['url']); ?>"
|
||||
target="_blank"
|
||||
class="<?php echo esc_attr($button_class); ?>"
|
||||
>
|
||||
<?php echo esc_html($button['text']); ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize tool data
|
||||
*
|
||||
* @param array $tool Raw tool data
|
||||
* @return array Sanitized tool data
|
||||
*/
|
||||
private static function sanitize_tool_data($tool) {
|
||||
return array(
|
||||
'name' => isset($tool['name']) ? sanitize_text_field($tool['name']) : '',
|
||||
'description' => isset($tool['description']) ? sanitize_text_field($tool['description']) : '',
|
||||
'button_group' => isset($tool['button_group']) ? $tool['button_group'] : array(),
|
||||
);
|
||||
}
|
||||
}
|
178
admin/includes/class-workflow-manager.php
Normal file
178
admin/includes/class-workflow-manager.php
Normal file
@ -0,0 +1,178 @@
|
||||
<?php
|
||||
/**
|
||||
* Workflow Manager Class
|
||||
*
|
||||
* @package WP_ALLSTARS
|
||||
* @since 0.2.0
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class WP_Allstars_Workflow_Manager {
|
||||
|
||||
/**
|
||||
* Initialize the class
|
||||
*/
|
||||
public static function init() {
|
||||
add_action('admin_init', array(__CLASS__, 'register_settings'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register workflow settings
|
||||
*/
|
||||
public static function register_settings() {
|
||||
register_setting('wp_allstars_workflow', 'wp_allstars_workflow_options');
|
||||
register_setting('wp_allstars_workflow', 'wp_allstars_auto_upload_images');
|
||||
register_setting('wp_allstars_workflow', 'wp_allstars_max_width');
|
||||
register_setting('wp_allstars_workflow', 'wp_allstars_max_height');
|
||||
register_setting('wp_allstars_workflow', 'wp_allstars_exclude_urls');
|
||||
register_setting('wp_allstars_workflow', 'wp_allstars_image_name_pattern');
|
||||
register_setting('wp_allstars_workflow', 'wp_allstars_image_alt_pattern');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the workflow tab content
|
||||
*/
|
||||
public static function display_tab_content() {
|
||||
?>
|
||||
<div class="wp-allstars-settings-content tab-content" id="workflow">
|
||||
<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('Enable Auto Upload Images', 'wp-allstars'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<p class="wp-setting-description">
|
||||
<?php esc_html_e('Import images that have external URLs into your Media Library when saving. Consider disabling during large data imports with many external image URLs.', 'wp-allstars'); ?>
|
||||
</p>
|
||||
</div>
|
||||
<div class="wp-allstars-toggle-settings">
|
||||
<div class="wp-allstars-setting-row">
|
||||
<label for="wp_allstars_max_width"><?php esc_html_e('Max Width', 'wp-allstars'); ?></label>
|
||||
<input type="number"
|
||||
id="wp_allstars_max_width"
|
||||
name="wp_allstars_max_width"
|
||||
value="<?php echo esc_attr(get_option('wp_allstars_max_width', 2560)); ?>"
|
||||
/>
|
||||
<p class="description"><?php esc_html_e('Maximum width for uploaded images in pixels.', 'wp-allstars'); ?></p>
|
||||
</div>
|
||||
<div class="wp-allstars-setting-row">
|
||||
<label for="wp_allstars_max_height"><?php esc_html_e('Max Height', 'wp-allstars'); ?></label>
|
||||
<input type="number"
|
||||
id="wp_allstars_max_height"
|
||||
name="wp_allstars_max_height"
|
||||
value="<?php echo esc_attr(get_option('wp_allstars_max_height', 2560)); ?>"
|
||||
/>
|
||||
<p class="description"><?php esc_html_e('Maximum height for uploaded images in pixels.', 'wp-allstars'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="wp-allstars-setting-row">
|
||||
<label for="wp_allstars_exclude_urls"><?php esc_html_e('Exclude URLs', 'wp-allstars'); ?></label>
|
||||
<textarea id="wp_allstars_exclude_urls"
|
||||
name="wp_allstars_exclude_urls"
|
||||
rows="3"
|
||||
placeholder="example.com another-domain.com"
|
||||
><?php echo esc_textarea(get_option('wp_allstars_exclude_urls', '')); ?></textarea>
|
||||
<p class="description"><?php esc_html_e('Enter domains to exclude (one per line). Images from these domains will not be imported.', 'wp-allstars'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="wp-allstars-setting-row">
|
||||
<label for="wp_allstars_image_name"><?php esc_html_e('Image Name Pattern', 'wp-allstars'); ?></label>
|
||||
<input type="text"
|
||||
id="wp_allstars_image_name"
|
||||
name="wp_allstars_image_name"
|
||||
value="<?php echo esc_attr(get_option('wp_allstars_image_name_pattern', '%filename%')); ?>"
|
||||
/>
|
||||
<p class="description">
|
||||
<?php esc_html_e('Available patterns:', 'wp-allstars'); ?> %filename%, %post_id%, %postname%, %timestamp%, %date%, %year%, %month%, %day%
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="wp-allstars-setting-row">
|
||||
<label for="wp_allstars_image_alt"><?php esc_html_e('Image Alt Pattern', 'wp-allstars'); ?></label>
|
||||
<input type="text"
|
||||
id="wp_allstars_image_alt"
|
||||
name="wp_allstars_image_alt"
|
||||
value="<?php echo esc_attr(get_option('wp_allstars_image_alt_pattern', '%filename%')); ?>"
|
||||
/>
|
||||
<p class="description">
|
||||
<?php esc_html_e('Available patterns:', 'wp-allstars'); ?> %filename%, %post_title%, %post_id%, %postname%, %timestamp%
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save workflow settings via AJAX
|
||||
*/
|
||||
public static function save_settings() {
|
||||
// Verify nonce for security
|
||||
check_ajax_referer('wp-allstars-nonce', 'nonce');
|
||||
|
||||
// Check if user has proper permissions
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error('Insufficient permissions');
|
||||
return;
|
||||
}
|
||||
|
||||
$options = array();
|
||||
|
||||
// Auto upload images setting
|
||||
$options['auto_upload_images'] = isset($_POST['auto_upload_images']) ?
|
||||
(bool) $_POST['auto_upload_images'] :
|
||||
false;
|
||||
|
||||
// Max dimensions
|
||||
$options['max_width'] = isset($_POST['max_width']) ?
|
||||
absint($_POST['max_width']) :
|
||||
2560;
|
||||
|
||||
$options['max_height'] = isset($_POST['max_height']) ?
|
||||
absint($_POST['max_height']) :
|
||||
2560;
|
||||
|
||||
// Exclude URLs
|
||||
$options['exclude_urls'] = isset($_POST['exclude_urls']) ?
|
||||
sanitize_textarea_field($_POST['exclude_urls']) :
|
||||
'';
|
||||
|
||||
// Name and alt patterns
|
||||
$options['image_name_pattern'] = isset($_POST['image_name_pattern']) ?
|
||||
sanitize_text_field($_POST['image_name_pattern']) :
|
||||
'%filename%';
|
||||
|
||||
$options['image_alt_pattern'] = isset($_POST['image_alt_pattern']) ?
|
||||
sanitize_text_field($_POST['image_alt_pattern']) :
|
||||
'%filename%';
|
||||
|
||||
// Update the options
|
||||
update_option('wp_allstars_workflow_options', $options);
|
||||
|
||||
// Also update individual options for backward compatibility
|
||||
update_option('wp_allstars_auto_upload_images', $options['auto_upload_images']);
|
||||
update_option('wp_allstars_max_width', $options['max_width']);
|
||||
update_option('wp_allstars_max_height', $options['max_height']);
|
||||
update_option('wp_allstars_exclude_urls', $options['exclude_urls']);
|
||||
update_option('wp_allstars_image_name_pattern', $options['image_name_pattern']);
|
||||
update_option('wp_allstars_image_alt_pattern', $options['image_alt_pattern']);
|
||||
|
||||
wp_send_json_success('Workflow settings saved');
|
||||
}
|
||||
}
|
74
admin/js/wp-allstars-admin-colors.js
Normal file
74
admin/js/wp-allstars-admin-colors.js
Normal 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);
|
@ -1,327 +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();
|
||||
|
||||
// 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
|
||||
// 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;
|
||||
|
||||
// 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('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);
|
||||
url: wpAllstars.ajaxurl,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'wp_allstars_update_option',
|
||||
nonce: wpAllstars.nonce,
|
||||
option: option,
|
||||
value: value
|
||||
},
|
||||
error: function() {
|
||||
$button.removeClass('updating-message').text('Activate');
|
||||
alert('Failed to activate plugin. Please try again or activate from the Plugins page.');
|
||||
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);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 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 standard WordPress behavior
|
||||
$('.theme-actions .install-now').on('click', function(e) {
|
||||
// We're not preventing default here - let the standard WordPress installer handle it
|
||||
// Just add the updating message
|
||||
var $button = $(this);
|
||||
var slug = $button.data('slug');
|
||||
$button.addClass('updating-message').text('Installing...');
|
||||
console.log('Installing theme using standard WordPress URL:', $button.attr('href'));
|
||||
// The rest will be handled by WordPress core
|
||||
// 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);
|
||||
});
|
||||
|
||||
// Activate theme - use standard WordPress behavior
|
||||
$('.theme-actions .activate-now').on('click', function(e) {
|
||||
// We're not preventing default here - let the standard WordPress activation handle it
|
||||
// Just add the updating message
|
||||
var $button = $(this);
|
||||
var slug = $button.data('slug');
|
||||
$button.addClass('updating-message').text('Activating...');
|
||||
console.log('Activating theme using standard WordPress URL:', $button.attr('href'));
|
||||
// The rest will be handled by WordPress core
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
184
admin/js/wp-allstars-ui-enhancements.js
Normal file
184
admin/js/wp-allstars-ui-enhancements.js
Normal 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);
|
@ -73,22 +73,22 @@ if (!defined('ABSPATH')) {
|
||||
});
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
<a class="button button-secondary preview install-theme-preview" href="<?php echo esc_url($theme_data->preview_url); ?>" target="_blank">
|
||||
<a class="button button-secondary green-button-secondary preview install-theme-preview" href="<?php echo esc_url($theme_data->preview_url); ?>" target="_blank">
|
||||
<?php esc_html_e('Preview'); ?>
|
||||
</a>
|
||||
<a class="button button-secondary" href="https://www.kadencewp.com/kadence-theme/starter-templates/" target="_blank">
|
||||
<a class="button button-secondary green-button-secondary" href="https://www.kadencewp.com/kadence-theme/starter-templates/" target="_blank">
|
||||
<?php esc_html_e('Templates'); ?>
|
||||
</a>
|
||||
<a class="button button-secondary" href="https://www.kadencewp.com/wordpress-solutions/kadence-ai/" target="_blank">
|
||||
<a class="button button-secondary green-button-secondary" href="https://www.kadencewp.com/wordpress-solutions/kadence-ai/" target="_blank">
|
||||
<?php esc_html_e('Starter AI'); ?>
|
||||
</a>
|
||||
<a class="button button-secondary" href="https://www.kadencewp.com/kadence-theme/marketplace/" target="_blank">
|
||||
<a class="button button-secondary green-button-secondary" href="https://www.kadencewp.com/kadence-theme/marketplace/" target="_blank">
|
||||
<?php esc_html_e('Marketplace'); ?>
|
||||
</a>
|
||||
<a class="button button-secondary" href="https://www.kadencewp.com/pricing/" target="_blank">
|
||||
<a class="button button-secondary green-button-secondary" href="https://www.kadencewp.com/pricing/" target="_blank">
|
||||
<?php esc_html_e('Pricing'); ?>
|
||||
</a>
|
||||
<a class="button button-primary" href="https://www.kadencewp.com/kadence-theme/" target="_blank">
|
||||
<a class="button button-primary go-pro-button" href="https://www.kadencewp.com/kadence-theme/" target="_blank">
|
||||
<?php esc_html_e('Go Pro'); ?>
|
||||
</a>
|
||||
</div>
|
||||
|
2128
admin/settings.php
2128
admin/settings.php
File diff suppressed because it is too large
Load Diff
34
debug.php
Normal file
34
debug.php
Normal 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
30
debug2.php
Normal 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>";
|
||||
}
|
||||
}
|
||||
}
|
169
includes/class-wp-allstars-admin-colors.php
Normal file
169
includes/class-wp-allstars-admin-colors.php
Normal file
@ -0,0 +1,169 @@
|
||||
<?php
|
||||
/**
|
||||
* WP ALLSTARS Admin Colors Feature
|
||||
*
|
||||
* Handles setting the admin color scheme based on user preferences
|
||||
*
|
||||
* @package WP_ALLSTARS
|
||||
* @since 0.2.3.1
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin Colors Handler Class
|
||||
*/
|
||||
class WP_Allstars_Admin_Colors {
|
||||
|
||||
/**
|
||||
* Option name for the admin color scheme setting
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $option_name = 'wp_allstars_admin_color_scheme';
|
||||
|
||||
/**
|
||||
* Modern color scheme key
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $modern_scheme = 'modern';
|
||||
|
||||
/**
|
||||
* Default color scheme key
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $default_scheme = 'fresh';
|
||||
|
||||
/**
|
||||
* Initialize the class and set up hooks
|
||||
*/
|
||||
public function __construct() {
|
||||
// Set up hooks
|
||||
add_action('admin_init', array($this, 'set_admin_color_scheme'));
|
||||
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'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue scripts and styles for the color scheme toggle
|
||||
*/
|
||||
public function enqueue_color_scripts() {
|
||||
// Only enqueue on our plugin pages
|
||||
$screen = get_current_screen();
|
||||
if (!isset($screen->id) || strpos($screen->id, 'wp-allstars') === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
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,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 option is enabled
|
||||
$enable_modern = get_option($this->option_name, false);
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 AJAX request to update color scheme
|
||||
*/
|
||||
public function handle_color_scheme_update() {
|
||||
// Verify nonce
|
||||
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'wp_allstars_color_nonce')) {
|
||||
wp_send_json_error('Invalid nonce');
|
||||
}
|
||||
|
||||
// Verify user can manage options
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error('Insufficient permissions');
|
||||
}
|
||||
|
||||
// Get the new value
|
||||
$enabled = isset($_POST['enabled']) ? (bool) $_POST['enabled'] : false;
|
||||
|
||||
// Update the option
|
||||
update_option($this->option_name, $enabled);
|
||||
|
||||
// Get current user
|
||||
$user_id = get_current_user_id();
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
@ -2,15 +2,20 @@
|
||||
/**
|
||||
* Auto Upload Images functionality
|
||||
*
|
||||
* @package WP_Allstars
|
||||
* @package WP_ALLSTARS
|
||||
* @since 0.2.0
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class WP_Allstars_Auto_Upload {
|
||||
/**
|
||||
* Initialize the class
|
||||
*/
|
||||
public function __construct() {
|
||||
add_filter('content_save_pre', array($this, 'process_content'), 10, 1);
|
||||
add_filter('content_save_pre', array($this, 'process_content'));
|
||||
add_action('wp_allstars_image_upload_error', array($this, 'log_error'), 10, 2);
|
||||
}
|
||||
|
||||
@ -57,7 +62,8 @@ class WP_Allstars_Auto_Upload {
|
||||
return str_replace($url, $local_url, $matches[0]);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
do_action('wp_allstars_image_upload_error', $url, $e->getMessage());
|
||||
// Trigger error action for logging
|
||||
do_action('wp_allstars_image_upload_error', esc_url($url), $e->getMessage());
|
||||
}
|
||||
|
||||
return $matches[0];
|
||||
@ -80,11 +86,12 @@ class WP_Allstars_Auto_Upload {
|
||||
*
|
||||
* @param string $url External image URL
|
||||
* @return string|false Local URL on success, false on failure
|
||||
* @throws Exception If download or upload fails
|
||||
*/
|
||||
private function upload_image($url) {
|
||||
// Get file info
|
||||
$file_array = array();
|
||||
$file_array['name'] = basename($url);
|
||||
$file_array = array(
|
||||
'name' => sanitize_file_name(basename($url))
|
||||
);
|
||||
|
||||
// Download file to temp location
|
||||
$file_array['tmp_name'] = download_url($url);
|
||||
@ -93,17 +100,18 @@ class WP_Allstars_Auto_Upload {
|
||||
throw new Exception('Failed to download image: ' . $file_array['tmp_name']->get_error_message());
|
||||
}
|
||||
|
||||
// Check file type
|
||||
// Check file type for security
|
||||
$wp_filetype = wp_check_filetype_and_ext($file_array['tmp_name'], $file_array['name']);
|
||||
if (!$wp_filetype['type']) {
|
||||
unlink($file_array['tmp_name']);
|
||||
throw new Exception('Invalid file type');
|
||||
}
|
||||
|
||||
// Upload the file
|
||||
// Upload the file to media library
|
||||
$attachment_id = media_handle_sideload($file_array, 0);
|
||||
|
||||
if (is_wp_error($attachment_id)) {
|
||||
unlink($file_array['tmp_name']);
|
||||
throw new Exception('Failed to upload image: ' . $attachment_id->get_error_message());
|
||||
}
|
||||
|
||||
@ -117,10 +125,12 @@ class WP_Allstars_Auto_Upload {
|
||||
* @param string $error Error message
|
||||
*/
|
||||
public function log_error($url, $error) {
|
||||
error_log(sprintf(
|
||||
'[WP ALLSTARS] Auto Upload Images Error - URL: %s, Error: %s',
|
||||
$url,
|
||||
$error
|
||||
));
|
||||
if (WP_DEBUG) {
|
||||
error_log(sprintf(
|
||||
'[WP ALLSTARS] Auto Upload Images Error - URL: %s, Error: %s',
|
||||
esc_url_raw($url),
|
||||
sanitize_text_field($error)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
60
includes/class-wp-allstars-sync-guard.php
Normal file
60
includes/class-wp-allstars-sync-guard.php
Normal 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>';
|
||||
}
|
||||
}
|
330
includes/class-wp-allstars-ui-enhancements.php
Normal file
330
includes/class-wp-allstars-ui-enhancements.php
Normal 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
|
||||
}
|
||||
}
|
@ -1,97 +1,139 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: WP ALLSTARS Plugin
|
||||
* Plugin URI: https://www.wpallstars.com
|
||||
* Description: WP ALLSTARS Plugin for WordPress. Speed Matters.
|
||||
* Version: 0.1.0 (Beta)
|
||||
* Author: WP ALLSTARS
|
||||
* Author URI: https://www.wpallstars.com
|
||||
* License: GPL-2.0+
|
||||
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
* WP ALLSTARS Plugin
|
||||
*
|
||||
* A comprehensive WordPress optimization and management tool designed to enhance
|
||||
* site performance, improve workflow, and provide recommendations for plugins and hosting.
|
||||
*
|
||||
* @package WP_ALLSTARS
|
||||
* @version v0.2.3.3
|
||||
*
|
||||
* Plugin Name: WP Allstars
|
||||
* Plugin URI: https://wpallstars.com
|
||||
* Description: A superstar stack of premium WordPress functionality, designed for SEO pros.
|
||||
* Author: Marcus Quinn
|
||||
* Author URI: https://wpallstars.com
|
||||
* Text Domain: wp-allstars
|
||||
* Domain Path: /languages
|
||||
* Requires at least: 5.0
|
||||
* Requires PHP: 7.2
|
||||
* @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.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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with WP Allstars. If not, see https://www.gnu.org/licenses/gpl-2.0.html.
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if ( ! defined( 'WPINC' ) ) {
|
||||
die;
|
||||
if (!defined('WPINC')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Define plugin version - extract from plugin 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;
|
||||
}
|
||||
|
||||
// Define the version constant - first try get_plugin_data() if available,
|
||||
// otherwise fall back to direct string extraction
|
||||
if (function_exists('get_plugin_data')) {
|
||||
$plugin_data = get_plugin_data(__FILE__, false, false);
|
||||
define('WP_ALLSTARS_VERSION', $plugin_data['Version']);
|
||||
} else {
|
||||
// Manual extraction as fallback
|
||||
$plugin_file = file_get_contents(__FILE__);
|
||||
preg_match('/Version:\s*([^\s]+)/i', $plugin_file, $matches);
|
||||
define('WP_ALLSTARS_VERSION', isset($matches[1]) ? $matches[1] : '0.1.0 (Beta)');
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
// Activation hook
|
||||
// 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() {
|
||||
// Add activation logic later if needed
|
||||
// Setup initial config
|
||||
}
|
||||
register_activation_hook( __FILE__, 'wp_allstars_activate' );
|
||||
register_activation_hook(__FILE__, 'wp_allstars_activate');
|
||||
|
||||
// Load core functionality
|
||||
require_once plugin_dir_path(__FILE__) . 'includes/class-wp-allstars-auto-upload.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 UI and configurations
|
||||
if ( is_admin() ) {
|
||||
require_once plugin_dir_path( __FILE__ ) . 'admin/pro-plugins-config.php';
|
||||
require_once plugin_dir_path( __FILE__ ) . 'admin/settings.php';
|
||||
}
|
||||
|
||||
// This function is not needed as we're localizing in wp_allstars_admin_assets
|
||||
// function wp_allstars_localize_script() {
|
||||
// wp_localize_script( 'wp-allstars-admin', 'wpAllstars', [
|
||||
// 'ajaxurl' => admin_url( 'admin-ajax.php' ),
|
||||
// 'nonce' => wp_create_nonce( 'wp-allstars-nonce' )
|
||||
// ] );
|
||||
// }
|
||||
// add_action( 'admin_enqueue_scripts', 'wp_allstars_localize_script' );
|
||||
|
||||
// Admin assets
|
||||
function wp_allstars_admin_assets() {
|
||||
// Enqueue styles
|
||||
wp_enqueue_style(
|
||||
'wp-allstars-admin',
|
||||
plugins_url( 'admin/css/wp-allstars-admin.css', __FILE__ ),
|
||||
array(),
|
||||
WP_ALLSTARS_VERSION
|
||||
// Admin includes
|
||||
if (is_admin()) {
|
||||
$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'
|
||||
);
|
||||
|
||||
// Enqueue script
|
||||
// Enqueue WordPress updates script for theme installation
|
||||
wp_enqueue_script('updates');
|
||||
|
||||
wp_enqueue_script(
|
||||
'wp-allstars-admin',
|
||||
plugins_url( 'admin/js/wp-allstars-admin.js', __FILE__ ),
|
||||
array('jquery', 'updates'),
|
||||
WP_ALLSTARS_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
// Localize script for AJAX
|
||||
$ajax_data = array(
|
||||
'ajaxurl' => admin_url( 'admin-ajax.php' ),
|
||||
'adminUrl' => admin_url(),
|
||||
'nonce' => wp_create_nonce( 'wp-allstars-nonce' ),
|
||||
'updateNonce' => wp_create_nonce( 'updates' )
|
||||
);
|
||||
wp_localize_script( 'wp-allstars-admin', 'wpAllstars', $ajax_data );
|
||||
foreach ($admin_includes as $file) {
|
||||
wp_allstars_require_if_exists(plugin_dir_path(__FILE__) . $file);
|
||||
}
|
||||
|
||||
// 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');
|
||||
|
||||
// Admin settings
|
||||
wp_allstars_require_if_exists(plugin_dir_path(__FILE__) . 'admin/settings.php');
|
||||
}
|
||||
add_action( 'admin_enqueue_scripts', 'wp_allstars_admin_assets' );
|
||||
|
||||
// Initialize classes
|
||||
$wp_allstars_auto_upload = new WP_Allstars_Auto_Upload();
|
||||
/**
|
||||
* Auto Upload feature initialization
|
||||
*
|
||||
* Initialize the Auto Upload feature when a user is logged in
|
||||
*/
|
||||
function wp_allstars_init_auto_upload() {
|
||||
// Only initialize for logged-in users
|
||||
if (is_user_logged_in()) {
|
||||
new WP_Allstars_Auto_Upload();
|
||||
}
|
||||
}
|
||||
add_action('init', 'wp_allstars_init_auto_upload');
|
||||
|
||||
/**
|
||||
* Initialize core features
|
||||
*/
|
||||
function wp_allstars_init_features() {
|
||||
// Initialize Admin Colors feature if the class exists
|
||||
if (class_exists('WP_Allstars_Admin_Colors')) {
|
||||
new WP_Allstars_Admin_Colors();
|
||||
}
|
||||
|
||||
// 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');
|
Reference in New Issue
Block a user