148 Commits

Author SHA1 Message Date
d490604513 [STABLE] Merge sync guard feature 2025-04-08 00:57:39 +01:00
e57f22f277 [FUNCTIONAL] Add sync guard to prevent plugin loading during file sync 2025-04-08 00:57:16 +01:00
bae13ca936 [STABLE] Add development framework documentation 2025-04-08 00:56:11 +01:00
c597f21818 Make plugin file loading more robust to prevent fatal errors 2025-04-08 00:45:42 +01:00
0fdb2a60e2 Testing stable v0.2.3 version 2025-04-08 00:44:54 +01:00
b74d8112ca Update plugin version to v0.2.3 2025-03-25 02:43:08 +00:00
05ff272b51 Improve theme install/activate buttons: maintain button size and use spinner animation 2025-03-25 02:34:40 +00:00
e19dfecd6c Fix AJAX functionality for theme Install and Activate buttons 2025-03-25 02:31:50 +00:00
ff306ed32c Fix AJAX functionality for Install Now and Activate buttons 2025-03-25 02:29:01 +00:00
bcb4a7e05b Add Search Atlas to Tools section 2025-03-25 02:25:25 +00:00
0d3c497b23 Update plugin version to v0.2.2 2025-03-25 02:21:06 +00:00
e2bfefc6f6 Change plugin tiles max-width from 700px to 660px 2025-03-25 02:18:54 +00:00
5652ae2ad3 Set plugin tiles to max 700px width while keeping subnav at 900px 2025-03-25 02:17:18 +00:00
394cefa3cf Apply direct and specific 900px width styles to free plugins nav and container 2025-03-25 02:15:21 +00:00
d9a06e3813 Remove grey line from sub-nav panel and fix 900px width issues 2025-03-25 02:13:15 +00:00
f5a17e343e Fix secondary navigation rollover border and width consistently 2025-03-25 02:10:44 +00:00
63c2b7231a Fix secondary nav bottom border and increase max-width to 900px 2025-03-25 02:08:31 +00:00
e1e8e19946 Add rollover underline styling to free plugins secondary navigation to match main tabs 2025-03-25 02:05:24 +00:00
291cbe34f5 Make free plugins secondary navigation max-width match other tabs (700px) 2025-03-25 02:03:19 +00:00
62f368756a Fix missing hover effects for hosting and tools tiles to match Pro Plugins section 2025-03-25 02:01:38 +00:00
4153564acb Fix extra gap above workflow tab content to match other tabs 2025-03-25 01:59:08 +00:00
7eef6caab8 Fix workflow tab 'Enable Auto Upload Images' panel width and styling to match other tabs 2025-03-25 01:57:57 +00:00
d464d4cbe8 Fix workflow tab content width to be consistent with other tabs 2025-03-25 01:56:10 +00:00
817b564813 Fix content width consistency across tabs - ensure all tabs have 700px content width 2025-03-25 01:54:03 +00:00
4f88de74f6 Fix width issues and field notifications 2025-03-25 01:51:33 +00:00
2998604468 Align buttons to left, fix readme panel width, and ensure consistent 700px width for all tab content 2025-03-25 01:40:21 +00:00
d89ecc5548 Fix single column layout for Pro Plugins, Hosting, and Tools tabs with inline CSS 2025-03-25 01:36:37 +00:00
89009dca92 Convert Pro Plugins, Hosting, and Tools tabs to single column layout 2025-03-25 01:34:19 +00:00
a374f26e34 Adjust Free Plugins top padding to 15px for better spacing 2025-03-25 01:32:14 +00:00
d9b136f925 Reduce top padding from 25px to 10px in Free Plugins section 2025-03-25 01:31:31 +00:00
576d79b1e7 Add 25px gap before plugin tiles in Free Plugins section 2025-03-25 01:29:30 +00:00
a467a6aa10 Remove duplicate 'Read Me' title from readme tab content 2025-03-25 01:27:58 +00:00
1f885f1745 Increase tab spacing to a consistent 25px across all tabs 2025-03-25 01:26:06 +00:00
2158855a1a Refactor tab spacing to be consistent across all tabs by centralizing margin settings 2025-03-25 01:24:25 +00:00
233006f155 Fix tab spacing inconsistencies 2025-03-25 01:22:33 +00:00
4e951f1fb7 Include Workflow tab in spacing fix to ensure consistent layout 2025-03-25 01:21:01 +00:00
fd78d35186 Fix inconsistent spacing in General, Advanced, and Read Me tabs 2025-03-25 01:19:27 +00:00
fba03d6e43 Revert tab spacing changes that caused content to appear under wrong tabs 2025-03-25 01:17:44 +00:00
9b307f1b9d Standardize spacing between tabs and content across all tab types 2025-03-25 01:15:53 +00:00
894a31d5b6 Set top content padding to 25px to increase space between main and secondary tabs 2025-03-25 01:13:47 +00:00
01740ed72c Reduce spacing between main tab and secondary tabs 2025-03-25 01:12:42 +00:00
bbb0dc377a Restore original gap between subcategory tabs and plugin content 2025-03-25 01:11:52 +00:00
8e6371fe9d Revert changes to layout and compatibility text positioning 2025-03-25 01:10:29 +00:00
d9413aff1c Reduce gap between subcategory filters and plugin content to zero 2025-03-25 01:09:04 +00:00
f1c3087900 Reduce tab content top padding to close gap between tabs and plugins 2025-03-25 01:07:18 +00:00
2d644e9c37 Fix compatibility text positioning using transform instead of margin 2025-03-25 01:05:50 +00:00
fbb4cb69ba Reduce gap between subcategory tabs and plugin content by 10px 2025-03-25 01:04:33 +00:00
7a3b8a948f Move compatibility text another 10px to the left 2025-03-25 01:03:13 +00:00
d8130b1e19 Move compatibility text further left by increasing margin-right to 35px 2025-03-25 01:02:01 +00:00
b069bf3f3c Reduce gap between filter nav bar and results to be consistent with other tabs 2025-03-25 00:59:23 +00:00
ba0878b230 Update theme tiles to be constrained to max-width of 800px 2025-03-25 00:57:40 +00:00
4f391f0cda Fix responsive navigation: make top tabs and filter links wrap properly at smaller window widths 2025-03-25 00:55:46 +00:00
d5a4a29ae9 Fix compatibility text alignment using margin-right instead of padding-left 2025-03-25 00:54:10 +00:00
daccb54342 Double padding-left for compatibility text to move it further left 2025-03-25 00:53:05 +00:00
90f6969e1b Move compatibility text 25px to the left instead of right 2025-03-25 00:52:00 +00:00
f7b8629926 Move compatibility text 25px to the right for better alignment 2025-03-25 00:50:52 +00:00
aac7ac1195 Fix inconsistent tile width between 1086px and 1400px window widths 2025-03-25 00:47:54 +00:00
6528d8e79a Make plugin layout consistent for all screen widths based on 768px layout 2025-03-25 00:45:29 +00:00
21b0ef599d Fix text overlap on desktop screens by increasing content margins and button width 2025-03-25 00:41:58 +00:00
5f45ea85fa Fix mobile layout and text wrapping: prevent button overlap, improve text wrapping on desktop, fix mobile responsiveness 2025-03-25 00:39:30 +00:00
c3d1aff49f Refine single column plugin layout: full-width nav, fix descriptions, right-align compatibility text, transparent loading spinner 2025-03-25 00:36:08 +00:00
d389f92bd6 Update plugin tile layout to single centered column with max width 700px 2025-03-25 00:28:19 +00:00
23c5d0adce Improve free plugins tile layout: Implement consistent grid layout matching pro plugins section, add responsive design with breakpoints, improve spacing and alignment, standardize styling, fix mobile layout, add hover effects 2025-03-25 00:15:09 +00:00
1384145138 Align plugin description text with plugin name 2025-03-25 00:03:52 +00:00
169b226a39 Fix Free Plugins grid centering with improved flexbox layout 2025-03-24 23:50:09 +00:00
69ad1d55a7 Improve Free Plugins grid: center tiles and fix text alignment 2025-03-24 23:48:33 +00:00
42150fe694 Simplify Free Plugins grid with clean, centered tile layout 2025-03-24 23:43:37 +00:00
6040c1b5bd Fix: Increase plugin card padding and improve responsive grid layout 2025-03-24 23:34:18 +00:00
1224937955 Fix: Improve Free Plugins grid layout with consistent spacing and card styling 2025-03-24 23:29:13 +00:00
34b09de04e Fix: Position notification badges 3px higher with transform translateY 2025-03-24 23:24:27 +00:00
41adfb56e4 Fix: Move notification badges up by 3px for better vertical alignment 2025-03-24 23:21:41 +00:00
f03da91142 Fix: Properly align accordion panel borders to prevent overflow 2025-03-24 23:19:06 +00:00
69623d2660 Fix: Remove horizontal gaps in accordion content panels 2025-03-24 23:15:20 +00:00
e90f6168ed Fix: Improve accordion box styling and plugin card layouts with proper vertical gutters 2025-03-24 23:12:39 +00:00
eb768d9090 Fix: Properly target all settings rows, add plugin tile gutters, improve responsive padding 2025-03-24 23:08:45 +00:00
1b548a59e2 Fix: Improve targeting for General/Advanced tabs, add 75% breakpoint, add gutters to Free Plugin tiles 2025-03-24 23:01:01 +00:00
03d9511f4b Improve settings layout: fix text overlap with chevrons, standardize width across tabs, enhance responsive behavior 2025-03-24 22:57:33 +00:00
2b01f3523f Fix: Target individual setting rows to limit width to 50% on desktop 2025-03-24 22:48:08 +00:00
016f6000a6 Limit settings width to 50% in General, Advanced, and Workflow tabs to match readme panel 2025-03-24 22:45:33 +00:00
1cf243d5e1 Fine-tune numbered list indentation - move 2px to the right 2025-03-24 22:35:36 +00:00
09aebfcc98 Fix numbered list indentation to match bullet lists with dedicated class and targeted CSS 2025-03-24 22:33:07 +00:00
e00c627410 Adjust numbered list indentation to match bullet list indentation 2025-03-24 22:31:06 +00:00
c16e1d62fd Comprehensive fix for list styling in readme with improved markdown parser and CSS 2025-03-24 22:29:01 +00:00
ad2aba88a3 Enhance list styling to ensure consistent display across all readme sections 2025-03-24 22:24:31 +00:00
4de39fbd85 Reduce left padding for numbered lists to visually align with bullet lists 2025-03-24 22:21:40 +00:00
ea881f7691 Standardize bullet and numbered list styling with consistent indentation and spacing 2025-03-24 22:19:26 +00:00
19cd4d3355 Add support for numbered lists in Read Me tab with consistent styling 2025-03-24 22:17:38 +00:00
5a28089043 Fix bullet list styling on Read Me tab with proper bullets and reduced line spacing 2025-03-24 22:15:57 +00:00
9cd079206f Fix Pricing buttons to always use green styling with dedicated class and CSS rules 2025-03-24 22:11:04 +00:00
a82bd8b3f4 Fix secondary button borders to ensure all are green with more specific CSS selectors 2025-03-24 22:08:04 +00:00
7c6afdc8c7 Fix button styling: green borders on all secondary buttons, vertical text alignment, and blue version text 2025-03-24 22:05:55 +00:00
f8c098b5a1 Update CSS to ensure secondary buttons on all tabs have green borders 2025-03-24 22:03:00 +00:00
1eb732684b Add green styling to secondary buttons and Visit Website button across the plugin 2025-03-24 22:00:08 +00:00
a4b594c0e2 Update Go Pro buttons to use darker green colors with consistent hover states 2025-03-24 21:52:39 +00:00
5f90586044 Add hover effect for Go Pro buttons to make green darker on hover 2025-03-24 21:45:09 +00:00
a2b7ba6d72 Rename About tab to Read Me and display README.md content 2025-03-24 21:37:09 +00:00
e83dbcfff7 Center About panel and make it responsive 2025-03-24 21:32:15 +00:00
28f87f689e Add About tab with markdown support 2025-03-24 21:30:03 +00:00
5f195f8cfb Remove duplicate margin from plugin table to fix spacing 2025-03-24 21:18:48 +00:00
d2e8cc858c Add direct inline style to set 22px spacing between filter menu and plugin content 2025-03-24 21:16:53 +00:00
dc6b1a046f Set consistent 22px top margin on plugin browser container 2025-03-24 21:10:25 +00:00
221eefab9e Reduce filter menu bottom margin from 25px to 22px for consistent spacing 2025-03-24 21:07:27 +00:00
a81b6ac5a7 Fix double padding issue in tab content spacing 2025-03-24 21:05:24 +00:00
634f29eee7 Refactor tab content spacing for consistent 22px gap across all sections 2025-03-24 21:02:48 +00:00
e94a1d902d Fix theme list spacing by adding !important to margin-top rule 2025-03-24 20:59:50 +00:00
1c477aa0f2 Standardize tab-to-content spacing to consistent 22px throughout plugin 2025-03-24 20:55:14 +00:00
9108a5345c Increase gap between tabs and content by 2px (padding-top: 20px → 22px) 2025-03-24 20:51:40 +00:00
16d0d5e2ef Increase gap between tabs and content by 2px (padding-top: 20px → 22px) 2025-03-24 20:51:27 +00:00
8fa4b67da9 Preserve previous category order in dynamically generated Free Plugins menu 2025-03-24 20:43:14 +00:00
673d4a60fd Make Free Plugins filter menu dynamically generated from data file 2025-03-24 20:40:52 +00:00
4d671d5901 Update Free Plugins filter menu to show all available categories 2025-03-24 20:38:51 +00:00
0c96faaf60 Fix loading spinner positioning on Free Plugins tab 2025-03-24 20:34:15 +00:00
83d7debe54 Fix security token verification in Free Plugins tab 2025-03-24 20:28:33 +00:00
ccc57dc72b Fix duplicate loading spinners in Free Plugins tab 2025-03-24 20:26:28 +00:00
f0d00accaf Fix Free Plugins tab HTML structure and JS selectors 2025-03-24 20:02:40 +00:00
19e6455abb Fix free plugins tab loading and settings toggle error 2025-03-24 19:59:15 +00:00
f7fb0c6545 Restore original pro-plugins configuration data with updated function name 2025-03-24 18:58:15 +00:00
9e1c077080 Refactor plugin structure:
- Rename pro-plugins-config.php to data/pro-plugins.php
- Rename recommended-plugins.php to free-plugins.php
- Rename class-recommended-plugins-manager.php to class-free-plugins-manager.php
- Update all references throughout the codebase
- Add enhanced hover effects to Go Pro buttons
2025-03-24 18:42:24 +00:00
4bbcbe3d12 Fix: Update admin menu registration to use correct class method 2025-03-24 18:11:02 +00:00
46696eff87 Fix: Resolve critical error by restoring pro plugins function and required includes 2025-03-24 18:06:04 +00:00
8cef4c8868 Code cleanup: Improved documentation and removed backward compatibility code 2025-03-24 18:04:15 +00:00
da5d08587c UI Improvements: Center-aligned tabs and filters, standardized button styles 2025-03-24 17:55:29 +00:00
c2276f4ebd Fix: Ensure consistent padding in Theme tab matching other tabs 2025-03-24 17:45:52 +00:00
b267156b68 Fix: Ensure consistent padding across all tab content areas 2025-03-24 17:43:14 +00:00
ddd64643c4 Fix: Ensure consistent padding and wrapper structure across all tabs 2025-03-24 17:36:48 +00:00
ddd2846171 Fix: Add proper tab content padding and fix Theme tab loading issues 2025-03-24 17:30:23 +00:00
4fe9d45eba Fix: Restore original tab order and fix method name mismatches to resolve critical errors 2025-03-24 17:24:44 +00:00
ad489bddb5 Refactor: Clean up settings.php by removing all HTML content and properly delegating to Admin Manager class 2025-03-24 17:19:25 +00:00
5fdc3e277c refactor: move script and style enqueuing to Admin Manager class 2025-03-24 17:09:11 +00:00
096c9be284 refactor: move settings registration to Admin Manager class 2025-03-24 17:07:41 +00:00
2b4e3cecd3 refactor: move AJAX option handler to Admin Manager class 2025-03-24 17:06:09 +00:00
d280ec197b refactor: create Admin Manager class and move menu registration 2025-03-24 17:04:22 +00:00
5352b38348 refactor: move Recommended Plugins tab to WP_Allstars_Recommended_Plugins_Manager class 2025-03-24 16:31:46 +00:00
2405f98eb8 refactor: move Hosting tab functionality to WP_Allstars_Hosting_Manager class 2025-03-24 16:17:31 +00:00
24ffdf8950 fix: theme tab loading by properly enqueuing required scripts 2025-03-24 16:11:50 +00:00
93c3290b63 refactor: move Theme tab functionality to WP_Allstars_Theme_Manager class 2025-03-24 16:07:11 +00:00
436a829646 ui: move Theme tab before Free Plugins tab in navigation 2025-03-24 16:00:11 +00:00
20fb06a29e fix: tools tab styling issues by making CSS classes consistent 2025-03-24 15:57:47 +00:00
8fa2b00d7a refactor: move Settings and Tools tabs to dedicated classes
- Created WP_Allstars_Settings_Manager class to handle General and Advanced tabs
- Created WP_Allstars_Tools_Manager class to handle Tools tab functionality
- Moved inline CSS to properly enqueued styles
- Further reduced code duplication in settings.php
- Improved code organization with OOP principles
2025-03-24 15:52:16 +00:00
f0ffa7e552 refactor: move Pro Plugins section to dedicated class
- Created new WP_Allstars_Pro_Plugins_Manager class to handle all Pro Plugins functionality
- Moved styling from inline CSS to properly enqueued styles
- Improved code organization by separating concerns
- Reduced code duplication in settings.php
2025-03-24 15:38:44 +00:00
55d092d568 Remove 'Version' prefix from version display in admin header 2025-03-24 15:19:54 +00:00
1b02e8eb24 Update version to v0.2.0 (Beta) 2025-03-24 15:18:27 +00:00
c8835de92f Fix theme tab critical error by adding required content section 2025-03-24 15:15:36 +00:00
d9c710969b Update plugin card button styling for consistent UI 2025-03-24 14:53:42 +00:00
2c68b66dbc Fix plugin display issues in the Plugin Manager class 2025-03-24 14:40:05 +00:00
9b0e7acd2d Refactor plugin functionality into Plugin Manager class 2025-03-24 14:17:09 +00:00
930530cc96 Add Coolify to hosting providers 2025-03-24 14:04:48 +00:00
ecd3887bb9 Restructure data arrays into separate files for improved maintainability 2025-03-24 13:57:41 +00:00
30 changed files with 4835 additions and 2267 deletions

2
.gitignore vendored
View File

@ -38,7 +38,7 @@ $RECYCLE.BIN/
.git_status_temp.txt .git_status_temp.txt
project-documents/ project-documents/
reference-plugins/ reference-plugins/
*.bak *.bak*
node_modules/ node_modules/
composer.lock composer.lock
package-lock.json package-lock.json

111
DEVELOPMENT.md Normal file
View File

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

View File

@ -1,6 +1,7 @@
# WP Allstars # WP Allstars
A WordPress plugin that enhances your WordPress experience with curated plugins, themes, and optimization tools. A WordPress plugin that enhances your WordPress experience with curated plugins, themes, and optimization tools.
Testing a stable v0.2.3 version with rsync deployment.
## Description ## Description

51
ROADMAP.md Normal file
View File

@ -0,0 +1,51 @@
# 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 | 🔄 To be implemented |
| More Robust File Loading | v0.2.6-fix | High | Low | Low | ✅ Implemented in v0.2.3-stable |
| Enhanced Admin UI | v0.2.4+ | Medium | Medium | 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
### Enhanced Admin UI
- **Description**: Improve the admin interface with better styling and more intuitive navigation
- **Why it failed before**: Too many changes at once without proper testing
- **Implementation plan**:
1. Small, incremental UI improvements
2. Focus on one component at a time
3. Thorough testing after each change
- **Testing criteria**: UI changes shouldn't affect functionality, should be responsive
## Development Order
The suggested implementation order is:
1. Sync Guard
2. Enhanced Admin UI (component by component)
3. Plugin Dashboard improvements
4. New Category Pages
Each feature should be developed in its own branch and only merged after thorough testing.

32
STABILITY.md Normal file
View File

@ -0,0 +1,32 @@
# 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-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. Features from later versions are being analyzed and reimplemented in a stable manner.
## 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]

70
TESTING.md Normal file
View File

@ -0,0 +1,70 @@
# WP Allstars Plugin Testing Procedures
This document outlines the testing procedures for the WP Allstars Plugin to ensure stability and reliability.
## Pre-Merge Testing Checklist
### Basic Functionality Tests
- [ ] Plugin activates without errors
- [ ] Plugin deactivates without errors
- [ ] Admin menu appears correctly
- [ ] All submenu items load without errors
- [ ] Settings can be saved without errors
- [ ] Plugin works with WordPress debug mode enabled
### Feature-Specific Tests
Each new feature should have its own testing checklist added here.
#### Multisite Category Feature
- [ ] "Multisite" category appears in the correct location in the UI
- [ ] Network Plugin Auditor appears in the Multisite category
- [ ] Category filter works when clicked
- [ ] Plugin can be installed from the category
#### Sync Guard Feature
- [ ] Plugin doesn't load when .syncing file is present
- [ ] .syncing file is created during sync operations
- [ ] .syncing file is removed after sync completes
- [ ] User is notified when plugin is in sync mode
### Compatibility Tests
- [ ] Plugin works with latest WordPress version
- [ ] Plugin works with PHP 7.4+
- [ ] Plugin works with common themes (Twenty Twenty-Three, Kadence)
- [ ] Plugin co-exists with other popular plugins without conflicts
### Browser Compatibility
- [ ] UI works correctly in Chrome
- [ ] UI works correctly in Firefox
- [ ] UI works correctly in Safari
- [ ] UI works correctly in Edge
### Mobile Responsiveness
- [ ] Admin interface is usable on mobile devices
- [ ] No layout issues on small screens
## Testing Process
1. Create a clean WordPress installation for testing
2. Install and activate the plugin
3. Enable WordPress debug mode (WP_DEBUG = true)
4. Complete all tests in the checklist
5. Document any issues found
6. Fix issues and retest
7. Only mark as [STABLE] when all tests pass
## Continuous Integration
For future implementation:
- [ ] Automated unit tests
- [ ] Integration tests
- [ ] End-to-end tests
- [ ] Code quality checks

View File

@ -33,7 +33,7 @@
} }
.wp-allstars-version { .wp-allstars-version {
color: #d35400; /* Updated to dark orange */ color: #0073aa; /* Changed to WordPress blue */
font-size: 13px; font-size: 13px;
font-weight: 400; font-weight: 400;
} }
@ -48,6 +48,11 @@
position: sticky; position: sticky;
top: 32px; top: 32px;
z-index: 100; z-index: 100;
text-align: center; /* Center align the tabs */
display: flex;
flex-wrap: wrap; /* Enable wrapping */
justify-content: center; /* Ensure better centering for tabs */
margin-bottom: 25px !important; /* Increase from 15px to 25px for all tabs */
} }
.nav-tab { .nav-tab {
@ -83,6 +88,27 @@
font-weight: 600; font-weight: 600;
} }
/* Responsive nav tabs */
@media screen and (max-width: 782px) {
.nav-tab-wrapper,
.wrap h2.nav-tab-wrapper {
padding: 0 10px;
}
.nav-tab {
padding: 10px 15px;
font-size: 13px;
line-height: 1.8;
}
}
@media screen and (max-width: 600px) {
.nav-tab {
padding: 8px 12px;
font-size: 12px;
}
}
/* Base Toggle Switch Component */ /* Base Toggle Switch Component */
.wp-toggle-switch { .wp-toggle-switch {
position: relative; position: relative;
@ -137,6 +163,39 @@ input:checked + .wp-toggle-slider:before {
transform: translateX(16px); transform: translateX(16px);
} }
/* Tab Content Area - GLOBAL SETTINGS - All tab spacing should inherit from here */
.wp-allstars-tab-content {
padding-top: 0 !important; /* Remove all padding-top from tab content */
}
/* Reset all tab content padding */
.wp-allstars-settings-content {
padding-top: 0 !important;
}
/* Remove previous spacing attempts */
#general .wp-allstars-settings-section,
#advanced .wp-allstars-settings-section,
#readme .wp-allstars-settings-section,
#workflow .wp-allstars-settings-section,
#theme .wp-allstars-settings-section,
#recommended .wp-allstars-settings-section,
#pro .wp-allstars-settings-section,
#hosting .wp-allstars-settings-section,
#tools .wp-allstars-settings-section {
padding-top: 0 !important;
margin-top: 0 !important;
}
/* Apply consistent spacing to the container for all tab types */
.wp-allstars-settings-section,
.wpa-plugin-container,
.wpa-pro-plugins,
.wp-allstars-markdown-content {
padding-top: 0 !important;
margin-top: 0 !important;
}
/* Base Setting Styles (Shared between simple and expandable) */ /* Base Setting Styles (Shared between simple and expandable) */
.wp-setting-base, .wp-setting-base,
.wp-setting-row, .wp-setting-row,
@ -302,7 +361,7 @@ input:checked + .wp-toggle-slider:before {
/* Settings Container */ /* Settings Container */
.wpa-settings-content { .wpa-settings-content {
margin-top: 20px; margin-top: 22px;
padding: 0 20px; padding: 0 20px;
} }
@ -354,7 +413,7 @@ input:checked + .wp-toggle-slider:before {
/* Plugin List Container */ /* Plugin List Container */
.wp-list-table-container { .wp-list-table-container {
margin-top: 20px; margin-top: 22px;
padding: 0 20px; padding: 0 20px;
position: relative; position: relative;
min-height: 400px; min-height: 400px;
@ -492,10 +551,12 @@ input:checked + .wp-toggle-slider:before {
/* Theme Container */ /* Theme Container */
#wpa-theme-list { #wpa-theme-list {
margin-top: 20px; margin-top: 0;
padding: 0 20px; padding: 0 20px;
position: relative; position: relative;
min-height: 400px; min-height: 400px;
max-width: 800px;
margin: 0 auto;
} }
/* Theme Card Styles - Scoped to our plugin only */ /* Theme Card Styles - Scoped to our plugin only */
@ -508,6 +569,7 @@ input:checked + .wp-toggle-slider:before {
margin-bottom: 20px; margin-bottom: 20px;
overflow: hidden; overflow: hidden;
transition: all 0.2s ease; transition: all 0.2s ease;
width: 100%;
} }
.theme-card:hover { .theme-card:hover {
@ -561,6 +623,31 @@ input:checked + .wp-toggle-slider:before {
gap: 8px; gap: 8px;
} }
/* Fix theme buttons to maintain consistent size and prevent layout jumps */
.theme-actions .button {
min-width: 80px !important;
text-align: center !important;
position: relative !important;
padding-left: 12px !important;
padding-right: 12px !important;
}
/* Style for the updating message with spinner */
.theme-actions .button.updating-message:before,
.theme-actions .button.updated-message:before {
margin-top: 0 !important;
padding-right: 3px !important;
vertical-align: bottom !important;
}
/* Style theme actions container spacing */
.theme-actions {
display: flex !important;
flex-wrap: wrap !important;
gap: 8px !important;
padding: 15px !important;
}
/* Responsive Adjustments */ /* Responsive Adjustments */
@media screen and (max-width: 1200px) { @media screen and (max-width: 1200px) {
.plugin-card .name, .plugin-card .name,
@ -645,6 +732,7 @@ input:checked + .wp-toggle-slider:before {
height: 20px; height: 20px;
box-sizing: border-box; box-sizing: border-box;
position: relative; position: relative;
transform: translateY(-3px);
} }
.wp-setting-notification.error { .wp-setting-notification.error {
@ -665,7 +753,7 @@ input:checked + .wp-toggle-slider:before {
.wp-allstars-setting-row label .wp-setting-notification { .wp-allstars-setting-row label .wp-setting-notification {
position: absolute; position: absolute;
right: -60px; right: -60px;
top: -2px; top: -5px;
transform: translateY(0); transform: translateY(0);
line-height: 1.4; line-height: 1.4;
} }
@ -694,13 +782,13 @@ input:checked + .wp-toggle-slider:before {
z-index: 1; z-index: 1;
} }
/* Panel styles for Pro Plugins, Hosting, and Tools tabs */ /* Panel styles for Pro Plugins, Hosting, and Tools tabs - Single Column Layout */
.wpa-pro-plugins { .wpa-pro-plugins {
padding: 20px; padding: 20px;
display: grid; display: flex;
grid-template-columns: repeat(auto-fill, minmax(450px, 1fr)); flex-direction: column;
gap: 24px; align-items: center;
max-width: 1920px; max-width: 700px; /* Match Free Plugins max-width */
margin: 0 auto; margin: 0 auto;
} }
@ -713,6 +801,13 @@ input:checked + .wp-toggle-slider:before {
flex-direction: column; flex-direction: column;
transition: all 0.2s ease; transition: all 0.2s ease;
box-shadow: 0 1px 3px rgba(0,0,0,0.1); box-shadow: 0 1px 3px rgba(0,0,0,0.1);
width: 100%; /* Full width of container */
margin-bottom: 24px; /* Match Free Plugins spacing */
max-width: 100%; /* Ensure it doesn't exceed container */
}
.wpa-pro-plugin:last-child {
margin-bottom: 0;
} }
.wpa-pro-plugin:hover { .wpa-pro-plugin:hover {
@ -740,6 +835,7 @@ input:checked + .wp-toggle-slider:before {
flex-wrap: wrap; flex-wrap: wrap;
gap: 8px; gap: 8px;
margin-top: auto; margin-top: auto;
justify-content: flex-end; /* Right-align buttons like Free Plugins */
} }
.wpa-pro-plugin .button { .wpa-pro-plugin .button {
@ -780,10 +876,16 @@ input:checked + .wp-toggle-slider:before {
color: #fff; color: #fff;
} }
/* Adjust spacing between pro plugins content and tabs navigation */
#pro .wpa-pro-plugins,
#hosting .wpa-pro-plugins,
#tools .wpa-pro-plugins {
padding-top: 15px; /* Match Free Plugins padding */
}
/* Simplify media queries since we're using single column at all widths */
@media screen and (max-width: 960px) { @media screen and (max-width: 960px) {
.wpa-pro-plugins { .wpa-pro-plugins {
grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
gap: 20px;
padding: 16px; padding: 16px;
} }
.wpa-pro-plugin { .wpa-pro-plugin {
@ -793,14 +895,682 @@ input:checked + .wp-toggle-slider:before {
@media screen and (max-width: 782px) { @media screen and (max-width: 782px) {
.wpa-pro-plugins { .wpa-pro-plugins {
grid-template-columns: 1fr;
gap: 16px;
padding: 12px; padding: 12px;
} }
.wpa-pro-plugin { .wpa-pro-plugin {
padding: 16px; padding: 16px;
} }
.wpa-pro-plugin .button { }
/* Markdown Content Styles for About Tab */
.wp-allstars-markdown-content {
line-height: 1.6;
color: #333;
padding: 0 20px 20px 20px !important; /* No top padding, consistent with other containers */
}
.wp-allstars-markdown-content h1 {
font-size: 2em;
margin: 0.67em 0;
border-bottom: 1px solid #eaecef;
padding-bottom: 0.3em;
}
.wp-allstars-markdown-content h2 {
font-size: 1.5em;
margin: 0.83em 0;
border-bottom: 1px solid #eaecef;
padding-bottom: 0.3em;
}
.wp-allstars-markdown-content h3 {
font-size: 1.25em;
margin: 1em 0;
}
.wp-allstars-markdown-content ul {
padding-left: 2em;
margin: 1em 0;
}
.wp-allstars-markdown-content li {
margin: 0.5em 0;
}
.wp-allstars-markdown-content a {
color: #0073aa;
text-decoration: none;
}
.wp-allstars-markdown-content a:hover {
color: #00a0d2;
text-decoration: underline;
}
.wp-allstars-markdown-content p {
margin: 1em 0;
}
/* Go Pro Button Styles */
.button.button-primary[style*="background-color: #27ae60"],
.theme-install-actions .button.button-primary,
.wpa-pro-plugin .button-group .button.button-primary,
.go-pro-button {
transition: all 0.3s ease !important;
background-color: #219653 !important; /* Darker green */
border-color: #1e874b !important; /* Even darker for border */
color: #ffffff !important;
}
.button.button-primary[style*="background-color: #27ae60"]:hover,
.theme-install-actions .button.button-primary:hover,
.wpa-pro-plugin .button-group .button.button-primary:hover,
.go-pro-button:hover {
background-color: #1b7b42 !important; /* Even darker green on hover */
border-color: #186a39 !important; /* Darkest for border */
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2) !important;
}
/* Green Secondary Button Styles */
.green-button-secondary,
.green-visit-website,
#pro .button-group .button.button-secondary,
#hosting .button-group .button.button-secondary,
#tools .button-group .button.button-secondary,
#readme .button-group .button.button-secondary,
#pro .button.button-secondary,
#hosting .button.button-secondary,
#tools .button.button-secondary,
#readme .button.button-secondary,
.button.button-secondary,
/* More specific selectors to override WP defaults */
.wp-allstars-tabs-wrapper .button.button-secondary,
.wp-allstars-settings-content .button.button-secondary,
.wpa-pro-plugins .button.button-secondary,
.wpa-pro-plugin .button.button-secondary,
body.wp-admin .button.button-secondary {
transition: all 0.3s ease !important;
color: #219653 !important; /* Darker green */
border-color: #219653 !important; /* Darker green */
background-color: transparent !important;
}
.green-button-secondary:hover,
.green-visit-website:hover,
#pro .button-group .button.button-secondary:hover,
#hosting .button-group .button.button-secondary:hover,
#tools .button-group .button.button-secondary:hover,
#readme .button-group .button.button-secondary:hover,
#pro .button.button-secondary:hover,
#hosting .button.button-secondary:hover,
#tools .button.button-secondary:hover,
#readme .button.button-secondary:hover,
.button.button-secondary:hover,
.wp-allstars-tabs-wrapper .button.button-secondary:hover,
.wp-allstars-settings-content .button.button-secondary:hover,
.wpa-pro-plugins .button.button-secondary:hover,
.wpa-pro-plugin .button.button-secondary:hover,
body.wp-admin .button.button-secondary:hover {
color: #1b7b42 !important; /* Even darker green on hover */
border-color: #1b7b42 !important; /* Even darker green on hover */
background-color: rgba(33, 150, 83, 0.05) !important; /* Very light green background */
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) !important;
}
/* Button text vertical alignment */
.button, .button-primary, .button-secondary {
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
}
/* Specific styling for Pricing buttons */
.pricing-button,
a.button.pricing-button,
body.wp-admin .button.pricing-button,
#pro a.button.pricing-button,
#hosting a.button.pricing-button,
#tools a.button.pricing-button,
#readme a.button.pricing-button {
color: #219653 !important;
border-color: #219653 !important;
background-color: transparent !important;
}
.pricing-button:hover,
a.button.pricing-button:hover,
body.wp-admin .button.pricing-button:hover,
#pro a.button.pricing-button:hover,
#hosting a.button.pricing-button:hover,
#tools a.button.pricing-button:hover,
#readme a.button.pricing-button:hover {
color: #1b7b42 !important;
border-color: #1b7b42 !important;
background-color: rgba(33, 150, 83, 0.05) !important;
}
/* Limit width of content in all main tabs */
.wp-allstars-tab-content .wp-allstars-settings-section,
#readme .wpa-pro-plugins {
display: block;
padding: 20px;
}
/* Target the specific setting rows to limit their width */
.wp-allstars-tab-content .wp-setting-row,
.wp-allstars-tab-content .wp-allstars-toggle,
#readme .wpa-pro-plugin {
max-width: 700px; /* Change from 50% to match global 700px width */
margin: 0 auto 20px auto;
box-sizing: border-box;
padding: 0;
}
/* Filter navigation - container at max-width to match other tabs */
#wpa-plugin-filters {
max-width: 900px !important;
margin: 0 auto 25px auto !important;
box-sizing: border-box;
padding: 15px;
border-radius: 8px;
background: #fff;
}
/* Filter links should be centered within container */
#wpa-plugin-filters .filter-links {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
margin: 0;
padding-bottom: 0;
}
/* Style the filter links similar to main tabs with proper border */
#wpa-plugin-filters .filter-links a {
margin: 0;
padding: 10px 15px;
font-size: 14px;
line-height: 1.6;
font-weight: 400;
background: transparent;
color: #50575e;
text-decoration: none;
white-space: nowrap;
border: none;
border-bottom: 2px solid transparent;
display: inline-block;
transition: all 0.2s ease;
}
#wpa-plugin-filters .filter-links a:hover,
#wpa-plugin-filters .filter-links a:focus {
color: #2271b1;
background: transparent;
border-bottom: 2px solid #2271b1;
}
#wpa-plugin-filters .filter-links a.current {
border-bottom: 2px solid #2271b1;
background: transparent;
color: #2271b1;
font-weight: 600;
}
/* Override max-width for free plugins specific elements */
#wpa-plugin-filters,
#recommended .wpa-plugin-container {
max-width: 900px !important;
width: 100% !important;
}
/* Free Plugins - Single Column Centered Layout */
#recommended .wpa-plugin-container {
padding: 15px 20px 20px 20px !important;
display: flex;
flex-direction: column;
align-items: center;
margin: 0 auto;
}
/* Use consistent layout similar to 768px width for all screen sizes */
#recommended .plugin-card {
width: 100%;
margin: 0 0 24px 0;
padding: 24px;
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
background: #fff;
transition: all 0.2s ease;
display: flex;
flex-direction: column;
position: relative;
}
#recommended .plugin-card:last-child {
margin-bottom: 0;
}
#recommended .plugin-card:hover {
border-color: #2271b1;
box-shadow: 0 2px 6px rgba(0,0,0,0.15);
}
#recommended .plugin-card-top {
padding: 0;
min-height: auto;
flex-grow: 1;
}
#recommended .plugin-card .plugin-icon {
position: relative;
float: left;
width: 64px;
height: 64px;
margin: 0 20px 15px 0;
}
#recommended .plugin-card .name,
#recommended .plugin-card .desc {
margin-left: 84px;
margin-right: 0; /* Full width content */
}
#recommended .plugin-card .name h3 {
margin: 0 0 12px;
font-size: 16px;
font-weight: 600;
color: #1d2327;
line-height: 1.4;
word-wrap: break-word;
}
#recommended .plugin-card .desc {
margin-top: 0;
color: #50575e;
font-size: 14px;
line-height: 1.6;
margin-bottom: 20px;
}
/* Position action links below content, not absolute */
#recommended .plugin-card .action-links {
position: relative;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
gap: 8px;
padding: 0;
margin-top: 10px;
}
#recommended .plugin-card .plugin-action-buttons {
margin: 0;
float: none;
width: auto;
}
#recommended .plugin-card .plugin-action-buttons .button {
width: auto;
min-width: 120px;
text-align: center;
}
/* Plugin card bottom with right-aligned compatibility text */
#recommended .plugin-card .plugin-card-bottom {
background: #f6f7f7;
padding: 15px 20px;
border-top: 1px solid #ddd;
text-align: right;
margin-top: auto;
}
/* Style compatibility message */
#recommended .plugin-card .column-compatibility {
text-align: center;
font-size: 13px;
color: #00a32a;
margin: 5px 0;
}
/* Loading spinner without background */
.wpa-loading-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: transparent;
z-index: 10;
display: flex;
align-items: center;
justify-content: center;
}
/* Extra small screens only */
@media screen and (max-width: 480px) {
#recommended .plugin-card {
padding-top: 80px; /* Add space for icon */
}
#recommended .plugin-card .name,
#recommended .plugin-card .desc {
margin-left: 0;
}
#recommended .plugin-card .plugin-icon {
position: absolute;
top: 16px;
left: 16px;
float: none;
}
#recommended .plugin-card .action-links {
flex-direction: column;
align-items: stretch;
}
#recommended .plugin-card .plugin-action-buttons {
width: 100%;
}
#recommended .plugin-card .plugin-action-buttons .button {
width: 100%; width: 100%;
} }
} }
/* Center the plugin container */
#recommended #the-list {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
/* Explicitly target readme content */
#readme .wp-allstars-markdown-content {
padding: 0 20px 20px 20px !important; /* No top padding, consistent with other containers */
}
/* Prevent text from overlapping dropdown chevron icon */
.wp-allstars-toggle-header {
position: relative;
padding: 15px;
padding-right: 40px; /* Make room for chevron */
}
.wp-allstars-toggle-header::after {
right: 15px;
z-index: 1; /* Ensure chevron stays above text */
}
/* Fix gaps in advanced settings accordion */
.wp-allstars-toggle-settings {
padding: 15px 0;
margin: 0;
background-color: #f8f8f8;
border-top: 1px solid #ddd;
width: calc(100% - 2px); /* Account for parent border */
margin-left: 1px; /* Center within parent borders */
box-sizing: border-box;
}
.wp-allstars-setting-row {
margin-bottom: 15px;
padding: 0 15px;
}
.wp-allstars-setting-row:last-child {
margin-bottom: 0;
}
/* Remove side gaps in text inputs and textareas */
.wp-allstars-toggle-settings input[type="text"],
.wp-allstars-toggle-settings textarea {
width: 100%;
max-width: 100%;
box-sizing: border-box;
}
/* Ensure text doesn't overflow */
.wp-setting-label,
.wp-allstars-toggle-header label,
.wp-setting-description {
white-space: normal;
word-wrap: break-word;
padding-right: 25px;
max-width: calc(100% - 40px); /* Ensure space for the chevron */
}
/* First breakpoint - 75% width */
@media screen and (max-width: 1400px) {
#readme .wp-allstars-markdown-content {
padding: 15px;
}
}
/* Second breakpoint - 100% width */
@media screen and (max-width: 1100px) {
#readme .wp-allstars-markdown-content {
padding: 10px;
}
}
/* Readme list styling */
#readme .wp-allstars-markdown-content ul.wp-allstars-list,
#readme .wp-allstars-markdown-content ul {
padding-left: 25px;
margin: 10px 0;
list-style-type: disc;
}
#readme .wp-allstars-markdown-content ol.wp-allstars-list,
#readme .wp-allstars-markdown-content ol {
padding-left: 25px; /* Same as bullets */
margin: 10px 0;
list-style-type: decimal;
}
/* Special styling for numbered lists to align with bullet lists */
#readme .wp-allstars-markdown-content ol.numbered-list {
padding-left: 21px; /* Moved 2px to the right as requested */
}
#readme .wp-allstars-markdown-content ol.numbered-list li {
margin-left: 4px; /* Fine-tune the alignment */
}
#readme .wp-allstars-markdown-content li {
margin-bottom: 5px;
line-height: 1.4;
display: list-item !important;
padding-left: 5px; /* Add consistent padding for all list items */
}
/* Ensure consistent spacing for all lists across sections */
#readme .wp-allstars-markdown-content h2 + ul,
#readme .wp-allstars-markdown-content h3 + ul,
#readme .wp-allstars-markdown-content p + ul,
#readme .wp-allstars-markdown-content h2 + ol,
#readme .wp-allstars-markdown-content h3 + ol,
#readme .wp-allstars-markdown-content p + ol,
#readme .wp-allstars-markdown-content h2 + .wp-allstars-list,
#readme .wp-allstars-markdown-content h3 + .wp-allstars-list,
#readme .wp-allstars-markdown-content p + .wp-allstars-list {
margin-top: 10px;
margin-bottom: 15px;
}
/* Additional fix for specific sections that need help */
#readme .wp-allstars-markdown-content h2 + ul,
#readme .wp-allstars-markdown-content h3 + ul {
padding-left: 25px !important;
margin-left: 0 !important;
list-style-type: disc !important;
}
/* Global setting for all content panels width - apply to ALL tabs */
.wp-allstars-settings-content,
.wp-allstars-tab-content > div,
.wp-allstars-settings-section,
.wpa-pro-plugins,
.wpa-pro-plugin,
#wpa-plugin-list,
#wpa-theme-list,
.wp-allstars-markdown-content,
.wpa-plugin-container,
#readme .wpa-pro-plugin,
.wp-allstars-toggle {
max-width: 700px !important;
margin-left: auto !important;
margin-right: auto !important;
width: 100% !important;
box-sizing: border-box !important;
}
/* Fix specific tab content - ensure all sections use the same width */
#general .wp-setting-row,
#general .wp-allstars-toggle,
#advanced .wp-setting-row,
#advanced .wp-allstars-toggle,
#workflow .wp-setting-row,
#workflow .wp-allstars-toggle,
#readme .wp-allstars-markdown-content {
max-width: 700px !important;
width: 100% !important;
box-sizing: border-box !important;
margin-left: auto !important;
margin-right: auto !important;
}
/* Specific fix for workflow tab container */
#workflow.wp-allstars-settings-content,
#workflow .wp-allstars-toggle {
max-width: 700px !important;
width: 100% !important;
margin-left: auto !important;
margin-right: auto !important;
box-sizing: border-box !important;
}
/* Fix to ensure consistent tab structure - "Enable Auto Upload Images" panel */
#workflow.tab-content {
padding: 0 20px 20px 20px !important; /* Changed from 20px to 0 20px 20px 20px to remove top padding */
}
/* Fix spacing in workflow tab to match other tabs */
#workflow .wp-allstars-toggle {
margin-bottom: 15px !important;
}
/* Consistent padding for toggle headers across all tabs */
#workflow .wp-allstars-toggle-header,
#general .wp-setting-header,
#advanced .wp-allstars-toggle-header {
padding: 15px !important;
}
/* Ensure consistent hover styles across all tab tile layouts */
.wpa-pro-plugin:hover,
#pro .wpa-pro-plugin:hover,
#hosting .wpa-pro-plugin:hover,
#tools .wpa-pro-plugin:hover,
#recommended .plugin-card:hover {
border-color: #2271b1 !important;
box-shadow: 0 2px 6px rgba(0,0,0,0.15) !important;
transition: all 0.2s ease !important;
}
/* Direct override for free plugins tab width - setting the tab content container to 900px */
#recommended.wp-allstars-settings-content,
#recommended.tab-content {
max-width: 900px !important;
width: 100% !important;
}
/* Target the specific filter container directly with !important */
#wpa-plugin-filters {
max-width: 900px !important;
width: 900px !important;
margin-left: auto !important;
margin-right: auto !important;
box-sizing: border-box !important;
padding: 15px !important;
border-radius: 8px !important;
background: #fff !important;
}
/* Filter links should be centered within container */
#wpa-plugin-filters .filter-links {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
margin: 0;
padding-bottom: 0;
}
/* Style the filter links similar to main tabs with proper border */
#wpa-plugin-filters .filter-links a {
margin: 0;
padding: 10px 15px;
font-size: 14px;
line-height: 1.6;
font-weight: 400;
background: transparent;
color: #50575e;
text-decoration: none;
white-space: nowrap;
border: none;
border-bottom: 2px solid transparent;
display: inline-block;
transition: all 0.2s ease;
}
#wpa-plugin-filters .filter-links a:hover,
#wpa-plugin-filters .filter-links a:focus {
color: #2271b1;
background: transparent;
border-bottom: 2px solid #2271b1;
}
#wpa-plugin-filters .filter-links a.current {
border-bottom: 2px solid #2271b1;
background: transparent;
color: #2271b1;
font-weight: 600;
}
/* Target the plugin container directly with !important for 900px width */
#recommended .wpa-plugin-container,
#wpa-plugin-list.wpa-plugin-container {
max-width: 900px !important;
width: 900px !important;
margin-left: auto !important;
margin-right: auto !important;
padding: 15px 20px 20px 20px !important;
display: flex;
flex-direction: column;
align-items: center;
box-sizing: border-box !important;
}
/* Set the individual plugin cards to max 660px width */
#recommended .plugin-card {
width: 100% !important;
max-width: 660px !important;
margin: 0 auto 24px auto !important;
padding: 24px !important;
border: 1px solid #ddd !important;
border-radius: 8px !important;
box-shadow: 0 1px 3px rgba(0,0,0,0.1) !important;
background: #fff !important;
transition: all 0.2s ease !important;
display: flex !important;
flex-direction: column !important;
position: relative !important;
box-sizing: border-box !important;
}

View File

@ -1,7 +1,7 @@
/* Plugin Browser Styles */ /* Plugin Browser Styles */
.wp-allstars-wrap .wp-allstars-plugin-browser { .wp-allstars-wrap .wp-allstars-plugin-browser {
margin: 0 -8px !important; margin: 0 !important;
padding: 0 8px !important; padding: 0 !important;
width: 100% !important; width: 100% !important;
max-width: 100% !important; max-width: 100% !important;
} }
@ -9,37 +9,57 @@
/* Plugin List Container */ /* Plugin List Container */
.wp-allstars-wrap #wpa-plugin-list { .wp-allstars-wrap #wpa-plugin-list {
display: flex; display: flex;
flex-wrap: wrap; flex-direction: column;
align-items: center;
margin: 0; 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 { .wp-allstars-wrap #wpa-plugin-filters.wp-filter {
margin-left: 0; margin: 0 0 11px 0 !important;
margin-right: 0; width: 100% !important;
width: 100%; max-width: 100% !important;
box-sizing: border-box; box-sizing: border-box;
text-align: center;
} }
/* Standard WordPress Plugin Grid Layout - exactly matching core */ /* Center filter links */
.wp-allstars-wrap .wp-list-table.plugin-install { .wp-filter .filter-links {
margin-top: 20px;
clear: both;
padding: 0;
}
.wp-allstars-wrap #the-list {
margin: 0;
display: flex; display: flex;
flex-wrap: wrap; 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 { .plugin-card {
margin: 0 8px 16px; margin: 0 0 24px 0 !important;
width: calc(50% - 16px); width: 100% !important;
background-color: #fff; background-color: #fff;
border: 1px solid #dcdcde; border: 1px solid #dcdcde;
border-radius: 8px; border-radius: 8px;
@ -47,6 +67,13 @@
box-sizing: border-box; box-sizing: border-box;
transition: all 0.2s ease; transition: all 0.2s ease;
overflow: hidden; overflow: hidden;
display: flex;
flex-direction: column;
position: relative !important;
}
.plugin-card:last-child {
margin-bottom: 0 !important;
} }
.plugin-card:hover { .plugin-card:hover {
@ -54,23 +81,123 @@
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
} }
/* Ensure the right edge aligns with the navigation above */ /* Card Content */
.plugin-card:nth-child(even) { .plugin-card-top {
margin-right: 0; padding: 24px !important;
position: relative;
flex-grow: 1;
} }
.plugin-card:nth-child(odd) { .plugin-icon {
margin-left: 0; position: relative !important;
float: left !important;
width: 64px !important;
height: 64px !important;
margin: 0 20px 15px 0 !important;
} }
/* Consistent styling for all widths */ /* Name and description positioning - 768px style */
/* Force equal spacing between all cards */ .name.column-name {
.plugin-card:nth-child(odd) { margin: 0 0 12px 84px !important;
margin-right: 8px; margin-right: 0 !important; /* Full width content */
} }
.plugin-card:nth-child(even) { .name.column-name h3 {
margin-left: 8px; 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 */ /* 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; min-height: 100px !important;
position: relative !important; position: relative !important;
padding: 20px !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; overflow: hidden !important;
} }
@ -152,7 +279,7 @@ body.wp-admin .wp-list-table.plugin-install #the-list .plugin-card .plugin-card-
@supports (display: flex) { @supports (display: flex) {
body.wp-admin .wp-list-table.plugin-install #the-list .plugin-card .plugin-card-top { body.wp-admin .wp-list-table.plugin-install #the-list .plugin-card .plugin-card-top {
padding: 20px !important; padding: 20px !important;
padding-top: 20px !important; padding-top: 22px !important;
min-height: 100px !important; min-height: 100px !important;
} }
} }
@ -236,13 +363,6 @@ body.wp-admin .plugin-card-bottom {
margin-top: 0 !important; margin-top: 0 !important;
text-align: left !important; text-align: left !important;
margin-left: 0 !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 */ /* 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; line-height: 28px !important;
padding-top: 0 !important; padding-top: 0 !important;
padding-bottom: 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 */ /* Ensure consistent layout for action buttons */
@ -370,7 +524,6 @@ body.wp-admin .plugin-card-bottom .compatibility-untested *,
display: block; display: block;
} }
.plugin-card:hover { .plugin-card:hover {
border-color: #999; border-color: #999;
} }
@ -523,7 +676,7 @@ body.wp-admin .plugin-card-bottom .compatibility-untested *,
.wp-filter { .wp-filter {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
margin: 12px 0 25px; margin: 12px 0 0;
padding: 0 10px; padding: 0 10px;
background: #fff; background: #fff;
border: 1px solid #dcdcde; border: 1px solid #dcdcde;
@ -617,6 +770,12 @@ body.wp-admin .plugin-card-bottom .compatibility-untested *,
} }
/* Theme Browser */ /* Theme Browser */
.theme-browser {
max-width: 800px;
margin: 0 auto;
width: 100%;
}
.theme-browser .theme { .theme-browser .theme {
cursor: pointer; cursor: pointer;
float: left; float: left;
@ -751,3 +910,10 @@ body.wp-admin .plugin-card-bottom .compatibility-untested *,
.theme-browser .theme:nth-child(2n) { .theme-browser .theme:nth-child(2n) {
margin-right: 0; 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 */

161
admin/data/free-plugins.php Normal file
View 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'
)
);
}

View 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/'
)
)
)
);
}

View File

@ -3,7 +3,7 @@
* Pro Plugins Configuration * Pro Plugins Configuration
*/ */
function wp_allstars_get_pro_plugins_config() { function wp_allstars_get_pro_plugins() {
return array( return array(
'magic-login-pro' => array( 'magic-login-pro' => array(
'name' => 'Magic Login Pro', 'name' => 'Magic Login Pro',

46
admin/data/readme.php Normal file
View 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
];
}

View 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
View 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
)
)
),
);
}

View File

@ -0,0 +1,313 @@
<?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_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);
}
}

View 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();
}
}

View 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);
}
}

View 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&amp;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);
}
}
}

View 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);
}
}

View 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();

View File

@ -0,0 +1,168 @@
<?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');
// 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">
<!-- 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);
// 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');
}
}

View 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();
}
}

View 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(),
);
}
}

View 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&#10;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');
}
}

View File

@ -83,7 +83,7 @@ jQuery(document).ready(function($) {
// Handle text input changes // 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() { $('.wp-allstars-setting-row input[type="text"], .wp-allstars-setting-row input[type="number"], .wp-allstars-setting-row textarea').on('blur change', function() {
var $input = $(this); var $input = $(this);
var option = $input.attr('name'); var option = $input.attr('name');
var value = $input.val(); var value = $input.val();
@ -295,6 +295,9 @@ jQuery(document).ready(function($) {
}); });
} }
// Expose initPluginActions to global scope for use in other scripts
window.initPluginActions = initPluginActions;
// Initialize theme handlers // Initialize theme handlers
function initThemeHandlers() { function initThemeHandlers() {
console.log('Initializing theme handlers'); console.log('Initializing theme handlers');
@ -302,26 +305,83 @@ jQuery(document).ready(function($) {
$('.theme-actions .install-now').off('click'); $('.theme-actions .install-now').off('click');
$('.theme-actions .activate-now').off('click'); $('.theme-actions .activate-now').off('click');
// Install theme - use standard WordPress behavior // Install theme - use wp.updates.installTheme AJAX method
$('.theme-actions .install-now').on('click', function(e) { $('.theme-actions .install-now').on('click', function(e) {
// We're not preventing default here - let the standard WordPress installer handle it e.preventDefault();
// Just add the updating message
var $button = $(this); var $button = $(this);
var slug = $button.data('slug'); var slug = $button.data('slug');
$button.addClass('updating-message').text('Installing...'); var buttonText = $button.text();
console.log('Installing theme using standard WordPress URL:', $button.attr('href'));
// The rest will be handled by WordPress core $button.addClass('updating-message').attr('aria-label', wp.updates.l10n.installing);
wp.updates.installTheme({
slug: slug,
success: function(response) {
$button.removeClass('updating-message').addClass('updated-message').attr('aria-label', wp.updates.l10n.installed);
setTimeout(function() {
// Replace the button with an activate button
var $parent = $button.parent();
$button.remove();
// Create activate URL with nonce
var activateUrl = ajaxurl + '?action=wp_allstars_activate_theme&theme=' + slug + '&_wpnonce=' + wpAllstars.nonce;
$parent.prepend('<a href="' + activateUrl + '" class="button button-primary activate-now" data-slug="' + slug + '" data-name="Kadence" data-nonce="' + wpAllstars.nonce + '">Activate</a>');
// Re-initialize the event handlers
initThemeHandlers();
}, 1000);
},
error: function(response) {
$button.removeClass('updating-message').text(buttonText);
alert(response.errorMessage || 'Error installing theme');
}
});
}); });
// Activate theme - use standard WordPress behavior // Activate theme - use AJAX
$('.theme-actions .activate-now').on('click', function(e) { $('.theme-actions .activate-now').on('click', function(e) {
// We're not preventing default here - let the standard WordPress activation handle it e.preventDefault();
// Just add the updating message
var $button = $(this); var $button = $(this);
var slug = $button.data('slug'); var slug = $button.data('slug');
$button.addClass('updating-message').text('Activating...'); var nonce = $button.data('nonce');
console.log('Activating theme using standard WordPress URL:', $button.attr('href')); var buttonText = $button.text();
// The rest will be handled by WordPress core
$button.addClass('updating-message').attr('aria-label', 'Activating...');
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'wp_allstars_activate_theme',
theme: slug,
_wpnonce: wpAllstars.nonce
},
success: function(response) {
if (response.success) {
$button.removeClass('updating-message').addClass('updated-message').attr('aria-label', 'Activated');
setTimeout(function() {
// Replace the button with an active button
var $parent = $button.parent();
$button.remove();
$parent.prepend('<button type="button" class="button button-disabled" disabled="disabled">Active</button>');
// Optionally reload the page to show the activated theme
// window.location.reload();
}, 1000);
} else {
$button.removeClass('updating-message').text(buttonText);
alert(response.data || 'Error activating theme');
}
},
error: function(xhr, status, error) {
$button.removeClass('updating-message').text(buttonText);
alert('Failed to activate theme. Please try again or activate from the Themes page. Error: ' + error);
}
});
}); });
} }
// Expose initThemeHandlers to global scope for use in other scripts
window.initThemeHandlers = initThemeHandlers;
}); });

View File

@ -73,22 +73,22 @@ if (!defined('ABSPATH')) {
}); });
</script> </script>
<?php endif; ?> <?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'); ?> <?php esc_html_e('Preview'); ?>
</a> </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'); ?> <?php esc_html_e('Templates'); ?>
</a> </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'); ?> <?php esc_html_e('Starter AI'); ?>
</a> </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'); ?> <?php esc_html_e('Marketplace'); ?>
</a> </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'); ?> <?php esc_html_e('Pricing'); ?>
</a> </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'); ?> <?php esc_html_e('Go Pro'); ?>
</a> </a>
</div> </div>

File diff suppressed because it is too large Load Diff

View File

@ -2,15 +2,20 @@
/** /**
* Auto Upload Images functionality * Auto Upload Images functionality
* *
* @package WP_Allstars * @package WP_ALLSTARS
* @since 0.2.0
*/ */
if (!defined('ABSPATH')) {
exit;
}
class WP_Allstars_Auto_Upload { class WP_Allstars_Auto_Upload {
/** /**
* Initialize the class * Initialize the class
*/ */
public function __construct() { 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); 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]); return str_replace($url, $local_url, $matches[0]);
} }
} catch (Exception $e) { } 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]; return $matches[0];
@ -80,11 +86,12 @@ class WP_Allstars_Auto_Upload {
* *
* @param string $url External image URL * @param string $url External image URL
* @return string|false Local URL on success, false on failure * @return string|false Local URL on success, false on failure
* @throws Exception If download or upload fails
*/ */
private function upload_image($url) { private function upload_image($url) {
// Get file info $file_array = array(
$file_array = array(); 'name' => sanitize_file_name(basename($url))
$file_array['name'] = basename($url); );
// Download file to temp location // Download file to temp location
$file_array['tmp_name'] = download_url($url); $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()); 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']); $wp_filetype = wp_check_filetype_and_ext($file_array['tmp_name'], $file_array['name']);
if (!$wp_filetype['type']) { if (!$wp_filetype['type']) {
unlink($file_array['tmp_name']); unlink($file_array['tmp_name']);
throw new Exception('Invalid file type'); throw new Exception('Invalid file type');
} }
// Upload the file // Upload the file to media library
$attachment_id = media_handle_sideload($file_array, 0); $attachment_id = media_handle_sideload($file_array, 0);
if (is_wp_error($attachment_id)) { if (is_wp_error($attachment_id)) {
unlink($file_array['tmp_name']);
throw new Exception('Failed to upload image: ' . $attachment_id->get_error_message()); 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 * @param string $error Error message
*/ */
public function log_error($url, $error) { public function log_error($url, $error) {
error_log(sprintf( if (WP_DEBUG) {
'[WP ALLSTARS] Auto Upload Images Error - URL: %s, Error: %s', error_log(sprintf(
$url, '[WP ALLSTARS] Auto Upload Images Error - URL: %s, Error: %s',
$error esc_url_raw($url),
)); sanitize_text_field($error)
));
}
} }
} }

View File

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

View File

@ -1,97 +1,126 @@
<?php <?php
/** /**
* Plugin Name: WP ALLSTARS Plugin * WP ALLSTARS Plugin
* Plugin URI: https://www.wpallstars.com *
* Description: WP ALLSTARS Plugin for WordPress. Speed Matters. * A comprehensive WordPress optimization and management tool designed to enhance
* Version: 0.1.0 (Beta) * site performance, improve workflow, and provide recommendations for plugins and hosting.
* Author: WP ALLSTARS *
* Author URI: https://www.wpallstars.com * @package WP_ALLSTARS
* License: GPL-2.0+ * @version v0.2.3.1
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt *
* 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 * Text Domain: wp-allstars
* Domain Path: /languages * Domain Path: /languages
* Requires at least: 5.0 * @version v0.2.3.1
* Requires PHP: 7.2 *
* 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.1 (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')) {
if ( ! defined( 'WPINC' ) ) { exit;
die;
} }
// Define plugin version - extract from plugin header define('WP_ALLSTARS_VERSION', 'v0.2.3.1');
if (!function_exists('get_plugin_data')) {
require_once(ABSPATH . 'wp-admin/includes/plugin.php'); /**
* 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 * Check for sync operations before loading the plugin
if (function_exists('get_plugin_data')) { */
$plugin_data = get_plugin_data(__FILE__, false, false); // Simple sync detection - check for .syncing file
define('WP_ALLSTARS_VERSION', $plugin_data['Version']); if (file_exists(__DIR__ . '/.syncing')) {
} else { // Only load the minimal code needed for admin notice
// Manual extraction as fallback if (is_admin()) {
$plugin_file = file_get_contents(__FILE__); add_action('admin_notices', function() {
preg_match('/Version:\s*([^\s]+)/i', $plugin_file, $matches); echo '<div class="notice notice-warning is-dismissible">';
define('WP_ALLSTARS_VERSION', isset($matches[1]) ? $matches[1] : '0.1.0 (Beta)'); 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() { 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 // Core includes
require_once plugin_dir_path(__FILE__) . 'includes/class-wp-allstars-auto-upload.php'; wp_allstars_require_if_exists(plugin_dir_path(__FILE__) . 'includes/class-wp-allstars-auto-upload.php');
// Load admin UI and configurations // Admin includes
if ( is_admin() ) { if (is_admin()) {
require_once plugin_dir_path( __FILE__ ) . 'admin/pro-plugins-config.php'; $admin_includes = array(
require_once plugin_dir_path( __FILE__ ) . 'admin/settings.php'; 'admin/includes/class-admin-manager.php',
} 'admin/includes/class-settings-manager.php',
'admin/includes/class-theme-manager.php',
// This function is not needed as we're localizing in wp_allstars_admin_assets 'admin/includes/class-workflow-manager.php',
// function wp_allstars_localize_script() { 'admin/includes/class-tools-manager.php',
// wp_localize_script( 'wp-allstars-admin', 'wpAllstars', [ 'admin/includes/class-hosting-manager.php',
// 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'admin/includes/class-pro-plugins-manager.php',
// 'nonce' => wp_create_nonce( 'wp-allstars-nonce' ) 'admin/includes/class-plugin-manager.php',
// ] ); 'admin/includes/class-free-plugins-manager.php',
// } 'admin/includes/class-readme-manager.php'
// 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
); );
// Enqueue script foreach ($admin_includes as $file) {
// Enqueue WordPress updates script for theme installation wp_allstars_require_if_exists(plugin_dir_path(__FILE__) . $file);
wp_enqueue_script('updates'); }
wp_enqueue_script( // Settings and data
'wp-allstars-admin', wp_allstars_require_if_exists(plugin_dir_path(__FILE__) . 'admin/data/pro-plugins.php');
plugins_url( 'admin/js/wp-allstars-admin.js', __FILE__ ), wp_allstars_require_if_exists(plugin_dir_path(__FILE__) . 'admin/data/readme.php');
array('jquery', 'updates'),
WP_ALLSTARS_VERSION,
true
);
// Localize script for AJAX // Admin settings
$ajax_data = array( wp_allstars_require_if_exists(plugin_dir_path(__FILE__) . 'admin/settings.php');
'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 );
} }
add_action( 'admin_enqueue_scripts', 'wp_allstars_admin_assets' );
// Initialize classes /**
* 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 plugin classes
*/
$wp_allstars_auto_upload = new WP_Allstars_Auto_Upload(); $wp_allstars_auto_upload = new WP_Allstars_Auto_Upload();