Compare commits
265 Commits
main
...
bugfix/iss
| Author | SHA1 | Date | |
|---|---|---|---|
| 29622dd54c | |||
| 1afa6b71d7 | |||
| 8bb4784204 | |||
| b223165012 | |||
| 4228bcc330 | |||
| 7bac0dc63d | |||
| 7c272b5399 | |||
| 81e5b14604 | |||
| 9dca8880cc | |||
| ad03358e2a | |||
| 7d0ee0adea | |||
| 9fdfa7a8a9 | |||
| d6dcda908c | |||
| 7640f01d0c | |||
| 632dda5952 | |||
| 8fda3f1163 | |||
| 79f78882a6 | |||
| e1ee99ac9c | |||
| 6300f1c545 | |||
| c3738a3106 | |||
| e5d2994e40 | |||
| 7eb7aedc39 | |||
| 9cddf28c09 | |||
| a1e5b166ff | |||
| 79829ddce0 | |||
| ef43525c4a | |||
| 708acc39de | |||
| 40f6f596fa | |||
| 0b17fe8ad9 | |||
| a8f968562c | |||
| 595855ce10 | |||
| 1d41af86c3 | |||
| a6db436a48 | |||
| 4a817ab231 | |||
| 1f96fe9965 | |||
| 5d148f8af9 | |||
| 0e906eb981 | |||
| 02a635f72c | |||
| 6625e8ca4a | |||
| 52632ec322 | |||
| 1c1980bb22 | |||
| 41724f72c0 | |||
| 58f5f8f71b | |||
| a9d9c69b65 | |||
| b58036f3f5 | |||
| 3f695bb003 | |||
| 340628877c | |||
| 6684375ea3 | |||
| df7f303ffb | |||
| a7459aba5f | |||
| 66d6167cf5 | |||
| 8befc726bf | |||
| 6e9fb5a9c4 | |||
| 788bb6104f | |||
| f6d30e92d0 | |||
| a509d15acc | |||
| a44826e75e | |||
| 3b73654202 | |||
| 7d3379cda4 | |||
| cd38e0317a | |||
| 8c735ccb2b | |||
| e660915402 | |||
| 5ca320c580 | |||
| bb6de9a3cb | |||
| e8fcc7e1d0 | |||
| c17b6f1818 | |||
| 1590be3ba6 | |||
| 5e65d07a4f | |||
| 84952ff2d1 | |||
| 6300b687aa | |||
| eb388a846d | |||
| 331307f8b0 | |||
| 57f2093adb | |||
| 94872a33c8 | |||
| 53ac0ce696 | |||
| 4a9649bd65 | |||
| 6c340ec19e | |||
| 0960368136 | |||
| e6dcda3f6e | |||
| ca5a9cf38b | |||
| 859161fd0c | |||
| db8c84a80a | |||
| b1966067ea | |||
| bb31e0e934 | |||
| 5f598f0f7e | |||
| a17a574a7e | |||
| e9a967fcd0 | |||
| 0c4e91fcec | |||
| f3d6bd2434 | |||
| 953bf3f6bb | |||
| e5b0181baf | |||
| 771cc96da8 | |||
| ef60ce0c9d | |||
| fa92ca58df | |||
| 8fa2c19fe4 | |||
| 0f83330d85 | |||
| c29841b8ae | |||
| f5c8162ec7 | |||
| 5cd8dcc31e | |||
| ce6c6e42a9 | |||
| f48276cc58 | |||
| 3ca2fe58fa | |||
| c37d2975d3 | |||
| 089e083f40 | |||
| 3c1ec14c2d | |||
| 189d0de673 | |||
| 920b1a0a7d | |||
| 1cfc6f5a13 | |||
| 13d2f92ee5 | |||
| 1089ea491a | |||
| 35d7623722 | |||
| 78e2929b27 | |||
| d0b42262a4 | |||
| 999105228a | |||
| b10ea120cd | |||
| 6eb7b2c4e3 | |||
| 2b726a4b46 | |||
| 960468f176 | |||
| 17375cf555 | |||
| fae342fe33 | |||
| cde6d979b5 | |||
| c0748c0d0b | |||
| 64567f3d0f | |||
| 7783f8de79 | |||
| 5f95ba762e | |||
| 81f490efcb | |||
| e823026626 | |||
| f704685e96 | |||
| f652e9e0c3 | |||
| 400632a3b3 | |||
| fb0949df0a | |||
| c7e01493ef | |||
| 4d74fe35dc | |||
| d6b2349af8 | |||
| 572c23df89 | |||
| 824f2a97e8 | |||
| 2e25c48135 | |||
| 11fbce90a0 | |||
| 1841b6b8bd | |||
| 474a5d2753 | |||
| 78c3d03030 | |||
| 051bc763f8 | |||
| ed160ed51b | |||
| e8d81ef45b | |||
| 47d77c6451 | |||
| d058898022 | |||
| e5edff8cfa | |||
| f09854329b | |||
| 5bdd04f592 | |||
| f7515b5861 | |||
| 8ed22642e2 | |||
| 136f07d9c4 | |||
| 40ebbce1cc | |||
| af11f827c4 | |||
| bfd2d4b063 | |||
| 6e95542ac5 | |||
| baa2a050d3 | |||
| 61ca9d4768 | |||
| 3d1bf9d113 | |||
| 348eb872a8 | |||
| 6554392dd6 | |||
| ce96ea2e96 | |||
| 445d022232 | |||
| d3e5d0d0c0 | |||
| 2481d63561 | |||
| cdc73bc010 | |||
| 67c6c65611 | |||
| ebdb172a14 | |||
| 57a4c98f46 | |||
| 4c1bee9dbe | |||
| 200cc5671d | |||
| 398d24ed90 | |||
| ad30d716db | |||
| 19ec65326b | |||
| 3048e91a78 | |||
| 3926927791 | |||
| 728c5dcf3d | |||
| 109c07cfed | |||
| ea628c521b | |||
| ae7bd5cb89 | |||
| 1f4be45862 | |||
| 78bd0708d3 | |||
| 36840c46c1 | |||
| aa62142e4c | |||
| 0ab1a1df4d | |||
| 69cd192f49 | |||
| 4ebe55b940 | |||
| 5b4037bf0d | |||
| fd314fd7c7 | |||
| 546ed59a61 | |||
| 069dc2e8d7 | |||
| 9d36b47f9f | |||
| 5cd2a7d374 | |||
| 497c44c3c6 | |||
| e3f11ac03f | |||
| 04cdd49a3f | |||
| cdd9b050c7 | |||
| 6031751015 | |||
| a885ef1e0b | |||
| c930a5484a | |||
| 45feb7b550 | |||
| cb79402c5f | |||
| 1af79e0bfd | |||
| a88af434db | |||
| 4eac81ba0e | |||
| 92124e139f | |||
| eb4e71f98f | |||
| 3dfd5f2658 | |||
| d58f5fdb72 | |||
| 07d0e7e44b | |||
| e9139ec9d9 | |||
| 7d8b9361c5 | |||
| 63f2520f70 | |||
| fbe4eba3ff | |||
| cc6acc2a4e | |||
| ed7d33e2aa | |||
| fb8a998487 | |||
| 2ac9b046b5 | |||
| d1c5950dcb | |||
| 2e9914e325 | |||
| b9fa979600 | |||
| 2a025ec18c | |||
| 95e4361cd5 | |||
| 6d9a9658ea | |||
| 7051fb1193 | |||
| 6527fde363 | |||
| 643f5c6d41 | |||
| b7bf97d5b4 | |||
| a5d3c09243 | |||
| c7435f5a49 | |||
| aa136c7a4a | |||
| 455edb99f9 | |||
| 584d774931 | |||
| b2b8af4216 | |||
| a0df887d5c | |||
| 4d69c446db | |||
| 4441106963 | |||
| 35f50aa03b | |||
| 6d3aeb889a | |||
| b18f1c46b4 | |||
| bcdbbb454c | |||
| 3d739915d7 | |||
| 51183c378e | |||
| 71c0a77a31 | |||
| 0e219975ae | |||
| 058ae4b64e | |||
| 3fa42ae1c7 | |||
| 275958bfdb | |||
| 93412896e8 | |||
| 6784ef4824 | |||
| 0874c4f59e | |||
| 4696cdfba6 | |||
| 1cf46254b7 | |||
| 3c1db9d4fb | |||
| bfa528c90e | |||
| 233a64913b | |||
| 1c049a91c5 | |||
| 1e2f7a5cd8 | |||
| 7072f21d49 | |||
| af48e84614 | |||
| 5083fcee50 | |||
| 79d1314aed | |||
| 2f4d88f8dd | |||
| bfac63799b | |||
| 9d3e67d16b |
@@ -16,7 +16,7 @@ git checkout -b fix/bug-description
|
||||
|
||||
Use a descriptive name that clearly indicates what bug is being fixed. If there's an issue number, include it in the branch name (e.g., `fix/123-plugin-activation-error`).
|
||||
|
||||
For more detailed git workflow guidelines, see **@.ai-workflows/git-workflow.md**.
|
||||
For more detailed git workflow guidelines, see **@.agents/git-workflow.md**.
|
||||
|
||||
### 2. Understand the Bug
|
||||
|
||||
@@ -111,7 +111,7 @@ After fixing a bug and confirming it works, determine the appropriate version in
|
||||
|
||||
This approach is more time-efficient as it allows you to focus on fixing the bug without worrying about version updates until the fix is confirmed working.
|
||||
|
||||
For detailed guidelines on time-efficient development and testing, see **@.ai-workflows/incremental-development.md**.
|
||||
For detailed guidelines on time-efficient development and testing, see **@.agents/incremental-development.md**.
|
||||
|
||||
## Testing Previous Versions
|
||||
|
||||
154
.agents/code-quality-checks.md
Normal file
154
.agents/code-quality-checks.md
Normal file
@@ -0,0 +1,154 @@
|
||||
# Code Quality Checks Workflow
|
||||
|
||||
## Scope
|
||||
|
||||
This document is intended for plugin developers and code reviewers working on this repository. It outlines the process for ensuring code quality before pushing changes to the repository. Following these steps will help catch issues early and save time in the review process.
|
||||
|
||||
## Pre-Push Checklist
|
||||
|
||||
Before pushing your changes to the repository, run through the following checks:
|
||||
|
||||
1. **Run Unit Tests**
|
||||
|
||||
```bash
|
||||
composer test
|
||||
```
|
||||
|
||||
Ensure all tests pass. If any tests fail, resolve the issues before proceeding.
|
||||
|
||||
2. **Run PHP CodeSniffer**
|
||||
|
||||
```bash
|
||||
composer phpcs
|
||||
```
|
||||
|
||||
This will check your code against WordPress coding standards. Fix any issues before proceeding.
|
||||
|
||||
3. **Run PHP Code Beautifier and Fixer**
|
||||
|
||||
```bash
|
||||
composer phpcbf
|
||||
```
|
||||
|
||||
This will automatically fix many coding standard issues.
|
||||
|
||||
4. **Run PHPStan**
|
||||
|
||||
```bash
|
||||
composer phpstan
|
||||
```
|
||||
|
||||
This will perform static analysis on your code to find potential bugs and issues.
|
||||
|
||||
5. **Run PHP Mess Detector**
|
||||
|
||||
```bash
|
||||
composer phpmd
|
||||
```
|
||||
|
||||
This will check for potential problems like unused variables, empty catch blocks, etc.
|
||||
|
||||
## Common Issues and How to Fix Them
|
||||
|
||||
### 1. Inline Comments
|
||||
|
||||
All inline comments must end with proper punctuation (period, exclamation mark, or question mark).
|
||||
|
||||
```php
|
||||
// Incorrect comment
|
||||
$var = true;
|
||||
|
||||
// Correct comment.
|
||||
$var = true;
|
||||
```
|
||||
|
||||
### 2. Superglobal Access
|
||||
|
||||
Never access superglobals like `$_GET`, `$_POST`, etc. directly. Always use WordPress functions to sanitize and validate input.
|
||||
|
||||
```php
|
||||
// Incorrect
|
||||
$page = $_GET['page'];
|
||||
|
||||
// Correct
|
||||
$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
|
||||
// For testing environments
|
||||
if (defined('PHPUNIT_RUNNING') && PHPUNIT_RUNNING) {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- This rule is ignored in tests to allow direct access for testing purposes
|
||||
$page = isset($_GET['page']) ? wp_unslash($_GET['page']) : '';
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Avoid Unnecessary Else Clauses
|
||||
|
||||
Simplify your code by avoiding unnecessary else clauses.
|
||||
|
||||
```php
|
||||
// Less preferred
|
||||
if (condition) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Preferred
|
||||
if (condition) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
```
|
||||
|
||||
### 4. Proper Function Spacing
|
||||
|
||||
Ensure proper spacing in function calls and declarations.
|
||||
|
||||
```php
|
||||
// Incorrect
|
||||
function_name($param1,$param2);
|
||||
|
||||
// Correct
|
||||
function_name( $param1, $param2 );
|
||||
```
|
||||
|
||||
### 5. Naming Conventions
|
||||
|
||||
Follow WordPress naming conventions:
|
||||
|
||||
* Functions and variables: snake_case with plugin-specific prefix (e.g., `myplugin_function_name`)
|
||||
* Classes: CamelCase
|
||||
* Constants: UPPERCASE_WITH_UNDERSCORES with plugin-specific prefix (e.g., `MYPLUGIN_CONSTANT_NAME`)
|
||||
|
||||
## Automated Checks in CI/CD
|
||||
|
||||
Our CI/CD pipeline includes the following automated checks:
|
||||
|
||||
1. **CodeFactor**: Analyzes code quality and style
|
||||
2. **Codacy**: Performs static code analysis
|
||||
3. **SonarCloud**: Checks for code smells, bugs, and security vulnerabilities
|
||||
4. **CodeRabbit**: Provides AI-powered code review
|
||||
|
||||
Although CI runs these checks, catching issues locally helps save time and minimize follow-up commits.
|
||||
|
||||
## Using AI to Help with Code Quality
|
||||
|
||||
You can use AI assistants to help improve code quality:
|
||||
|
||||
1. Run the code quality checks locally
|
||||
2. If issues are found, ask the AI assistant to help fix them
|
||||
3. Apply the suggested fixes
|
||||
4. Run the checks again to verify the issues are resolved
|
||||
|
||||
Example prompt:
|
||||
|
||||
```text
|
||||
I ran PHPCS and got the following errors. Can you help me fix them?
|
||||
|
||||
[Paste error output here]
|
||||
```
|
||||
|
||||
For more AI assistance guidelines, see the [AI Assistant Guide](./../AGENTS.md).
|
||||
|
||||
## Conclusion
|
||||
|
||||
This workflow helps maintain high code quality and accelerates the review process. Remember, it's always more efficient to resolve issues locally than to go through multiple rounds of CI/CD and code review.
|
||||
286
.agents/code-review.md
Normal file
286
.agents/code-review.md
Normal file
@@ -0,0 +1,286 @@
|
||||
# Code Review Guide for AI Assistants
|
||||
|
||||
This document provides guidance for AI assistants to help with code review for this project.
|
||||
|
||||
## Code Review Checklist
|
||||
|
||||
### Testing with WordPress Playground
|
||||
|
||||
Before submitting code for review, test it with WordPress Playground:
|
||||
|
||||
* [ ] Test in single site environment:
|
||||
[Open in WordPress Playground][playground-single]
|
||||
* [ ] Test in multisite environment:
|
||||
[Open in WordPress Playground][playground-multisite]
|
||||
|
||||
[playground-single]: https://playground.wordpress.net/?blueprint-url=https://raw.githubusercontent.com/wpallstars/wp-plugin-starter-template-for-ai-coding/main/playground/blueprint.json&_t=5
|
||||
[playground-multisite]: https://playground.wordpress.net/?blueprint-url=https://raw.githubusercontent.com/wpallstars/wp-plugin-starter-template-for-ai-coding/main/playground/multisite-blueprint.json&_t=18
|
||||
* [ ] Verify plugin functionality works in both environments
|
||||
* [ ] Check for any JavaScript errors in the browser console
|
||||
* [ ] Run Cypress tests locally: `npm run test:playground:single` and `npm run test:playground:multisite`
|
||||
|
||||
For more details on WordPress Playground testing, see the [Testing Framework](../.wiki/Testing.md) documentation.
|
||||
|
||||
When reviewing code, check for the following:
|
||||
|
||||
### Functionality
|
||||
|
||||
* [ ] Does the code work as expected?
|
||||
* [ ] Does it handle edge cases appropriately?
|
||||
* [ ] Are there any logical errors?
|
||||
* [ ] Is error handling implemented properly?
|
||||
|
||||
### Code Quality
|
||||
|
||||
* [ ] Does the code follow WordPress coding standards?
|
||||
* [ ] Is the code well-organized and easy to understand?
|
||||
* [ ] Are there any code smells (duplicate code, overly complex functions, etc.)?
|
||||
* [ ] Are functions and variables named appropriately?
|
||||
* [ ] Are there appropriate comments and documentation?
|
||||
|
||||
### Security
|
||||
|
||||
* [ ] Is user input properly validated and sanitized?
|
||||
* [ ] Is output properly escaped?
|
||||
* [ ] Are capability checks used for user actions?
|
||||
* [ ] Are nonces used for form submissions?
|
||||
* [ ] Are there any potential SQL injection vulnerabilities?
|
||||
* [ ] Are there any potential XSS vulnerabilities?
|
||||
|
||||
### Performance
|
||||
|
||||
* [ ] Are there any performance bottlenecks?
|
||||
* [ ] Are database queries optimized?
|
||||
* [ ] Is caching used appropriately?
|
||||
* [ ] Are assets (CSS, JS) properly enqueued?
|
||||
|
||||
### Compatibility
|
||||
|
||||
* [ ] Is the code compatible with the minimum supported WordPress version (5.0)?
|
||||
* [ ] Is the code compatible with the minimum supported PHP version (7.0)?
|
||||
* [ ] Are there any browser compatibility issues?
|
||||
* [ ] Are there any conflicts with other plugins?
|
||||
|
||||
### Internationalization
|
||||
|
||||
* [ ] Are all user-facing strings translatable?
|
||||
* [ ] Is the correct text domain used?
|
||||
* [ ] Are translation functions used correctly?
|
||||
|
||||
### Accessibility
|
||||
|
||||
* [ ] Does the code follow accessibility best practices?
|
||||
* [ ] Are ARIA attributes used appropriately?
|
||||
* [ ] Is keyboard navigation supported?
|
||||
* [ ] Is screen reader support implemented?
|
||||
|
||||
### Testing
|
||||
|
||||
* [ ] Are there appropriate unit tests for PHP code?
|
||||
* [ ] Are there appropriate end-to-end tests for UI functionality?
|
||||
* [ ] Do tests cover both single site and multisite scenarios?
|
||||
* [ ] Are tests well-organized and maintainable?
|
||||
* [ ] Do tests use appropriate assertions and expectations?
|
||||
|
||||
## Automated Code Review Tools
|
||||
|
||||
This project uses several automated code review tools to maintain high quality standards.
|
||||
|
||||
These tools are free for public repositories and should be integrated into new repositories.
|
||||
|
||||
**Important**: Before pushing, run local code quality checks as described in
|
||||
[Code Quality Checks Workflow](./code-quality-checks.md) to catch issues early.
|
||||
|
||||
### 1. CodeRabbit
|
||||
|
||||
[CodeRabbit](https://www.coderabbit.ai/) is an AI-powered code review tool.
|
||||
|
||||
It provides automated feedback on pull requests.
|
||||
|
||||
* **Integration**: Add the CodeRabbit GitHub App to your repository
|
||||
* **Benefits**: Provides AI-powered code reviews, identifies potential issues, and suggests improvements
|
||||
* **Usage**: CodeRabbit automatically reviews pull requests when they are created or updated
|
||||
|
||||
### 2. CodeFactor
|
||||
|
||||
[CodeFactor](https://www.codefactor.io/) continuously monitors code quality.
|
||||
|
||||
It provides feedback on code style, complexity, and potential issues.
|
||||
|
||||
* **Integration**: Add the CodeFactor GitHub App to your repository
|
||||
* **Benefits**: Provides a grade for your codebase, identifies issues, and tracks code quality over time
|
||||
* **Usage**: CodeFactor automatically analyzes your codebase and provides feedback on pull requests
|
||||
|
||||
### 3. Codacy
|
||||
|
||||
[Codacy](https://www.codacy.com/) is a code quality tool.
|
||||
|
||||
It provides static analysis, code coverage, and code duplication detection.
|
||||
|
||||
* **Integration**: Add the Codacy GitHub App to your repository
|
||||
* **Benefits**: Provides a grade for your codebase, identifies issues, and tracks code quality over time
|
||||
* **Usage**: Codacy automatically analyzes your codebase and provides feedback on pull requests
|
||||
|
||||
### 4. PHPStan
|
||||
|
||||
[PHPStan](https://phpstan.org/) is a static analysis tool that finds errors in your code without running it.
|
||||
|
||||
* **Integration**: Included in the project's composer.json and GitHub Actions workflow
|
||||
* **Benefits**: Detects undefined variables, methods, and properties; type-related issues; and logical errors
|
||||
* **Usage**: Run `composer phpstan` or `npm run lint:phpstan` locally, or let GitHub Actions run it automatically
|
||||
|
||||
### 5. PHP Mess Detector
|
||||
|
||||
[PHP Mess Detector](https://phpmd.org/) looks for potential problems in your code.
|
||||
|
||||
It detects bugs, suboptimal code, overcomplicated expressions, and unused code.
|
||||
|
||||
* **Integration**: Included in the project's composer.json and GitHub Actions workflow
|
||||
* **Benefits**: Identifies code smells, complexity issues, unused code, naming problems, and more
|
||||
* **Usage**: Run `composer phpmd` or `npm run lint:phpmd` locally, or let GitHub Actions run it automatically
|
||||
|
||||
### Using AI Assistants with Code Review Tools
|
||||
|
||||
When you receive feedback from these code review tools, you can use AI assistants to help address the issues:
|
||||
|
||||
1. Copy the output from the code review tool
|
||||
2. Paste it into your AI assistant chat
|
||||
3. Ask the AI to help you understand and resolve the issues
|
||||
4. Apply the suggested fixes
|
||||
5. Commit the changes and verify that the issues are resolved
|
||||
|
||||
### Markdown Formatting Standards
|
||||
|
||||
When writing or updating Markdown files in this project, follow these standards:
|
||||
|
||||
* Always use asterisks (*) for bullet points, not hyphens (-)
|
||||
* Use proper heading hierarchy (# for main title, ## for sections, etc.)
|
||||
* Use code blocks with language specification for code examples
|
||||
* Use relative links for internal documentation
|
||||
* Include alt text for images
|
||||
|
||||
Example prompt for AI assistants:
|
||||
|
||||
```text
|
||||
I received the following feedback from [Tool Name]. Please help me understand and resolve these issues:
|
||||
|
||||
[Paste the tool output here]
|
||||
```
|
||||
|
||||
## Code Review Process
|
||||
|
||||
### 1. Understand the Context
|
||||
|
||||
Before reviewing code, understand:
|
||||
|
||||
* What problem is the code trying to solve?
|
||||
* What are the requirements?
|
||||
* What are the constraints?
|
||||
|
||||
### 2. Review the Code
|
||||
|
||||
Review the code with the checklist above in mind.
|
||||
|
||||
### 3. Provide Feedback
|
||||
|
||||
When providing feedback:
|
||||
|
||||
* Be specific and clear
|
||||
* Explain why a change is needed
|
||||
* Provide examples or suggestions when possible
|
||||
* Prioritize feedback (critical issues vs. minor improvements)
|
||||
* Be constructive and respectful
|
||||
|
||||
### 4. Follow Up
|
||||
|
||||
After the code has been updated:
|
||||
|
||||
* Review the changes
|
||||
* Verify that issues have been addressed
|
||||
* Provide additional feedback if necessary
|
||||
|
||||
## Common Issues to Look For
|
||||
|
||||
### PHP Issues
|
||||
|
||||
* Undefined variables or functions
|
||||
* Incorrect function parameters
|
||||
* Missing return statements
|
||||
* Improper error handling
|
||||
* Inefficient loops or conditionals
|
||||
* Hardcoded values that should be configurable
|
||||
|
||||
### WordPress-Specific Issues
|
||||
|
||||
* Incorrect hook usage
|
||||
* Missing or incorrect nonces
|
||||
* Missing capability checks
|
||||
* Direct database queries instead of using WordPress functions
|
||||
* Improper enqueuing of scripts and styles
|
||||
* Not using WordPress functions for common tasks
|
||||
|
||||
### JavaScript Issues
|
||||
|
||||
* Undefined variables or functions
|
||||
* Event listener memory leaks
|
||||
* jQuery conflicts
|
||||
* Browser compatibility issues
|
||||
* Missing error handling
|
||||
|
||||
### CSS Issues
|
||||
|
||||
* Browser compatibility issues
|
||||
* Specificity issues
|
||||
* Unused styles
|
||||
* Overriding WordPress admin styles inappropriately
|
||||
|
||||
## Example Feedback
|
||||
|
||||
### Good Feedback Example
|
||||
|
||||
```markdown
|
||||
In function `handle_remove_reference()`:
|
||||
|
||||
1. The nonce check is missing, which could lead to CSRF vulnerabilities.
|
||||
Consider adding:
|
||||
```php
|
||||
if (!isset($_GET['_wpnonce']) || !wp_verify_nonce($_GET['_wpnonce'], 'fpden_remove_reference')) {
|
||||
wp_die(__('Security check failed.', 'fix-plugin-does-not-exist-notices'));
|
||||
}
|
||||
```
|
||||
|
||||
2. The user capability check should be more specific. Instead of:
|
||||
```php
|
||||
if (!current_user_can('manage_options')) {
|
||||
```
|
||||
Consider using:
|
||||
```php
|
||||
if (!current_user_can('activate_plugins')) {
|
||||
```
|
||||
This is more appropriate for the action being performed.
|
||||
|
||||
3. The success message should be translatable:
|
||||
```php
|
||||
// Change this:
|
||||
add_settings_error(
|
||||
'fpden',
|
||||
'fpden_removed',
|
||||
'Plugin reference removed successfully.',
|
||||
'updated'
|
||||
);
|
||||
|
||||
// To this:
|
||||
add_settings_error(
|
||||
'fpden',
|
||||
'fpden_removed',
|
||||
__( 'Plugin reference removed successfully.', 'fix-plugin-does-not-exist-notices' ),
|
||||
'updated'
|
||||
);
|
||||
```
|
||||
```
|
||||
|
||||
### Poor Feedback Example
|
||||
|
||||
```text
|
||||
This code has security issues and doesn't follow best practices. Fix it.
|
||||
```
|
||||
@@ -31,9 +31,9 @@ This document serves as a persistent memory for developer preferences establishe
|
||||
|
||||
### Documentation
|
||||
|
||||
- Prefer token-efficient documentation in `.ai-assistant.md` that references `.ai-workflows/` files
|
||||
- Document the release workflow in `.ai-assistant.md` and `.ai-workflows/release-process.md`
|
||||
- Store environment variable documentation in `.ai-workflows/local-env-vars.md`
|
||||
- Prefer token-efficient documentation in `AGENTS.md` that references `.agents/` files
|
||||
- Document the release workflow in `AGENTS.md` and `.agents/release-process.md`
|
||||
- Store environment variable documentation in `.agents/local-env-vars.md`
|
||||
- Maintain consistent documentation across readme.txt, README.md, and CHANGELOG.md
|
||||
|
||||
### Asset Organization
|
||||
576
.agents/error-checking-feedback-loops.md
Normal file
576
.agents/error-checking-feedback-loops.md
Normal file
@@ -0,0 +1,576 @@
|
||||
# Error Checking and Feedback Loops
|
||||
|
||||
This document outlines the processes for error checking, debugging, and establishing feedback loops.
|
||||
|
||||
The goal is to create a seamless, autonomous CI/CD pipeline.
|
||||
|
||||
The AI can identify, diagnose, and fix issues with minimal human intervention.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [GitHub Actions Workflow Monitoring](#github-actions-workflow-monitoring)
|
||||
* [Local Build and Test Feedback](#local-build-and-test-feedback)
|
||||
* [Code Quality Tool Integration](#code-quality-tool-integration)
|
||||
* [Automated Error Resolution](#automated-error-resolution)
|
||||
* [Feedback Loop Architecture](#feedback-loop-architecture)
|
||||
* [When to Consult Humans](#when-to-consult-humans)
|
||||
|
||||
## GitHub Actions Workflow Monitoring
|
||||
|
||||
### Checking Workflow Status via GitHub API
|
||||
|
||||
AI assistants can directly monitor GitHub Actions workflows using the GitHub API.
|
||||
|
||||
This helps identify failures and diagnose issues:
|
||||
|
||||
```text
|
||||
github-api /repos/{owner}/{repo}/actions/runs
|
||||
```
|
||||
|
||||
#### Step-by-Step Process
|
||||
|
||||
1. **Get Recent Workflow Runs**:
|
||||
|
||||
```text
|
||||
github-api /repos/wpallstars/wp-plugin-starter-template-for-ai-coding/actions/runs
|
||||
```
|
||||
|
||||
2. **Filter for Failed Runs**:
|
||||
|
||||
```text
|
||||
github-api /repos/wpallstars/wp-plugin-starter-template-for-ai-coding/actions/runs?status=failure
|
||||
```
|
||||
|
||||
3. **Get Details for a Specific Run**:
|
||||
|
||||
```text
|
||||
github-api /repos/wpallstars/wp-plugin-starter-template-for-ai-coding/actions/runs/{run_id}
|
||||
```
|
||||
|
||||
4. **Get Jobs for a Workflow Run**:
|
||||
|
||||
```text
|
||||
github-api /repos/wpallstars/wp-plugin-starter-template-for-ai-coding/actions/runs/{run_id}/jobs
|
||||
```
|
||||
|
||||
5. **Analyze Job Logs** (if accessible via API):
|
||||
|
||||
```text
|
||||
github-api /repos/wpallstars/wp-plugin-starter-template-for-ai-coding/actions/jobs/{job_id}/logs
|
||||
```
|
||||
|
||||
### Common GitHub Actions Errors and Solutions
|
||||
|
||||
#### Missing or Outdated Action Versions
|
||||
|
||||
**Error**: `Missing download info for actions/upload-artifact@v3`
|
||||
|
||||
**Solution**: Update to the latest version of the action:
|
||||
|
||||
```yaml
|
||||
uses: actions/upload-artifact@v4
|
||||
```
|
||||
|
||||
#### Port Configuration Issues for WordPress Multisite
|
||||
|
||||
**Error**: `The current host is 127.0.0.1:8888, but WordPress multisites do not support custom ports.`
|
||||
|
||||
**Solution**: Use port 80 for multisite environments:
|
||||
|
||||
```bash
|
||||
npx @wp-playground/cli server --blueprint playground/multisite-blueprint.json --port 80 --login &
|
||||
```
|
||||
|
||||
#### Artifact Path Syntax Issues
|
||||
|
||||
**Error**: Invalid path syntax for artifacts
|
||||
|
||||
**Solution**: Use multi-line format for better readability:
|
||||
|
||||
```yaml
|
||||
path: |
|
||||
cypress/videos
|
||||
cypress/screenshots
|
||||
```
|
||||
|
||||
#### Concurrency Control
|
||||
|
||||
**Problem**: Redundant workflow runs when multiple commits land quickly
|
||||
|
||||
**Solution**: Add concurrency control to cancel in-progress runs:
|
||||
|
||||
```yaml
|
||||
concurrency:
|
||||
group: playground-tests-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
```
|
||||
|
||||
## Local Build and Test Feedback
|
||||
|
||||
### Monitoring Local Test Runs
|
||||
|
||||
AI assistants can monitor local test runs by analyzing the output of test commands.
|
||||
|
||||
#### PHP Unit Tests
|
||||
|
||||
```bash
|
||||
composer run phpunit
|
||||
```
|
||||
|
||||
#### Cypress Tests
|
||||
|
||||
```bash
|
||||
npm run test:single
|
||||
npm run test:multisite
|
||||
```
|
||||
|
||||
#### WordPress Playground Tests
|
||||
|
||||
```bash
|
||||
npm run test:playground:single
|
||||
npm run test:playground:multisite
|
||||
```
|
||||
|
||||
### Capturing and Analyzing Test Output
|
||||
|
||||
1. **Run Tests with Output Capture**:
|
||||
|
||||
```bash
|
||||
npm run test:single > test-output.log 2>&1
|
||||
```
|
||||
|
||||
2. **Analyze Output for Errors**:
|
||||
|
||||
```bash
|
||||
grep -E -i '\b(error|fail|exception)' test-output.log
|
||||
```
|
||||
|
||||
3. **Parse Structured Test Results** (if available):
|
||||
|
||||
```bash
|
||||
cat cypress/results/results.json
|
||||
```
|
||||
|
||||
### Common Local Test Errors and Solutions
|
||||
|
||||
#### WordPress Playground Port Issues
|
||||
|
||||
**Error**: `The current host is 127.0.0.1:8888, but WordPress multisites do not support custom ports.`
|
||||
|
||||
**Solution**: Modify the port in the blueprint or test configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"features": {
|
||||
"networking": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Cypress Selector Errors
|
||||
|
||||
**Error**: `Timed out retrying after 4000ms: expected '<body...>' to have class 'wp-admin'`
|
||||
|
||||
**Solution**: Update selectors to be more robust and handle login states:
|
||||
|
||||
```javascript
|
||||
cy.get('body').then(($body) => {
|
||||
if ($body.hasClass('login')) {
|
||||
cy.get('#user_login').type('admin');
|
||||
cy.get('#user_pass').type('password');
|
||||
cy.get('#wp-submit').click();
|
||||
}
|
||||
});
|
||||
|
||||
// Check for admin bar instead of body class
|
||||
cy.get('#wpadminbar').should('exist');
|
||||
```
|
||||
|
||||
## Code Quality Tool Integration
|
||||
|
||||
### Automated Code Quality Checks
|
||||
|
||||
AI assistants can integrate with various code quality tools to identify and fix issues.
|
||||
|
||||
#### PHPCS (PHP CodeSniffer)
|
||||
|
||||
```bash
|
||||
composer run phpcs
|
||||
```
|
||||
|
||||
#### ESLint (JavaScript)
|
||||
|
||||
```bash
|
||||
npm run lint:js
|
||||
```
|
||||
|
||||
#### Stylelint (CSS)
|
||||
|
||||
```bash
|
||||
npm run lint:css
|
||||
```
|
||||
|
||||
### Parsing Code Quality Tool Output
|
||||
|
||||
1. **Run Code Quality Check**:
|
||||
|
||||
```bash
|
||||
composer run phpcs > phpcs-output.log 2>&1
|
||||
```
|
||||
|
||||
2. **Analyze Output for Errors**:
|
||||
|
||||
```bash
|
||||
grep -E -i '\b(ERROR|WARNING)' phpcs-output.log
|
||||
```
|
||||
|
||||
3. **Automatically Fix Issues** (when possible):
|
||||
|
||||
```bash
|
||||
composer run phpcbf
|
||||
```
|
||||
|
||||
### Monitoring Code Quality Feedback in Pull Requests
|
||||
|
||||
Automated code quality tools often provide feedback directly in pull requests.
|
||||
|
||||
AI assistants can check these comments to identify and address issues.
|
||||
|
||||
#### Accessing PR Comments via GitHub API
|
||||
|
||||
```text
|
||||
github-api /repos/wpallstars/wp-plugin-starter-template-for-ai-coding/pulls/{pull_number}/comments
|
||||
```
|
||||
|
||||
#### Accessing PR Review Comments
|
||||
|
||||
```text
|
||||
github-api /repos/wpallstars/wp-plugin-starter-template-for-ai-coding/pulls/{pull_number}/reviews
|
||||
```
|
||||
|
||||
#### Checking CodeRabbit Feedback
|
||||
|
||||
CodeRabbit provides AI-powered code review comments via the GitHub API.
|
||||
|
||||
1. **Get PR Comments**:
|
||||
|
||||
```text
|
||||
github-api /repos/wpallstars/wp-plugin-starter-template-for-ai-coding/pulls/{pull_number}/comments
|
||||
```
|
||||
|
||||
2. **Filter for CodeRabbit Comments**:
|
||||
Look for comments from the `coderabbitai` user.
|
||||
|
||||
3. **Parse Actionable Feedback**:
|
||||
* Code quality issues
|
||||
* Suggested improvements
|
||||
* Best practice recommendations
|
||||
* Specific code snippets to fix
|
||||
|
||||
#### Checking Codacy and CodeFactor Feedback
|
||||
|
||||
These tools provide automated code quality checks and post results as PR comments.
|
||||
|
||||
1. **Check PR Status Checks**:
|
||||
|
||||
```text
|
||||
github-api /repos/wpallstars/wp-plugin-starter-template-for-ai-coding/commits/{sha}/check-runs
|
||||
```
|
||||
|
||||
2. **Get Detailed Reports** (if available via API):
|
||||
|
||||
```text
|
||||
github-api /repos/wpallstars/wp-plugin-starter-template-for-ai-coding/commits/{sha}/check-runs/{id}
|
||||
```
|
||||
|
||||
3. **Parse Common Issues**:
|
||||
* Code style violations
|
||||
* Potential bugs
|
||||
* Security vulnerabilities
|
||||
* Performance issues
|
||||
* Duplication
|
||||
|
||||
#### Checking SonarCloud Analysis
|
||||
|
||||
SonarCloud provides detailed code quality and security analysis.
|
||||
|
||||
1. **Check SonarCloud Status**:
|
||||
|
||||
```text
|
||||
github-api /repos/wpallstars/wp-plugin-starter-template-for-ai-coding/commits/{sha}/check-runs?check_name=SonarCloud
|
||||
```
|
||||
|
||||
2. **Parse SonarCloud Issues**:
|
||||
* Code smells
|
||||
* Bugs
|
||||
* Vulnerabilities
|
||||
* Security hotspots
|
||||
* Coverage gaps
|
||||
|
||||
### Common Code Quality Issues and Solutions
|
||||
|
||||
#### WordPress Coding Standards
|
||||
|
||||
**Error**: `ERROR: Expected snake_case for function name, but found camelCase`
|
||||
|
||||
**Solution**: Rename functions to follow snake_case convention:
|
||||
|
||||
```php
|
||||
// Before
|
||||
function getPluginVersion() { ... }
|
||||
|
||||
// After
|
||||
function get_plugin_version() { ... }
|
||||
```
|
||||
|
||||
#### Missing Docblocks
|
||||
|
||||
**Error**: `ERROR: Missing doc comment for function`
|
||||
|
||||
**Solution**: Add proper docblocks:
|
||||
|
||||
```php
|
||||
/**
|
||||
* Get the plugin version.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @return string The plugin version.
|
||||
*/
|
||||
function get_plugin_version() { ... }
|
||||
```
|
||||
|
||||
## Automated Error Resolution
|
||||
|
||||
### Error Resolution Workflow
|
||||
|
||||
1. **Identify Error**: Use GitHub API or local test output to identify errors
|
||||
2. **Categorize Error**: Determine error type and severity
|
||||
3. **Search for Solution**: Look for patterns in known solutions
|
||||
4. **Apply Fix**: Make necessary code changes
|
||||
5. **Verify Fix**: Run tests again to confirm the issue is resolved
|
||||
6. **Document Solution**: Update documentation with the solution
|
||||
|
||||
### Processing Code Quality Feedback
|
||||
|
||||
#### Extracting Actionable Items from PR Comments
|
||||
|
||||
1. **Collect All Feedback**:
|
||||
|
||||
```text
|
||||
github-api /repos/wpallstars/wp-plugin-starter-template-for-ai-coding/pulls/{number}/comments
|
||||
github-api /repos/wpallstars/wp-plugin-starter-template-for-ai-coding/pulls/{number}/reviews
|
||||
```
|
||||
|
||||
2. **Categorize Issues**:
|
||||
* Critical: Security vulnerabilities, breaking bugs
|
||||
* High: Code quality violations, potential bugs
|
||||
* Medium: Style issues, best practices
|
||||
* Low: Documentation, minor improvements
|
||||
|
||||
3. **Prioritize Fixes**:
|
||||
* Address critical issues first
|
||||
* Group related issues for efficient fixing
|
||||
* Consider dependencies between issues
|
||||
|
||||
4. **Create Fix Plan**:
|
||||
* Document files that need changes
|
||||
* Outline specific changes needed
|
||||
* Note any potential side effects
|
||||
|
||||
#### Responding to Code Quality Tool Comments
|
||||
|
||||
1. **Acknowledge Feedback**: React to or reply to comments
|
||||
2. **Implement Fixes**: Make the necessary code changes
|
||||
3. **Explain Changes** (if needed): Add comments explaining decisions
|
||||
4. **Request Review** (if needed): Ask for re-review after fixes
|
||||
|
||||
## Feedback Loop Architecture
|
||||
|
||||
### Complete Feedback Loop System
|
||||
|
||||
```text
|
||||
Code Changes ──► Local Testing ──► GitHub Actions
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
AI Assistant ◀── Error Analysis ◀── Status Check
|
||||
│
|
||||
▼
|
||||
Fix Generation ──► Human Review (only when necessary)
|
||||
```
|
||||
|
||||
### Key Components
|
||||
|
||||
1. **Code Changes**: Initial code modifications
|
||||
2. **Local Testing**: Immediate feedback on local environment
|
||||
3. **GitHub Actions**: Remote CI/CD pipeline validation
|
||||
4. **Status Check**: Monitoring workflow status via GitHub API
|
||||
5. **Error Analysis**: Parsing and categorizing errors
|
||||
6. **AI Assistant**: Central intelligence for error resolution
|
||||
7. **Fix Generation**: Creating and implementing solutions
|
||||
8. **Human Review**: Optional step for complex decisions
|
||||
|
||||
## Handling Direct Feedback from Code Review Tools
|
||||
|
||||
### Accessing and Processing CodeRabbit Feedback
|
||||
|
||||
CodeRabbit provides detailed AI-powered code reviews.
|
||||
|
||||
These can be directly accessed and processed.
|
||||
|
||||
#### Example CodeRabbit Feedback
|
||||
|
||||
```text
|
||||
coderabbitai bot left a comment
|
||||
Actionable comments posted: 1
|
||||
|
||||
🧹 Nitpick comments (3)
|
||||
.github/workflows/playground-tests-fix.yml (3)
|
||||
9-13: Add concurrency control to avoid redundant runs.
|
||||
```
|
||||
|
||||
#### Processing Steps
|
||||
|
||||
1. **Extract Specific Recommendations**:
|
||||
* Identify file paths and line numbers
|
||||
* Parse suggested code changes
|
||||
* Understand the rationale for changes
|
||||
|
||||
2. **Implement Recommendations**: Apply the suggested changes
|
||||
|
||||
3. **Verify Implementation**:
|
||||
* Run local tests if applicable
|
||||
* Commit changes with descriptive message
|
||||
* Monitor CI/CD pipeline for success
|
||||
|
||||
### Handling SonarCloud and Codacy Feedback
|
||||
|
||||
These tools provide structured feedback that can be systematically addressed.
|
||||
|
||||
#### Example SonarCloud Feedback
|
||||
|
||||
```text
|
||||
SonarCloud Quality Gate failed
|
||||
- 3 Bugs
|
||||
- 5 Code Smells
|
||||
- 1 Security Hotspot
|
||||
```
|
||||
|
||||
#### SonarCloud Processing Steps
|
||||
|
||||
1. **Access Detailed Reports**:
|
||||
* Use the SonarCloud API or web interface
|
||||
* Categorize issues by severity and type
|
||||
|
||||
2. **Address Issues Systematically**:
|
||||
* Fix bugs first
|
||||
* Address security hotspots
|
||||
* Resolve code smells
|
||||
|
||||
3. **Document Resolutions**:
|
||||
* Note patterns of issues for future prevention
|
||||
* Update coding guidelines if necessary
|
||||
|
||||
## When to Consult Humans
|
||||
|
||||
While the goal is to create an autonomous system, there are scenarios where human input is necessary.
|
||||
|
||||
### Scenarios Requiring Human Consultation
|
||||
|
||||
1. **Product Design Decisions**: Features, UX, and strategic direction
|
||||
2. **Security-Critical Changes**: Changes that could impact security posture
|
||||
3. **Architectural Decisions**: Major structural changes to the codebase
|
||||
4. **Deployment Approvals**: Final approval for production releases
|
||||
5. **Access Requirements**: When additional permissions are needed
|
||||
6. **Ambiguous Errors**: When errors have multiple possible interpretations
|
||||
7. **Novel Problems**: Issues without precedent or documented solutions
|
||||
8. **External Service Issues**: Problems with third-party services
|
||||
|
||||
### Effective Human Consultation
|
||||
|
||||
When consulting humans, provide:
|
||||
|
||||
1. **Clear Context**: Explain what you were trying to accomplish
|
||||
2. **Error Details**: Provide specific error messages and logs
|
||||
3. **Attempted Solutions**: Document what you've already tried
|
||||
4. **Specific Questions**: Ask targeted questions rather than open-ended ones
|
||||
5. **Recommendations**: Suggest possible solutions for approval
|
||||
|
||||
## Contributing to External Repositories
|
||||
|
||||
When issues are caused by bugs or missing features in external dependencies or GitHub Actions,
|
||||
AI assistants can contribute fixes upstream.
|
||||
|
||||
### Workflow for External Contributions
|
||||
|
||||
1. **Clone the Repository Locally**:
|
||||
|
||||
```bash
|
||||
cd ~/Git
|
||||
git clone https://github.com/owner/repo.git
|
||||
cd repo
|
||||
git checkout -b feature/descriptive-branch-name
|
||||
```
|
||||
|
||||
2. **Make Changes and Commit**:
|
||||
|
||||
```bash
|
||||
# Make your changes
|
||||
git add -A
|
||||
git commit -m "Descriptive commit message
|
||||
|
||||
Detailed explanation of what the change does and why.
|
||||
|
||||
Fixes #issue-number"
|
||||
```
|
||||
|
||||
3. **Fork and Push**:
|
||||
|
||||
```bash
|
||||
# Create a fork (if not already forked)
|
||||
gh repo fork owner/repo --clone=false --remote=true
|
||||
|
||||
# Add fork as remote
|
||||
git remote add fork https://github.com/your-username/repo.git
|
||||
|
||||
# Push to fork
|
||||
git push fork feature/descriptive-branch-name
|
||||
```
|
||||
|
||||
4. **Create Pull Request**:
|
||||
|
||||
```bash
|
||||
gh pr create \
|
||||
--repo owner/repo \
|
||||
--head your-username:feature/descriptive-branch-name \
|
||||
--title "Clear, descriptive title" \
|
||||
--body "## Summary
|
||||
|
||||
Description of changes...
|
||||
|
||||
Fixes #issue-number"
|
||||
```
|
||||
|
||||
### Best Practices for External Contributions
|
||||
|
||||
* Always clone to `~/Git/` for consistency
|
||||
* Check existing issues and PRs before starting work
|
||||
* Follow the project's contribution guidelines
|
||||
* Keep changes focused and minimal
|
||||
* Include tests if the project has a test suite
|
||||
* Reference the issue number in commits and PR description
|
||||
|
||||
### Local Repository Management
|
||||
|
||||
Keep cloned repositories in `~/Git/` organized:
|
||||
|
||||
* `~/Git/wp-plugin-starter-template-for-ai-coding/` - Main project
|
||||
* `~/Git/wp-performance-action/` - Forked for contributions
|
||||
* Other cloned repos as needed
|
||||
|
||||
## Conclusion
|
||||
|
||||
This error checking and feedback loop system creates a comprehensive framework for AI-driven development.
|
||||
|
||||
By systematically monitoring, analyzing, and resolving errors, the AI assistant can maintain high code quality.
|
||||
|
||||
For related workflows, refer to the other documents in the `.agents/` directory.
|
||||
@@ -16,7 +16,7 @@ git checkout -b feature/descriptive-name
|
||||
|
||||
Use a descriptive name that clearly indicates what the feature is about. If there's an issue number, include it in the branch name (e.g., `feature/123-update-source-selector`).
|
||||
|
||||
For more detailed git workflow guidelines, see **@.ai-workflows/git-workflow.md**.
|
||||
For more detailed git workflow guidelines, see **@.agents/git-workflow.md**.
|
||||
|
||||
### 2. Implement the Feature
|
||||
|
||||
@@ -44,7 +44,7 @@ Update relevant documentation to reflect the new feature:
|
||||
- Add screenshots or examples if applicable
|
||||
- Remember that any feature addition will require a version increment in all relevant files
|
||||
|
||||
For detailed guidelines on maintaining wiki documentation, see **@.ai-workflows/wiki-documentation.md**.
|
||||
For detailed guidelines on maintaining wiki documentation, see **@.agents/wiki-documentation.md**.
|
||||
|
||||
### 4. Testing
|
||||
|
||||
@@ -100,7 +100,7 @@ git tag -a v{MAJOR}.{MINOR+1}.0-stable -m "Stable version {MAJOR}.{MINOR+1}.0"
|
||||
|
||||
**IMPORTANT**: Don't update version numbers during initial development and testing. Only create a version branch and update version numbers when the feature is confirmed working.
|
||||
|
||||
For detailed guidelines on time-efficient development and testing, see **@.ai-workflows/incremental-development.md**.
|
||||
For detailed guidelines on time-efficient development and testing, see **@.agents/incremental-development.md**.
|
||||
|
||||
### 7. Push to Remote (Optional for Collaboration)
|
||||
|
||||
@@ -173,7 +173,7 @@ When developing features in a workspace with multiple repositories:
|
||||
- Adapt the feature to fit the current repository's needs and architecture
|
||||
- Document the inspiration source in code comments
|
||||
|
||||
For detailed guidelines on working in multi-repository workspaces, see **@.ai-workflows/multi-repo-workspace.md**.
|
||||
For detailed guidelines on working in multi-repository workspaces, see **@.agents/multi-repo-workspace.md**.
|
||||
|
||||
## Feature Types and Implementation Guidelines
|
||||
|
||||
@@ -8,7 +8,7 @@ This document outlines the folder structure of the plugin and explains the purpo
|
||||
- **includes/** - Contains core plugin functionality and classes
|
||||
- **languages/** - Contains translation files
|
||||
- **scripts/** - Contains build and deployment scripts
|
||||
- **.ai-workflows/** - Contains documentation for AI assistants
|
||||
- **.agents/** - Contains documentation for AI assistants
|
||||
- **.github/** - Contains GitHub-specific files like workflows
|
||||
- **.wordpress-org/** - Contains WordPress.org assets like banners and screenshots
|
||||
|
||||
@@ -186,7 +186,7 @@ When preparing for a release:
|
||||
- Update version numbers
|
||||
- Update changelogs
|
||||
- Create tag
|
||||
- See **@.ai-workflows/release-process.md** for complete details
|
||||
- See **@.agents/release-process.md** for complete details
|
||||
|
||||
## Contributing to External Repositories
|
||||
|
||||
@@ -233,7 +233,7 @@ Monitor the PR for feedback from maintainers and be prepared to make additional
|
||||
- Review code thoroughly before approving
|
||||
- Test changes locally when possible
|
||||
- Provide constructive feedback
|
||||
- See **@.ai-workflows/code-review.md** for detailed code review guidelines
|
||||
- See **@.agents/code-review.md** for detailed code review guidelines
|
||||
|
||||
### Suggested Improvements
|
||||
|
||||
@@ -39,6 +39,7 @@ This document provides guidance for AI assistants to help with incremental devel
|
||||
### Marking Stable Versions
|
||||
|
||||
When the user confirms that changes are working correctly:
|
||||
|
||||
1. Create a version branch and update version numbers
|
||||
2. Tag the version branch as stable
|
||||
```bash
|
||||
@@ -62,6 +63,7 @@ git checkout -b fix/plugin-activation-error
|
||||
### 2. Make Changes Without Updating Version Numbers
|
||||
|
||||
During the development and testing phase:
|
||||
|
||||
- Implement the necessary changes
|
||||
- **Don't update version numbers** in any files yet
|
||||
- Focus on the functionality
|
||||
@@ -79,6 +81,7 @@ CURRENT_VERSION=$(grep -o "Version: [0-9.]*" wp-fix-plugin-does-not-exist-notice
|
||||
```
|
||||
|
||||
This will:
|
||||
|
||||
1. Create a build directory
|
||||
2. Copy required files to the build directory
|
||||
3. Deploy the plugin to your local WordPress testing environment
|
||||
@@ -88,6 +91,7 @@ This will:
|
||||
### 4. Test and Evaluate
|
||||
|
||||
Test the changes thoroughly in the local environment:
|
||||
|
||||
- Verify that the specific issue is fixed or feature works as expected
|
||||
- Check for any regressions or new issues
|
||||
- Document the results
|
||||
@@ -3,17 +3,20 @@
|
||||
This file contains important paths and URLs for local development.
|
||||
|
||||
## Repository Paths
|
||||
|
||||
- Local development repository: ~/Git/wp-fix-plugin-does-not-exist-notices
|
||||
- LocalWP plugin testing site storage: ~/Local/plugin-testing/app/wp-fix-plugin-does-not-exist-notices
|
||||
- LocalWP plugin testing site configuration: ~/Local/plugin-testing/conf/
|
||||
|
||||
## URLs
|
||||
- LocalWP plugin testing URL: http://plugin-testing.local/
|
||||
- PHP details: http://plugin-testing.local/local-phpinfo.php
|
||||
- XDebug info: http://plugin-testing.local/local-xdebuginfo.php
|
||||
- Adminer Evo: http://localhost:10010/?username=root&db=local
|
||||
- Mailpit: http://localhost:10000/
|
||||
|
||||
- LocalWP plugin testing URL: <http://plugin-testing.local/>
|
||||
- PHP details: <http://plugin-testing.local/local-phpinfo.php>
|
||||
- XDebug info: <http://plugin-testing.local/local-xdebuginfo.php>
|
||||
- Adminer Evo: <http://localhost:10010/?username=root&db=local>
|
||||
- Mailpit: <http://localhost:10000/>
|
||||
|
||||
## Build and Deploy Scripts
|
||||
|
||||
- Build script: ~/Git/wp-fix-plugin-does-not-exist-notices/build.sh
|
||||
- Local deploy script: ~/Git/wp-fix-plugin-does-not-exist-notices/deploy-local.sh
|
||||
331
.agents/local-testing-guide.md
Normal file
331
.agents/local-testing-guide.md
Normal file
@@ -0,0 +1,331 @@
|
||||
# Local Testing Guide for AI Assistants
|
||||
|
||||
This guide provides instructions for AI coding assistants to set up and run local
|
||||
WordPress testing environments for this plugin.
|
||||
|
||||
## Overview
|
||||
|
||||
Three testing approaches are available:
|
||||
|
||||
1. **WordPress Playground CLI** - Quick browser-based testing (recommended for AI)
|
||||
2. **LocalWP** - Full local WordPress environment
|
||||
3. **wp-env** - Docker-based WordPress environment
|
||||
|
||||
Each approach has trade-offs. Choose based on the testing needs.
|
||||
|
||||
## Quick Reference
|
||||
|
||||
```bash
|
||||
# Playground CLI (fastest for AI testing)
|
||||
npm run playground:start # Start single site
|
||||
npm run playground:start:multisite # Start multisite
|
||||
npm run playground:stop # Stop server
|
||||
npm run playground:status # Check status
|
||||
|
||||
# LocalWP (full environment)
|
||||
npm run localwp:create # Create single site
|
||||
npm run localwp:create:multisite # Create multisite
|
||||
npm run localwp:sync # Sync plugin changes
|
||||
npm run localwp:reset # Reset to clean state
|
||||
|
||||
# wp-env (Docker-based)
|
||||
npm run start # Start wp-env
|
||||
npm run stop # Stop wp-env
|
||||
```
|
||||
|
||||
## WordPress Playground CLI
|
||||
|
||||
Uses `@wp-playground/cli` version 3.0.22+ for instant WordPress testing.
|
||||
|
||||
### When to Use
|
||||
|
||||
* Quick plugin functionality testing
|
||||
* Verifying admin UI changes
|
||||
* Testing single site vs multisite behavior
|
||||
* CI/CD pipeline testing (note: may be flaky in GitHub Actions)
|
||||
|
||||
### Starting Playground
|
||||
|
||||
```bash
|
||||
# Single site on port 8888
|
||||
npm run playground:start
|
||||
|
||||
# Multisite on port 8889
|
||||
npm run playground:start:multisite
|
||||
```
|
||||
|
||||
### Accessing the Site
|
||||
|
||||
After starting, the script provides access details:
|
||||
|
||||
* **Single Site**: http://localhost:8888
|
||||
* **Multisite**: http://localhost:8889
|
||||
* **Admin Login**: admin / password
|
||||
|
||||
### Blueprint Configuration
|
||||
|
||||
Blueprints define the WordPress setup. Located in `playground/`:
|
||||
|
||||
* `blueprint.json` - Single site configuration
|
||||
* `multisite-blueprint.json` - Multisite configuration
|
||||
|
||||
Blueprints install:
|
||||
* Plugin Toggle (debugging helper)
|
||||
* Kadence Blocks (testing with block plugins)
|
||||
|
||||
### Stopping Playground
|
||||
|
||||
```bash
|
||||
npm run playground:stop
|
||||
```
|
||||
|
||||
### Status Check
|
||||
|
||||
```bash
|
||||
npm run playground:status
|
||||
```
|
||||
|
||||
Shows running processes and port usage.
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
If Playground fails to start:
|
||||
|
||||
1. Check if ports 8888/8889 are in use: `lsof -i :8888`
|
||||
2. Check logs: `cat .playground.log`
|
||||
3. Stop any orphaned processes: `npm run playground:stop`
|
||||
4. Ensure npm dependencies are installed: `npm install`
|
||||
|
||||
## LocalWP Integration
|
||||
|
||||
LocalWP provides a full WordPress environment with database persistence.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* LocalWP installed at `/Applications/Local.app` (macOS)
|
||||
* Local Sites directory at `~/Local Sites/`
|
||||
|
||||
### When to Use
|
||||
|
||||
* Testing database migrations
|
||||
* Long-term development environment
|
||||
* Testing with specific PHP/MySQL versions
|
||||
* Network/multisite configuration testing
|
||||
* Testing WP-CLI commands
|
||||
|
||||
### Creating Sites
|
||||
|
||||
LocalWP requires manual site creation through the GUI.
|
||||
|
||||
```bash
|
||||
npm run localwp:create
|
||||
```
|
||||
|
||||
This guides you through:
|
||||
|
||||
1. Opening LocalWP
|
||||
2. Creating a site with standardized name
|
||||
3. Syncing plugin files
|
||||
|
||||
### URL Patterns
|
||||
|
||||
Sites use consistent naming:
|
||||
|
||||
* **Single Site**: `wp-plugin-starter-template-single.local`
|
||||
* **Multisite**: `wp-plugin-starter-template-multisite.local`
|
||||
|
||||
### Syncing Plugin Files
|
||||
|
||||
After making code changes:
|
||||
|
||||
```bash
|
||||
npm run localwp:sync
|
||||
```
|
||||
|
||||
This uses rsync to copy plugin files, excluding:
|
||||
* node_modules
|
||||
* vendor
|
||||
* tests
|
||||
* .git
|
||||
* dist
|
||||
|
||||
### Resetting
|
||||
|
||||
To reset the plugin to a clean state:
|
||||
|
||||
```bash
|
||||
npm run localwp:reset
|
||||
```
|
||||
|
||||
### Site Information
|
||||
|
||||
View all LocalWP sites:
|
||||
|
||||
```bash
|
||||
./bin/localwp-setup.sh info
|
||||
```
|
||||
|
||||
## wp-env (Docker)
|
||||
|
||||
Docker-based environment using `@wordpress/env`.
|
||||
|
||||
### When to Use
|
||||
|
||||
* Consistent environment across machines
|
||||
* PHPUnit testing
|
||||
* WP-CLI operations
|
||||
* CI/CD testing
|
||||
|
||||
### Starting
|
||||
|
||||
```bash
|
||||
npm run start # or: wp-env start
|
||||
```
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
npm run test:phpunit # Single site tests
|
||||
npm run test:phpunit:multisite # Multisite tests
|
||||
```
|
||||
|
||||
### Running WP-CLI Commands
|
||||
|
||||
```bash
|
||||
wp-env run cli wp plugin list
|
||||
wp-env run cli wp option get siteurl
|
||||
```
|
||||
|
||||
## Testing Workflows for AI Assistants
|
||||
|
||||
### Verifying a Code Change
|
||||
|
||||
1. Make the code change
|
||||
2. Start Playground: `npm run playground:start`
|
||||
3. Navigate to relevant admin page
|
||||
4. Verify expected behavior
|
||||
5. Stop Playground: `npm run playground:stop`
|
||||
|
||||
### Testing Multisite Functionality
|
||||
|
||||
1. Start multisite: `npm run playground:start:multisite`
|
||||
2. Navigate to Network Admin
|
||||
3. Test network-wide functionality
|
||||
4. Test per-site functionality
|
||||
5. Stop: `npm run playground:stop`
|
||||
|
||||
### Running PHPUnit Tests
|
||||
|
||||
```bash
|
||||
# Single site
|
||||
composer test
|
||||
|
||||
# Multisite
|
||||
WP_MULTISITE=1 composer test
|
||||
|
||||
# Specific test file
|
||||
vendor/bin/phpunit tests/phpunit/test-core.php
|
||||
```
|
||||
|
||||
### Running Cypress E2E Tests
|
||||
|
||||
```bash
|
||||
# With Playground (headless)
|
||||
npm run test:playground:single
|
||||
npm run test:playground:multisite
|
||||
|
||||
# With wp-env (headless)
|
||||
npm run test:e2e:single
|
||||
npm run test:e2e:multisite
|
||||
```
|
||||
|
||||
## Environment Comparison
|
||||
|
||||
| Feature | Playground CLI | LocalWP | wp-env |
|
||||
|---------|---------------|---------|--------|
|
||||
| Setup Time | Instant | 5-10 min | 2-5 min |
|
||||
| Persistence | None | Full | Partial |
|
||||
| PHP Versions | Limited | Many | Limited |
|
||||
| Database | In-memory | MySQL | MySQL |
|
||||
| WP-CLI | Yes | Yes | Yes |
|
||||
| Multisite | Yes | Yes | Yes |
|
||||
| GitHub Actions | Flaky | N/A | Works |
|
||||
| Best For | Quick testing | Full dev | CI/Testing |
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Port Already in Use
|
||||
|
||||
```bash
|
||||
# Check what's using the port
|
||||
lsof -i :8888
|
||||
|
||||
# Kill the process if needed
|
||||
kill $(lsof -t -i :8888)
|
||||
```
|
||||
|
||||
### Playground Won't Start
|
||||
|
||||
1. Ensure dependencies installed: `npm install`
|
||||
2. Check Node.js version: `node --version` (requires 18+)
|
||||
3. Check logs: `cat .playground.log`
|
||||
|
||||
### LocalWP Site Not Found
|
||||
|
||||
The script expects sites at:
|
||||
* `~/Local Sites/wp-plugin-starter-template-single/`
|
||||
* `~/Local Sites/wp-plugin-starter-template-multisite/`
|
||||
|
||||
Verify the site name matches exactly.
|
||||
|
||||
### wp-env Docker Issues
|
||||
|
||||
```bash
|
||||
# Restart Docker
|
||||
wp-env stop
|
||||
docker system prune -f
|
||||
wp-env start
|
||||
```
|
||||
|
||||
## Blueprint Reference
|
||||
|
||||
Blueprints use JSON format. Key steps:
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
|
||||
"landingPage": "/wp-admin/",
|
||||
"login": true,
|
||||
"features": {
|
||||
"networking": true,
|
||||
"phpVersion": "7.4"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"step": "defineWpConfigConsts",
|
||||
"consts": {
|
||||
"WP_DEBUG": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"step": "wp-cli",
|
||||
"command": "wp plugin install plugin-toggle --activate"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
For multisite, add:
|
||||
|
||||
```json
|
||||
{
|
||||
"step": "enableMultisite"
|
||||
}
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
* [WordPress Playground CLI](https://wordpress.github.io/wordpress-playground/)
|
||||
* [WordPress Playground Blueprints](https://wordpress.github.io/wordpress-playground/blueprints)
|
||||
* [LocalWP Documentation](https://localwp.com/help-docs/)
|
||||
* [@wordpress/env Documentation](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-env/)
|
||||
@@ -36,6 +36,7 @@ Suggesting changes or improvements based on other repositories, leading to scope
|
||||
### 1. Repository Verification
|
||||
|
||||
**ALWAYS** verify which repository you're currently working in before:
|
||||
|
||||
- Making code suggestions
|
||||
- Creating or updating documentation
|
||||
- Discussing features or functionality
|
||||
@@ -44,6 +45,7 @@ Suggesting changes or improvements based on other repositories, leading to scope
|
||||
### 2. Explicit Code Search Scoping
|
||||
|
||||
When searching for code or functionality:
|
||||
|
||||
- Explicitly limit searches to the current repository
|
||||
- Use repository-specific paths in search queries
|
||||
- Verify search results are from the current repository before using them
|
||||
@@ -6,11 +6,12 @@ This document outlines the process for preparing and publishing new releases of
|
||||
|
||||
1. Create a version branch
|
||||
2. Update version numbers in all required files
|
||||
3. Build and test the plugin
|
||||
4. Commit version changes
|
||||
5. Create version tags
|
||||
6. Push to remote repositories
|
||||
7. Merge into main branch
|
||||
3. Run code quality checks
|
||||
4. Build and test the plugin
|
||||
5. Commit version changes
|
||||
6. Create version tags
|
||||
7. Push to remote repositories
|
||||
8. Merge into main branch
|
||||
|
||||
## Detailed Steps
|
||||
|
||||
@@ -48,7 +49,30 @@ Update version numbers in all required files:
|
||||
5. **languages/wp-plugin-starter-template.pot**:
|
||||
- Update the `Project-Id-Version` header
|
||||
|
||||
### 3. Build and Test the Plugin
|
||||
### 3. Run Code Quality Checks
|
||||
|
||||
Before building the plugin, run code quality checks to ensure the code meets standards:
|
||||
|
||||
```bash
|
||||
# Run unit tests
|
||||
composer test
|
||||
|
||||
# Run PHP CodeSniffer
|
||||
composer phpcs
|
||||
|
||||
# Run PHP Code Beautifier and Fixer if needed
|
||||
composer phpcbf
|
||||
|
||||
# Run PHPStan
|
||||
composer phpstan
|
||||
|
||||
# Run PHP Mess Detector
|
||||
composer phpmd
|
||||
```
|
||||
|
||||
Fix any issues found by these tools before proceeding. See the [Code Quality Checks Workflow](./code-quality-checks.md) for more details.
|
||||
|
||||
### 4. Build and Test the Plugin
|
||||
|
||||
Build the plugin with the new version:
|
||||
|
||||
@@ -57,17 +81,19 @@ Build the plugin with the new version:
|
||||
```
|
||||
|
||||
This will:
|
||||
|
||||
- Create a clean build in the `build/` directory
|
||||
- Generate a ZIP file for distribution
|
||||
- Deploy to a local WordPress installation if configured
|
||||
|
||||
Test the plugin thoroughly:
|
||||
|
||||
- Test with the latest WordPress version
|
||||
- Test with the minimum supported WordPress version (5.0)
|
||||
- Test with PHP 7.0+ (minimum supported version)
|
||||
- Test all features and functionality
|
||||
|
||||
### 4. Commit Version Changes
|
||||
### 5. Commit Version Changes
|
||||
|
||||
Commit all version changes:
|
||||
|
||||
@@ -76,7 +102,7 @@ git add wp-plugin-starter-template.php readme.txt README.md CHANGELOG.md languag
|
||||
git commit -m "Version {MAJOR}.{MINOR}.{PATCH} - [brief description]"
|
||||
```
|
||||
|
||||
### 5. Create Version Tags
|
||||
### 6. Create Version Tags
|
||||
|
||||
Create version tags:
|
||||
|
||||
@@ -87,23 +113,39 @@ git tag -a v{MAJOR}.{MINOR}.{PATCH}-stable -m "Stable version {MAJOR}.{MINOR}.{P
|
||||
|
||||
The `-stable` tag is used by Git Updater to identify the stable version.
|
||||
|
||||
### 6. Push to Remote Repositories
|
||||
### 7. Push to Remote Repositories
|
||||
|
||||
Push the version branch and tags to remote repositories:
|
||||
|
||||
```bash
|
||||
# List remote tags (replace 'github' and 'gitea' if your remotes have different names)
|
||||
git ls-remote --tags github
|
||||
git ls-remote --tags gitea
|
||||
```
|
||||
|
||||
If the tags (e.g., `v{MAJOR}.{MINOR}.{PATCH}` and `v{MAJOR}.{MINOR}.{PATCH}-stable`) already exist remotely but point to the wrong commit, delete them from the remote first:
|
||||
|
||||
```bash
|
||||
# Delete incorrect remote tags (replace 'github', 'gitea', and tag names)
|
||||
git push github --delete v{MAJOR}.{MINOR}.{PATCH}
|
||||
git push github --delete v{MAJOR}.{MINOR}.{PATCH}-stable
|
||||
git push gitea --delete v{MAJOR}.{MINOR}.{PATCH}
|
||||
git push gitea --delete v{MAJOR}.{MINOR}.{PATCH}-stable
|
||||
```
|
||||
|
||||
Once you've confirmed the tags don't exist remotely or have deleted incorrect ones, push the new local tags:
|
||||
|
||||
```bash
|
||||
# Push to GitHub
|
||||
git push github refs/heads/v{MAJOR}.{MINOR}.{PATCH}:refs/heads/v{MAJOR}.{MINOR}.{PATCH}
|
||||
git push github refs/tags/v{MAJOR}.{MINOR}.{PATCH}:refs/tags/v{MAJOR}.{MINOR}.{PATCH}
|
||||
git push github refs/tags/v{MAJOR}.{MINOR}.{PATCH}-stable:refs/tags/v{MAJOR}.{MINOR}.{PATCH}-stable
|
||||
git push github --tags
|
||||
|
||||
# Push to Gitea
|
||||
git push gitea refs/heads/v{MAJOR}.{MINOR}.{PATCH}:refs/heads/v{MAJOR}.{MINOR}.{PATCH}
|
||||
git push gitea refs/tags/v{MAJOR}.{MINOR}.{PATCH}:refs/tags/v{MAJOR}.{MINOR}.{PATCH}
|
||||
git push gitea refs/tags/v{MAJOR}.{MINOR}.{PATCH}-stable:refs/tags/v{MAJOR}.{MINOR}.{PATCH}-stable
|
||||
git push gitea --tags
|
||||
```
|
||||
|
||||
### 7. Merge into Main Branch
|
||||
### 8. Merge into Main Branch
|
||||
|
||||
Merge the version branch into the main branch:
|
||||
|
||||
@@ -123,6 +165,7 @@ Follow semantic versioning (MAJOR.MINOR.PATCH):
|
||||
- **PATCH**: Backward-compatible bug fixes
|
||||
|
||||
Examples:
|
||||
|
||||
- Bug fix: 1.0.0 → 1.0.1
|
||||
- New feature: 1.0.0 → 1.1.0
|
||||
- Breaking change: 1.0.0 → 2.0.0
|
||||
@@ -150,7 +193,15 @@ If the plugin is hosted on WordPress.org:
|
||||
|
||||
After releasing a new version:
|
||||
|
||||
1. Update the wiki documentation if needed
|
||||
2. Announce the release in relevant channels
|
||||
3. Monitor for any issues or feedback
|
||||
4. Start planning the next release
|
||||
1. Update the wiki documentation:
|
||||
- Update the Changelog.md file in the .wiki directory to match the main CHANGELOG.md
|
||||
- Add the new version information to the Home.md file in the Latest Updates section
|
||||
- Ensure all wiki pages are up-to-date with the new features or changes
|
||||
- Verify that the _Sidebar.md file has the correct navigation structure
|
||||
2. Verify that GitHub Actions workflows are running correctly:
|
||||
- Check that the release workflow created the release with the correct assets
|
||||
- Check that the sync-wiki workflow synced the wiki changes
|
||||
- Fix any permissions issues in the workflow files if needed
|
||||
3. Announce the release in relevant channels
|
||||
4. Monitor for any issues or feedback
|
||||
5. Start planning the next release
|
||||
@@ -8,6 +8,7 @@ The wiki documentation is organized into the following sections:
|
||||
|
||||
1. **User Documentation**:
|
||||
- Home
|
||||
- Starter Prompt (must be listed before Installation Guide)
|
||||
- Installation Guide
|
||||
- Usage Instructions
|
||||
- Frequently Asked Questions
|
||||
@@ -88,8 +89,10 @@ Documentation should be updated:
|
||||
|
||||
1. Identify the relevant wiki file(s) in the `.wiki/` directory
|
||||
2. Make the necessary changes
|
||||
3. Commit and push the changes to the `main` branch
|
||||
4. The GitHub Actions workflow will automatically sync the changes with the GitHub wiki
|
||||
3. **Always ensure the Changelog.md in the wiki is updated to match the main CHANGELOG.md file**
|
||||
4. **Always ensure the _Sidebar.md file has the correct navigation structure with Starter Prompt listed before Installation Guide**
|
||||
5. Commit and push the changes to the `main` branch
|
||||
6. The GitHub Actions workflow will automatically sync the changes with the GitHub wiki
|
||||
|
||||
### Creating New Pages
|
||||
|
||||
@@ -124,7 +127,7 @@ When working in a multi-repository workspace, it's critical to ensure that wiki
|
||||
- If referencing functionality from another repository, clearly indicate that it's external
|
||||
- Use phrases like "unlike Repository X, this plugin does not include..."
|
||||
|
||||
For detailed guidelines on working in multi-repository workspaces, see **@.ai-workflows/multi-repo-workspace.md**.
|
||||
For detailed guidelines on working in multi-repository workspaces, see **@.agents/multi-repo-workspace.md**.
|
||||
|
||||
## Best Practices
|
||||
|
||||
121
.ai-assistant.md
121
.ai-assistant.md
@@ -1,121 +0,0 @@
|
||||
# AI Assistant Guide for WordPress Plugin Development
|
||||
|
||||
This guide helps AI assistants understand the project structure, workflows, and best practices for this repository.
|
||||
|
||||
## IMPORTANT: Repository Context
|
||||
|
||||
This workspace may contain multiple repository folders. Always focus ONLY on the current repository you're working in and avoid hallucinating functionality from other repositories in the workspace.
|
||||
|
||||
- **Current Repository**: wp-plugin-starter-template-for-ai-coding
|
||||
- **Repository Purpose**: A comprehensive starter template for WordPress plugins with best practices for AI-assisted development
|
||||
- **Repository Scope**: All code changes, documentation, and functionality discussions should be limited to THIS repository only
|
||||
|
||||
## Project Overview
|
||||
|
||||
- **Plugin Name**: WordPress Plugin Starter Template
|
||||
- **Plugin Slug**: wp-plugin-starter-template
|
||||
- **Text Domain**: wp-plugin-starter-template
|
||||
- **Namespace**: WPALLSTARS\PluginStarterTemplate
|
||||
- **Version**: 0.1.1
|
||||
- **Requires WordPress**: 5.0+
|
||||
- **Requires PHP**: 7.0+
|
||||
- **License**: GPL-2.0+
|
||||
|
||||
## Repository Structure
|
||||
|
||||
- **wp-plugin-starter-template.php**: Main plugin file with plugin headers
|
||||
- **includes/**: Core plugin functionality
|
||||
- **plugin.php**: Main plugin class that initializes everything
|
||||
- **core.php**: Core functionality class
|
||||
- **updater.php**: Update mechanism for multiple sources
|
||||
- **admin/**: Admin-specific functionality
|
||||
- **lib/**: Admin classes
|
||||
- **css/**: Admin stylesheets
|
||||
- **js/**: Admin JavaScript files
|
||||
- **languages/**: Translation files
|
||||
- **.github/workflows/**: GitHub Actions workflows
|
||||
- **.ai-workflows/**: Documentation for AI assistants
|
||||
- **.wiki/**: Wiki documentation templates
|
||||
|
||||
## Coding Standards
|
||||
|
||||
This project follows the [WordPress Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/):
|
||||
|
||||
- Use tabs for indentation, not spaces
|
||||
- Follow WordPress naming conventions:
|
||||
- Class names: `Class_Name`
|
||||
- Function names: `function_name`
|
||||
- Variable names: `$variable_name`
|
||||
- Use proper DocBlocks for all classes, methods, and functions
|
||||
- Ensure all user-facing strings are translatable
|
||||
- Validate and sanitize all inputs
|
||||
- Escape all outputs
|
||||
|
||||
## Common Tasks
|
||||
|
||||
For detailed instructions on common tasks like creating releases, adding features, fixing bugs, and testing previous versions, see **@.ai-workflows/release-process.md**.
|
||||
|
||||
## Avoiding Cross-Repository Confusion
|
||||
|
||||
When working in a multi-repository workspace, follow these guidelines to avoid confusion:
|
||||
|
||||
1. **Verify Repository Context**: Always check which repository you're currently working in before making any changes or recommendations.
|
||||
|
||||
2. **Limit Code Search Scope**: When searching for code or functionality, explicitly limit your search to the current repository.
|
||||
|
||||
3. **Don't Assume Features**: Never assume that features present in one repository should be implemented in another. Each repository has its own specific purpose and feature set.
|
||||
|
||||
4. **Repository-Specific Documentation**: Documentation should only reflect the actual features and functionality of the current repository.
|
||||
|
||||
5. **Cross-Repository Inspiration**: If you want to implement a feature inspired by another repository, explicitly mention that it's a new feature being added, not an existing one.
|
||||
|
||||
6. **Verify Before Implementation**: Before implementing or documenting a feature, verify that it actually exists in the current repository by checking the codebase.
|
||||
|
||||
## Internationalization (i18n)
|
||||
|
||||
All user-facing strings should be translatable:
|
||||
|
||||
- Use `__()` for simple strings
|
||||
- Use `_e()` for echoed strings
|
||||
- Use `esc_html__()` for escaped strings
|
||||
- Use `esc_html_e()` for escaped and echoed strings
|
||||
- Always use the plugin's text domain: `wp-plugin-starter-template`
|
||||
|
||||
Example:
|
||||
```php
|
||||
echo esc_html__('This is a translatable string', 'wp-plugin-starter-template');
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
- Validate and sanitize all inputs
|
||||
- Escape all outputs
|
||||
- Use nonces for form submissions
|
||||
- Use capability checks for user actions
|
||||
- Follow the principle of least privilege
|
||||
|
||||
## Documentation
|
||||
|
||||
- Keep code comments up-to-date
|
||||
- Update README.md and readme.txt when adding new features
|
||||
- Update wiki documentation in the `.wiki/` directory
|
||||
- Update changelog in both CHANGELOG.md and readme.txt
|
||||
|
||||
## Git Workflow
|
||||
|
||||
- Create feature branches from `main`
|
||||
- Use descriptive branch names (e.g., `feature/add-settings-page`)
|
||||
- Make atomic commits with clear messages
|
||||
- Create pull requests for review
|
||||
- Tag releases with version numbers (e.g., `v1.0.0`)
|
||||
|
||||
## Developer Preferences
|
||||
|
||||
When working with this repository, remember these preferences:
|
||||
|
||||
1. Follow WordPress coding standards
|
||||
2. Use OOP approach with namespaced classes
|
||||
3. Keep code modular and maintainable
|
||||
3. Reference these preferences in future interactions
|
||||
|
||||
This ensures consistency across coding sessions and reduces the need for developers to repeatedly explain their preferences.
|
||||
@@ -1,163 +0,0 @@
|
||||
# Code Review Guide for AI Assistants
|
||||
|
||||
This document provides guidance for AI assistants to help with code review for the Fix Plugin Does Not Exist Notices plugin.
|
||||
|
||||
## Code Review Checklist
|
||||
|
||||
When reviewing code, check for the following:
|
||||
|
||||
### Functionality
|
||||
|
||||
- [ ] Does the code work as expected?
|
||||
- [ ] Does it handle edge cases appropriately?
|
||||
- [ ] Are there any logical errors?
|
||||
- [ ] Is error handling implemented properly?
|
||||
|
||||
### Code Quality
|
||||
|
||||
- [ ] Does the code follow WordPress coding standards?
|
||||
- [ ] Is the code well-organized and easy to understand?
|
||||
- [ ] Are there any code smells (duplicate code, overly complex functions, etc.)?
|
||||
- [ ] Are functions and variables named appropriately?
|
||||
- [ ] Are there appropriate comments and documentation?
|
||||
|
||||
### Security
|
||||
|
||||
- [ ] Is user input properly validated and sanitized?
|
||||
- [ ] Is output properly escaped?
|
||||
- [ ] Are capability checks used for user actions?
|
||||
- [ ] Are nonces used for form submissions?
|
||||
- [ ] Are there any potential SQL injection vulnerabilities?
|
||||
- [ ] Are there any potential XSS vulnerabilities?
|
||||
|
||||
### Performance
|
||||
|
||||
- [ ] Are there any performance bottlenecks?
|
||||
- [ ] Are database queries optimized?
|
||||
- [ ] Is caching used appropriately?
|
||||
- [ ] Are assets (CSS, JS) properly enqueued?
|
||||
|
||||
### Compatibility
|
||||
|
||||
- [ ] Is the code compatible with the minimum supported WordPress version (5.0)?
|
||||
- [ ] Is the code compatible with the minimum supported PHP version (7.0)?
|
||||
- [ ] Are there any browser compatibility issues?
|
||||
- [ ] Are there any conflicts with other plugins?
|
||||
|
||||
### Internationalization
|
||||
|
||||
- [ ] Are all user-facing strings translatable?
|
||||
- [ ] Is the correct text domain used?
|
||||
- [ ] Are translation functions used correctly?
|
||||
|
||||
### Accessibility
|
||||
|
||||
- [ ] Does the code follow accessibility best practices?
|
||||
- [ ] Are ARIA attributes used appropriately?
|
||||
- [ ] Is keyboard navigation supported?
|
||||
- [ ] Is screen reader support implemented?
|
||||
|
||||
## Code Review Process
|
||||
|
||||
### 1. Understand the Context
|
||||
|
||||
Before reviewing code, understand:
|
||||
- What problem is the code trying to solve?
|
||||
- What are the requirements?
|
||||
- What are the constraints?
|
||||
|
||||
### 2. Review the Code
|
||||
|
||||
Review the code with the checklist above in mind.
|
||||
|
||||
### 3. Provide Feedback
|
||||
|
||||
When providing feedback:
|
||||
- Be specific and clear
|
||||
- Explain why a change is needed
|
||||
- Provide examples or suggestions when possible
|
||||
- Prioritize feedback (critical issues vs. minor improvements)
|
||||
- Be constructive and respectful
|
||||
|
||||
### 4. Follow Up
|
||||
|
||||
After the code has been updated:
|
||||
- Review the changes
|
||||
- Verify that issues have been addressed
|
||||
- Provide additional feedback if necessary
|
||||
|
||||
## Common Issues to Look For
|
||||
|
||||
### PHP Issues
|
||||
|
||||
- Undefined variables or functions
|
||||
- Incorrect function parameters
|
||||
- Missing return statements
|
||||
- Improper error handling
|
||||
- Inefficient loops or conditionals
|
||||
- Hardcoded values that should be configurable
|
||||
|
||||
### WordPress-Specific Issues
|
||||
|
||||
- Incorrect hook usage
|
||||
- Missing or incorrect nonces
|
||||
- Missing capability checks
|
||||
- Direct database queries instead of using WordPress functions
|
||||
- Improper enqueuing of scripts and styles
|
||||
- Not using WordPress functions for common tasks
|
||||
|
||||
### JavaScript Issues
|
||||
|
||||
- Undefined variables or functions
|
||||
- Event listener memory leaks
|
||||
- jQuery conflicts
|
||||
- Browser compatibility issues
|
||||
- Missing error handling
|
||||
|
||||
### CSS Issues
|
||||
|
||||
- Browser compatibility issues
|
||||
- Specificity issues
|
||||
- Unused styles
|
||||
- Overriding WordPress admin styles inappropriately
|
||||
|
||||
## Example Feedback
|
||||
|
||||
### Good Feedback Example
|
||||
|
||||
```
|
||||
In function `handle_remove_reference()`:
|
||||
|
||||
1. The nonce check is missing, which could lead to CSRF vulnerabilities.
|
||||
Consider adding:
|
||||
```php
|
||||
if (!isset($_GET['_wpnonce']) || !wp_verify_nonce($_GET['_wpnonce'], 'fpden_remove_reference')) {
|
||||
wp_die(__('Security check failed.', 'fix-plugin-does-not-exist-notices'));
|
||||
}
|
||||
```
|
||||
|
||||
2. The user capability check should be more specific. Instead of:
|
||||
```php
|
||||
if (!current_user_can('manage_options')) {
|
||||
```
|
||||
Consider using:
|
||||
```php
|
||||
if (!current_user_can('activate_plugins')) {
|
||||
```
|
||||
This is more appropriate for the action being performed.
|
||||
|
||||
3. The success message should be translatable:
|
||||
```php
|
||||
// Change this:
|
||||
add_settings_error('fpden', 'fpden_removed', 'Plugin reference removed successfully.', 'updated');
|
||||
|
||||
// To this:
|
||||
add_settings_error('fpden', 'fpden_removed', __('Plugin reference removed successfully.', 'fix-plugin-does-not-exist-notices'), 'updated');
|
||||
```
|
||||
```
|
||||
|
||||
### Poor Feedback Example
|
||||
|
||||
```
|
||||
This code has security issues and doesn't follow best practices. Fix it.
|
||||
```
|
||||
61
.codacy.yml
Normal file
61
.codacy.yml
Normal file
@@ -0,0 +1,61 @@
|
||||
---
|
||||
engines:
|
||||
markdownlint:
|
||||
enabled: true
|
||||
config_file: .markdownlint.json
|
||||
phpmd:
|
||||
enabled: true
|
||||
phpcs:
|
||||
enabled: true
|
||||
stylelint:
|
||||
enabled: false
|
||||
shellcheck:
|
||||
enabled: false
|
||||
# Disable tools that are causing issues
|
||||
eslint:
|
||||
enabled: false
|
||||
eslint-8:
|
||||
enabled: false
|
||||
eslint-9:
|
||||
enabled: false
|
||||
trivy:
|
||||
enabled: false
|
||||
semgrep:
|
||||
enabled: false
|
||||
checkov:
|
||||
enabled: false
|
||||
pmd:
|
||||
enabled: false
|
||||
pmd-7:
|
||||
enabled: false
|
||||
lizard:
|
||||
enabled: false
|
||||
jshint:
|
||||
enabled: false
|
||||
csslint:
|
||||
enabled: false
|
||||
jacksonlinter:
|
||||
enabled: false
|
||||
spectral:
|
||||
enabled: false
|
||||
|
||||
duplication:
|
||||
enabled: true
|
||||
exclude_patterns:
|
||||
- "tests/**"
|
||||
- "vendor/**"
|
||||
- "node_modules/**"
|
||||
|
||||
metrics:
|
||||
enabled: true
|
||||
|
||||
exclude_paths:
|
||||
- "vendor/**"
|
||||
- "node_modules/**"
|
||||
- "build/**"
|
||||
- "dist/**"
|
||||
- "bin/**"
|
||||
- ".github/**"
|
||||
- "tests/**"
|
||||
- "*.lock"
|
||||
- "*.json"
|
||||
50
.eslintrc.js
Normal file
50
.eslintrc.js
Normal file
@@ -0,0 +1,50 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es2021: true,
|
||||
node: true
|
||||
},
|
||||
extends: [
|
||||
'eslint:recommended'
|
||||
],
|
||||
plugins: [
|
||||
'cypress'
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module'
|
||||
},
|
||||
rules: {
|
||||
'comma-dangle': ['error', 'always-multiline'],
|
||||
'no-console': 'warn',
|
||||
'no-unused-vars': 'warn'
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
// cypress.config.js uses CommonJS (require/module.exports).
|
||||
// Override sourceType to 'script' so ESLint does not flag require as undefined.
|
||||
files: ['cypress.config.js', 'cypress.config.cjs'],
|
||||
parserOptions: {
|
||||
sourceType: 'script'
|
||||
},
|
||||
env: {
|
||||
node: true
|
||||
}
|
||||
}
|
||||
],
|
||||
globals: {
|
||||
cy: 'readonly',
|
||||
Cypress: 'readonly',
|
||||
describe: 'readonly',
|
||||
it: 'readonly',
|
||||
expect: 'readonly',
|
||||
beforeEach: 'readonly',
|
||||
afterEach: 'readonly',
|
||||
before: 'readonly',
|
||||
after: 'readonly',
|
||||
jQuery: 'readonly',
|
||||
wpstData: 'readonly',
|
||||
wpstModalData: 'readonly',
|
||||
wp: 'readonly'
|
||||
}
|
||||
};
|
||||
31
.eslintrc.json
Normal file
31
.eslintrc.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"jquery": true,
|
||||
"es6": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"globals": {
|
||||
"wp": "readonly",
|
||||
"wpstData": "readonly",
|
||||
"wpstModalData": "readonly",
|
||||
"Cypress": "readonly",
|
||||
"cy": "readonly",
|
||||
"describe": "readonly",
|
||||
"it": "readonly",
|
||||
"before": "readonly",
|
||||
"beforeEach": "readonly",
|
||||
"module": "readonly"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"indent": ["error", 2],
|
||||
"linebreak-style": ["error", "unix"],
|
||||
"quotes": ["error", "single"],
|
||||
"semi": ["error", "always"]
|
||||
},
|
||||
"ignorePatterns": ["vendor/**", "node_modules/**", "build/**", "dist/**", "bin/**"]
|
||||
}
|
||||
14
.github/actions/create-plugin-zip/action.yml
vendored
Normal file
14
.github/actions/create-plugin-zip/action.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
name: 'Create Plugin Zip'
|
||||
description: 'Creates a zip file of the WordPress plugin, excluding unnecessary files'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Create plugin zip
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p dist
|
||||
echo "Creating plugin zip file..."
|
||||
zip -r dist/plugin.zip . \
|
||||
-x "node_modules/**" "dist/**" ".git/**" ".github/**" ".wiki/**" "cypress/**" "playground/**" "tests/**" "vendor/**"
|
||||
echo "Plugin zip created at dist/plugin.zip"
|
||||
ls -la dist/
|
||||
72
.github/instructions/codacy.instructions.md
vendored
Normal file
72
.github/instructions/codacy.instructions.md
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
description: Configuration for AI behavior when interacting with Codacy's MCP Server
|
||||
applyTo: '**'
|
||||
---
|
||||
---
|
||||
# Codacy Rules
|
||||
Configuration for AI behavior when interacting with Codacy's MCP Server
|
||||
|
||||
## CRITICAL: After ANY successful `edit_file` or `reapply` operation
|
||||
- YOU MUST IMMEDIATELY run the `codacy_cli_analyze` tool from Codacy's MCP Server for each file that was edited, with:
|
||||
- `rootPath`: set to the workspace path
|
||||
- `file`: set to the path of the edited file
|
||||
- `tool`: leave empty or unset
|
||||
- If any issues are found in the new edits, propose and apply fixes for them.
|
||||
- > NOTE: Failure to follow this rule is considered a critical error.
|
||||
|
||||
## When you tried to run the `codacy_cli_analyze` tool and the Codacy CLI is not installed
|
||||
- Ask the user 'Codacy CLI is not installed. Would you like me to install it now?'
|
||||
- If the user responds with "yes", run the `codacy_cli_install` tool and then continue with the original task
|
||||
- If the user responds with "no", instruct the user that they can disable automatic analysis in the extension settings
|
||||
- Wait for the user to respond before proceeding with any other actions
|
||||
|
||||
## After every response
|
||||
- If you made any file edits in this conversation, verify you ran `codacy_cli_analyze` tool from Codacy's MCP Server
|
||||
|
||||
## When there are no Codacy MCP Server tools available, or the MCP Server is not reachable
|
||||
- Suggest the user the following troubleshooting steps:
|
||||
- Try to reset the MCP on the extension
|
||||
- If the user is using VSCode, suggest them to review their Copilot > MCP settings in Github, under their organization or personal account. Refer them to Settings > Copilot > Enable MCP servers in Copilot. Suggested URL (https://github.com/settings/copilot/features) or https://github.com/organizations/{organization-name}/settings/copilot/features (This can only be done by their organization admins / owners)
|
||||
- If none of the above steps work, suggest the user to contact Codacy support
|
||||
|
||||
## Trying to call a tool that needs a rootPath as a parameter
|
||||
- Always use the standard, non-URL-encoded file system path
|
||||
|
||||
## CRITICAL: Dependencies and Security Checks
|
||||
- IMMEDIATELY after ANY of these actions:
|
||||
- Running npm/yarn/pnpm install
|
||||
- Adding dependencies to package.json
|
||||
- Adding requirements to requirements.txt
|
||||
- Adding dependencies to pom.xml
|
||||
- Adding dependencies to build.gradle
|
||||
- Any other package manager operations
|
||||
- You MUST run the `codacy_cli_analyze` tool with:
|
||||
- `rootPath`: set to the workspace path
|
||||
- `tool`: set to "trivy"
|
||||
- `file`: leave empty or unset
|
||||
- If any vulnerabilities are found because of the newly added packages:
|
||||
- Stop all other operations
|
||||
- Propose and apply fixes for the security issues
|
||||
- Only continue with the original task after security issues are resolved
|
||||
- EXAMPLE:
|
||||
- After: npm install react-markdown
|
||||
- Do: Run codacy_cli_analyze with trivy
|
||||
- Before: Continuing with any other tasks
|
||||
|
||||
## General
|
||||
- Repeat the relevant steps for each modified file.
|
||||
- "Propose fixes" means to both suggest and, if possible, automatically apply the fixes.
|
||||
- You MUST NOT wait for the user to ask for analysis or remind you to run the tool.
|
||||
- Do not run `codacy_cli_analyze` looking for changes in duplicated code or code complexity metrics.
|
||||
- Complexity metrics are different from complexity issues. When trying to fix complexity in a repository or file, focus on solving the complexity issues and ignore the complexity metric.
|
||||
- Do not run `codacy_cli_analyze` looking for changes in code coverage.
|
||||
- Do not try to manually install Codacy CLI using either brew, npm, npx, or any other package manager.
|
||||
- If the Codacy CLI is not installed, just run the `codacy_cli_analyze` tool from Codacy's MCP Server.
|
||||
- When calling `codacy_cli_analyze`, only send provider, organization and repository if the project is a git repository.
|
||||
|
||||
## Whenever a call to a Codacy tool that uses `repository` or `organization` as a parameter returns a 404 error
|
||||
- Offer to run the `codacy_setup_repository` tool to add the repository to Codacy
|
||||
- If the user accepts, run the `codacy_setup_repository` tool
|
||||
- Do not ever try to run the `codacy_setup_repository` tool on your own
|
||||
- After setup, immediately retry the action that failed (only retry once)
|
||||
---
|
||||
173
.github/workflows/code-quality.yml
vendored
Normal file
173
.github/workflows/code-quality.yml
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
name: Code Quality
|
||||
|
||||
on:
|
||||
# Only run on push to main (not feature branches) to avoid duplicate runs.
|
||||
# Feature branches get CI via pull_request trigger.
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
phpcs:
|
||||
name: PHP CodeSniffer
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
clean: 'true'
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2
|
||||
with:
|
||||
php-version: '8.1'
|
||||
extensions: mbstring, intl, zip
|
||||
tools: composer:v2
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer install --prefer-dist --no-progress
|
||||
|
||||
- name: Run PHPCS
|
||||
run: composer phpcs
|
||||
continue-on-error: true
|
||||
|
||||
- name: Run PHPCBF (report only)
|
||||
run: |
|
||||
echo "Running PHPCBF in dry-run mode to show what would be fixed"
|
||||
composer phpcbf -- --dry-run
|
||||
continue-on-error: true
|
||||
|
||||
phpstan:
|
||||
name: PHPStan Static Analysis
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2
|
||||
with:
|
||||
php-version: '8.1'
|
||||
extensions: mbstring, intl, zip
|
||||
tools: composer:v2, phpstan
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer install --prefer-dist --no-progress
|
||||
|
||||
- name: Run PHPStan
|
||||
run: composer phpstan
|
||||
continue-on-error: true
|
||||
|
||||
phpmd:
|
||||
name: PHP Mess Detector
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2
|
||||
with:
|
||||
php-version: '8.1'
|
||||
extensions: mbstring, intl, zip
|
||||
tools: composer:v2, phpmd
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer install --prefer-dist --no-progress
|
||||
|
||||
- name: Run PHPMD
|
||||
run: composer phpmd
|
||||
continue-on-error: true
|
||||
|
||||
# NOTE: SonarCloud job is disabled because SONAR_TOKEN is not properly configured.
|
||||
# To enable, configure a valid SONAR_TOKEN secret and uncomment this job.
|
||||
# Generate a token at: https://sonarcloud.io/account/security
|
||||
#
|
||||
# sonarcloud:
|
||||
# name: SonarCloud Analysis
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - name: Checkout code
|
||||
# uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
#
|
||||
# - name: Set up JDK 17
|
||||
# uses: actions/setup-java@v4
|
||||
# with:
|
||||
# java-version: 17
|
||||
# distribution: 'temurin'
|
||||
#
|
||||
# - name: Cache SonarCloud packages
|
||||
# uses: actions/cache@v4
|
||||
# with:
|
||||
# path: ~/.sonar/cache
|
||||
# key: ${{ runner.os }}-sonar
|
||||
# restore-keys: ${{ runner.os }}-sonar
|
||||
#
|
||||
# - name: Check if SonarCloud token is set
|
||||
# id: check_sonar_token
|
||||
# run: |
|
||||
# if [ -z "${{ secrets.SONAR_TOKEN }}" ]; then
|
||||
# echo "SONAR_TOKEN is not set, skipping SonarCloud analysis"
|
||||
# echo "skip=true" >> $GITHUB_OUTPUT
|
||||
# else
|
||||
# echo "skip=false" >> $GITHUB_OUTPUT
|
||||
# fi
|
||||
#
|
||||
# - name: SonarCloud Scan
|
||||
# if: steps.check_sonar_token.outputs.skip != 'true'
|
||||
# uses: SonarSource/sonarqube-scan-action@9598b8a83feef37de07f549027fab50ecffe6a6e # master
|
||||
# env:
|
||||
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
# with:
|
||||
# args: >
|
||||
# -Dsonar.projectKey=wpallstars_wp-plugin-starter-template-for-ai-coding
|
||||
# -Dsonar.organization=wpallstars
|
||||
# -Dsonar.sources=.
|
||||
# -Dsonar.exclusions=vendor/**,node_modules/**,tests/**,bin/**,build/**,dist/**,.github/**,.git/**,cypress/**,playground/**,.wiki/**
|
||||
# -Dsonar.sourceEncoding=UTF-8
|
||||
# continue-on-error: true
|
||||
|
||||
codacy:
|
||||
name: Codacy Analysis
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Check if Codacy token is set
|
||||
id: check_codacy_token
|
||||
run: |
|
||||
if [ -z "${{ secrets.CODACY_PROJECT_TOKEN }}" ]; then
|
||||
echo "CODACY_PROJECT_TOKEN is not set, running Codacy without upload"
|
||||
echo "skip_upload=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "skip_upload=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Run Codacy Analysis CLI
|
||||
uses: codacy/codacy-analysis-cli-action@562ee3e92b8e92df8b67e0a5ff8aa8e261919c08 # v4
|
||||
with:
|
||||
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
verbose: true
|
||||
output: results.sarif
|
||||
format: sarif
|
||||
# Limit the number of issues to prevent GitHub Code Scanning rejection
|
||||
gh-code-scanning-compat: true
|
||||
max-allowed-issues: 20
|
||||
# Limit tools to prevent timeouts and stay under GitHub's 20 runs limit
|
||||
tool: phpcs,phpmd,markdownlint
|
||||
continue-on-error: true
|
||||
|
||||
- name: Upload SARIF results file
|
||||
if: steps.check_codacy_token.outputs.skip_upload != 'true'
|
||||
uses: github/codeql-action/upload-sarif@603b797f8b14b413fe025cd935a91c16c4782713 # v3
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
continue-on-error: true
|
||||
70
.github/workflows/phpunit.yml
vendored
Normal file
70
.github/workflows/phpunit.yml
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
name: PHPUnit Tests
|
||||
|
||||
on:
|
||||
# Only run on push to main (not feature branches) to avoid duplicate runs.
|
||||
# Feature branches get CI via pull_request trigger.
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: PHP ${{ matrix.php }} - WP ${{ matrix.wp }} - ${{ matrix.multisite && 'Multisite' || 'Single Site' }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php: [ '7.4', '8.0' ]
|
||||
wp: [ 'latest' ]
|
||||
multisite: [ false, true ]
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:5.7
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_DATABASE: wordpress_test
|
||||
ports:
|
||||
- 3306:3306
|
||||
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
extensions: dom, curl, libxml, mbstring, zip, pdo, mysql, pdo_mysql, bcmath, soap, intl, gd, exif, iconv
|
||||
coverage: none
|
||||
|
||||
- name: Install Composer dependencies
|
||||
uses: ramsey/composer-install@83af392bf5f031813d25e6fe4cd626cdba9a2df6 # v2.2.0
|
||||
|
||||
- name: Install WordPress test suite
|
||||
run: |
|
||||
set -e
|
||||
echo "Installing WordPress test suite with multisite=${{ matrix.multisite }}"
|
||||
bash bin/install-wp-tests.sh wordpress_test root root 127.0.0.1 ${{ matrix.wp }} false ${{ matrix.multisite && 'true' || 'false' }}
|
||||
echo "WordPress test suite installed successfully"
|
||||
|
||||
- name: Run PHPUnit tests
|
||||
env:
|
||||
WP_PHPUNIT__DIR: /tmp/wordpress-tests-lib
|
||||
WP_TESTS_DIR: /tmp/wordpress-tests-lib
|
||||
run: |
|
||||
if [ "${{ matrix.multisite }}" = "true" ]; then
|
||||
WP_MULTISITE=1 composer test
|
||||
else
|
||||
composer test
|
||||
fi
|
||||
106
.github/workflows/playground-tests-fix.yml
vendored
Normal file
106
.github/workflows/playground-tests-fix.yml
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
name: WordPress Playground Tests Fix
|
||||
|
||||
# DISABLED: WordPress Playground CLI doesn't work reliably in GitHub Actions CI environments
|
||||
# The server fails to start within timeout periods. These tests should be run locally instead.
|
||||
|
||||
on:
|
||||
# Disable automatic triggers - only run manually if needed for debugging
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
debug:
|
||||
description: 'Enable debug mode'
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
# Commented out triggers that cause CI noise:
|
||||
# push:
|
||||
# branches: [ main, feature/* ]
|
||||
# pull_request:
|
||||
# branches: [ main ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
playground-test:
|
||||
name: WordPress Playground Tests
|
||||
runs-on: ubuntu-latest
|
||||
# Allow failures since WordPress Playground CLI can be unreliable in CI environments
|
||||
continue-on-error: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install --legacy-peer-deps
|
||||
|
||||
- name: Add WordPress Playground CLI to dependencies
|
||||
run: |
|
||||
echo "Installing WordPress Playground CLI..."
|
||||
npm install --save-dev @wp-playground/cli @wp-playground/blueprints @wp-playground/client
|
||||
echo "WordPress Playground CLI installed"
|
||||
npx @wp-playground/cli --version
|
||||
|
||||
- name: Create plugin zip
|
||||
uses: ./.github/actions/create-plugin-zip
|
||||
|
||||
- name: Run tests with WordPress Playground
|
||||
run: |
|
||||
# Set base URL for Cypress
|
||||
export CYPRESS_BASE_URL=http://localhost:8888
|
||||
|
||||
# Check if blueprint file exists
|
||||
echo "Checking blueprint file..."
|
||||
ls -la playground/
|
||||
cat playground/blueprint.json
|
||||
|
||||
# Start WordPress Playground with our blueprint
|
||||
echo "Starting WordPress Playground server..."
|
||||
npx @wp-playground/cli server --blueprint playground/blueprint.json --port 8888 --login &
|
||||
SERVER_PID=$!
|
||||
|
||||
# Wait for WordPress Playground to be ready (increased timeout to 180s)
|
||||
echo "Waiting for WordPress Playground to be ready..."
|
||||
TIMEOUT=180
|
||||
ELAPSED=0
|
||||
while ! curl -s http://localhost:8888 > /dev/null 2>&1; do
|
||||
if [ $ELAPSED -ge $TIMEOUT ]; then
|
||||
echo "Timeout waiting for WordPress Playground to start"
|
||||
kill $SERVER_PID || true
|
||||
exit 1
|
||||
fi
|
||||
echo "Waiting... ($ELAPSED/$TIMEOUT seconds)"
|
||||
sleep 5
|
||||
ELAPSED=$((ELAPSED + 5))
|
||||
done
|
||||
echo "WordPress Playground is ready after $ELAPSED seconds"
|
||||
|
||||
# Run Cypress tests against WordPress Playground
|
||||
echo "Running Cypress tests..."
|
||||
npx cypress run --spec "cypress/e2e/playground-single-site.cy.js"
|
||||
TEST_EXIT_CODE=$?
|
||||
|
||||
# Kill the server process
|
||||
kill $SERVER_PID || true
|
||||
|
||||
# Return the test exit code
|
||||
exit $TEST_EXIT_CODE
|
||||
|
||||
- name: Upload Cypress artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: cypress-playground-results
|
||||
path: |
|
||||
cypress/videos
|
||||
cypress/screenshots
|
||||
276
.github/workflows/playground-tests.yml
vendored
Normal file
276
.github/workflows/playground-tests.yml
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
name: WordPress Playground Tests
|
||||
|
||||
# Re-enabled with @wp-playground/cli v3.0.22 which has improved CI stability.
|
||||
# Tests use continue-on-error: true so they won't block PRs if flaky.
|
||||
#
|
||||
# To run locally:
|
||||
# npm run playground:start
|
||||
# npm run playground:start:multisite
|
||||
|
||||
on:
|
||||
# Only run on push to main (not feature branches) to avoid duplicate runs.
|
||||
# Feature branches get CI via pull_request trigger.
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
debug:
|
||||
description: 'Enable debug mode'
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
code-quality:
|
||||
name: Code Quality Check
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [20]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install --legacy-peer-deps
|
||||
|
||||
- name: Verify package.json and package-lock.json
|
||||
run: |
|
||||
echo "Verifying package.json and package-lock.json are in sync"
|
||||
npm install --dry-run --legacy-peer-deps
|
||||
|
||||
- name: Lint JavaScript files
|
||||
run: npm run lint:js
|
||||
|
||||
playground-single-test:
|
||||
name: WordPress Playground Single Site Tests
|
||||
runs-on: ubuntu-latest
|
||||
needs: code-quality
|
||||
# Allow failures since WordPress Playground CLI can be unreliable in CI environments
|
||||
continue-on-error: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install --legacy-peer-deps
|
||||
|
||||
- name: Verify WordPress Playground CLI
|
||||
run: |
|
||||
echo "WordPress Playground CLI version:"
|
||||
npx @wp-playground/cli --version
|
||||
|
||||
- name: Create plugin zip
|
||||
uses: ./.github/actions/create-plugin-zip
|
||||
|
||||
- name: Run tests with WordPress Playground
|
||||
run: |
|
||||
# Set base URL for Cypress
|
||||
export CYPRESS_BASE_URL=http://127.0.0.1:8888
|
||||
|
||||
# Check if blueprint file exists
|
||||
echo "Checking blueprint file..."
|
||||
ls -la playground/
|
||||
cat playground/blueprint.json
|
||||
|
||||
# Start WordPress Playground with our blueprint (using @wp-playground/cli 3.x)
|
||||
echo "Starting WordPress Playground server..."
|
||||
npx @wp-playground/cli server \
|
||||
--blueprint playground/blueprint.json \
|
||||
--port 8888 \
|
||||
--login \
|
||||
--php 8.0 \
|
||||
--verbosity normal \
|
||||
2>&1 | tee playground-server.log &
|
||||
SERVER_PID=$!
|
||||
|
||||
# Wait for WordPress Playground to be ready
|
||||
echo "Waiting for WordPress Playground to be ready..."
|
||||
TIMEOUT=120
|
||||
ELAPSED=0
|
||||
while ! curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8888 2>/dev/null | grep -q "200\|302"; do
|
||||
if [ $ELAPSED -ge $TIMEOUT ]; then
|
||||
echo "Timeout waiting for WordPress Playground to start"
|
||||
echo "=== Server log ==="
|
||||
cat playground-server.log || true
|
||||
kill $SERVER_PID 2>/dev/null || true
|
||||
exit 1
|
||||
fi
|
||||
# Check if server process is still running
|
||||
if ! kill -0 $SERVER_PID 2>/dev/null; then
|
||||
echo "Server process died unexpectedly"
|
||||
echo "=== Server log ==="
|
||||
cat playground-server.log || true
|
||||
exit 1
|
||||
fi
|
||||
echo "Waiting... ($ELAPSED/$TIMEOUT seconds)"
|
||||
sleep 5
|
||||
ELAPSED=$((ELAPSED + 5))
|
||||
done
|
||||
echo "WordPress Playground is ready after $ELAPSED seconds"
|
||||
|
||||
# Run Cypress tests against WordPress Playground
|
||||
echo "Running Cypress tests..."
|
||||
npx cypress run --spec "cypress/e2e/playground-single-site.cy.js"
|
||||
TEST_EXIT_CODE=$?
|
||||
|
||||
# Kill the server process
|
||||
kill $SERVER_PID 2>/dev/null || true
|
||||
|
||||
# Return the test exit code
|
||||
exit $TEST_EXIT_CODE
|
||||
|
||||
- name: Upload Cypress artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: cypress-single-site-results
|
||||
path: |
|
||||
cypress/videos
|
||||
cypress/screenshots
|
||||
|
||||
playground-multisite-test:
|
||||
name: WordPress Playground Multisite Tests
|
||||
runs-on: ubuntu-latest
|
||||
needs: [code-quality, playground-single-test]
|
||||
# DISABLED: WordPress Multisite does not support custom ports (requires port 80/443).
|
||||
# This is a fundamental WordPress limitation. Multisite tests can only run locally
|
||||
# where port 80 can be used. See: https://developer.wordpress.org/advanced-administration/multisite/
|
||||
if: false
|
||||
continue-on-error: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install --legacy-peer-deps
|
||||
|
||||
- name: Verify WordPress Playground CLI
|
||||
run: |
|
||||
echo "WordPress Playground CLI version:"
|
||||
npx @wp-playground/cli --version
|
||||
|
||||
- name: Create plugin zip
|
||||
uses: ./.github/actions/create-plugin-zip
|
||||
|
||||
- name: Run tests with WordPress Playground
|
||||
run: |
|
||||
# Set base URL for Cypress
|
||||
export CYPRESS_BASE_URL=http://127.0.0.1:8889
|
||||
|
||||
# Check if blueprint file exists
|
||||
echo "Checking multisite blueprint file..."
|
||||
ls -la playground/
|
||||
cat playground/multisite-blueprint.json
|
||||
|
||||
# Start WordPress Playground with our blueprint (using @wp-playground/cli 3.x)
|
||||
# Use a different port for multisite to avoid conflicts with single site tests
|
||||
echo "Starting WordPress Playground server for multisite..."
|
||||
npx @wp-playground/cli server \
|
||||
--blueprint playground/multisite-blueprint.json \
|
||||
--port 8889 \
|
||||
--login \
|
||||
--php 8.0 \
|
||||
--verbosity normal \
|
||||
2>&1 | tee playground-server.log &
|
||||
SERVER_PID=$!
|
||||
|
||||
# Wait for WordPress Playground to be ready
|
||||
echo "Waiting for WordPress Playground to be ready..."
|
||||
TIMEOUT=120
|
||||
ELAPSED=0
|
||||
while ! curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8889 2>/dev/null | grep -q "200\|302"; do
|
||||
if [ $ELAPSED -ge $TIMEOUT ]; then
|
||||
echo "Timeout waiting for WordPress Playground to start"
|
||||
echo "=== Server log ==="
|
||||
cat playground-server.log || true
|
||||
kill $SERVER_PID 2>/dev/null || true
|
||||
exit 1
|
||||
fi
|
||||
# Check if server process is still running
|
||||
if ! kill -0 $SERVER_PID 2>/dev/null; then
|
||||
echo "Server process died unexpectedly"
|
||||
echo "=== Server log ==="
|
||||
cat playground-server.log || true
|
||||
exit 1
|
||||
fi
|
||||
echo "Waiting... ($ELAPSED/$TIMEOUT seconds)"
|
||||
sleep 5
|
||||
ELAPSED=$((ELAPSED + 5))
|
||||
done
|
||||
echo "WordPress Playground is ready after $ELAPSED seconds"
|
||||
|
||||
# Run Cypress tests against WordPress Playground
|
||||
echo "Running Cypress multisite tests..."
|
||||
npx cypress run --spec "cypress/e2e/playground-multisite.cy.js"
|
||||
TEST_EXIT_CODE=$?
|
||||
|
||||
# Kill the server process
|
||||
kill $SERVER_PID 2>/dev/null || true
|
||||
|
||||
# Return the test exit code
|
||||
exit $TEST_EXIT_CODE
|
||||
|
||||
- name: Upload Cypress artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: cypress-multisite-results
|
||||
path: |
|
||||
cypress/videos
|
||||
cypress/screenshots
|
||||
|
||||
performance-test:
|
||||
name: WordPress Performance Tests
|
||||
runs-on: ubuntu-latest
|
||||
needs: code-quality
|
||||
# DISABLED: Performance tests are flaky in CI due to Lighthouse/Playwright resource constraints.
|
||||
# The wp-performance-action uses WordPress Playground internally and Lighthouse for metrics,
|
||||
# which requires significant resources and is not reliable in shared CI runners.
|
||||
# Run performance tests locally or on dedicated infrastructure for accurate results.
|
||||
if: false
|
||||
continue-on-error: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: WordPress Performance Tests
|
||||
uses: swissspidy/wp-performance-action@b7e3ffcf0fc4a48b62492e021e0ebeb51430ff11 # v2.0.3
|
||||
with:
|
||||
plugins: |
|
||||
./
|
||||
urls: |
|
||||
/
|
||||
/wp-admin/
|
||||
# Don't pass blueprint - let the action use its own internal setup.
|
||||
# Our blueprint includes features that may conflict with the action's Lighthouse setup.
|
||||
wp-version: 'latest'
|
||||
php-version: '8.0'
|
||||
iterations: 5
|
||||
repetitions: 1
|
||||
46
.github/workflows/release.yml
vendored
46
.github/workflows/release.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Release
|
||||
name: Release - Build and publish plugin releases
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -10,12 +10,14 @@ jobs:
|
||||
build:
|
||||
name: Build and Release
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2
|
||||
with:
|
||||
php-version: '7.4'
|
||||
extensions: mbstring, intl, zip
|
||||
@@ -36,31 +38,41 @@ jobs:
|
||||
|
||||
- name: Create build directory
|
||||
run: |
|
||||
mkdir -p build/wp-plugin-starter-template
|
||||
cp -R *.php README.md LICENSE CHANGELOG.md readme.txt composer.json build/wp-plugin-starter-template/
|
||||
cp -R admin includes languages vendor build/wp-plugin-starter-template/
|
||||
mkdir -p build/wp-plugin-starter-template/assets/banner build/wp-plugin-starter-template/assets/icon build/wp-plugin-starter-template/assets/screenshots
|
||||
if [ -d "assets/banner" ]; then cp -R assets/banner/* build/wp-plugin-starter-template/assets/banner/; fi
|
||||
if [ -d "assets/icon" ]; then cp -R assets/icon/* build/wp-plugin-starter-template/assets/icon/; fi
|
||||
if [ -d "assets/screenshots" ]; then cp -R assets/screenshots/* build/wp-plugin-starter-template/assets/screenshots/; fi
|
||||
mkdir -p build/wp-plugin-starter-template-for-ai-coding
|
||||
cp -R *.php README.md LICENSE CHANGELOG.md readme.txt composer.json build/wp-plugin-starter-template-for-ai-coding/
|
||||
cp -R admin includes languages vendor build/wp-plugin-starter-template-for-ai-coding/
|
||||
mkdir -p build/wp-plugin-starter-template-for-ai-coding/assets/banner build/wp-plugin-starter-template-for-ai-coding/assets/icon build/wp-plugin-starter-template-for-ai-coding/assets/screenshots
|
||||
if [ -d "assets/banner" ]; then cp -R assets/banner/* build/wp-plugin-starter-template-for-ai-coding/assets/banner/; fi
|
||||
if [ -d "assets/icon" ]; then cp -R assets/icon/* build/wp-plugin-starter-template-for-ai-coding/assets/icon/; fi
|
||||
if [ -d "assets/screenshots" ]; then cp -R assets/screenshots/* build/wp-plugin-starter-template-for-ai-coding/assets/screenshots/; fi
|
||||
|
||||
- name: Create ZIP file
|
||||
run: |
|
||||
cd build
|
||||
zip -r ../wp-plugin-starter-template-${{ env.VERSION }}.zip wp-plugin-starter-template -x "*.DS_Store" -x "*.git*"
|
||||
zip -r ../wp-plugin-starter-template-for-ai-coding-${{ env.VERSION }}.zip wp-plugin-starter-template-for-ai-coding -x "*.DS_Store" -x "*.git*"
|
||||
cd ..
|
||||
|
||||
- name: Extract changelog
|
||||
id: extract_changelog
|
||||
run: |
|
||||
CHANGELOG=$(grep -A 20 "#### \[${{ env.VERSION }}\]" CHANGELOG.md | sed -n '/####/,/####/p' | sed '$d')
|
||||
echo "CHANGELOG<<EOF" >> $GITHUB_ENV
|
||||
echo "$CHANGELOG" >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: softprops/action-gh-release@v1
|
||||
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
||||
with:
|
||||
files: wp-plugin-starter-template-${{ env.VERSION }}.zip
|
||||
name: Version ${{ env.VERSION }}
|
||||
files: wp-plugin-starter-template-for-ai-coding-${{ env.VERSION }}.zip
|
||||
name: v${{ env.VERSION }} - WordPress Plugin Starter Template
|
||||
draft: false
|
||||
prerelease: false
|
||||
body: |
|
||||
Release of version ${{ env.VERSION }}
|
||||
|
||||
See [CHANGELOG.md](https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding/blob/main/CHANGELOG.md) for details.
|
||||
# WordPress Plugin Starter Template v${{ env.VERSION }}
|
||||
|
||||
${{ env.CHANGELOG }}
|
||||
|
||||
[View full changelog](https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding/blob/main/CHANGELOG.md)
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
66
.github/workflows/sonarcloud.yml
vendored
Normal file
66
.github/workflows/sonarcloud.yml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
name: SonarCloud Analysis
|
||||
|
||||
# DISABLED: Using SonarCloud Automatic Analysis instead of CI-based analysis.
|
||||
# Custom Quality Gates require a paid plan, which isn't suitable for FOSS projects.
|
||||
# The free Automatic Analysis provides code quality feedback without coverage requirements.
|
||||
#
|
||||
# To re-enable CI-based analysis:
|
||||
# 1. Uncomment the triggers below
|
||||
# 2. Disable Automatic Analysis on SonarCloud.io
|
||||
# 3. Consider upgrading to a paid plan for custom Quality Gate settings
|
||||
|
||||
on:
|
||||
# Disabled - using Automatic Analysis instead
|
||||
# push:
|
||||
# branches: [ main, feature/* ]
|
||||
# pull_request:
|
||||
# branches: [ main ]
|
||||
# types: [opened, synchronize, reopened]
|
||||
workflow_dispatch: # Keep manual trigger for testing
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
sonarcloud:
|
||||
name: SonarCloud
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Check if SonarCloud token is set
|
||||
id: check_token
|
||||
run: |
|
||||
if [ -z "${{ secrets.SONARCLOUD_GITHUB }}" ]; then
|
||||
echo "SONARCLOUD_GITHUB is not set, skipping SonarCloud analysis"
|
||||
echo "skip=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "skip=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: SonarCloud Scan
|
||||
if: steps.check_token.outputs.skip != 'true'
|
||||
uses: SonarSource/sonarqube-scan-action@9598b8a83feef37de07f549027fab50ecffe6a6e # master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONARCLOUD_GITHUB }}
|
||||
with:
|
||||
args: >
|
||||
-Dsonar.projectKey=wpallstars_wp-plugin-starter-template-for-ai-coding
|
||||
-Dsonar.organization=wpallstars
|
||||
-Dsonar.sources=.
|
||||
-Dsonar.tests=tests
|
||||
-Dsonar.sourceEncoding=UTF-8
|
||||
-Dsonar.cpd.exclusions=tests/**
|
||||
-Dsonar.exclusions=vendor/**,node_modules/**,tests/**,bin/**,build/**,dist/**,.github/**,.git/**,cypress/**,playground/**,.wiki/**
|
||||
-Dsonar.php.coverage.reportPaths=coverage.xml
|
||||
-Dsonar.php.tests.reportPath=test-report.xml
|
||||
26
.github/workflows/sync-wiki.yml
vendored
26
.github/workflows/sync-wiki.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Sync Wiki
|
||||
name: Sync Wiki - Update GitHub wiki from .wiki directory
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -11,9 +11,11 @@ jobs:
|
||||
sync-wiki:
|
||||
name: Sync Wiki to GitHub
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
|
||||
|
||||
- name: Configure Git
|
||||
run: |
|
||||
@@ -23,29 +25,33 @@ jobs:
|
||||
- name: Clone wiki repository
|
||||
run: |
|
||||
git clone https://github.com/${{ github.repository }}.wiki.git wiki
|
||||
|
||||
|
||||
- name: Sync wiki content
|
||||
run: |
|
||||
# Remove all files from wiki repository except .git
|
||||
find wiki -mindepth 1 -maxdepth 1 -not -name '.git' -exec rm -rf {} \;
|
||||
|
||||
|
||||
# Copy .wiki content to wiki repository
|
||||
cp -r .wiki/* wiki/
|
||||
|
||||
|
||||
# Go to wiki repository
|
||||
cd wiki
|
||||
|
||||
|
||||
# Add all changes
|
||||
git add .
|
||||
|
||||
|
||||
# Check if there are changes to commit
|
||||
if git diff --staged --quiet; then
|
||||
echo "No changes to commit"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
# Commit changes
|
||||
git commit -m "Sync wiki from source repository"
|
||||
|
||||
|
||||
# Push changes
|
||||
git push https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git
|
||||
git push https://${WIKI_ACTOR}:${WIKI_TOKEN}@github.com/${WIKI_REPO}.wiki.git
|
||||
env:
|
||||
WIKI_ACTOR: ${{ github.actor }}
|
||||
WIKI_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
WIKI_REPO: ${{ github.repository }}
|
||||
|
||||
36
.github/workflows/tests.yml
vendored
36
.github/workflows/tests.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Tests
|
||||
name: Tests - Run PHP compatibility and unit tests
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -12,19 +12,25 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['7.0', '7.4', '8.0']
|
||||
|
||||
php-versions: ['7.4', '8.0']
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
with:
|
||||
clean: 'true'
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: mbstring, intl, zip
|
||||
tools: composer:v2
|
||||
|
||||
- name: Clear Composer Cache
|
||||
run: composer clear-cache
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer install --prefer-dist --no-progress
|
||||
|
||||
@@ -34,20 +40,32 @@ jobs:
|
||||
code-style:
|
||||
name: Code Style
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
with:
|
||||
clean: 'true'
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2
|
||||
with:
|
||||
php-version: '7.4'
|
||||
extensions: mbstring, intl, zip
|
||||
tools: composer:v2, phpcs
|
||||
|
||||
- name: Clear Composer Cache
|
||||
run: composer clear-cache
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer install --prefer-dist --no-progress
|
||||
|
||||
- name: Run PHPCS
|
||||
run: ./vendor/bin/phpcs --standard=WordPress
|
||||
run: composer run phpcs
|
||||
continue-on-error: true
|
||||
|
||||
- name: Run PHPCBF (report only)
|
||||
run: |
|
||||
echo "Running PHPCBF in dry-run mode to show what would be fixed"
|
||||
composer run phpcbf -- --dry-run
|
||||
continue-on-error: true
|
||||
|
||||
132
.github/workflows/wordpress-tests.yml
vendored
Normal file
132
.github/workflows/wordpress-tests.yml
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
name: WordPress Tests
|
||||
|
||||
# DISABLED: WordPress Playground CLI doesn't work reliably in GitHub Actions CI environments
|
||||
# The server fails to start within timeout periods. These tests should be run locally instead.
|
||||
|
||||
on:
|
||||
# Disable automatic triggers - only run manually if needed for debugging
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
debug:
|
||||
description: 'Enable debug mode'
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
# Commented out triggers that cause CI noise:
|
||||
# push:
|
||||
# branches: [ main, feature/* ]
|
||||
# pull_request:
|
||||
# branches: [ main ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
code-quality:
|
||||
name: Code Quality Check
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [20]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install --legacy-peer-deps
|
||||
|
||||
- name: Verify package.json and package-lock.json
|
||||
run: |
|
||||
echo "Verifying package.json and package-lock.json are in sync"
|
||||
npm install --dry-run --legacy-peer-deps
|
||||
|
||||
- name: Lint JavaScript files
|
||||
run: npm run lint:js
|
||||
|
||||
# Note about e2e tests
|
||||
- name: Note about e2e tests
|
||||
run: |
|
||||
echo "Note: We now use WordPress Playground for e2e tests instead of Docker."
|
||||
echo "Please run tests locally before submitting PRs using:"
|
||||
echo "npm run test:playground:single"
|
||||
echo "npm run test:playground:multisite"
|
||||
echo "Or use the online WordPress Playground links in the documentation."
|
||||
|
||||
# Use WordPress Playground for e2e tests
|
||||
e2e-test:
|
||||
name: WordPress Playground Tests
|
||||
runs-on: ubuntu-latest
|
||||
needs: code-quality
|
||||
# Allow failures since WordPress Playground CLI can be unreliable in CI environments
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install --legacy-peer-deps
|
||||
|
||||
- name: Install WordPress Playground CLI
|
||||
run: npm install --save-dev @wp-playground/cli
|
||||
|
||||
- name: Create plugin zip
|
||||
uses: ./.github/actions/create-plugin-zip
|
||||
|
||||
- name: Run tests with WordPress Playground
|
||||
run: |
|
||||
# Set base URL for Cypress
|
||||
export CYPRESS_BASE_URL=http://localhost:8888
|
||||
|
||||
# Start WordPress Playground with our blueprint
|
||||
npx @wp-playground/cli server --blueprint playground/blueprint.json --port 8888 --login &
|
||||
SERVER_PID=$!
|
||||
|
||||
# Wait for WordPress Playground to be ready (increased timeout to 180s)
|
||||
echo "Waiting for WordPress Playground to be ready..."
|
||||
TIMEOUT=180
|
||||
ELAPSED=0
|
||||
while ! curl -s http://localhost:8888 > /dev/null 2>&1; do
|
||||
if [ $ELAPSED -ge $TIMEOUT ]; then
|
||||
echo "Timeout waiting for WordPress Playground to start"
|
||||
kill $SERVER_PID || true
|
||||
exit 1
|
||||
fi
|
||||
echo "Waiting... ($ELAPSED/$TIMEOUT seconds)"
|
||||
sleep 5
|
||||
ELAPSED=$((ELAPSED + 5))
|
||||
done
|
||||
echo "WordPress Playground is ready after $ELAPSED seconds"
|
||||
|
||||
# Run tests against WordPress Playground
|
||||
npx cypress run --spec "cypress/e2e/playground-single-site.cy.js"
|
||||
TEST_EXIT_CODE=$?
|
||||
|
||||
# Kill the server process
|
||||
kill $SERVER_PID || true
|
||||
|
||||
# Return the test exit code
|
||||
exit $TEST_EXIT_CODE
|
||||
|
||||
- name: Upload Cypress artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: cypress-results
|
||||
path: |
|
||||
cypress/videos
|
||||
cypress/screenshots
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -62,3 +62,7 @@ temp/
|
||||
# Test Coverage
|
||||
coverage/
|
||||
.phpunit.result.cache
|
||||
.agents/loop-state/
|
||||
|
||||
# Local tool configs
|
||||
.superset/
|
||||
|
||||
18
.markdownlint.json
Normal file
18
.markdownlint.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"MD004": {
|
||||
"style": "asterisk"
|
||||
},
|
||||
"MD012": false,
|
||||
"MD022": false,
|
||||
"MD031": false,
|
||||
"MD032": false,
|
||||
"MD013": {
|
||||
"line_length": 120,
|
||||
"code_blocks": false
|
||||
},
|
||||
"MD024": {
|
||||
"siblings_only": true
|
||||
},
|
||||
"MD040": false,
|
||||
"MD041": false
|
||||
}
|
||||
16
.markdownlintrc
Normal file
16
.markdownlintrc
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"default": true,
|
||||
"MD004": {
|
||||
"style": "asterisk"
|
||||
},
|
||||
"MD007": {
|
||||
"indent": 2
|
||||
},
|
||||
"MD013": false,
|
||||
"MD033": false,
|
||||
"MD040": true,
|
||||
"MD041": false,
|
||||
"MD046": {
|
||||
"style": "fenced"
|
||||
}
|
||||
}
|
||||
14
.qoder/settings.json
Normal file
14
.qoder/settings.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"permissions": {
|
||||
"ask": [
|
||||
"Read(!./**)",
|
||||
"Edit(!./**)"
|
||||
],
|
||||
"allow": [
|
||||
"Read(./**)",
|
||||
"Edit(./**)"
|
||||
]
|
||||
},
|
||||
"memoryImport": {},
|
||||
"monitoring": {}
|
||||
}
|
||||
16
.stylelintrc.json
Normal file
16
.stylelintrc.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "stylelint-config-standard",
|
||||
"rules": {
|
||||
"alpha-value-notation": "percentage",
|
||||
"color-function-notation": "modern",
|
||||
"font-weight-notation": "numeric",
|
||||
"media-feature-range-notation": "context"
|
||||
},
|
||||
"ignoreFiles": [
|
||||
"vendor/**",
|
||||
"node_modules/**",
|
||||
"build/**",
|
||||
"dist/**",
|
||||
"bin/**"
|
||||
]
|
||||
}
|
||||
108
.wiki/AI-Workflow-Documentation.md
Normal file
108
.wiki/AI-Workflow-Documentation.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# AI Workflow Documentation
|
||||
|
||||
This document provides an overview of the AI-assisted development workflows for this plugin.
|
||||
|
||||
## Introduction to AI-Assisted Development
|
||||
|
||||
AI-assisted development uses artificial intelligence tools to help with coding, documentation, testing, and other development tasks. This plugin is designed to work seamlessly with AI assistants to make development faster and more efficient.
|
||||
|
||||
## Setting Up Your AI Environment
|
||||
|
||||
### Required Files
|
||||
|
||||
To get the most out of AI-assisted development, make sure to include these files in your AI IDE context:
|
||||
|
||||
1. **AGENTS.md**: Contains essential information about the project structure and conventions
|
||||
2. **.agents/**: Directory containing detailed workflow documentation for common tasks
|
||||
|
||||
### Pinning Files in AI IDEs
|
||||
|
||||
For the best results, pin these files in your AI IDE chat context:
|
||||
|
||||
- **Claude**: Use the "Pin" feature to keep files in context
|
||||
- **GitHub Copilot**: Use the "Pin" feature in the chat interface
|
||||
- **ChatGPT**: Use the "Pin" feature in the Advanced Data Analysis mode
|
||||
- **Other AI IDEs**: Refer to your specific IDE's documentation for pinning files
|
||||
|
||||
## AI Workflow Files
|
||||
|
||||
The `.agents/` directory contains detailed guides for common development tasks:
|
||||
|
||||
1. **plugin-customization.md**: Guide for customizing the plugin for specific needs
|
||||
2. **feature-development.md**: Workflow for developing new features
|
||||
3. **bug-fixing.md**: Process for identifying and fixing bugs
|
||||
4. **testing.md**: Guide for writing and running tests
|
||||
5. **documentation.md**: Workflow for updating documentation
|
||||
6. **release-process.md**: Steps for creating new releases
|
||||
7. **wiki-documentation.md**: Guide for maintaining wiki documentation
|
||||
|
||||
## Using the Starter Prompt
|
||||
|
||||
The [Starter Prompt](Starter-Prompt) is a comprehensive guide for AI tools to help customize the template for your specific plugin. It includes:
|
||||
|
||||
1. **Project Overview**: Description of the plugin and its purpose
|
||||
2. **Customization Steps**: Detailed steps for customizing the template
|
||||
3. **File Structure**: Overview of the plugin's file structure
|
||||
4. **Coding Standards**: Guidelines for code style and quality
|
||||
5. **Testing Requirements**: Instructions for testing the plugin
|
||||
|
||||
## AI-Assisted Development Workflows
|
||||
|
||||
### Customizing the Plugin
|
||||
|
||||
1. Open your AI IDE and pin the `AGENTS.md` file and `.agents/` directory
|
||||
2. Provide the Starter Prompt to the AI
|
||||
3. Follow the AI's guidance to customize the plugin
|
||||
4. Review and test the changes
|
||||
|
||||
### Developing New Features
|
||||
|
||||
1. Define the feature requirements
|
||||
2. Ask the AI to help design the feature
|
||||
3. Implement the feature with AI assistance
|
||||
4. Write tests for the feature
|
||||
5. Update documentation
|
||||
|
||||
### Fixing Bugs
|
||||
|
||||
1. Describe the bug to the AI
|
||||
2. Ask the AI to help identify the cause
|
||||
3. Implement the fix with AI assistance
|
||||
4. Write tests to prevent regression
|
||||
5. Update documentation if necessary
|
||||
|
||||
### Writing Tests
|
||||
|
||||
1. Describe the functionality to be tested
|
||||
2. Ask the AI to help write unit tests
|
||||
3. Ask the AI to help write end-to-end tests
|
||||
4. Run the tests and fix any issues
|
||||
|
||||
### Updating Documentation
|
||||
|
||||
1. Describe the changes that need documentation
|
||||
2. Ask the AI to help update the relevant documentation files
|
||||
3. Review and refine the documentation
|
||||
|
||||
## Best Practices for AI-Assisted Development
|
||||
|
||||
1. **Be Specific**: Provide clear, detailed instructions to the AI
|
||||
2. **Review Carefully**: Always review AI-generated code before committing
|
||||
3. **Iterative Approach**: Work with the AI in small, iterative steps
|
||||
4. **Provide Context**: Keep relevant files in the AI's context
|
||||
5. **Ask Questions**: If you're unsure about something, ask the AI to explain
|
||||
6. **Test Thoroughly**: Always test AI-generated code
|
||||
|
||||
## Troubleshooting AI Assistance
|
||||
|
||||
If you encounter issues with AI assistance:
|
||||
|
||||
1. **Refresh Context**: Sometimes the AI may lose context. Try refreshing the conversation or repinning files
|
||||
2. **Be More Specific**: Provide more detailed instructions
|
||||
3. **Break Down Tasks**: Divide complex tasks into smaller, manageable parts
|
||||
4. **Provide Examples**: Show examples of what you want
|
||||
5. **Try Different Approaches**: If one approach doesn't work, try a different one
|
||||
|
||||
## Conclusion
|
||||
|
||||
AI-assisted development can significantly speed up your workflow and improve code quality. By following these guidelines and using the provided AI workflow documentation, you can make the most of AI tools in your development process.
|
||||
140
.wiki/Architecture-Overview.md
Normal file
140
.wiki/Architecture-Overview.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# Architecture Overview
|
||||
|
||||
This document provides an overview of the plugin's architecture, explaining the core components and how they interact.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
The plugin follows a structured organization to maintain clean separation of concerns:
|
||||
|
||||
```
|
||||
wp-plugin-starter-template/
|
||||
├── admin/ # Admin-specific functionality
|
||||
│ ├── css/ # Admin stylesheets
|
||||
│ ├── js/ # Admin JavaScript files
|
||||
│ └── lib/ # Admin PHP classes
|
||||
├── assets/ # Frontend assets
|
||||
│ ├── css/ # Frontend stylesheets
|
||||
│ ├── js/ # Frontend JavaScript files
|
||||
│ └── images/ # Images used by the plugin
|
||||
├── includes/ # Core plugin functionality
|
||||
│ ├── core.php # Core functionality class
|
||||
│ ├── plugin.php # Main plugin class
|
||||
│ └── Multisite/ # Multisite-specific functionality
|
||||
├── languages/ # Translation files
|
||||
├── tests/ # Test files
|
||||
│ ├── e2e/ # End-to-end tests
|
||||
│ └── unit/ # Unit tests
|
||||
├── cypress/ # Cypress testing files
|
||||
│ └── e2e/ # End-to-end test specifications
|
||||
├── bin/ # Utility scripts
|
||||
│ └── setup-test-env.sh # Test environment setup script
|
||||
├── .github/ # GitHub-specific files
|
||||
│ └── workflows/ # GitHub Actions workflows
|
||||
├── .agents/ # AI workflow documentation
|
||||
├── .wiki/ # Wiki documentation
|
||||
│ ├── Testing-Framework.md # Testing framework documentation
|
||||
│ └── Multisite-Development.md # Multisite development guide
|
||||
└── wp-plugin-starter-template.php # Main plugin file
|
||||
```
|
||||
|
||||
## Core Components
|
||||
|
||||
### Main Plugin File
|
||||
|
||||
The `wp-plugin-starter-template.php` file serves as the entry point for WordPress. It:
|
||||
|
||||
1. Defines plugin metadata
|
||||
2. Prevents direct access
|
||||
3. Defines plugin constants
|
||||
4. Loads the main plugin class
|
||||
5. Initializes the plugin
|
||||
|
||||
### Plugin Class
|
||||
|
||||
The `Plugin` class in `includes/plugin.php` is the main controller for the plugin. It:
|
||||
|
||||
1. Initializes core functionality
|
||||
2. Sets up hooks and filters
|
||||
3. Manages plugin activation/deactivation
|
||||
4. Handles plugin updates
|
||||
|
||||
### Core Class
|
||||
|
||||
The `Core` class in `includes/core.php` contains the core functionality of the plugin. It:
|
||||
|
||||
1. Implements the main plugin features
|
||||
2. Provides utility methods
|
||||
3. Manages data processing
|
||||
|
||||
### Admin Class
|
||||
|
||||
The `Admin` class in `admin/lib/admin.php` handles all admin-specific functionality. It:
|
||||
|
||||
1. Creates admin menu pages
|
||||
2. Registers settings
|
||||
3. Enqueues admin assets
|
||||
4. Processes admin form submissions
|
||||
|
||||
### Multisite Support
|
||||
|
||||
The `Multisite` class in `includes/Multisite/class-multisite.php` provides a foundation for multisite functionality.
|
||||
|
||||
It:
|
||||
|
||||
1. Serves as a placeholder for multisite features
|
||||
2. Can be extended for custom multisite functionality
|
||||
3. Provides examples of multisite-specific methods
|
||||
|
||||
## Object-Oriented Approach
|
||||
|
||||
The plugin follows object-oriented programming principles:
|
||||
|
||||
1. **Encapsulation**: Each class encapsulates its own functionality
|
||||
2. **Inheritance**: Classes can extend others to inherit functionality
|
||||
3. **Namespaces**: PHP namespaces are used to avoid conflicts
|
||||
4. **Autoloading**: PSR-4 autoloading for efficient class loading
|
||||
|
||||
## Hook System
|
||||
|
||||
The plugin integrates with WordPress through its hook system:
|
||||
|
||||
1. **Actions**: Used to add functionality at specific points
|
||||
2. **Filters**: Used to modify data before it's used by WordPress
|
||||
|
||||
## Data Flow
|
||||
|
||||
1. WordPress loads the main plugin file
|
||||
2. The Plugin class is instantiated
|
||||
3. The Plugin class initializes the Core class
|
||||
4. The Plugin class initializes the Admin class (in admin context)
|
||||
5. WordPress hooks trigger plugin functionality as needed
|
||||
|
||||
## Extensibility
|
||||
|
||||
The plugin is designed to be extensible:
|
||||
|
||||
1. **Filters**: Key data points can be modified via filters
|
||||
2. **Actions**: Additional functionality can be added via actions
|
||||
3. **Class Structure**: Classes can be extended to add or modify functionality
|
||||
|
||||
## Testing
|
||||
|
||||
The plugin includes a comprehensive testing framework:
|
||||
|
||||
1. **Unit Tests**: For testing individual components
|
||||
2. **End-to-End Tests**: For testing the plugin as a whole
|
||||
3. **WordPress Environment**: Using wp-env for local testing
|
||||
4. **Multisite Testing**: Support for testing in multisite environments
|
||||
5. **Continuous Integration**: Automated tests via GitHub Actions
|
||||
|
||||
## Conclusion
|
||||
|
||||
This architecture provides a solid foundation for WordPress plugin development.
|
||||
|
||||
It follows best practices and modern coding standards.
|
||||
|
||||
It's designed to be maintainable, extensible, and easy to understand.
|
||||
|
||||
For testing framework details, see [Testing Framework](Testing-Framework.md).
|
||||
|
||||
For multisite development, refer to [Multisite Development](Multisite-Development.md).
|
||||
@@ -2,12 +2,63 @@
|
||||
|
||||
This page documents all notable changes to the WordPress Plugin Starter Template.
|
||||
|
||||
## Version 0.1.6 (2025-04-19)
|
||||
|
||||
### Fixed
|
||||
|
||||
- GitHub Actions workflows permissions for releases and wiki sync
|
||||
|
||||
## Version 0.1.5 (2025-04-19)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Release workflow to use correct plugin directory name
|
||||
|
||||
### Added
|
||||
|
||||
- Testing setup with wp-env and Cypress
|
||||
- Multisite compatibility
|
||||
- npm scripts for development and testing
|
||||
|
||||
## Version 0.1.3 (2025-04-19)
|
||||
|
||||
### Added
|
||||
|
||||
- Improved AI IDE context recommendations in documentation
|
||||
- Enhanced Starter Prompt with guidance on pinning AGENTS.md and .agents/
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated README.md and readme.txt with AI IDE context recommendations
|
||||
- Improved documentation for AI-assisted development
|
||||
- Moved Starter Prompt to the wiki for better organization
|
||||
|
||||
## Version 0.1.2 (2025-04-18)
|
||||
|
||||
### Added
|
||||
|
||||
- STARTER-PROMPT.md with comprehensive guide for customizing the template
|
||||
- Additional AI workflow files for better development guidance
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated documentation files with improved instructions
|
||||
|
||||
## Version 0.1.1 (2025-04-18)
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated LICENSE file with correct GPL-2.0 text
|
||||
|
||||
## Version 0.1.0 (2025-04-17)
|
||||
|
||||
### Added
|
||||
|
||||
- Initial release with basic template structure
|
||||
- Added core plugin architecture with OOP approach
|
||||
- Added admin interface components and styling
|
||||
- Added update mechanism with multiple source options
|
||||
- Added documentation templates for users and developers
|
||||
- Added AI workflow documentation for AI-assisted development
|
||||
- Added GitHub Actions workflows for automated tasks
|
||||
- Added wiki documentation templates
|
||||
- Core plugin architecture with OOP approach
|
||||
- Admin interface components and styling
|
||||
- Update mechanism with multiple source options
|
||||
- Documentation templates for users and developers
|
||||
- AI workflow documentation for AI-assisted development
|
||||
- GitHub Actions workflows for automated tasks
|
||||
- Wiki documentation templates
|
||||
|
||||
290
.wiki/Coding-Standards.md
Normal file
290
.wiki/Coding-Standards.md
Normal file
@@ -0,0 +1,290 @@
|
||||
# Coding Standards
|
||||
|
||||
This document outlines the coding standards used in this plugin. Following these standards ensures consistency, readability, and maintainability of the codebase.
|
||||
|
||||
## PHP Coding Standards
|
||||
|
||||
This plugin follows the [WordPress Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/php/) with some additional guidelines.
|
||||
|
||||
### File Structure
|
||||
|
||||
* Each PHP file should begin with the PHP opening tag `<?php` (no closing tag)
|
||||
* Files should use the Unix line endings (LF)
|
||||
* Files should be encoded in UTF-8 without BOM
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
* **Classes**: Use `PascalCase` for class names
|
||||
```php
|
||||
class MyClassName {}
|
||||
```
|
||||
|
||||
* **Methods and Functions**: Use `snake_case` for method and function names
|
||||
```php
|
||||
function my_function_name() {}
|
||||
public function my_method_name() {}
|
||||
```
|
||||
|
||||
* **Variables**: Use `snake_case` for variable names
|
||||
```php
|
||||
$my_variable_name = 'value';
|
||||
```
|
||||
|
||||
* **Constants**: Use `UPPERCASE_WITH_UNDERSCORES` for constants
|
||||
```php
|
||||
define('MY_CONSTANT', 'value');
|
||||
const MY_CLASS_CONSTANT = 'value';
|
||||
```
|
||||
|
||||
* **Namespaces**: Use `PascalCase` for namespace segments
|
||||
```php
|
||||
namespace WPALLSTARS\PluginStarterTemplate;
|
||||
```
|
||||
|
||||
* **Hooks**: Prefix hooks with the plugin's prefix
|
||||
```php
|
||||
do_action('wpst_hook_name');
|
||||
apply_filters('wpst_filter_name', $value);
|
||||
```
|
||||
|
||||
### Indentation and Formatting
|
||||
|
||||
* Use 4 spaces for indentation (not tabs)
|
||||
* Opening braces for classes and functions should be on the same line
|
||||
* Control structures should have one space between the statement and the opening parenthesis
|
||||
* Each line should be no longer than 100 characters
|
||||
|
||||
```php
|
||||
if ($condition) {
|
||||
// Code here
|
||||
} elseif ($another_condition) {
|
||||
// More code
|
||||
} else {
|
||||
// Default code
|
||||
}
|
||||
```
|
||||
|
||||
### Documentation
|
||||
|
||||
* All classes, methods, and functions should be documented using PHPDoc
|
||||
* Include descriptions of parameters, return values, and any exceptions thrown
|
||||
|
||||
```php
|
||||
/**
|
||||
* Short description of the function.
|
||||
*
|
||||
* Longer description if needed.
|
||||
*
|
||||
* @param string $param1 Description of the parameter.
|
||||
* @param int $param2 Description of the parameter.
|
||||
* @return bool Description of the return value.
|
||||
* @throws Exception When something goes wrong.
|
||||
*/
|
||||
function my_function($param1, $param2) {
|
||||
// Function code
|
||||
}
|
||||
```
|
||||
|
||||
### Object-Oriented Programming
|
||||
|
||||
* Each class should have a single responsibility
|
||||
* Use visibility declarations for all properties and methods (public, protected, private)
|
||||
* Use type hints for parameters and return types when possible
|
||||
|
||||
```php
|
||||
class MyClass {
|
||||
/**
|
||||
* Property description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $property;
|
||||
|
||||
/**
|
||||
* Method description.
|
||||
*
|
||||
* @param string $param Description of the parameter.
|
||||
* @return bool Description of the return value.
|
||||
*/
|
||||
public function my_method(string $param): bool {
|
||||
// Method code
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## JavaScript Coding Standards
|
||||
|
||||
This plugin follows the [WordPress JavaScript Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/javascript/).
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
* **Variables and Functions**: Use `camelCase` for variable and function names
|
||||
```javascript
|
||||
var myVariableName = 'value';
|
||||
function myFunctionName() {}
|
||||
```
|
||||
|
||||
* **Constants**: Use `UPPERCASE_WITH_UNDERSCORES` for constants
|
||||
```javascript
|
||||
var MY_CONSTANT = 'value';
|
||||
```
|
||||
|
||||
### Indentation and Formatting
|
||||
|
||||
* Use 4 spaces for indentation (not tabs)
|
||||
* Opening braces should be on the same line as the statement
|
||||
* Each line should be no longer than 100 characters
|
||||
|
||||
```javascript
|
||||
if (condition) {
|
||||
// Code here
|
||||
} else if (anotherCondition) {
|
||||
// More code
|
||||
} else {
|
||||
// Default code
|
||||
}
|
||||
```
|
||||
|
||||
### Documentation
|
||||
|
||||
* Use JSDoc for documenting functions and objects
|
||||
|
||||
```javascript
|
||||
/**
|
||||
* Short description of the function.
|
||||
*
|
||||
* @param {string} param1 - Description of the parameter.
|
||||
* @param {number} param2 - Description of the parameter.
|
||||
* @returns {boolean} Description of the return value.
|
||||
*/
|
||||
function myFunction(param1, param2) {
|
||||
// Function code
|
||||
}
|
||||
```
|
||||
|
||||
## CSS Coding Standards
|
||||
|
||||
This plugin follows the [WordPress CSS Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/css/).
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
* Use lowercase for selectors
|
||||
* Use hyphens to separate words in class and ID names
|
||||
* Prefix classes and IDs with the plugin's prefix
|
||||
|
||||
```css
|
||||
.wpst-container {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#wpst-header {
|
||||
padding: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
### Indentation and Formatting
|
||||
|
||||
* Use 4 spaces for indentation (not tabs)
|
||||
* Each property should be on its own line
|
||||
* Include a space after the colon in property declarations
|
||||
* End each declaration with a semicolon
|
||||
* Use single quotes for attribute selectors and property values
|
||||
|
||||
```css
|
||||
.wpst-container {
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
font-family: 'Helvetica', sans-serif;
|
||||
}
|
||||
```
|
||||
|
||||
## Automated Code Checking
|
||||
|
||||
This plugin uses automated tools to enforce coding standards:
|
||||
|
||||
### Local Development Tools
|
||||
|
||||
1. **PHP_CodeSniffer (PHPCS)**: Checks PHP code against the WordPress Coding Standards
|
||||
```bash
|
||||
composer run phpcs
|
||||
```
|
||||
|
||||
2. **PHP Code Beautifier and Fixer (PHPCBF)**: Automatically fixes some coding standard violations
|
||||
```bash
|
||||
composer run phpcbf
|
||||
```
|
||||
|
||||
3. **ESLint**: Checks JavaScript code against the WordPress Coding Standards
|
||||
```bash
|
||||
npm run lint:js
|
||||
```
|
||||
|
||||
4. **Stylelint**: Checks CSS code against the WordPress Coding Standards
|
||||
```bash
|
||||
npm run lint:css
|
||||
```
|
||||
|
||||
### Continuous Integration Tools
|
||||
|
||||
This project integrates with several code quality tools that automatically analyze your code when you create a pull request. These tools are free for public repositories and should be integrated into any new repositories based on this template.
|
||||
|
||||
1. **CodeRabbit**: AI-powered code review tool
|
||||
* Provides automated feedback on pull requests
|
||||
* Identifies potential issues and suggests improvements
|
||||
* [Website](https://www.coderabbit.ai/)
|
||||
|
||||
2. **CodeFactor**: Continuous code quality monitoring
|
||||
* Provides a grade for your codebase
|
||||
* Identifies issues related to code style, complexity, and potential bugs
|
||||
* Tracks code quality over time
|
||||
* [Website](https://www.codefactor.io/)
|
||||
|
||||
3. **Codacy**: Code quality and static analysis
|
||||
* Provides a grade for your codebase
|
||||
* Identifies issues related to code style, security, and performance
|
||||
* Tracks code quality over time
|
||||
* [Website](https://www.codacy.com/)
|
||||
|
||||
4. **SonarCloud**: Code quality and security analysis
|
||||
* Provides detailed analysis of code quality
|
||||
* Identifies security vulnerabilities and technical debt
|
||||
* Tracks code quality over time
|
||||
* [Website](https://sonarcloud.io/)
|
||||
|
||||
### How to Pass Code Quality Checks
|
||||
|
||||
To ensure your code passes the quality checks from these tools, follow these guidelines:
|
||||
|
||||
1. **Run Local Checks First**
|
||||
* Before pushing your code, run PHPCS and PHPCBF locally
|
||||
* Fix any issues identified by these tools
|
||||
|
||||
2. **Address Common Issues**
|
||||
* **Indentation**: Use 4 spaces for indentation (not tabs)
|
||||
* **Line Length**: Keep lines under 100 characters
|
||||
* **Naming Conventions**: Follow WordPress naming conventions
|
||||
* **Documentation**: Add PHPDoc comments to classes, methods, and functions
|
||||
* **Error Handling**: Implement proper error handling
|
||||
* **Security**: Validate and sanitize input, escape output
|
||||
* **Markdown**: Use asterisks (*) for bullet points, not hyphens (-)
|
||||
|
||||
3. **Using AI Assistants with Code Quality Tools**
|
||||
* When you receive feedback from code quality tools, you can use AI assistants to help address the issues
|
||||
* Copy the output from the code quality tool and paste it into your AI assistant chat
|
||||
* Request the AI's assistance to interpret and resolve the reported issues
|
||||
* Example prompt:
|
||||
|
||||
```text
|
||||
I received the following feedback from [Tool Name]. Please help me understand and resolve these issues:
|
||||
|
||||
[Paste the tool output here]
|
||||
```
|
||||
|
||||
4. **Iterative Improvement**
|
||||
* Address issues one at a time, starting with the most critical
|
||||
* Commit and push your changes to see if they resolve the issues
|
||||
* Continue this process until all issues are resolved
|
||||
|
||||
## Conclusion
|
||||
|
||||
Following these coding standards ensures that the plugin's code is consistent, readable, and maintainable. All contributors should adhere to these standards when submitting code to the project.
|
||||
180
.wiki/Contributing.md
Normal file
180
.wiki/Contributing.md
Normal file
@@ -0,0 +1,180 @@
|
||||
# Contributing
|
||||
|
||||
Thank you for considering contributing to this project! This document provides guidelines and instructions for contributing.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
By participating in this project, you agree to abide by our code of conduct:
|
||||
|
||||
* Be respectful and inclusive
|
||||
* Be patient and welcoming
|
||||
* Be considerate
|
||||
* Be collaborative
|
||||
* Be open-minded
|
||||
|
||||
## How to Contribute
|
||||
|
||||
### Reporting Bugs
|
||||
|
||||
If you find a bug, please report it by creating an issue on GitHub:
|
||||
|
||||
1. Go to the [Issues](https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding/issues) page
|
||||
2. Click "New Issue"
|
||||
3. Select "Bug Report"
|
||||
4. Fill out the template with as much detail as possible
|
||||
5. Submit the issue
|
||||
|
||||
Please include:
|
||||
|
||||
* A clear, descriptive title
|
||||
* Steps to reproduce the bug
|
||||
* Expected behavior
|
||||
* Actual behavior
|
||||
* Screenshots (if applicable)
|
||||
* Your environment (WordPress version, PHP version, browser, etc.)
|
||||
|
||||
### Suggesting Enhancements
|
||||
|
||||
If you have an idea for an enhancement:
|
||||
|
||||
1. Go to the [Issues](https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding/issues) page
|
||||
2. Click "New Issue"
|
||||
3. Select "Feature Request"
|
||||
4. Fill out the template with as much detail as possible
|
||||
5. Submit the issue
|
||||
|
||||
Please include:
|
||||
|
||||
* A clear, descriptive title
|
||||
* A detailed description of the enhancement
|
||||
* Why this enhancement would be useful
|
||||
* Any relevant examples or mockups
|
||||
|
||||
### Pull Requests
|
||||
|
||||
If you want to contribute code:
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a new branch for your feature or bugfix
|
||||
3. Make your changes
|
||||
4. Run tests to ensure your changes don't break anything
|
||||
5. Submit a pull request
|
||||
|
||||
#### Pull Request Process
|
||||
|
||||
1. Fork the repository on [GitHub](https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding/) or [Gitea](https://gitea.wpallstars.com/wpallstars/wp-plugin-starter-template-for-ai-coding/)
|
||||
2. Clone your fork: `git clone https://github.com/YOUR-USERNAME/wp-plugin-starter-template-for-ai-coding.git`
|
||||
3. Create your feature branch: `git checkout -b feature/amazing-feature`
|
||||
4. Make your changes
|
||||
5. Commit your changes: `git commit -m 'Add some amazing feature'`
|
||||
6. Push to the branch: `git push origin feature/amazing-feature`
|
||||
7. Submit a pull request
|
||||
|
||||
#### Pull Request Guidelines
|
||||
|
||||
* Follow the coding standards (see [Coding Standards](Coding-Standards))
|
||||
* Write tests for your changes
|
||||
* Update documentation as needed
|
||||
* Keep pull requests focused on a single change
|
||||
* Write a clear, descriptive title and description
|
||||
* Reference any related issues
|
||||
* Ensure your code passes the automated code quality checks (see below)
|
||||
|
||||
#### Code Quality Tools
|
||||
|
||||
This project uses several automated code quality tools to ensure high standards. These tools are free for public repositories and will automatically analyze your code when you create a pull request:
|
||||
|
||||
1. **CodeRabbit**: AI-powered code review tool
|
||||
* [Website](https://www.coderabbit.ai/)
|
||||
* Provides automated feedback on pull requests
|
||||
|
||||
2. **CodeFactor**: Continuous code quality monitoring
|
||||
* [Website](https://www.codefactor.io/)
|
||||
* Provides a grade for your codebase
|
||||
|
||||
3. **Codacy**: Code quality and static analysis
|
||||
* [Website](https://www.codacy.com/)
|
||||
* Identifies issues related to code style, security, and performance
|
||||
|
||||
4. **SonarCloud**: Code quality and security analysis
|
||||
* [Website](https://sonarcloud.io/)
|
||||
* Provides detailed analysis of code quality and security
|
||||
|
||||
#### Using AI Assistants with Code Quality Tools
|
||||
|
||||
When you receive feedback from these code quality tools, you can use AI assistants to help address the issues:
|
||||
|
||||
1. Copy the output from the code quality tool
|
||||
2. Paste it into your AI assistant chat
|
||||
3. Request the AI's assistance to interpret and resolve the reported issues
|
||||
4. Apply the suggested fixes
|
||||
5. Commit the changes and verify that the issues are resolved
|
||||
|
||||
Example prompt for AI assistants:
|
||||
|
||||
```text
|
||||
I received the following feedback from [Tool Name]. Please help me understand and resolve these issues:
|
||||
|
||||
[Paste the tool output here]
|
||||
```
|
||||
|
||||
## Development Environment
|
||||
|
||||
To set up your development environment:
|
||||
|
||||
1. Clone the repository: `git clone https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding.git`
|
||||
2. Install dependencies: `composer install && npm install`
|
||||
3. Start the development environment: `npm run start`
|
||||
|
||||
### Testing
|
||||
|
||||
Before submitting a pull request, make sure to run the tests:
|
||||
|
||||
* PHP Unit Tests: `npm run test:php`
|
||||
* End-to-End Tests: `npm run test:e2e`
|
||||
* Coding Standards: `npm run lint:php`
|
||||
|
||||
#### Code Quality Checks
|
||||
|
||||
To ensure your code meets the quality standards, run these commands before submitting a pull request:
|
||||
|
||||
* Check coding standards: `composer run phpcs`
|
||||
* Fix coding standards automatically: `composer run phpcbf`
|
||||
* Check JavaScript coding standards: `npm run lint:js`
|
||||
* Check CSS coding standards: `npm run lint:css`
|
||||
|
||||
These checks will assist in identifying and resolving issues before they are caught by the automated code quality tools in the pull request process.
|
||||
|
||||
## Documentation
|
||||
|
||||
If you're adding a new feature or changing existing functionality, please update the documentation:
|
||||
|
||||
* Update the README.md file if necessary
|
||||
* Update the readme.txt file if necessary
|
||||
* Update or create wiki pages as needed
|
||||
* Update code comments
|
||||
|
||||
## Community
|
||||
|
||||
Join our community to discuss the project:
|
||||
|
||||
* [GitHub Discussions](https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding/discussions)
|
||||
* [Gitea Issues](https://gitea.wpallstars.com/wpallstars/wp-plugin-starter-template-for-ai-coding/issues)
|
||||
|
||||
## Recognition
|
||||
|
||||
Contributors will be recognized in the following ways:
|
||||
|
||||
* Added to the contributors list in readme.txt
|
||||
* Mentioned in release notes for significant contributions
|
||||
* Thanked in the Changelog for specific contributions
|
||||
|
||||
## License
|
||||
|
||||
By contributing to this project, you agree that your contributions will be licensed under the project's [GPL-2.0+ License](https://www.gnu.org/licenses/gpl-2.0.html).
|
||||
|
||||
## Questions?
|
||||
|
||||
If you have any questions about contributing, please open an issue or contact the maintainers.
|
||||
|
||||
Thank you for your contributions!
|
||||
162
.wiki/Customization-Guide.md
Normal file
162
.wiki/Customization-Guide.md
Normal file
@@ -0,0 +1,162 @@
|
||||
# Customization Guide
|
||||
|
||||
This guide provides detailed instructions on how to customize the plugin starter template for your specific needs.
|
||||
|
||||
## Basic Customization
|
||||
|
||||
### Renaming the Plugin
|
||||
|
||||
1. **Main Plugin File**: Rename `wp-plugin-starter-template.php` to match your plugin name (e.g., `my-awesome-plugin.php`)
|
||||
|
||||
2. **Update Plugin Header**: Edit the plugin header in your main plugin file:
|
||||
```php
|
||||
/**
|
||||
* Plugin Name: My Awesome Plugin
|
||||
* Plugin URI: https://www.example.com
|
||||
* Description: A brief description of your plugin
|
||||
* Version: 0.1.0
|
||||
* Author: Your Name
|
||||
* Author URI: https://www.example.com
|
||||
* License: GPL-2.0+
|
||||
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
* Text Domain: my-awesome-plugin
|
||||
* Domain Path: /languages
|
||||
*/
|
||||
```
|
||||
|
||||
3. **Update Text Domain**: Change the text domain throughout the codebase from `wp-plugin-starter-template` to your plugin's text domain
|
||||
|
||||
### Updating Namespaces
|
||||
|
||||
1. **Change Namespace**: Update all namespace references from `WPALLSTARS\PluginStarterTemplate` to your own namespace (e.g., `MyCompany\MyAwesomePlugin`)
|
||||
|
||||
2. **Update Autoloading**: Modify the `composer.json` file to reflect your new namespace:
|
||||
```json
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"MyCompany\\MyAwesomePlugin\\": "includes/"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. **Run Composer**: After updating the namespace, run `composer dump-autoload` to update the autoloader
|
||||
|
||||
### Customizing Documentation
|
||||
|
||||
1. **README.md**: Update the README.md file with your plugin's information
|
||||
2. **readme.txt**: Update the readme.txt file for WordPress.org compatibility
|
||||
3. **CHANGELOG.md**: Start a fresh changelog for your plugin
|
||||
4. **Wiki Documentation**: Customize the wiki documentation to match your plugin
|
||||
|
||||
## Advanced Customization
|
||||
|
||||
### Adding Custom Functionality
|
||||
|
||||
1. **Core Functionality**: Modify the `includes/core.php` file to implement your core functionality
|
||||
|
||||
2. **Admin Interface**: Customize the `admin/lib/admin.php` file to create your admin interface
|
||||
|
||||
3. **Frontend Features**: Add frontend functionality as needed
|
||||
|
||||
### Customizing Assets
|
||||
|
||||
1. **CSS**: Modify or add stylesheets in the `assets/css/` directory
|
||||
2. **JavaScript**: Customize JavaScript files in the `assets/js/` directory
|
||||
3. **Images**: Add your own images to the `assets/images/` directory
|
||||
|
||||
### Adding Custom Post Types
|
||||
|
||||
If your plugin needs custom post types, add them to the Core class:
|
||||
|
||||
```php
|
||||
public function register_post_types() {
|
||||
register_post_type('my_custom_post', [
|
||||
'labels' => [
|
||||
'name' => __('Custom Posts', 'my-awesome-plugin'),
|
||||
'singular_name' => __('Custom Post', 'my-awesome-plugin'),
|
||||
],
|
||||
'public' => true,
|
||||
'has_archive' => true,
|
||||
'supports' => ['title', 'editor', 'thumbnail'],
|
||||
'menu_icon' => 'dashicons-admin-post',
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
### Adding Custom Taxonomies
|
||||
|
||||
For custom taxonomies, add them to the Core class:
|
||||
|
||||
```php
|
||||
public function register_taxonomies() {
|
||||
register_taxonomy('custom_category', 'my_custom_post', [
|
||||
'labels' => [
|
||||
'name' => __('Custom Categories', 'my-awesome-plugin'),
|
||||
'singular_name' => __('Custom Category', 'my-awesome-plugin'),
|
||||
],
|
||||
'hierarchical' => true,
|
||||
'show_admin_column' => true,
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
### Adding Settings Pages
|
||||
|
||||
To add a settings page, customize the Admin class:
|
||||
|
||||
```php
|
||||
public function add_menu_pages() {
|
||||
add_menu_page(
|
||||
__('My Plugin Settings', 'my-awesome-plugin'),
|
||||
__('My Plugin', 'my-awesome-plugin'),
|
||||
'manage_options',
|
||||
'my-awesome-plugin',
|
||||
[$this, 'render_settings_page'],
|
||||
'dashicons-admin-generic',
|
||||
100
|
||||
);
|
||||
}
|
||||
|
||||
public function render_settings_page() {
|
||||
include plugin_dir_path(__FILE__) . '../templates/settings-page.php';
|
||||
}
|
||||
```
|
||||
|
||||
### Customizing Update Mechanism
|
||||
|
||||
The template includes functionality for updates from different sources. Customize the update source options in the main plugin file:
|
||||
|
||||
```php
|
||||
/**
|
||||
* GitHub Plugin URI: username/repository
|
||||
* GitHub Branch: main
|
||||
* Primary Branch: main
|
||||
* Release Branch: main
|
||||
* Release Asset: true
|
||||
* Requires at least: 5.0
|
||||
* Requires PHP: 7.0
|
||||
* Update URI: https://example.com/plugin-updates
|
||||
*/
|
||||
```
|
||||
|
||||
## Testing Your Customizations
|
||||
|
||||
After making your customizations, it's important to test your plugin:
|
||||
|
||||
1. **Unit Tests**: Update and run the unit tests to ensure your core functionality works correctly
|
||||
2. **End-to-End Tests**: Update and run the end-to-end tests to test the plugin as a whole
|
||||
3. **Manual Testing**: Test your plugin in different WordPress environments
|
||||
|
||||
## Building Your Plugin
|
||||
|
||||
Once you've customized the plugin to your needs, build it for distribution:
|
||||
|
||||
```bash
|
||||
./build.sh {VERSION}
|
||||
```
|
||||
|
||||
This will create a ZIP file that you can install in WordPress or distribute to users.
|
||||
|
||||
## Conclusion
|
||||
|
||||
By following this customization guide, you can transform the plugin starter template into a fully functional plugin that meets your specific needs. Remember to maintain the same level of code quality and documentation as you customize the template.
|
||||
126
.wiki/Error-Checking-Feedback-Loops.md
Normal file
126
.wiki/Error-Checking-Feedback-Loops.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# Error Checking and Feedback Loops
|
||||
|
||||
This document explains how to check for code quality issues and get feedback from automated tools in our development workflow.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Overview](#overview)
|
||||
* [Local Error Checking](#local-error-checking)
|
||||
* [CI/CD Feedback Loops](#cicd-feedback-loops)
|
||||
* [Common Issues and Solutions](#common-issues-and-solutions)
|
||||
* [Improving Code Quality](#improving-code-quality)
|
||||
|
||||
## Overview
|
||||
|
||||
Our development process includes multiple layers of error checking and feedback loops to ensure high code quality:
|
||||
|
||||
1. **Local Development**: Run linters and tests locally before committing
|
||||
2. **Pull Request**: Automated checks run when you create or update a PR
|
||||
3. **Code Review**: Human reviewers provide feedback on your code
|
||||
4. **Continuous Integration**: Tests run in various environments to ensure compatibility
|
||||
|
||||
## Local Error Checking
|
||||
|
||||
### PHP Code Quality Checks
|
||||
|
||||
Run these commands locally to check for PHP code quality issues:
|
||||
|
||||
```bash
|
||||
# Run all PHP code quality checks
|
||||
npm run lint:php
|
||||
|
||||
# Run specific checks
|
||||
npm run lint:phpcs # PHP CodeSniffer
|
||||
npm run lint:phpstan # PHPStan static analysis
|
||||
npm run lint:phpmd # PHP Mess Detector
|
||||
```
|
||||
|
||||
### JavaScript/CSS Checks
|
||||
|
||||
```bash
|
||||
# Run ESLint for JavaScript files
|
||||
npm run lint:js
|
||||
|
||||
# Run stylelint for CSS files
|
||||
npm run lint:css
|
||||
```
|
||||
|
||||
### Running Tests Locally
|
||||
|
||||
```bash
|
||||
# Run Cypress tests for single site
|
||||
npm run test:playground:single
|
||||
|
||||
# Run Cypress tests for multisite
|
||||
npm run test:playground:multisite
|
||||
```
|
||||
|
||||
## CI/CD Feedback Loops
|
||||
|
||||
When you push code or create a pull request, several automated checks run:
|
||||
|
||||
### GitHub Actions Workflows
|
||||
|
||||
* **Code Quality**: Runs PHP CodeSniffer, PHPStan, and PHP Mess Detector
|
||||
* **WordPress Tests**: Runs tests in WordPress environments
|
||||
* **WordPress Playground Tests**: Runs tests in WordPress Playground environments
|
||||
* **Tests - Run PHP compatibility and unit tests**: Checks compatibility with different PHP versions
|
||||
|
||||
### Third-Party Code Quality Services
|
||||
|
||||
* **CodeFactor**: Provides automated code reviews and quality grades
|
||||
* **Codacy**: Analyzes code quality and security issues
|
||||
* **SonarCloud**: Detects bugs, vulnerabilities, and code smells
|
||||
|
||||
## Common Issues and Solutions
|
||||
|
||||
### PHP CodeSniffer Issues
|
||||
|
||||
* **Indentation**: Use tabs for indentation in PHP files
|
||||
* **Spacing**: Add spaces after commas, around operators, and after control structures
|
||||
* **Naming Conventions**: Use snake_case for functions and variables in PHP
|
||||
* **DocBlocks**: Add proper documentation for functions and classes
|
||||
|
||||
### PHPStan Issues
|
||||
|
||||
* **Undefined Variables**: Ensure all variables are defined before use
|
||||
* **Type Errors**: Use proper type hints and return types
|
||||
* **Null Checks**: Add null checks for variables that might be null
|
||||
|
||||
### JavaScript/CSS Issues
|
||||
|
||||
* **ESLint Errors**: Follow JavaScript best practices
|
||||
* **Stylelint Errors**: Follow CSS best practices
|
||||
* **Accessibility Issues**: Ensure UI elements are accessible
|
||||
|
||||
## Improving Code Quality
|
||||
|
||||
### Best Practices
|
||||
|
||||
* **Write Tests First**: Use test-driven development (TDD) when possible
|
||||
* **Small PRs**: Keep pull requests small and focused on a single issue
|
||||
* **Regular Commits**: Commit frequently with clear messages
|
||||
* **Code Reviews**: Request code reviews from team members
|
||||
* **Documentation**: Keep documentation up-to-date
|
||||
|
||||
### Using AI Assistants
|
||||
|
||||
AI assistants can help you understand and fix code quality issues:
|
||||
|
||||
1. Copy the error message or feedback
|
||||
2. Paste it into your AI assistant chat
|
||||
3. Ask for help understanding and fixing the issue
|
||||
4. Apply the suggested fixes
|
||||
5. Run the checks again to verify the issue is resolved
|
||||
|
||||
### Continuous Learning
|
||||
|
||||
* Review the code quality reports regularly
|
||||
* Learn from feedback and improve your coding practices
|
||||
* Stay updated on best practices for WordPress development
|
||||
|
||||
## Related Documentation
|
||||
|
||||
* [Testing Framework](Testing.md)
|
||||
* [Code Review Guide](../.ai-workflows/code-review.md)
|
||||
* [Architecture Overview](Architecture-Overview.md)
|
||||
190
.wiki/Extending-the-Plugin.md
Normal file
190
.wiki/Extending-the-Plugin.md
Normal file
@@ -0,0 +1,190 @@
|
||||
# Extending the Plugin
|
||||
|
||||
This guide explains how to extend the plugin's functionality through various extension points.
|
||||
|
||||
## Extension Points
|
||||
|
||||
The plugin is designed with extensibility in mind, providing several ways to extend or modify its functionality:
|
||||
|
||||
1. **Action Hooks**: Add custom functionality at specific points
|
||||
2. **Filter Hooks**: Modify data or behavior
|
||||
3. **Class Extension**: Extend existing classes to add or modify functionality
|
||||
4. **Template Overrides**: Customize the plugin's output
|
||||
|
||||
## Using Action Hooks
|
||||
|
||||
Action hooks allow you to add custom functionality at specific points in the plugin's execution. Here are some examples:
|
||||
|
||||
### Available Actions
|
||||
|
||||
- `wpst_plugin_init`: Fires when the plugin is initialized
|
||||
- `wpst_before_process`: Fires before the plugin processes data
|
||||
- `wpst_after_process`: Fires after the plugin processes data
|
||||
- `wpst_admin_init`: Fires when the admin functionality is initialized
|
||||
|
||||
### Example: Adding Custom Functionality
|
||||
|
||||
```php
|
||||
add_action('wpst_plugin_init', 'my_custom_init_function');
|
||||
|
||||
function my_custom_init_function() {
|
||||
// Your custom initialization code here
|
||||
}
|
||||
```
|
||||
|
||||
### Example: Adding Custom Admin Functionality
|
||||
|
||||
```php
|
||||
add_action('wpst_admin_init', 'my_custom_admin_function');
|
||||
|
||||
function my_custom_admin_function() {
|
||||
// Your custom admin initialization code here
|
||||
}
|
||||
```
|
||||
|
||||
## Using Filter Hooks
|
||||
|
||||
Filter hooks allow you to modify data or behavior at specific points. Here are some examples:
|
||||
|
||||
### Available Filters
|
||||
|
||||
- `wpst_settings`: Filter the plugin settings
|
||||
- `wpst_process_data`: Filter the data being processed
|
||||
- `wpst_admin_tabs`: Filter the admin tabs
|
||||
- `wpst_display_output`: Filter the output before display
|
||||
|
||||
### Example: Modifying Settings
|
||||
|
||||
```php
|
||||
add_filter('wpst_settings', 'my_custom_settings_filter');
|
||||
|
||||
function my_custom_settings_filter($settings) {
|
||||
// Modify the settings array
|
||||
$settings['custom_option'] = 'custom_value';
|
||||
return $settings;
|
||||
}
|
||||
```
|
||||
|
||||
### Example: Modifying Output
|
||||
|
||||
```php
|
||||
add_filter('wpst_display_output', 'my_custom_output_filter');
|
||||
|
||||
function my_custom_output_filter($output) {
|
||||
// Modify the output
|
||||
$output = str_replace('original', 'modified', $output);
|
||||
return $output;
|
||||
}
|
||||
```
|
||||
|
||||
## Extending Classes
|
||||
|
||||
You can extend the plugin's classes to add or modify functionality.
|
||||
|
||||
### Example: Extending the Core Class
|
||||
|
||||
```php
|
||||
use WPALLSTARS\PluginStarterTemplate\Core;
|
||||
|
||||
class My_Extended_Core extends Core {
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
// Add your custom initialization here
|
||||
}
|
||||
|
||||
// Override an existing method
|
||||
public function filter_content($content) {
|
||||
// Modify the content
|
||||
$content = parent::filter_content($content);
|
||||
$content = str_replace('original', 'modified', $content);
|
||||
return $content;
|
||||
}
|
||||
|
||||
// Add a new method
|
||||
public function custom_method() {
|
||||
// Your custom method implementation
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Example: Extending the Admin Class
|
||||
|
||||
```php
|
||||
use WPALLSTARS\PluginStarterTemplate\Admin\Admin;
|
||||
|
||||
class My_Extended_Admin extends Admin {
|
||||
public function __construct($core) {
|
||||
parent::__construct($core);
|
||||
// Add your custom initialization here
|
||||
}
|
||||
|
||||
// Override an existing method
|
||||
public function enqueue_admin_assets($hook) {
|
||||
parent::enqueue_admin_assets($hook);
|
||||
// Add your custom assets
|
||||
wp_enqueue_script(
|
||||
'my-custom-script',
|
||||
plugin_dir_url(__FILE__) . 'js/custom-script.js',
|
||||
['jquery'],
|
||||
'1.0.0',
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// Add a new method
|
||||
public function custom_admin_method() {
|
||||
// Your custom method implementation
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Creating Add-ons
|
||||
|
||||
You can create separate add-on plugins that extend the functionality of the main plugin.
|
||||
|
||||
### Example: Basic Add-on Structure
|
||||
|
||||
```php
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: My Awesome Add-on
|
||||
* Description: Extends the WordPress Plugin Starter Template with awesome features
|
||||
* Version: 1.0.0
|
||||
* Author: Your Name
|
||||
* License: GPL-2.0+
|
||||
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
* Text Domain: my-awesome-addon
|
||||
* Requires: WordPress Plugin Starter Template
|
||||
*/
|
||||
|
||||
// Check if the main plugin is active
|
||||
if (!class_exists('WPALLSTARS\\PluginStarterTemplate\\Plugin')) {
|
||||
add_action('admin_notices', 'my_addon_missing_main_plugin_notice');
|
||||
return;
|
||||
}
|
||||
|
||||
function my_addon_missing_main_plugin_notice() {
|
||||
echo '<div class="error"><p>';
|
||||
echo __('My Awesome Add-on requires the WordPress Plugin Starter Template to be installed and activated.', 'my-awesome-addon');
|
||||
echo '</p></div>';
|
||||
}
|
||||
|
||||
// Initialize the add-on
|
||||
add_action('wpst_plugin_init', 'initialize_my_addon');
|
||||
|
||||
function initialize_my_addon() {
|
||||
// Your add-on initialization code here
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices for Extensions
|
||||
|
||||
1. **Use Namespaces**: Use PHP namespaces to avoid conflicts with other plugins
|
||||
2. **Follow Coding Standards**: Maintain the same coding standards as the main plugin
|
||||
3. **Document Your Extensions**: Provide clear documentation for your extensions
|
||||
4. **Test Thoroughly**: Test your extensions with different WordPress versions
|
||||
5. **Version Compatibility**: Specify which versions of the main plugin your extension is compatible with
|
||||
|
||||
## Conclusion
|
||||
|
||||
By using these extension points, you can customize and extend the plugin's functionality to meet your specific needs without modifying the core plugin files. This approach ensures that your customizations will continue to work even when the main plugin is updated.
|
||||
@@ -11,6 +11,7 @@ The WordPress Plugin Starter Template is a comprehensive starting point for deve
|
||||
### Who is this template for?
|
||||
|
||||
This template is designed for:
|
||||
|
||||
- WordPress plugin developers looking for a solid foundation
|
||||
- Developers who want to leverage AI assistance in their development workflow
|
||||
- Anyone who wants to create a WordPress plugin following best practices
|
||||
@@ -79,8 +80,8 @@ To configure the update mechanism:
|
||||
|
||||
The template includes:
|
||||
|
||||
1. Detailed documentation in the `.ai-assistant.md` file
|
||||
2. Workflow guidelines in the `.ai-workflows/` directory
|
||||
1. Detailed documentation in the `AGENTS.md` file
|
||||
2. Workflow guidelines in the `.agents/` directory
|
||||
3. Clear code structure and comments that help AI understand the codebase
|
||||
4. Best practices for AI-friendly code organization
|
||||
|
||||
@@ -95,7 +96,7 @@ This template is designed to work well with various AI coding assistants, includ
|
||||
|
||||
### How do I use the AI workflow documentation?
|
||||
|
||||
The AI workflow documentation in the `.ai-workflows/` directory provides guidelines for AI assistants working with this template. These files help ensure consistent, high-quality code and documentation when using AI tools for development.
|
||||
The AI workflow documentation in the `.agents/` directory provides guidelines for AI assistants working with this template. These files help ensure consistent, high-quality code and documentation when using AI tools for development.
|
||||
|
||||
## Contributing Questions
|
||||
|
||||
|
||||
@@ -4,6 +4,11 @@ Welcome to the documentation wiki for the WordPress Plugin Starter Template.
|
||||
|
||||
This template provides a solid foundation for developing WordPress plugins with best practices for AI-assisted development.
|
||||
|
||||
## Latest Updates
|
||||
|
||||
- Version 0.1.6: Fixed GitHub Actions workflows permissions for releases and wiki sync
|
||||
- Version 0.1.5: Added testing setup with wp-env and Cypress, multisite compatibility
|
||||
|
||||
## Quick Links
|
||||
|
||||
- [Starter Prompt](Starter-Prompt)
|
||||
@@ -34,7 +39,7 @@ This template is based on the experience gained from developing the "Fix 'Plugin
|
||||
|
||||
To get started with this template, check out the [Starter Prompt](Starter-Prompt) for a comprehensive guide on customizing the template for your specific plugin needs.
|
||||
|
||||
**Important**: For the best AI assistance, add the .ai-assistant.md file and .ai-workflows/ directory to your AI IDE chat context. In most AI IDEs, you can pin these files to ensure they're considered in each message.
|
||||
**Important**: For the best AI assistance, add the AGENTS.md file and .agents/ directory to your AI IDE chat context. In most AI IDEs, you can pin these files to ensure they're considered in each message.
|
||||
|
||||
## Support
|
||||
|
||||
|
||||
175
.wiki/Multisite-Development.md
Normal file
175
.wiki/Multisite-Development.md
Normal file
@@ -0,0 +1,175 @@
|
||||
# Multisite Development
|
||||
|
||||
This guide explains how to extend the WordPress Plugin Starter Template for multisite environments.
|
||||
|
||||
## Overview
|
||||
|
||||
WordPress Multisite allows you to run multiple WordPress sites from a single installation.
|
||||
|
||||
The plugin template includes a basic structure for multisite-specific functionality.
|
||||
|
||||
You can extend this to add features for multisite environments.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
The plugin includes a dedicated directory for multisite-specific functionality:
|
||||
|
||||
```bash
|
||||
includes/
|
||||
└── Multisite/
|
||||
├── class-multisite.php # Base class for multisite functionality
|
||||
└── README.md # Documentation for multisite development
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
### 1. Understand the Base Class
|
||||
|
||||
The `Multisite` class in `includes/Multisite/class-multisite.php` provides a foundation for multisite functionality.
|
||||
|
||||
It includes:
|
||||
|
||||
* A constructor for initialization
|
||||
* Example methods for multisite functionality
|
||||
|
||||
### 2. Load Multisite Classes
|
||||
|
||||
To use multisite-specific functionality, you need to load and initialize the classes in your main plugin file:
|
||||
|
||||
```php
|
||||
// Load multisite support classes if in multisite environment
|
||||
if ( is_multisite() ) {
|
||||
require_once WP_PLUGIN_STARTER_TEMPLATE_PATH . 'includes/Multisite/class-multisite.php';
|
||||
|
||||
// Initialize multisite support
|
||||
$multisite = new WPALLSTARS\PluginStarterTemplate\Multisite\Multisite();
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Extend the Base Class
|
||||
|
||||
You can extend the base `Multisite` class or create additional classes in the `Multisite` directory.
|
||||
|
||||
This allows you to implement specific features:
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace WPALLSTARS\PluginStarterTemplate\Multisite;
|
||||
|
||||
class Domain_Mapping extends Multisite {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
// Add hooks for domain mapping functionality
|
||||
add_action( 'init', array( $this, 'register_domain_mapping' ) );
|
||||
}
|
||||
|
||||
public function register_domain_mapping() {
|
||||
// Implement domain mapping functionality
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Common Multisite Features
|
||||
|
||||
Here are some common features you might want to implement for multisite environments:
|
||||
|
||||
### Network Admin Pages
|
||||
|
||||
To add pages to the network admin menu:
|
||||
|
||||
```php
|
||||
add_action( 'network_admin_menu', array( $this, 'add_network_menu' ) );
|
||||
|
||||
public function add_network_menu() {
|
||||
add_submenu_page(
|
||||
'settings.php',
|
||||
__( 'Plugin Settings', 'your-text-domain' ),
|
||||
__( 'Plugin Settings', 'your-text-domain' ),
|
||||
'manage_network_options',
|
||||
'your-plugin-slug',
|
||||
array( $this, 'render_network_settings' )
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Site Creation Hooks
|
||||
|
||||
To perform actions when a new site is created:
|
||||
|
||||
```php
|
||||
add_action( 'wp_initialize_site', array( $this, 'on_site_creation' ), 10, 2 );
|
||||
|
||||
public function on_site_creation( $new_site, $args ) {
|
||||
// Get the blog ID
|
||||
$blog_id = $new_site->blog_id;
|
||||
|
||||
// Switch to the new blog
|
||||
switch_to_blog( $blog_id );
|
||||
|
||||
// Perform site-specific setup
|
||||
update_option( 'your_plugin_option', 'default_value' );
|
||||
|
||||
// Restore the current blog
|
||||
restore_current_blog();
|
||||
}
|
||||
```
|
||||
|
||||
### Network Settings
|
||||
|
||||
To save network-wide settings:
|
||||
|
||||
```php
|
||||
// Process network settings form
|
||||
add_action( 'network_admin_edit_your_plugin_action', array( $this, 'save_network_settings' ) );
|
||||
|
||||
public function save_network_settings() {
|
||||
// Check nonce
|
||||
check_admin_referer( 'your_plugin_nonce' );
|
||||
|
||||
// Save settings
|
||||
update_site_option( 'your_plugin_network_option', sanitize_text_field( $_POST['your_option'] ) );
|
||||
|
||||
// Redirect back to settings page
|
||||
wp_redirect( add_query_arg( array(
|
||||
'page' => 'your-plugin-slug',
|
||||
'updated' => 'true'
|
||||
), network_admin_url( 'settings.php' ) ) );
|
||||
exit;
|
||||
}
|
||||
```
|
||||
|
||||
## Testing Multisite Functionality
|
||||
|
||||
To test your multisite functionality, use the testing framework included in the plugin template:
|
||||
|
||||
```bash
|
||||
# Set up multisite environment
|
||||
npm run setup:multisite
|
||||
|
||||
# Run tests
|
||||
npm run test:multisite
|
||||
```
|
||||
|
||||
For more details on testing, see the [Testing Framework](Testing-Framework.md) documentation.
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always Check for Multisite**: Use `is_multisite()` to check if the current installation is a multisite network.
|
||||
|
||||
2. **Use Network-Specific Functions**: WordPress provides specific functions for multisite.
|
||||
Use `update_site_option()` instead of `update_option()` for network-wide settings.
|
||||
|
||||
3. **Handle Blog Switching Properly**: When working with specific sites, use `switch_to_blog()`.
|
||||
Always call `restore_current_blog()` when done.
|
||||
|
||||
4. **Respect Network Admin Capabilities**: Use capabilities like `manage_network_options` for network admin.
|
||||
|
||||
5. **Test in Both Environments**: Test in both single site and multisite to ensure compatibility.
|
||||
|
||||
## Conclusion
|
||||
|
||||
By following this guide, you can extend the WordPress Plugin Starter Template.
|
||||
|
||||
The included structure provides a solid foundation for multisite features.
|
||||
309
.wiki/Playground-Testing.md
Normal file
309
.wiki/Playground-Testing.md
Normal file
@@ -0,0 +1,309 @@
|
||||
# WordPress Playground Testing
|
||||
|
||||
This document explains how to use WordPress Playground for testing our plugin.
|
||||
|
||||
## What is WordPress Playground?
|
||||
|
||||
[WordPress Playground](https://wordpress.org/playground/) is a project that runs WordPress entirely in the browser.
|
||||
|
||||
It uses WebAssembly, which means:
|
||||
|
||||
* No server required - WordPress runs in the browser
|
||||
* Fast startup times
|
||||
* Isolated testing environment
|
||||
* Works well with CI/CD pipelines
|
||||
|
||||
## Using WordPress Playground Online
|
||||
|
||||
The easiest way to test our plugin with WordPress Playground is to use the online version:
|
||||
|
||||
1. Single site testing: [Open in WordPress Playground][playground-single]
|
||||
|
||||
2. Multisite testing: [Open in WordPress Playground][playground-multisite]
|
||||
|
||||
[playground-single]: https://playground.wordpress.net/?blueprint-url=https://raw.githubusercontent.com/wpallstars/wp-plugin-starter-template-for-ai-coding/main/playground/blueprint.json&_t=2
|
||||
[playground-multisite]: https://playground.wordpress.net/?blueprint-url=https://raw.githubusercontent.com/wpallstars/wp-plugin-starter-template-for-ai-coding/main/playground/multisite-blueprint.json&_t=2
|
||||
|
||||
Both links automatically set up WordPress with WP_DEBUG enabled and the Plugin Toggle and
|
||||
Kadence Blocks plugins pre-installed and activated.
|
||||
|
||||
The multisite link additionally enables WordPress multisite and network-activates both plugins.
|
||||
|
||||
## WP-CLI Commands for WordPress Playground
|
||||
|
||||
WordPress Playground supports WP-CLI commands for programmatic interaction.
|
||||
|
||||
Here are some useful commands for testing:
|
||||
|
||||
### General Commands
|
||||
|
||||
```bash
|
||||
# Get WordPress version
|
||||
wp core version
|
||||
|
||||
# List installed plugins
|
||||
wp plugin list
|
||||
|
||||
# Install a plugin
|
||||
wp plugin install plugin-slug
|
||||
|
||||
# Activate a plugin
|
||||
wp plugin activate plugin-slug
|
||||
|
||||
# Deactivate a plugin
|
||||
wp plugin deactivate plugin-slug
|
||||
|
||||
# Get plugin status
|
||||
wp plugin status plugin-slug
|
||||
```
|
||||
|
||||
### Multisite Commands
|
||||
|
||||
```bash
|
||||
# List all sites in the network
|
||||
wp site list
|
||||
|
||||
# Create a new site
|
||||
wp site create --slug=testsite
|
||||
|
||||
# Delete a site
|
||||
wp site delete 2
|
||||
|
||||
# Network activate a plugin
|
||||
wp plugin activate plugin-slug --network
|
||||
|
||||
# Activate a plugin for a specific site
|
||||
wp plugin activate plugin-slug --url=example.com/testsite
|
||||
|
||||
# Create a new user and add them to a site
|
||||
wp user create testuser test@example.com --role=editor
|
||||
wp user add-role testuser editor --url=example.com/testsite
|
||||
```
|
||||
|
||||
### Testing Commands
|
||||
|
||||
```bash
|
||||
# Run a specific test
|
||||
wp scaffold plugin-tests my-plugin
|
||||
wp test run --filter=test_function_name
|
||||
|
||||
# Check for PHP errors
|
||||
wp site health check
|
||||
|
||||
# Export/import content for testing
|
||||
wp export
|
||||
wp import
|
||||
```
|
||||
|
||||
## Plugin Activation in Multisite
|
||||
|
||||
In a WordPress multisite environment, there are two ways to activate plugins:
|
||||
|
||||
1. **Network Activation**: Activates a plugin for all sites in the network
|
||||
* In the WordPress admin, go to Network Admin > Plugins
|
||||
* Click "Network Activate" under the plugin
|
||||
* Or use WP-CLI:
|
||||
* To activate an already installed plugin: `wp plugin activate plugin-name --network`
|
||||
* To install and activate in one step: `wp plugin install plugin-name --activate-network`
|
||||
|
||||
2. **Per-Site Activation**: Activates a plugin for a specific site
|
||||
* In the WordPress admin, go to the specific site's admin area
|
||||
* Go to Plugins and activate the plugin for that site only
|
||||
* Or use WP-CLI: `wp plugin activate plugin-name --url=site-url`
|
||||
|
||||
Our multisite blueprint uses network activation for both the Plugin Toggle and Kadence Blocks plugins.
|
||||
|
||||
## Running Tests with WordPress Playground
|
||||
|
||||
We have two blueprints for testing:
|
||||
|
||||
1. `playground/blueprint.json` - For single site testing
|
||||
2. `playground/multisite-blueprint.json` - For multisite testing
|
||||
|
||||
To run tests with WordPress Playground:
|
||||
|
||||
1. Open the appropriate WordPress Playground link:
|
||||
* [Single site][playground-single]
|
||||
* [Multisite][playground-multisite]
|
||||
|
||||
2. Test the plugin manually in the browser
|
||||
|
||||
## Local Testing with HTML Files
|
||||
|
||||
We've also included HTML files that embed WordPress Playground:
|
||||
|
||||
1. Open `playground/index.html` in your browser for single site testing
|
||||
2. Open `playground/multisite.html` in your browser for multisite testing
|
||||
3. Open `playground/test.html` in your browser for a unified interface with buttons
|
||||
to switch between single site and multisite
|
||||
|
||||
You can serve these files locally with a simple HTTP server:
|
||||
|
||||
```bash
|
||||
# Using Python
|
||||
python -m http.server 8888 --directory playground
|
||||
|
||||
# Then open http://localhost:8888/index.html in your browser
|
||||
# Or open http://localhost:8888/multisite.html for multisite testing
|
||||
```
|
||||
|
||||
### Using wp-now
|
||||
|
||||
Alternatively, you can use [wp-now](https://github.com/WordPress/playground-tools/tree/trunk/packages/wp-now).
|
||||
|
||||
This tool from the WordPress Playground team makes it easy to run WordPress locally:
|
||||
|
||||
```bash
|
||||
# Install wp-now globally
|
||||
npm install -g @wp-playground/wp-now
|
||||
|
||||
# Start a WordPress instance with the current plugin
|
||||
wp-now start
|
||||
|
||||
# Start with multisite enabled
|
||||
wp-now start --multisite
|
||||
|
||||
# Start with specific PHP and WordPress versions
|
||||
wp-now start --php 8.0 --wp 6.2
|
||||
|
||||
# Start with WP_DEBUG enabled
|
||||
wp-now start --wp-debug
|
||||
```
|
||||
|
||||
This will start a local WordPress instance with your plugin installed and activated.
|
||||
|
||||
## Customizing Blueprints
|
||||
|
||||
You can customize the blueprints to suit your testing needs.
|
||||
|
||||
See the [WordPress Playground Blueprints documentation][blueprints-docs] for details.
|
||||
|
||||
[blueprints-docs]: https://wordpress.github.io/wordpress-playground/blueprints/
|
||||
|
||||
## WordPress Playground JavaScript API
|
||||
|
||||
WordPress Playground provides a JavaScript API for programmatic interaction with WordPress.
|
||||
|
||||
This is useful for automated testing and CI/CD integration.
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```javascript
|
||||
// Import the WordPress Playground client
|
||||
import { createWordPressPlayground } from '@wp-playground/client';
|
||||
|
||||
// Create a playground instance
|
||||
const playground = await createWordPressPlayground({
|
||||
iframe: document.getElementById('wp-playground'),
|
||||
remoteUrl: 'https://playground.wordpress.net/remote.html',
|
||||
});
|
||||
|
||||
// Run a blueprint
|
||||
await playground.run({
|
||||
steps: [
|
||||
{ step: 'enableMultisite' },
|
||||
{ step: 'wp-cli', command: 'wp site create --slug=testsite' },
|
||||
{ step: 'wp-cli', command: 'wp plugin install plugin-toggle kadence-blocks --activate-network' }
|
||||
]
|
||||
});
|
||||
|
||||
// Run WP-CLI commands
|
||||
const result = await playground.run({
|
||||
step: 'wp-cli',
|
||||
command: 'wp plugin list --format=json'
|
||||
});
|
||||
|
||||
// Parse the JSON output
|
||||
const plugins = JSON.parse(result.output);
|
||||
console.log(plugins);
|
||||
```
|
||||
|
||||
### Automated Testing
|
||||
|
||||
You can use the JavaScript API with testing frameworks like Jest or Cypress:
|
||||
|
||||
```javascript
|
||||
describe('Plugin Tests', () => {
|
||||
let playground;
|
||||
|
||||
beforeAll(async () => {
|
||||
playground = await createWordPressPlayground({
|
||||
iframe: document.getElementById('wp-playground'),
|
||||
remoteUrl: 'https://playground.wordpress.net/remote.html',
|
||||
});
|
||||
|
||||
// Set up WordPress with our blueprint
|
||||
await playground.run({
|
||||
steps: [
|
||||
{ step: 'enableMultisite' },
|
||||
{ step: 'wp-cli', command: 'wp site create --slug=testsite' },
|
||||
{ step: 'wp-cli', command: 'wp plugin install plugin-toggle kadence-blocks --activate-network' }
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
test('Plugin is activated', async () => {
|
||||
const result = await playground.run({
|
||||
step: 'wp-cli',
|
||||
command: 'wp plugin list --format=json'
|
||||
});
|
||||
|
||||
const plugins = JSON.parse(result.output);
|
||||
const pluginToggle = plugins.find(plugin => plugin.name === 'plugin-toggle');
|
||||
expect(pluginToggle.status).toBe('active');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
We have a GitHub Actions workflow that uses WordPress Playground for testing.
|
||||
|
||||
See `.github/workflows/playground-tests.yml` for details.
|
||||
|
||||
### Example GitHub Actions Workflow
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
playground-test:
|
||||
name: WordPress Playground Tests
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Install WordPress Playground CLI
|
||||
run: npm install -g @wordpress/playground-tools
|
||||
|
||||
- name: Create plugin zip
|
||||
run: |
|
||||
mkdir -p dist
|
||||
zip -r dist/plugin.zip . -x "node_modules/*" "dist/*" ".git/*"
|
||||
|
||||
- name: Run tests with WordPress Playground
|
||||
run: |
|
||||
# Start WordPress Playground with our blueprint
|
||||
wp-playground start --blueprint playground/blueprint.json --port 8888 &
|
||||
|
||||
# Wait for WordPress Playground to be ready
|
||||
echo "Waiting for WordPress Playground to be ready..."
|
||||
timeout 60 bash -c 'until curl -s http://localhost:8888; do sleep 2; done'
|
||||
|
||||
# Run Cypress tests against WordPress Playground
|
||||
npm run test:single:headless
|
||||
```
|
||||
|
||||
## Performance Testing
|
||||
|
||||
We also use [WP Performance Tests GitHub Action](https://github.com/marketplace/actions/wp-performance-tests).
|
||||
|
||||
This action tests our plugin against various WordPress and PHP versions to ensure good performance.
|
||||
180
.wiki/Release-Process.md
Normal file
180
.wiki/Release-Process.md
Normal file
@@ -0,0 +1,180 @@
|
||||
# Release Process
|
||||
|
||||
This document outlines the process for creating and publishing new releases of the plugin.
|
||||
|
||||
## Version Numbering
|
||||
|
||||
This plugin follows [Semantic Versioning](https://semver.org/) (SemVer):
|
||||
|
||||
- **MAJOR version** (x.0.0): Incompatible API changes
|
||||
- **MINOR version** (0.x.0): Add functionality in a backward-compatible manner
|
||||
- **PATCH version** (0.0.x): Backward-compatible bug fixes
|
||||
|
||||
## Pre-Release Checklist
|
||||
|
||||
Before creating a new release, complete the following checklist:
|
||||
|
||||
1. **Code Review**: Ensure all code has been reviewed and approved
|
||||
2. **Testing**: Verify that all tests pass
|
||||
- Unit tests
|
||||
- End-to-end tests
|
||||
- Manual testing in different environments
|
||||
3. **Documentation**: Update all relevant documentation
|
||||
- README.md
|
||||
- readme.txt
|
||||
- Wiki pages
|
||||
- Code comments
|
||||
4. **Changelog**: Update CHANGELOG.md with all changes since the last release
|
||||
5. **Version Numbers**: Update version numbers in:
|
||||
- Main plugin file header
|
||||
- Plugin initialization
|
||||
- readme.txt
|
||||
- package.json (if applicable)
|
||||
- composer.json (if applicable)
|
||||
|
||||
## Creating a Release
|
||||
|
||||
### Manual Release Process
|
||||
|
||||
1. **Create a Release Branch**:
|
||||
```bash
|
||||
git checkout -b release/x.y.z
|
||||
```
|
||||
|
||||
2. **Update Version Numbers**:
|
||||
- Update the version number in the main plugin file header
|
||||
- Update the version number in the plugin initialization
|
||||
- Update the "Stable tag" in readme.txt
|
||||
- Update the version in package.json and composer.json (if applicable)
|
||||
|
||||
3. **Update Changelog**:
|
||||
- Add a new section to CHANGELOG.md for the new version
|
||||
- Add a new section to the Changelog in readme.txt
|
||||
- Add a new section to the Upgrade Notice in readme.txt
|
||||
|
||||
4. **Commit Changes**:
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Bump version to x.y.z"
|
||||
```
|
||||
|
||||
5. **Create a Pull Request**:
|
||||
- Push the release branch to GitHub
|
||||
- Create a pull request against the main branch
|
||||
- Have the pull request reviewed and approved
|
||||
|
||||
6. **Merge the Pull Request**:
|
||||
- Merge the pull request into the main branch
|
||||
|
||||
7. **Create a Release Tag**:
|
||||
```bash
|
||||
git checkout main
|
||||
git pull
|
||||
git tag -a vx.y.z -m "Version x.y.z"
|
||||
git push origin vx.y.z
|
||||
```
|
||||
|
||||
8. **Create a GitHub Release**:
|
||||
- Go to the GitHub repository
|
||||
- Click on "Releases"
|
||||
- Click "Draft a new release"
|
||||
- Select the tag you just created
|
||||
- Add a title and description
|
||||
- Upload the built plugin ZIP file
|
||||
- Publish the release
|
||||
|
||||
### Automated Release Process
|
||||
|
||||
This plugin uses GitHub Actions to automate the release process:
|
||||
|
||||
1. **Create a Release Branch**:
|
||||
```bash
|
||||
git checkout -b release/x.y.z
|
||||
```
|
||||
|
||||
2. **Update Version Numbers and Changelog** (as described above)
|
||||
|
||||
3. **Commit Changes**:
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Bump version to x.y.z"
|
||||
```
|
||||
|
||||
4. **Create a Pull Request** (as described above)
|
||||
|
||||
5. **Merge the Pull Request** (as described above)
|
||||
|
||||
6. **Create a Release Tag**:
|
||||
```bash
|
||||
git checkout main
|
||||
git pull
|
||||
git tag -a vx.y.z -m "Version x.y.z"
|
||||
git push origin vx.y.z
|
||||
```
|
||||
|
||||
7. **Automated GitHub Release**:
|
||||
- The GitHub Actions workflow will automatically:
|
||||
- Build the plugin
|
||||
- Create a GitHub release
|
||||
- Upload the built plugin ZIP file
|
||||
- Update the wiki (if configured)
|
||||
|
||||
## Post-Release Tasks
|
||||
|
||||
After creating a release, complete the following tasks:
|
||||
|
||||
1. **Verify the Release**:
|
||||
- Check that the GitHub release was created successfully
|
||||
- Download the ZIP file and verify its contents
|
||||
- Test the plugin by installing it from the ZIP file
|
||||
|
||||
2. **Update Documentation**:
|
||||
- Update any external documentation that references the plugin version
|
||||
- Update the plugin's website (if applicable)
|
||||
|
||||
3. **Announce the Release**:
|
||||
- Announce the release on relevant channels (blog, social media, etc.)
|
||||
- Notify users who have reported issues that are fixed in this release
|
||||
|
||||
4. **Start Planning the Next Release**:
|
||||
- Create issues for the next release
|
||||
- Update the project roadmap
|
||||
|
||||
## Hotfix Process
|
||||
|
||||
For critical bugs that need to be fixed immediately:
|
||||
|
||||
1. **Create a Hotfix Branch**:
|
||||
```bash
|
||||
git checkout -b hotfix/x.y.z
|
||||
```
|
||||
|
||||
2. **Fix the Bug**:
|
||||
- Make the necessary changes to fix the bug
|
||||
- Add tests to prevent regression
|
||||
|
||||
3. **Update Version Numbers and Changelog** (as described above)
|
||||
|
||||
4. **Commit Changes**:
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Hotfix: description of the fix"
|
||||
```
|
||||
|
||||
5. **Create a Pull Request** (as described above)
|
||||
|
||||
6. **Merge the Pull Request** (as described above)
|
||||
|
||||
7. **Create a Release Tag and GitHub Release** (as described above)
|
||||
|
||||
## Release Branches
|
||||
|
||||
This plugin uses the following branch strategy:
|
||||
|
||||
- **main**: The main development branch
|
||||
- **release/x.y.z**: Temporary branches for preparing releases
|
||||
- **hotfix/x.y.z**: Temporary branches for hotfixes
|
||||
|
||||
## Conclusion
|
||||
|
||||
Following this release process ensures that releases are consistent, well-documented, and properly tested. It also helps users understand what has changed between versions and how to upgrade safely.
|
||||
@@ -4,7 +4,7 @@ This document provides a comprehensive prompt to help you get started with creat
|
||||
|
||||
## Important: Optimize AI Context
|
||||
|
||||
**Before starting, add the .ai-assistant.md file and .ai-workflows/ directory to your AI IDE chat context.** In most AI IDEs, you can pin these files to ensure they're considered in each message. This will help the AI understand the project structure and follow the established best practices.
|
||||
**Before starting, add the AGENTS.md file and .agents/ directory to your AI IDE chat context.** In most AI IDEs, you can pin these files to ensure they're considered in each message. This will help the AI understand the project structure and follow the established best practices.
|
||||
|
||||
## Initial Setup Prompt
|
||||
|
||||
@@ -35,7 +35,7 @@ I need help with the following tasks:
|
||||
2. Customizing the plugin structure for my specific needs
|
||||
3. Setting up the initial functionality for my plugin
|
||||
|
||||
I've added the .ai-assistant.md and .ai-workflows/ directory to the chat context to ensure you have all the necessary information about the project structure and best practices.
|
||||
I've added the AGENTS.md and .agents/ directory to the chat context to ensure you have all the necessary information about the project structure and best practices.
|
||||
|
||||
Please guide me through this process step by step, starting with identifying all files that need to be updated with my plugin information.
|
||||
```
|
||||
@@ -52,7 +52,7 @@ The AI will help you identify and update the following files with your plugin in
|
||||
6. **languages/pot file**: Rename and update the POT file
|
||||
7. **.github/workflows/**: Update GitHub Actions workflows with your repository information
|
||||
8. **.wiki/**: Update wiki documentation with your plugin information
|
||||
9. **.ai-assistant.md**: Update AI assistant guidance for your specific plugin
|
||||
9. **AGENTS.md**: Update AI assistant guidance for your specific plugin
|
||||
10. **includes/plugin.php**: Update namespace and class references
|
||||
11. **includes/core.php**: Update namespace and customize core functionality
|
||||
12. **admin/lib/admin.php**: Update namespace and customize admin functionality
|
||||
@@ -174,7 +174,7 @@ Please guide me through the process of building and testing my plugin:
|
||||
To ensure the AI assistant has all the necessary context about your plugin's structure and best practices:
|
||||
|
||||
```
|
||||
Please add the .ai-assistant.md and .ai-workflows/ directory to your AI IDE chat context. In most AI IDEs, you can pin these files to ensure they're considered in each message. This will help the AI understand the project structure and follow the established best practices.
|
||||
Please add the AGENTS.md and .agents/ directory to your AI IDE chat context. In most AI IDEs, you can pin these files to ensure they're considered in each message. This will help the AI understand the project structure and follow the established best practices.
|
||||
```
|
||||
|
||||
## Remember
|
||||
@@ -183,7 +183,7 @@ Please add the .ai-assistant.md and .ai-workflows/ directory to your AI IDE chat
|
||||
- The AI assistant can help you understand the existing code and make appropriate modifications, but you should review all changes to ensure they meet your requirements.
|
||||
- Always test your plugin thoroughly before releasing it.
|
||||
- Keep documentation updated as you develop your plugin.
|
||||
- Pin the .ai-assistant.md and .ai-workflows/ files in your AI IDE chat to ensure the AI has the necessary context for each interaction.
|
||||
- Pin the AGENTS.md and .agents/ files in your AI IDE chat to ensure the AI has the necessary context for each interaction.
|
||||
|
||||
## Credits
|
||||
|
||||
|
||||
142
.wiki/Testing-Framework.md
Normal file
142
.wiki/Testing-Framework.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# WordPress Plugin Testing Framework
|
||||
|
||||
This document outlines how to set up and run tests for our plugin.
|
||||
|
||||
It covers both single site and multisite WordPress environments.
|
||||
|
||||
## Overview
|
||||
|
||||
Our plugin is designed to work with both standard WordPress installations and WordPress Multisite.
|
||||
|
||||
This testing framework allows you to verify functionality in both environments.
|
||||
|
||||
## Setting Up the Test Environment
|
||||
|
||||
We use `@wordpress/env` and Cypress for testing our plugin.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* Node.js (v14 or higher)
|
||||
* npm or yarn
|
||||
* Docker and Docker Compose
|
||||
|
||||
### Installation
|
||||
|
||||
1. Clone the repository:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding.git
|
||||
cd wp-plugin-starter-template-for-ai-coding
|
||||
```
|
||||
|
||||
2. Install dependencies:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
## Testing in Single Site WordPress
|
||||
|
||||
1. Set up the single site environment:
|
||||
|
||||
```bash
|
||||
npm run setup:single
|
||||
```
|
||||
|
||||
This will:
|
||||
* Start a WordPress environment using wp-env
|
||||
* Activate our plugin
|
||||
|
||||
2. Run Cypress tests for single site:
|
||||
|
||||
```bash
|
||||
npm run test:single
|
||||
```
|
||||
|
||||
For headless testing:
|
||||
|
||||
```bash
|
||||
npm run test:single:headless
|
||||
```
|
||||
|
||||
3. Access the site manually:
|
||||
* Site: <http://localhost:8888>
|
||||
* Admin login: admin / password
|
||||
|
||||
## Testing in WordPress Multisite
|
||||
|
||||
1. Set up the multisite environment:
|
||||
|
||||
```bash
|
||||
npm run setup:multisite
|
||||
```
|
||||
|
||||
This will:
|
||||
* Start a WordPress environment using wp-env
|
||||
* Configure it as a multisite installation
|
||||
* Create a test subsite
|
||||
* Network activate our plugin
|
||||
|
||||
2. Run Cypress tests for multisite:
|
||||
|
||||
```bash
|
||||
npm run test:multisite
|
||||
```
|
||||
|
||||
For headless testing:
|
||||
|
||||
```bash
|
||||
npm run test:multisite:headless
|
||||
```
|
||||
|
||||
3. Access the sites manually:
|
||||
* Main site: <http://localhost:8888>
|
||||
* Test subsite: <http://localhost:8888/testsite>
|
||||
* Admin login: admin / password
|
||||
|
||||
## Continuous Integration
|
||||
|
||||
We use GitHub Actions to automatically run tests on pull requests.
|
||||
|
||||
The workflow is defined in `.github/workflows/wordpress-tests.yml` and runs tests in both environments.
|
||||
|
||||
## Writing Tests
|
||||
|
||||
### Single Site Tests
|
||||
|
||||
Add new single site tests to `cypress/e2e/single-site.cy.js`.
|
||||
|
||||
### Multisite Tests
|
||||
|
||||
Add new multisite tests to `cypress/e2e/multisite.cy.js`.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Database connection errors**: Make sure Docker is running and ports 8888 and 8889 are available.
|
||||
|
||||
2. **Multisite conversion fails**: Check the wp-env logs for details:
|
||||
|
||||
```bash
|
||||
wp-env logs
|
||||
```
|
||||
|
||||
3. **Plugin not activated**: Run the following command:
|
||||
|
||||
```bash
|
||||
# For single site
|
||||
wp-env run cli wp plugin activate wp-plugin-starter-template-for-ai-coding
|
||||
|
||||
# For multisite
|
||||
wp-env run cli wp plugin activate wp-plugin-starter-template-for-ai-coding --network
|
||||
```
|
||||
|
||||
### Getting Help
|
||||
|
||||
If you encounter any issues, please open an issue on our GitHub repository with:
|
||||
|
||||
* A description of the problem
|
||||
* Steps to reproduce
|
||||
* Any error messages
|
||||
* Your environment details (OS, Node.js version, etc.)
|
||||
263
.wiki/Testing.md
Normal file
263
.wiki/Testing.md
Normal file
@@ -0,0 +1,263 @@
|
||||
# Testing Framework
|
||||
|
||||
This document explains how to use the testing framework for our plugin.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Overview](#overview)
|
||||
* [Prerequisites](#prerequisites)
|
||||
* [Testing Approaches](#testing-approaches)
|
||||
* [wp-env Approach](#1-wp-env-approach)
|
||||
* [WordPress Playground Approach](#2-wordpress-playground-approach)
|
||||
* [Writing Tests](#writing-tests)
|
||||
* [CI/CD Integration](#cicd-integration)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
* [PHPUnit Tests](#phpunit-tests)
|
||||
* [Future Improvements](#future-improvements)
|
||||
|
||||
## Overview
|
||||
|
||||
Our testing framework uses:
|
||||
|
||||
See also:
|
||||
|
||||
* [Architecture Overview](Architecture-Overview.md) – high-level design
|
||||
* [Multisite Development](Multisite-Development.md) – deeper multisite guidance
|
||||
|
||||
Components:
|
||||
|
||||
* **wp-env**: For setting up WordPress environments (both single site and multisite)
|
||||
* **WordPress Playground**: For browser-based testing without Docker
|
||||
* **Cypress**: For end-to-end testing
|
||||
* **PHPUnit**: For unit testing (coming soon)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Node.js**: Version 16 or higher
|
||||
2. **npm**: For package management
|
||||
3. **Docker**: For running WordPress environments with wp-env (not needed for WordPress Playground)
|
||||
4. **PHP**: Version 7.4 or higher (for future PHPUnit tests)
|
||||
5. **Composer**: For managing PHP dependencies
|
||||
|
||||
## Testing Approaches
|
||||
|
||||
We provide two main approaches for testing:
|
||||
|
||||
1. **wp-env**: Traditional approach using Docker
|
||||
2. **WordPress Playground**: Browser-based approach without Docker
|
||||
|
||||
### 1. wp-env Approach
|
||||
|
||||
#### Setting Up Test Environments
|
||||
|
||||
We provide scripts to easily set up test environments:
|
||||
|
||||
##### Single Site Environment
|
||||
|
||||
```bash
|
||||
# Set up a single site environment
|
||||
npm run setup:single
|
||||
|
||||
# You can also use the unified setup script:
|
||||
bash bin/setup-test-env.sh single
|
||||
```
|
||||
|
||||
This will:
|
||||
|
||||
1. Start a WordPress single site environment using wp-env
|
||||
2. Install and activate our plugin
|
||||
3. Configure WordPress for testing
|
||||
|
||||
##### Multisite Environment
|
||||
|
||||
```bash
|
||||
# Set up a multisite environment
|
||||
npm run setup:multisite
|
||||
|
||||
# Or via the setup script:
|
||||
bash bin/setup-test-env.sh multisite
|
||||
```
|
||||
|
||||
This will:
|
||||
|
||||
1. Start a WordPress multisite environment using wp-env
|
||||
2. Install and activate our plugin network-wide
|
||||
3. Create a test subsite
|
||||
4. Configure WordPress for testing
|
||||
|
||||
#### Running Tests
|
||||
|
||||
We have Cypress tests for both single site and multisite environments:
|
||||
|
||||
##### Single Site Tests
|
||||
|
||||
```bash
|
||||
# Run tests in browser (interactive mode)
|
||||
npm run test:single
|
||||
|
||||
# Run tests headless (CI mode)
|
||||
npm run test:single:headless
|
||||
```
|
||||
|
||||
##### Multisite Tests
|
||||
|
||||
```bash
|
||||
# Run tests in browser (interactive mode)
|
||||
npm run test:multisite
|
||||
|
||||
# Run tests headless (CI mode)
|
||||
npm run test:multisite:headless
|
||||
```
|
||||
|
||||
##### All-in-One Commands
|
||||
|
||||
We also provide all-in-one commands that set up the environment and run the tests:
|
||||
|
||||
```bash
|
||||
# Set up single site environment and run tests
|
||||
npm run test:e2e:single
|
||||
|
||||
# Set up multisite environment and run tests
|
||||
npm run test:e2e:multisite
|
||||
```
|
||||
|
||||
### 2. WordPress Playground Approach
|
||||
|
||||
WordPress Playground runs WordPress entirely in the browser using WebAssembly. This means:
|
||||
|
||||
* No server required - WordPress runs in the browser
|
||||
* Fast startup times
|
||||
* Isolated testing environment
|
||||
* Works well with CI/CD pipelines
|
||||
|
||||
#### Using WordPress Playground Online
|
||||
|
||||
The easiest way to test our plugin with WordPress Playground is to use the online version:
|
||||
|
||||
1. Single site testing: [Open in WordPress Playground][playground-single]
|
||||
|
||||
2. Multisite testing: [Open in WordPress Playground][playground-multisite]
|
||||
|
||||
[playground-single]: https://playground.wordpress.net/?blueprint-url=https://raw.githubusercontent.com/wpallstars/wp-plugin-starter-template-for-ai-coding/main/playground/blueprint.json&_t=2
|
||||
[playground-multisite]: https://playground.wordpress.net/?blueprint-url=https://raw.githubusercontent.com/wpallstars/wp-plugin-starter-template-for-ai-coding/main/playground/multisite-blueprint.json&_t=2
|
||||
|
||||
These links automatically set up WordPress with multisite enabled and WP_DEBUG enabled.
|
||||
|
||||
Both the Plugin Toggle and Kadence Blocks plugins are pre-activated.
|
||||
|
||||
#### Local Testing with HTML Files
|
||||
|
||||
We've also included HTML files that embed WordPress Playground:
|
||||
|
||||
1. Open `playground/index.html` in your browser for single site testing
|
||||
2. Open `playground/multisite.html` in your browser for multisite testing
|
||||
3. Open `playground/test.html` in your browser for a unified interface with buttons
|
||||
to switch between single site and multisite
|
||||
|
||||
You can serve these files locally with a simple HTTP server:
|
||||
|
||||
```bash
|
||||
# Using Python
|
||||
python -m http.server 8888 --directory playground
|
||||
|
||||
# Then open http://localhost:8888/index.html in your browser
|
||||
# Or open http://localhost:8888/test.html for a unified single/multisite switcher
|
||||
```
|
||||
|
||||
## Writing Tests
|
||||
|
||||
### Cypress Tests
|
||||
|
||||
We have custom Cypress commands to make testing WordPress easier:
|
||||
|
||||
* `cy.loginAsAdmin()`: Logs in as the admin user
|
||||
* `cy.activatePlugin(pluginSlug)`: Activates a plugin
|
||||
* `cy.networkActivatePlugin(pluginSlug)`: Network activates a plugin in multisite
|
||||
|
||||
Example test:
|
||||
|
||||
```javascript
|
||||
describe('WordPress Single Site Tests', () => {
|
||||
it('Can login to the admin area', () => {
|
||||
cy.loginAsAdmin();
|
||||
cy.get('body.wp-admin').should('exist');
|
||||
});
|
||||
|
||||
it('Plugin is activated', () => {
|
||||
cy.loginAsAdmin();
|
||||
cy.visit('/wp-admin/plugins.php');
|
||||
cy.get('tr[data-slug="wp-plugin-starter-template-for-ai-coding"]')
|
||||
.should('have.class', 'active');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
We have GitHub Actions workflows for running tests in CI/CD:
|
||||
|
||||
* `.github/workflows/wordpress-tests.yml`: Runs wp-env e2e tests
|
||||
* `.github/workflows/playground-tests.yml`: Runs Playground e2e tests
|
||||
* `.github/workflows/phpunit.yml`: Runs PHPUnit tests (coming soon)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Docker not running**: Make sure Docker is running before starting wp-env
|
||||
2. **Port conflicts**: If ports 8888 or 8889 are in use, wp-env will fail to start
|
||||
3. **wp-env not installed**: Run `npm install -g @wordpress/env` to install wp-env globally
|
||||
4. **WordPress Playground not loading**: Check your network connection and try refreshing the page
|
||||
5. **Tests failing**: Check the error messages in the console and fix the issues
|
||||
|
||||
### Error Checking and Feedback Loops
|
||||
|
||||
For information on code quality issues and automated tool feedback, see the
|
||||
[Error Checking and Feedback Loops](Error-Checking-Feedback-Loops.md) documentation.
|
||||
|
||||
### Debugging
|
||||
|
||||
1. **Cypress debugging**: Use `cy.debug()` to pause test execution
|
||||
2. **wp-env debugging**: Run `wp-env logs` to see WordPress logs
|
||||
3. **GitHub Actions debugging**: Check the workflow logs for detailed error messages
|
||||
|
||||
## PHPUnit Tests
|
||||
|
||||
We use PHPUnit for unit testing PHP code. The tests are located in the `tests/phpunit` directory.
|
||||
|
||||
### Running PHPUnit Tests
|
||||
|
||||
```bash
|
||||
# Run PHPUnit tests for single site
|
||||
npm run test:phpunit
|
||||
|
||||
# Run PHPUnit tests for multisite
|
||||
npm run test:phpunit:multisite
|
||||
```
|
||||
|
||||
### Writing PHPUnit Tests
|
||||
|
||||
Here's an example of a PHPUnit test for the Multisite class:
|
||||
|
||||
```php
|
||||
<?php
|
||||
class MultisiteTest extends WP_UnitTestCase {
|
||||
|
||||
public function test_is_multisite_compatible() {
|
||||
$multisite = new WP_Plugin_Starter_Template_For_AI_Coding\Multisite\Multisite();
|
||||
$this->assertTrue($multisite->is_multisite_compatible());
|
||||
}
|
||||
|
||||
public function test_get_network_sites() {
|
||||
$multisite = new WP_Plugin_Starter_Template_For_AI_Coding\Multisite\Multisite();
|
||||
$sites = $multisite->get_network_sites();
|
||||
$this->assertIsArray($sites);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Future Improvements
|
||||
|
||||
1. **Performance tests**: Add performance testing
|
||||
2. **Accessibility tests**: Add accessibility testing
|
||||
|
||||
182
.wiki/Troubleshooting.md
Normal file
182
.wiki/Troubleshooting.md
Normal file
@@ -0,0 +1,182 @@
|
||||
# Troubleshooting
|
||||
|
||||
This guide provides solutions to common issues you might encounter when using or developing with this plugin.
|
||||
|
||||
## Installation Issues
|
||||
|
||||
### Plugin Installation Fails
|
||||
|
||||
**Problem**: The plugin fails to install in WordPress.
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. Verify that your WordPress version meets the minimum requirement (5.0+)
|
||||
2. Check that your PHP version meets the minimum requirement (7.0+)
|
||||
3. Ensure the ZIP file is properly formatted and contains all required files
|
||||
4. Try installing the plugin manually by uploading the unzipped folder to the `wp-content/plugins` directory
|
||||
|
||||
### Activation Error
|
||||
|
||||
**Problem**: You receive an error when activating the plugin.
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. Check the error message for specific details
|
||||
2. Verify that all plugin dependencies are installed and activated
|
||||
3. Check your server's error logs for more information
|
||||
4. Temporarily deactivate other plugins to check for conflicts
|
||||
|
||||
## Development Issues
|
||||
|
||||
### Composer Dependencies
|
||||
|
||||
**Problem**: Composer fails to install dependencies.
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. Verify that you have Composer installed and up to date
|
||||
2. Check that your PHP version meets the requirements for all dependencies
|
||||
3. Try clearing Composer's cache: `composer clear-cache`
|
||||
4. Run `composer install --verbose` to see detailed error messages
|
||||
|
||||
### NPM Dependencies
|
||||
|
||||
**Problem**: NPM fails to install dependencies.
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. Verify that you have Node.js and NPM installed and up to date
|
||||
2. Try clearing NPM's cache: `npm cache clean --force`
|
||||
3. Delete the `node_modules` directory and run `npm install` again
|
||||
4. Run `npm install --verbose` to see detailed error messages
|
||||
|
||||
### WordPress Environment (wp-env)
|
||||
|
||||
**Problem**: The WordPress environment fails to start.
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. Verify that Docker is installed and running
|
||||
2. Check that the Docker daemon has enough resources allocated
|
||||
3. Try stopping and removing existing containers: `npm run wp-env stop && npm run wp-env clean`
|
||||
4. Run `npm run wp-env start --debug` to see detailed error messages
|
||||
|
||||
### Unit Tests
|
||||
|
||||
**Problem**: Unit tests are failing.
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. Verify that you have PHPUnit installed and configured correctly
|
||||
2. Check that all dependencies are installed: `composer install`
|
||||
3. Run tests with verbose output: `./vendor/bin/phpunit --verbose`
|
||||
4. Check for syntax errors in your PHP files
|
||||
|
||||
### End-to-End Tests
|
||||
|
||||
**Problem**: End-to-end tests are failing.
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. Verify that the WordPress environment is running: `npm run start`
|
||||
2. Check that Cypress is installed correctly: `npx cypress verify`
|
||||
3. Run tests in interactive mode to debug: `npm run test:e2e`
|
||||
4. Check for issues with selectors or timing in your test scripts
|
||||
|
||||
## Plugin Functionality Issues
|
||||
|
||||
### Plugin Settings Not Saving
|
||||
|
||||
**Problem**: Changes to plugin settings are not being saved.
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. Check for JavaScript errors in the browser console
|
||||
2. Verify that the settings form is submitting correctly
|
||||
3. Check that the WordPress nonce is being verified correctly
|
||||
4. Ensure that the user has the necessary permissions to save settings
|
||||
|
||||
### Plugin Conflicts
|
||||
|
||||
**Problem**: The plugin conflicts with other plugins.
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. Deactivate other plugins one by one to identify the conflict
|
||||
2. Check for JavaScript errors in the browser console
|
||||
3. Check for PHP errors in the server logs
|
||||
4. Contact the developers of both plugins to report the conflict
|
||||
|
||||
### Performance Issues
|
||||
|
||||
**Problem**: The plugin is causing performance issues.
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. Check if the plugin is making excessive database queries
|
||||
2. Verify that assets (CSS/JS) are being properly enqueued and minified
|
||||
3. Consider implementing caching for resource-intensive operations
|
||||
4. Use a profiling tool to identify bottlenecks
|
||||
|
||||
## Update Issues
|
||||
|
||||
### Update Fails
|
||||
|
||||
**Problem**: The plugin fails to update.
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. Verify that your WordPress version meets the requirements for the new version
|
||||
2. Check that your PHP version meets the requirements for the new version
|
||||
3. Try updating manually by downloading the new version and replacing the old files
|
||||
4. Check for file permission issues on your server
|
||||
|
||||
### Lost Settings After Update
|
||||
|
||||
**Problem**: Plugin settings are lost after updating.
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. Check if the plugin includes a data migration process for updates
|
||||
2. Verify that the settings are being stored in the database correctly
|
||||
3. Restore settings from a backup if available
|
||||
4. Contact plugin support for assistance
|
||||
|
||||
## Multisite Issues
|
||||
|
||||
### Plugin Not Working on Multisite
|
||||
|
||||
**Problem**: The plugin doesn't work correctly on a multisite installation.
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. Verify that the plugin is network activated if required
|
||||
2. Check that the plugin is compatible with multisite (it should be!)
|
||||
3. Ensure that the plugin has the necessary permissions on each site
|
||||
4. Check for multisite-specific settings or options
|
||||
|
||||
## Getting Additional Help
|
||||
|
||||
If you're still experiencing issues after trying these troubleshooting steps:
|
||||
|
||||
1. Check the [Frequently Asked Questions](Frequently-Asked-Questions) for more information
|
||||
2. Search for similar issues in the [GitHub Issues](https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding/issues)
|
||||
3. Create a new issue with detailed information about your problem
|
||||
4. Contact the plugin developers for direct support
|
||||
|
||||
## Reporting Bugs
|
||||
|
||||
If you've identified a bug in the plugin:
|
||||
|
||||
1. Go to the [GitHub Issues](https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding/issues) page
|
||||
2. Click "New Issue"
|
||||
3. Select "Bug Report"
|
||||
4. Fill out the template with as much detail as possible
|
||||
5. Submit the issue
|
||||
|
||||
Please include:
|
||||
|
||||
- A clear description of the bug
|
||||
- Steps to reproduce the issue
|
||||
- Your environment details (WordPress version, PHP version, etc.)
|
||||
- Any relevant error messages or screenshots
|
||||
@@ -21,7 +21,7 @@ The template follows a modular structure:
|
||||
- `js/`: Admin JavaScript files
|
||||
- `languages/`: Translation files
|
||||
- `.github/workflows/`: GitHub Actions workflows
|
||||
- `.ai-workflows/`: Documentation for AI assistants
|
||||
- `.agents/`: Documentation for AI assistants
|
||||
- `.wiki/`: Wiki documentation templates
|
||||
|
||||
### Customizing for Your Plugin
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
## User Documentation
|
||||
|
||||
* [Home](Home)
|
||||
* [Starter Prompt](Starter-Prompt)
|
||||
* [Installation Guide](Installation-Guide)
|
||||
* [Usage Instructions](Usage-Instructions)
|
||||
* [Frequently Asked Questions](Frequently-Asked-Questions)
|
||||
* [Troubleshooting](Troubleshooting)
|
||||
|
||||
## Developer Documentation
|
||||
|
||||
* [Architecture Overview](Architecture-Overview)
|
||||
* [Customization Guide](Customization-Guide)
|
||||
* [Extending the Plugin](Extending-the-Plugin)
|
||||
* [Coding Standards](Coding-Standards)
|
||||
* [Testing Framework](Testing-Framework)
|
||||
* [Multisite Development](Multisite-Development)
|
||||
* [Release Process](Release-Process)
|
||||
|
||||
## AI Documentation
|
||||
|
||||
* [AI Workflow Documentation](AI-Workflow-Documentation)
|
||||
|
||||
## Additional Resources
|
||||
|
||||
* [Changelog](Changelog)
|
||||
* [Contributing](Contributing)
|
||||
|
||||
16
.wp-env.json
Normal file
16
.wp-env.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"core": null,
|
||||
"plugins": [
|
||||
"."
|
||||
],
|
||||
"themes": [],
|
||||
"config": {
|
||||
"WP_DEBUG": true,
|
||||
"WP_DEBUG_LOG": true,
|
||||
"WP_DEBUG_DISPLAY": false
|
||||
},
|
||||
"mappings": {
|
||||
"wp-content/mu-plugins": "./mu-plugins",
|
||||
"wp-content/plugins/wp-plugin-starter-template-for-ai-coding": "."
|
||||
}
|
||||
}
|
||||
22
.wp-env.multisite.json
Normal file
22
.wp-env.multisite.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"core": null,
|
||||
"plugins": [
|
||||
"."
|
||||
],
|
||||
"themes": [],
|
||||
"config": {
|
||||
"WP_DEBUG": true,
|
||||
"WP_DEBUG_LOG": true,
|
||||
"WP_DEBUG_DISPLAY": false,
|
||||
"WP_ALLOW_MULTISITE": true,
|
||||
"MULTISITE": true,
|
||||
"SUBDOMAIN_INSTALL": false,
|
||||
"PATH_CURRENT_SITE": "/",
|
||||
"SITE_ID_CURRENT_SITE": 1,
|
||||
"BLOG_ID_CURRENT_SITE": 1
|
||||
},
|
||||
"mappings": {
|
||||
"wp-content/mu-plugins": "./mu-plugins",
|
||||
"wp-content/plugins/wp-plugin-starter-template-for-ai-coding": "."
|
||||
}
|
||||
}
|
||||
197
AGENTS.md
Normal file
197
AGENTS.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# AI Assistant Guide for WordPress Plugin Development
|
||||
|
||||
This guide helps AI assistants understand the project structure, workflows, and best practices for this repository.
|
||||
|
||||
## IMPORTANT: Repository Context
|
||||
|
||||
This workspace may contain multiple repository folders.
|
||||
|
||||
Always focus ONLY on the current repository you're working in.
|
||||
|
||||
Avoid hallucinating functionality from other repositories in the workspace.
|
||||
|
||||
* **Current Repository**: wp-plugin-starter-template-for-ai-coding
|
||||
* **Repository Purpose**: A starter template for WordPress plugins with AI-assisted development
|
||||
* **Repository Scope**: All code changes and discussions should be limited to THIS repository only
|
||||
|
||||
## Project Overview
|
||||
|
||||
* **Plugin Name**: WordPress Plugin Starter Template
|
||||
* **Plugin Slug**: wp-plugin-starter-template
|
||||
* **Text Domain**: wp-plugin-starter-template
|
||||
* **Namespace**: WPALLSTARS\PluginStarterTemplate
|
||||
* **Version**: 0.1.15
|
||||
* **Requires WordPress**: 5.0+
|
||||
* **Requires PHP**: 7.4+
|
||||
* **License**: GPL-2.0+
|
||||
|
||||
## Repository Structure
|
||||
|
||||
* **wp-plugin-starter-template.php**: Main plugin file with plugin headers
|
||||
* **includes/**: Core plugin functionality
|
||||
* **plugin.php**: Main plugin class that initializes everything
|
||||
* **core.php**: Core functionality class
|
||||
* **updater.php**: Update mechanism for multiple sources
|
||||
* **admin/**: Admin-specific functionality
|
||||
* **lib/**: Admin classes
|
||||
* **css/**: Admin stylesheets
|
||||
* **js/**: Admin JavaScript files
|
||||
* **languages/**: Translation files
|
||||
* **.github/workflows/**: GitHub Actions workflows
|
||||
* **.agents/**: Documentation for AI assistants
|
||||
* **.wiki/**: Wiki documentation templates
|
||||
|
||||
## Coding Standards
|
||||
|
||||
This project follows the [WordPress Coding Standards](https://developer.wordpress.org/coding-standards/):
|
||||
|
||||
* Use 4 spaces for indentation, not tabs (this is a project-specific override of WordPress standards)
|
||||
* Follow WordPress naming conventions:
|
||||
* Class names: `Class_Name`
|
||||
* Function names: `function_name`
|
||||
* Variable names: `$variable_name`
|
||||
* Use proper DocBlocks for all classes, methods, and functions
|
||||
* Ensure all user-facing strings are translatable
|
||||
* Validate and sanitize all inputs
|
||||
* Escape all outputs
|
||||
* Use asterisks (*) for bullet points in all Markdown files, not hyphens (-)
|
||||
* Add periods to the end of all inline comments
|
||||
|
||||
### Code Quality Tools
|
||||
|
||||
This project uses several automated code quality tools to ensure high standards:
|
||||
|
||||
1. **PHP_CodeSniffer (PHPCS)**: Checks PHP code against the WordPress Coding Standards
|
||||
```bash
|
||||
composer run phpcs
|
||||
```
|
||||
|
||||
2. **PHP Code Beautifier and Fixer (PHPCBF)**: Automatically fixes some coding standard violations
|
||||
```bash
|
||||
composer run phpcbf
|
||||
```
|
||||
|
||||
3. **ESLint**: Checks JavaScript code against the WordPress Coding Standards
|
||||
```bash
|
||||
npm run lint:js
|
||||
```
|
||||
|
||||
4. **Stylelint**: Checks CSS code against the WordPress Coding Standards
|
||||
```bash
|
||||
npm run lint:css
|
||||
```
|
||||
|
||||
5. **Continuous Integration Tools**: The project integrates with several code quality tools:
|
||||
* **CodeRabbit**: AI-powered code review tool
|
||||
* **CodeFactor**: Continuous code quality monitoring
|
||||
* **Codacy**: Code quality and static analysis
|
||||
* **SonarCloud**: Code quality and security analysis
|
||||
|
||||
Always run PHPCS and PHPCBF locally before committing code to ensure it meets the project's coding standards.
|
||||
|
||||
## Common Tasks
|
||||
|
||||
For detailed instructions on releases, features, bugs, and testing, see **@.agents/release-process.md**.
|
||||
|
||||
For local testing with WordPress Playground, LocalWP, and wp-env, see **@.agents/local-testing-guide.md**.
|
||||
|
||||
## Avoiding Cross-Repository Confusion
|
||||
|
||||
When working in a multi-repository workspace, follow these guidelines to avoid confusion:
|
||||
|
||||
1. **Verify Repository Context**: Always check which repository you're currently working in
|
||||
before making any changes or recommendations.
|
||||
|
||||
2. **Limit Code Search Scope**: When searching for code or functionality,
|
||||
explicitly limit your search to the current repository.
|
||||
|
||||
3. **Don't Assume Features**: Never assume that features present in one repository
|
||||
should be implemented in another. Each repository has its own specific purpose and feature set.
|
||||
|
||||
4. **Repository-Specific Documentation**: Documentation should only reflect the actual features
|
||||
and functionality of the current repository.
|
||||
|
||||
5. **Cross-Repository Inspiration**: If you want to implement a feature inspired by another
|
||||
repository, explicitly mention that it's a new feature being added, not an existing one.
|
||||
|
||||
6. **Verify Before Implementation**: Before implementing or documenting a feature, verify that
|
||||
it actually exists in the current repository by checking the codebase.
|
||||
|
||||
7. **Consistent Markdown Formatting**: Always use asterisks (*) for bullet points in Markdown files, not hyphens (-).
|
||||
|
||||
## Internationalization (i18n)
|
||||
|
||||
All user-facing strings should be translatable:
|
||||
|
||||
* Use `__()` for simple strings
|
||||
* Use `_e()` for echoed strings
|
||||
* Use `esc_html__()` for escaped strings
|
||||
* Use `esc_html_e()` for escaped and echoed strings
|
||||
* Always use the plugin's text domain: `wp-plugin-starter-template`
|
||||
|
||||
Example:
|
||||
```php
|
||||
echo esc_html__('This is a translatable string', 'wp-plugin-starter-template');
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
* Validate and sanitize all inputs
|
||||
* Escape all outputs
|
||||
* Use nonces for form submissions
|
||||
* Use capability checks for user actions
|
||||
* Follow the principle of least privilege
|
||||
|
||||
## Documentation
|
||||
|
||||
* Keep code comments up-to-date
|
||||
* Update README.md and readme.txt when adding new features
|
||||
* Update wiki documentation in the `.wiki/` directory
|
||||
* Update changelog in both CHANGELOG.md and readme.txt
|
||||
* Use asterisks (*) for bullet points in all Markdown files
|
||||
|
||||
## Git Workflow
|
||||
|
||||
* Create feature branches from `main`
|
||||
* Use descriptive branch names (e.g., `feature/add-settings-page`)
|
||||
* Make atomic commits with clear messages
|
||||
* Create pull requests for review
|
||||
* Tag releases with version numbers (e.g., `v1.0.0`)
|
||||
|
||||
## Developer Preferences
|
||||
|
||||
When working with this repository, remember these preferences:
|
||||
|
||||
1. Follow WordPress coding standards
|
||||
2. Use OOP approach with namespaced classes
|
||||
3. Keep code modular and maintainable
|
||||
4. Reference these preferences in future interactions
|
||||
|
||||
This ensures consistency across coding sessions.
|
||||
|
||||
It reduces the need for developers to repeatedly explain their preferences.
|
||||
|
||||
## Autonomous CI/CD and Error Handling
|
||||
|
||||
This repository is set up for autonomous CI/CD with minimal human intervention.
|
||||
|
||||
As an AI assistant, you should:
|
||||
|
||||
1. **Monitor CI/CD Pipelines**: Use the GitHub API to check workflow status and identify failures
|
||||
2. **Diagnose Issues**: Analyze error logs and determine root causes
|
||||
3. **Implement Fixes**: Make necessary code changes to resolve issues
|
||||
4. **Verify Solutions**: Ensure fixes pass all tests and quality checks
|
||||
5. **Document Resolutions**: Update documentation with solutions for future reference
|
||||
|
||||
For detailed instructions on feedback loops and error checking, see
|
||||
**@.agents/error-checking-feedback-loops.md**.
|
||||
|
||||
### When to Consult Humans
|
||||
|
||||
Only consult humans for:
|
||||
|
||||
* Product design decisions
|
||||
* Security-critical changes
|
||||
* Major architectural decisions
|
||||
* Access to information not available through APIs or terminal
|
||||
* Novel problems without precedent or documented solutions
|
||||
116
CHANGELOG.md
116
CHANGELOG.md
@@ -1,29 +1,137 @@
|
||||
All notable changes to this project should be documented both here and in the main Readme files.
|
||||
|
||||
#### [0.1.3] - 2025-04-19
|
||||
#### Added
|
||||
- Improved AI IDE context recommendations in documentation
|
||||
- Enhanced Starter Prompt with guidance on pinning .ai-assistant.md and .ai-workflows/
|
||||
#### [0.1.15] - 2025-11-24
|
||||
|
||||
#### Release
|
||||
|
||||
- Maintenance release
|
||||
|
||||
#### [0.1.14] - 2025-11-24
|
||||
|
||||
#### Changed
|
||||
|
||||
- Renamed .ai-assistant.md to AGENTS.md
|
||||
- Renamed .ai-workflows directory to .agents
|
||||
- Updated all references in documentation and codebase
|
||||
|
||||
#### [0.1.13] - 2023-04-23
|
||||
|
||||
#### Improved
|
||||
|
||||
- Improved code quality with proper type declarations
|
||||
- Fixed inconsistent variable naming (camelCase to snake_case)
|
||||
- Improved path handling in admin class
|
||||
- Added textdomain loading functionality
|
||||
- Removed unused phpcs:ignore comment
|
||||
- Implemented proper return type declarations
|
||||
|
||||
#### [0.1.12] - 2023-04-22
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed WordPress mocking in unit tests
|
||||
- Added proper mocking for WordPress functions in tests
|
||||
- Improved code quality tool configurations
|
||||
|
||||
#### Added
|
||||
|
||||
- Detailed code quality checks workflow documentation
|
||||
- Updated documentation for better workflow efficiency
|
||||
|
||||
#### [0.1.11] - 2023-04-21
|
||||
|
||||
#### Improved
|
||||
|
||||
- Improved code quality with comprehensive fixes
|
||||
- Fixed indentation issues in PHP files
|
||||
- Updated CSS formatting with modern notation
|
||||
- Fixed JavaScript issues with proper global variables
|
||||
- Improved security by using filter_input() instead of direct superglobal access
|
||||
- Standardized naming conventions across the codebase
|
||||
- Fixed documentation and comments for better clarity
|
||||
|
||||
#### [0.1.10] - 2025-04-20
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed formatting issues in markdown files for better code quality
|
||||
- Improved URL formatting with angle brackets
|
||||
- Standardized list formatting across documentation files
|
||||
|
||||
#### [0.1.9] - 2025-04-18
|
||||
|
||||
#### Changed
|
||||
|
||||
- Alphabetized AI IDE list in README.md
|
||||
|
||||
#### [0.1.8] - 2025-04-19
|
||||
|
||||
#### Added
|
||||
|
||||
- More informative badges to README.md (Build Status, Requirements, WP.org placeholders, Release, Issues, Contributors, Wiki).
|
||||
|
||||
#### [0.1.7] - 2025-04-19
|
||||
|
||||
#### Fixed
|
||||
|
||||
- GitHub Actions tests workflow with proper file paths and dependencies
|
||||
|
||||
#### Improved
|
||||
|
||||
- Workflow names for better clarity in GitHub Actions UI
|
||||
|
||||
#### [0.1.6] - 2025-04-19
|
||||
|
||||
#### Fixed
|
||||
|
||||
- GitHub Actions workflows permissions for releases and wiki sync
|
||||
|
||||
#### [0.1.5] - 2025-04-19
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Release workflow to use correct plugin directory name
|
||||
|
||||
#### Added
|
||||
|
||||
- Testing setup with wp-env and Cypress
|
||||
- Multisite compatibility
|
||||
- npm scripts for development and testing
|
||||
|
||||
#### [0.1.3] - 2025-04-19
|
||||
|
||||
#### Added
|
||||
|
||||
- Improved AI IDE context recommendations in documentation
|
||||
- Enhanced Starter Prompt with guidance on pinning AGENTS.md and .agents/
|
||||
|
||||
#### Changed
|
||||
|
||||
- Updated README.md and readme.txt with AI IDE context recommendations
|
||||
- Improved documentation for AI-assisted development
|
||||
- Moved Starter Prompt to the wiki for better organization
|
||||
|
||||
#### [0.1.2] - 2025-04-18
|
||||
|
||||
#### Added
|
||||
|
||||
- STARTER-PROMPT.md with comprehensive guide for customizing the template
|
||||
- Additional AI workflow files for better development guidance
|
||||
|
||||
#### Changed
|
||||
|
||||
- Updated documentation files with improved instructions
|
||||
|
||||
#### [0.1.1] - 2025-04-18
|
||||
|
||||
#### Changed
|
||||
|
||||
- Updated LICENSE file with correct GPL-2.0 text
|
||||
|
||||
#### [0.1.0] - 2025-04-17
|
||||
|
||||
#### Added
|
||||
|
||||
- Initial release with basic template structure
|
||||
- Core plugin architecture with OOP approach
|
||||
- Admin interface components and styling
|
||||
|
||||
60
PR-DESCRIPTION.md
Normal file
60
PR-DESCRIPTION.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Add Comprehensive Testing Framework for Single Site and Multisite
|
||||
|
||||
This PR adds a comprehensive testing framework for our WordPress plugin template.
|
||||
|
||||
It allows testing in both single site and multisite WordPress environments.
|
||||
|
||||
The focus is purely on testing functionality, not on adding multisite-specific features.
|
||||
|
||||
## Changes
|
||||
|
||||
* Added wp-env configuration for both single site and multisite environments
|
||||
* Created Cypress e2e tests for both environments
|
||||
* Added GitHub Actions workflow to run tests automatically on PRs
|
||||
* Created a unified setup script for test environments
|
||||
* Added detailed documentation in the wiki
|
||||
* Updated README.md to reference the new testing approach
|
||||
* Added placeholder files for multisite functionality
|
||||
|
||||
## Testing
|
||||
|
||||
The testing framework can be used as follows:
|
||||
|
||||
### Single Site Testing
|
||||
|
||||
```bash
|
||||
# Set up single site environment
|
||||
npm run setup:single
|
||||
|
||||
# Run tests in interactive mode
|
||||
npm run test:single
|
||||
|
||||
# Run tests in headless mode
|
||||
npm run test:single:headless
|
||||
```
|
||||
|
||||
### Multisite Testing
|
||||
|
||||
```bash
|
||||
# Set up multisite environment
|
||||
npm run setup:multisite
|
||||
|
||||
# Run tests in interactive mode
|
||||
npm run test:multisite
|
||||
|
||||
# Run tests in headless mode
|
||||
npm run test:multisite:headless
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
Detailed documentation is available in the [Testing Framework](.wiki/Testing-Framework.md) wiki page.
|
||||
|
||||
## Inspiration
|
||||
|
||||
This implementation was inspired by the e2e testing approach in
|
||||
[wp-multisite-waas issue #55](https://github.com/superdav42/wp-multisite-waas/issues/55).
|
||||
|
||||
It focuses on testing our plugin in different WordPress environments.
|
||||
|
||||
It does not add domain mapping or other multisite-specific functionality from that plugin.
|
||||
541
README.md
541
README.md
@@ -1,31 +1,61 @@
|
||||
# WordPress Plugin Starter Template for AI Coding
|
||||
|
||||
[](https://www.gnu.org/licenses/gpl-2.0.html)
|
||||
[![License][badge-license]][url-license]
|
||||
[![Build Status][badge-build]][url-build]
|
||||
[![Requires PHP][badge-php]][url-requirements]
|
||||
[![Requires WordPress][badge-wp]][url-requirements]
|
||||
[![Wiki][badge-wiki]][url-wiki]
|
||||
[![CodeRabbit Reviews][badge-coderabbit]][url-coderabbit]
|
||||
[![CodeFactor][badge-codefactor]][url-codefactor]
|
||||
[![Quality Gate Status][badge-sonar-gate]][url-sonar]
|
||||
[![Codacy Badge][badge-codacy]][url-codacy]
|
||||
|
||||
[badge-license]: https://img.shields.io/badge/license-GPL--2.0%2B-blue.svg
|
||||
[badge-build]: https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding/actions/workflows/tests.yml/badge.svg
|
||||
[badge-php]: https://img.shields.io/badge/php-%3E%3D%207.4-blue.svg
|
||||
[badge-wp]: https://img.shields.io/badge/WordPress-%3E%3D%205.0-blue.svg
|
||||
[badge-wiki]: https://img.shields.io/badge/documentation-wiki-blue.svg
|
||||
[badge-coderabbit]: https://img.shields.io/coderabbit/prs/github/wpallstars/wp-plugin-starter-template-for-ai-coding?labelColor=171717&color=FF570A&label=CodeRabbit+Reviews
|
||||
[badge-codefactor]: https://www.codefactor.io/repository/github/wpallstars/wp-plugin-starter-template-for-ai-coding/badge
|
||||
[badge-sonar-gate]: https://sonarcloud.io/api/project_badges/measure?project=wpallstars_wp-plugin-starter-template-for-ai-coding&metric=alert_status
|
||||
[badge-codacy]: https://app.codacy.com/project/badge/Grade/905754fd010b481490b496fb800e6144
|
||||
|
||||
[url-license]: https://www.gnu.org/licenses/gpl-2.0.html
|
||||
[url-build]: https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding/actions/workflows/tests.yml
|
||||
[url-requirements]: https://wordpress.org/about/requirements/
|
||||
[url-wiki]: https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding/wiki
|
||||
[url-coderabbit]: https://coderabbit.ai
|
||||
[url-codefactor]: https://www.codefactor.io/repository/github/wpallstars/wp-plugin-starter-template-for-ai-coding
|
||||
[url-sonar]: https://sonarcloud.io/summary/new_code?id=wpallstars_wp-plugin-starter-template-for-ai-coding
|
||||
[url-codacy]: https://app.codacy.com/gh/wpallstars/wp-plugin-starter-template-for-ai-coding/dashboard
|
||||
|
||||
A comprehensive starter template for WordPress plugins with best practices for AI-assisted development.
|
||||
|
||||
## Description
|
||||
|
||||
The WordPress Plugin Starter Template provides a solid foundation for developing WordPress plugins. It incorporates best practices, modern coding standards, and a comprehensive structure that makes it easy to get started with plugin development.
|
||||
The WordPress Plugin Starter Template provides a solid foundation for developing WordPress plugins.
|
||||
|
||||
This template is based on the experience gained from developing the "Fix 'Plugin file does not exist' Notices" plugin and other successful WordPress plugins.
|
||||
It incorporates best practices, modern coding standards, and a comprehensive structure.
|
||||
|
||||
This template is based on experience from developing successful WordPress plugins.
|
||||
|
||||
### Key Features
|
||||
|
||||
* **Object-Oriented Architecture**: Well-structured, maintainable code using OOP principles
|
||||
* **Namespace Support**: Modern PHP namespacing for better organization and avoiding conflicts
|
||||
* **Comprehensive Documentation**: Detailed documentation for both users and developers
|
||||
* **Testing Framework**: PHPUnit setup for unit testing
|
||||
* **Testing Framework**: PHPUnit setup for unit testing and Cypress for e2e testing
|
||||
* **Internationalization Ready**: Full support for translation and localization
|
||||
* **Update Source Selection**: Choose between WordPress.org, GitHub, or Gitea for plugin updates
|
||||
* **AI Workflow Documentation**: Detailed guides for AI-assisted development
|
||||
* **Wiki Documentation**: Ready-to-use wiki structure for comprehensive documentation
|
||||
* **Multisite Compatible**: Fully tested and compatible with WordPress multisite installations
|
||||
|
||||
### How to Use This Template
|
||||
|
||||
1. Clone or download this repository
|
||||
2. **Important**: Begin by reading the [Starter Prompt](.wiki/Starter-Prompt.md) file for detailed instructions
|
||||
3. Add the .ai-assistant.md file and .ai-workflows/ directory to your AI IDE chat context (pin them if possible)
|
||||
3. Add the AGENTS.md file and .agents/ directory to your AI IDE chat context (pin them if possible)
|
||||
4. Use the prompt in the Starter Prompt file to guide the AI in customizing the template for your plugin
|
||||
5. Rename files and update namespaces to match your plugin
|
||||
6. Customize the functionality for your specific needs
|
||||
@@ -36,17 +66,19 @@ This template is based on the experience gained from developing the "Fix 'Plugin
|
||||
|
||||
This template includes comprehensive documentation for AI-assisted development:
|
||||
|
||||
* **.ai-assistant.md**: Guide for AI assistants to understand the project structure
|
||||
* **.ai-workflows/**: Detailed workflow documentation for common development tasks
|
||||
* **Starter Prompt**: Comprehensive prompt for AI tools to help customize the template (available in the [wiki](.wiki/Starter-Prompt.md))
|
||||
* **AGENTS.md**: Guide for AI assistants to understand the project structure
|
||||
* **.agents/**: Detailed workflow documentation for common development tasks
|
||||
* **Starter Prompt**: Prompt for AI tools to customize the template ([wiki](.wiki/Starter-Prompt.md))
|
||||
|
||||
**Important**: For the best AI assistance, add the .ai-assistant.md file and .ai-workflows/ directory to your AI IDE chat context. In most AI IDEs, you can pin these files to ensure they're considered in each message.
|
||||
**Important**: For the best AI assistance, add AGENTS.md and .agents/ to your AI IDE chat context.
|
||||
|
||||
In most AI IDEs, you can pin these files to ensure they're considered in each message.
|
||||
|
||||
## Installation
|
||||
|
||||
1. Clone or download this repository
|
||||
2. Read the [Starter Prompt](.wiki/Starter-Prompt.md) file for detailed instructions
|
||||
3. Add the .ai-assistant.md file and .ai-workflows/ directory to your AI IDE chat context
|
||||
3. Add the AGENTS.md file and .agents/ directory to your AI IDE chat context
|
||||
4. Use the prompt in the Starter Prompt file to guide the AI in customizing the template
|
||||
5. Rename files and update namespaces to match your plugin
|
||||
6. Customize the functionality for your specific needs
|
||||
@@ -59,16 +91,120 @@ This template includes comprehensive documentation for AI-assisted development:
|
||||
|
||||
To get started with this template, follow these steps:
|
||||
|
||||
1. In your terminal, navigate to the folder you keep you Git repositories (eg: `~/Git/`), then clone this repository to your local machine:
|
||||
1. Navigate to your Git repositories folder (e.g., `~/Git/`), then clone:
|
||||
```bash
|
||||
git clone https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding.git
|
||||
```
|
||||
|
||||
2. Open the [Starter Prompt](.wiki/Starter-Prompt.md) file and follow the instructions to customize the template for your plugin.
|
||||
2. Open the [Starter Prompt](.wiki/Starter-Prompt.md) file and follow the instructions
|
||||
to customize the template for your plugin.
|
||||
|
||||
3. Add the .ai-assistant.md file and .ai-workflows/ directory to your AI IDE chat context.
|
||||
3. Add the AGENTS.md file and .agents/ directory to your AI IDE chat context.
|
||||
|
||||
4. Use an AI assistant like GitHub Copilot, Claude, or ChatGPT to help you customize the template by providing the prompt from the Starter Prompt file.
|
||||
4. Use an AI assistant like GitHub Copilot, Claude, or ChatGPT to help customize
|
||||
the template by providing the prompt from the Starter Prompt file.
|
||||
|
||||
### Development Environment
|
||||
|
||||
This template includes configuration for WordPress Environment (wp-env) to make local development easier:
|
||||
|
||||
1. Install Node.js dependencies:
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
2. Start the WordPress environment:
|
||||
```bash
|
||||
npm run start
|
||||
```
|
||||
|
||||
3. For testing in different WordPress environments:
|
||||
|
||||
```bash
|
||||
# For single site testing
|
||||
npm run setup:single
|
||||
|
||||
# For multisite testing
|
||||
npm run setup:multisite
|
||||
```
|
||||
|
||||
See [Testing Framework](.wiki/Testing-Framework.md) for more details on our testing approach.
|
||||
|
||||
4. Access your local WordPress site at <http://localhost:8888> (admin credentials: admin/password)
|
||||
|
||||
### Testing
|
||||
|
||||
The template includes multiple testing approaches:
|
||||
|
||||
#### WordPress Playground Testing (No Docker Required)
|
||||
|
||||
Test your plugin directly in the browser without any local setup:
|
||||
|
||||
1. Single site testing:
|
||||
[Open in WordPress Playground][playground-single-readme]
|
||||
|
||||
2. Multisite testing:
|
||||
[Open in WordPress Playground][playground-multisite-readme]
|
||||
|
||||
[playground-single-readme]: https://playground.wordpress.net/?blueprint-url=https://raw.githubusercontent.com/wpallstars/wp-plugin-starter-template-for-ai-coding/feature/testing-framework/playground/blueprint.json&_t=5
|
||||
[playground-multisite-readme]: https://playground.wordpress.net/?blueprint-url=https://raw.githubusercontent.com/wpallstars/wp-plugin-starter-template-for-ai-coding/feature/testing-framework/playground/multisite-blueprint.json&_t=18
|
||||
|
||||
For more details, see the [Playground Testing](.wiki/Playground-Testing.md) documentation.
|
||||
|
||||
#### PHP Unit Tests
|
||||
|
||||
1. Install Composer dependencies:
|
||||
```bash
|
||||
composer install
|
||||
```
|
||||
|
||||
2. Run PHP unit tests:
|
||||
```bash
|
||||
npm run test:php
|
||||
```
|
||||
|
||||
3. Check PHP coding standards:
|
||||
```bash
|
||||
npm run lint:php
|
||||
```
|
||||
|
||||
4. Fix PHP coding standards issues:
|
||||
```bash
|
||||
npm run fix:php
|
||||
```
|
||||
|
||||
#### End-to-End Tests
|
||||
|
||||
1. Start the WordPress environment:
|
||||
```bash
|
||||
npm run start
|
||||
```
|
||||
|
||||
2. Run Cypress tests in interactive mode:
|
||||
```bash
|
||||
npm run test:e2e
|
||||
```
|
||||
|
||||
3. Run Cypress tests in headless mode:
|
||||
```bash
|
||||
npm run test:e2e:headless
|
||||
```
|
||||
|
||||
### Building for Production
|
||||
|
||||
Use the included build script to create a deployable version of your plugin:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
Or directly:
|
||||
|
||||
```bash
|
||||
./build.sh {VERSION}
|
||||
```
|
||||
|
||||
This will create a ZIP file that you can install in WordPress.
|
||||
|
||||
### Using with Git Updater
|
||||
|
||||
@@ -86,32 +222,38 @@ This template includes functionality that allows users to choose where they want
|
||||
1. In the Plugins list, find your plugin
|
||||
2. Click the "Update Source" link next to the plugin
|
||||
3. Select your preferred update source:
|
||||
- **WordPress.org**: Updates from the official WordPress.org repository
|
||||
- **GitHub**: Updates directly from the GitHub repo
|
||||
- **Gitea**: Updates directly from the Gitea repo
|
||||
* **WordPress.org**: Updates from the official WordPress.org repository
|
||||
* **GitHub**: Updates directly from the GitHub repo
|
||||
* **Gitea**: Updates directly from the Gitea repo
|
||||
4. Click "Save" to apply your preference
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### How do I customize this template for my plugin?
|
||||
|
||||
See the [Starter Prompt](.wiki/Starter-Prompt.md) file for detailed instructions on customizing this template for your specific plugin needs. Make sure to add the .ai-assistant.md file and .ai-workflows/ directory to your AI IDE chat context for the best results.
|
||||
See the [Starter Prompt](.wiki/Starter-Prompt.md) file for detailed instructions on
|
||||
customizing this template for your specific plugin needs.
|
||||
|
||||
Make sure to add the AGENTS.md file and .agents/ directory to your AI IDE chat context
|
||||
for the best results.
|
||||
|
||||
### What files do I need to update with my plugin information?
|
||||
|
||||
The main files you need to update include:
|
||||
|
||||
1. Main plugin file (rename and update header)
|
||||
2. README.md
|
||||
3. readme.txt
|
||||
4. CHANGELOG.md
|
||||
5. composer.json
|
||||
6. languages/pot file
|
||||
7. .github/workflows/
|
||||
8. .wiki/
|
||||
9. .ai-assistant.md
|
||||
10. includes/plugin.php
|
||||
11. includes/core.php
|
||||
12. admin/lib/admin.php
|
||||
6. package.json
|
||||
7. languages/pot file
|
||||
8. .github/workflows/
|
||||
9. .wiki/
|
||||
10. AGENTS.md
|
||||
11. includes/plugin.php
|
||||
12. includes/core.php
|
||||
13. admin/lib/admin.php
|
||||
|
||||
### How do I build and test my plugin?
|
||||
|
||||
@@ -125,7 +267,27 @@ This will create a ZIP file that you can install in WordPress.
|
||||
|
||||
### How do I add custom functionality to my plugin?
|
||||
|
||||
Customize the includes/core.php file to implement your core functionality and the admin/lib/admin.php file for admin-specific functionality.
|
||||
Customize the `includes/core.php` file to implement your core functionality and the
|
||||
`admin/lib/admin.php` file for admin-specific functionality.
|
||||
|
||||
### Is this template compatible with WordPress multisite?
|
||||
|
||||
Yes, this template is fully compatible with WordPress multisite installations.
|
||||
|
||||
We have a testing framework that allows you to verify functionality in both environments.
|
||||
|
||||
You can test multisite compatibility in two ways:
|
||||
|
||||
1. Using WordPress Playground (no Docker required):
|
||||
* [Open Multisite in WordPress Playground][playground-multisite-readme]
|
||||
|
||||
2. Using wp-env (requires Docker):
|
||||
```bash
|
||||
npm run setup:multisite
|
||||
```
|
||||
|
||||
For more details on our testing approach, see the [Testing Framework](.wiki/Testing-Framework.md)
|
||||
and [Playground Testing](.wiki/Playground-Testing.md) documentation.
|
||||
|
||||
## Support & Feedback
|
||||
|
||||
@@ -138,36 +300,256 @@ If you need help with this template, there are several ways to get support:
|
||||
|
||||
Contributions are welcome! Please feel free to submit a Pull Request.
|
||||
|
||||
1. Fork the repository on [GitHub](https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding/) or [Gitea](https://gitea.wpallstars.com/wpallstars/wp-plugin-starter-template-for-ai-coding/)
|
||||
1. Fork the repository on [GitHub][repo-github] or [Gitea][repo-gitea]
|
||||
|
||||
[repo-github]: https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding/
|
||||
[repo-gitea]: https://gitea.wpallstars.com/wpallstars/wp-plugin-starter-template-for-ai-coding/
|
||||
2. Create your feature branch: `git checkout -b feature/amazing-feature`
|
||||
3. Commit your changes: `git commit -m 'Add some amazing feature'`
|
||||
4. Push to the branch: `git push origin feature/amazing-feature`
|
||||
5. Submit a pull request
|
||||
|
||||
For more detailed information, see the [Contributing Guide](.wiki/Contributing.md).
|
||||
|
||||
### Code Quality Tools
|
||||
|
||||
This project uses several automated code quality tools to ensure high standards.
|
||||
|
||||
These tools are free for public repositories and should be integrated into any new
|
||||
repositories based on this template:
|
||||
|
||||
1. **CodeRabbit**: AI-powered code review tool
|
||||
* [Website](https://www.coderabbit.ai/)
|
||||
* Provides automated feedback on pull requests
|
||||
|
||||
2. **CodeFactor**: Continuous code quality monitoring
|
||||
* [Website](https://www.codefactor.io/)
|
||||
* Provides a grade for your codebase
|
||||
|
||||
3. **Codacy**: Code quality and static analysis
|
||||
* [Website](https://www.codacy.com/)
|
||||
* Identifies issues related to code style, security, and performance
|
||||
* Requires a `CODACY_PROJECT_TOKEN` secret in your GitHub repository settings
|
||||
* To set up Codacy:
|
||||
1. Go to [Codacy](https://www.codacy.com/) and sign in with your GitHub account
|
||||
2. Add your repository to Codacy
|
||||
3. Go to your project settings > Integrations > Project API
|
||||
4. Generate a project API token
|
||||
5. Add the token as a secret named `CODACY_PROJECT_TOKEN` in your GitHub repository settings
|
||||
6. Note: Codacy tokens are project-specific, so they need to be added at the
|
||||
repository level. You can use GitHub Actions to securely pass tokens
|
||||
between repositories if needed.
|
||||
|
||||
4. **SonarCloud**: Code quality and security analysis
|
||||
* [Website](https://sonarcloud.io/)
|
||||
* Provides detailed analysis of code quality and security
|
||||
* Requires a `SONAR_TOKEN` secret in your GitHub repository settings
|
||||
* To set up SonarCloud:
|
||||
1. Go to [SonarCloud](https://sonarcloud.io/) and sign in with your GitHub account
|
||||
2. Create a new organization or use an existing one
|
||||
3. Add your repository to SonarCloud
|
||||
4. Generate a token in SonarCloud (Account > Security > Tokens)
|
||||
5. Add the token as a secret named `SONAR_TOKEN` in your GitHub repository or
|
||||
organization settings (see "GitHub Secrets Management" section below)
|
||||
|
||||
5. **PHP_CodeSniffer (PHPCS)**: PHP code style checker
|
||||
* Enforces WordPress Coding Standards
|
||||
* Automatically runs in GitHub Actions workflow
|
||||
* Run locally with `composer phpcs`
|
||||
|
||||
6. **PHP Code Beautifier and Fixer (PHPCBF)**: Automatically fixes coding standard violations
|
||||
* Run locally with `composer phpcbf`
|
||||
|
||||
7. **PHPStan**: PHP static analysis tool
|
||||
* Detects bugs and errors without running the code
|
||||
* Run locally with `composer phpstan`
|
||||
|
||||
8. **PHP Mess Detector (PHPMD)**: Analyzes code for potential problems
|
||||
* Identifies complex code, unused parameters, etc.
|
||||
* Run locally with `composer phpmd`
|
||||
|
||||
For detailed setup instructions, see the [Code Quality Setup Guide](docs/code-quality-setup.md).
|
||||
|
||||
### Using AI Assistants with Code Quality Tools
|
||||
|
||||
When you receive feedback from these code quality tools, you can use AI assistants to help address the issues:
|
||||
|
||||
1. Copy the output from the code quality tool
|
||||
2. Paste it into your AI assistant chat
|
||||
3. Request the AI's assistance to interpret and resolve the reported issues
|
||||
4. Apply the suggested fixes
|
||||
5. Commit the changes and verify that the issues are resolved
|
||||
|
||||
For more information on coding standards and how to pass code quality checks,
|
||||
see the [Coding Standards Guide](.wiki/Coding-Standards.md).
|
||||
|
||||
### GitHub Secrets Management
|
||||
|
||||
GitHub offers three levels of secrets management, each with different scopes and use cases:
|
||||
|
||||
1. **Organization Secrets** (recommended for teams and organizations):
|
||||
* Available at: GitHub Organization > Settings > Secrets and variables > Actions
|
||||
* Scope: Can be shared across multiple repositories within the organization
|
||||
* Benefits: Centralized management, reduced duplication, easier rotation
|
||||
* Recommended for: `SONAR_TOKEN` and other tokens that apply to multiple repositories
|
||||
* Note: You can restrict which repositories can access organization secrets
|
||||
* Note: Codacy tokens (`CODACY_PROJECT_TOKEN`) are project-specific and should be set at the repository level
|
||||
|
||||
2. **Repository Secrets**:
|
||||
* Available at: Repository > Settings > Secrets and variables > Actions
|
||||
* Scope: Limited to a single repository
|
||||
* Benefits: Repository-specific, higher isolation
|
||||
* Recommended for: `CODACY_PROJECT_TOKEN` and other repository-specific credentials
|
||||
or tokens that shouldn't be shared
|
||||
|
||||
3. **Environment Secrets**:
|
||||
* Available at: Repository > Settings > Environments > (select environment) > Environment secrets
|
||||
* Scope: Limited to specific deployment environments (e.g., production, staging)
|
||||
* Benefits: Environment-specific, can have approval requirements
|
||||
* Recommended for: Deployment credentials that vary between environments
|
||||
|
||||
For code quality tools like SonarCloud, organization secrets are recommended if you have
|
||||
multiple repositories that use these tools.
|
||||
|
||||
This approach reduces management overhead and ensures consistent configuration across
|
||||
projects. For Codacy, since tokens are project-specific, they should be set at the
|
||||
repository level.
|
||||
|
||||
### Local Environment Setup for Code Quality Tools
|
||||
|
||||
To run code quality tools locally before committing to GitHub:
|
||||
|
||||
1. **Install dependencies**:
|
||||
|
||||
```bash
|
||||
composer install
|
||||
```
|
||||
|
||||
2. **Run PHP CodeSniffer**:
|
||||
|
||||
```bash
|
||||
composer phpcs
|
||||
```
|
||||
|
||||
3. **Fix coding standards automatically**:
|
||||
|
||||
```bash
|
||||
composer phpcbf
|
||||
```
|
||||
|
||||
4. **Run PHPStan static analysis**:
|
||||
|
||||
```bash
|
||||
composer phpstan
|
||||
```
|
||||
|
||||
5. **Run PHP Mess Detector**:
|
||||
|
||||
```bash
|
||||
composer phpmd
|
||||
```
|
||||
|
||||
6. **Run all linters at once**:
|
||||
|
||||
```bash
|
||||
composer lint
|
||||
```
|
||||
|
||||
7. **Set up environment variables for SonarCloud and Codacy**:
|
||||
|
||||
* **For macOS/Linux**:
|
||||
```bash
|
||||
export SONAR_TOKEN=your_sonar_token
|
||||
export CODACY_PROJECT_TOKEN=your_codacy_token
|
||||
```
|
||||
|
||||
* **For Windows (Command Prompt)**:
|
||||
|
||||
```cmd
|
||||
set SONAR_TOKEN=your_sonar_token
|
||||
set CODACY_PROJECT_TOKEN=your_codacy_token
|
||||
```
|
||||
|
||||
* **For Windows (PowerShell)**:
|
||||
|
||||
```powershell
|
||||
$env:SONAR_TOKEN="your_sonar_token"
|
||||
$env:CODACY_PROJECT_TOKEN="your_codacy_token"
|
||||
```
|
||||
|
||||
8. **Create a .env file** (alternative approach):
|
||||
|
||||
```env
|
||||
# .env (already included in .gitignore to prevent committing secrets)
|
||||
SONAR_TOKEN=your_sonar_token
|
||||
CODACY_PROJECT_TOKEN=your_codacy_token
|
||||
```
|
||||
|
||||
Then load these variables:
|
||||
|
||||
```bash
|
||||
# Using a tool like dotenv
|
||||
source .env
|
||||
```
|
||||
|
||||
9. **Run SonarCloud locally**:
|
||||
|
||||
```bash
|
||||
# Install SonarScanner
|
||||
npm install -g sonarqube-scanner
|
||||
|
||||
# Run analysis
|
||||
sonar-scanner \
|
||||
-Dsonar.projectKey=your_project_key \
|
||||
-Dsonar.organization=your_organization \
|
||||
-Dsonar.sources=. \
|
||||
-Dsonar.host.url=https://sonarcloud.io \
|
||||
-Dsonar.login=$SONAR_TOKEN
|
||||
```
|
||||
|
||||
10. **Run Codacy locally**:
|
||||
|
||||
```bash
|
||||
# Install Codacy CLI
|
||||
npm install -g codacy-coverage
|
||||
|
||||
# Run analysis
|
||||
codacy-analysis-cli analyze --directory . --project-token $CODACY_PROJECT_TOKEN
|
||||
```
|
||||
|
||||
For more detailed instructions, see the [Code Quality Setup Guide](docs/code-quality-setup.md).
|
||||
|
||||
By running these tools locally, you can identify and fix issues before pushing your code
|
||||
to GitHub, ensuring smoother CI/CD workflows.
|
||||
|
||||
## Developers
|
||||
|
||||
### AI-Powered Development
|
||||
|
||||
This repository is configured to work with various AI-powered development tools. You can use any of the following AI IDEs to contribute to this project:
|
||||
This repository is configured to work with various AI-powered development tools.
|
||||
|
||||
- [Augment Code](https://www.augmentcode.com/) - AI-powered coding assistant
|
||||
- [Cursor](https://cursor.com/) - AI-first code editor
|
||||
- [v0](https://v0.dev/) - AI-powered design and development tool
|
||||
- [Windsurf](https://www.windsurf.com/) - AI coding assistant
|
||||
- [Cline](https://cline.bot/) - AI terminal assistant
|
||||
- [Roo Code](https://roocode.com/) - AI pair programmer
|
||||
- [Loveable](https://lovable.dev/) - AI development environment
|
||||
- [Bolt](https://www.bolt.new/) - AI-powered code editor
|
||||
- [Cody](https://sourcegraph.com/cody) - Sourcegraph's AI coding assistant
|
||||
- [Continue](https://continue.dev/) - Open-source AI coding assistant
|
||||
You can use any of the following AI IDEs to contribute to this project:
|
||||
|
||||
* [Augment Code](https://www.augmentcode.com/) - AI-powered coding assistant
|
||||
* [Bolt](https://www.bolt.new/) - AI-powered code editor
|
||||
* [Cline](https://cline.bot/) - AI terminal assistant
|
||||
* [Cody](https://sourcegraph.com/cody) - Sourcegraph's AI coding assistant
|
||||
* [Continue](https://continue.dev/) - Open-source AI coding assistant
|
||||
* [Cursor](https://cursor.com/) - AI-first code editor
|
||||
* [Loveable](https://lovable.dev/) - AI development environment
|
||||
* [Roo Code](https://roocode.com/) - AI pair programmer
|
||||
* [v0](https://v0.dev/) - AI-powered design and development tool
|
||||
* [Windsurf](https://www.windsurf.com/) - AI coding assistant
|
||||
|
||||
The repository includes configuration files for all these tools to ensure a consistent development experience.
|
||||
|
||||
### Git Updater Integration
|
||||
|
||||
This template is designed to work seamlessly with the Git Updater plugin for updates from GitHub and Gitea. To ensure proper integration:
|
||||
This template is designed to work seamlessly with the Git Updater plugin for updates from
|
||||
GitHub and Gitea. To ensure proper integration:
|
||||
|
||||
1. **Required Headers**: The plugin includes specific headers in the main plugin file that Git Updater uses to determine update sources and branches:
|
||||
1. **Required Headers**: The plugin includes specific headers in the main plugin file
|
||||
that Git Updater uses to determine update sources and branches:
|
||||
```php
|
||||
* GitHub Plugin URI: wpallstars/wp-plugin-starter-template-for-ai-coding
|
||||
* GitHub Branch: main
|
||||
@@ -178,32 +560,96 @@ This template is designed to work seamlessly with the Git Updater plugin for upd
|
||||
* Gitea Branch: main
|
||||
```
|
||||
|
||||
2. **Tagging Releases**: When creating a new release, always tag it with the 'v' prefix (e.g., `v0.1.2`) to ensure GitHub Actions can create the proper release assets.
|
||||
2. **Tagging Releases**: When creating a new release, always tag it with the 'v' prefix
|
||||
(e.g., `v0.1.2`) to ensure GitHub Actions can create the proper release assets.
|
||||
|
||||
3. **GitHub Actions**: The repository includes a GitHub Actions workflow that automatically builds the plugin and creates a release with the .zip file when a new tag is pushed.
|
||||
3. **GitHub Actions**: The repository includes a GitHub Actions workflow that automatically
|
||||
builds the plugin and creates a release with the .zip file when a new tag is pushed.
|
||||
|
||||
4. **Update Source Selection**: The template includes a feature that allows users to choose their preferred update source (WordPress.org, GitHub, or Gitea).
|
||||
4. **Update Source Selection**: The template includes a feature that allows users to choose
|
||||
their preferred update source (WordPress.org, GitHub, or Gitea).
|
||||
|
||||
For more information on Git Updater integration, see the [Git Updater Required Headers documentation](https://git-updater.com/knowledge-base/required-headers/).
|
||||
For more information on Git Updater integration, see the
|
||||
[Git Updater Required Headers documentation](https://git-updater.com/knowledge-base/required-headers/).
|
||||
|
||||
## Changelog
|
||||
|
||||
### 0.1.13
|
||||
|
||||
* Improved: Code quality with proper type declarations
|
||||
* Fixed: Inconsistent variable naming (camelCase to snake_case)
|
||||
* Improved: Path handling in admin class
|
||||
* Added: Textdomain loading functionality
|
||||
* Removed: Unused phpcs:ignore comment
|
||||
* Implemented: Proper return type declarations
|
||||
|
||||
### 0.1.12
|
||||
|
||||
* Fixed: WordPress mocking in unit tests
|
||||
* Added: Proper mocking for WordPress functions in tests
|
||||
* Improved: Code quality tool configurations
|
||||
* Added: Detailed code quality checks workflow documentation
|
||||
* Updated: Documentation for better workflow efficiency
|
||||
|
||||
### 0.1.11
|
||||
|
||||
* Improved: Code quality with comprehensive fixes
|
||||
* Fixed: Indentation issues in PHP files
|
||||
* Updated: CSS formatting with modern notation
|
||||
* Fixed: JavaScript issues with proper global variables
|
||||
* Improved: Security by using filter_input() instead of direct superglobal access
|
||||
* Standardized: Naming conventions across the codebase
|
||||
* Fixed: Documentation and comments for better clarity
|
||||
|
||||
### 0.1.10
|
||||
|
||||
* Fixed: Formatting issues in markdown files for better code quality
|
||||
* Fixed: Improved URL formatting with angle brackets
|
||||
* Fixed: Standardized list formatting across documentation files
|
||||
|
||||
### 0.1.9
|
||||
|
||||
* Changed: Alphabetized AI IDE list.
|
||||
|
||||
### 0.1.8
|
||||
|
||||
* Added: More informative badges (Build Status, Requirements, WP.org placeholders, Release, Issues, Contributors, Wiki).
|
||||
|
||||
### 0.1.7
|
||||
|
||||
* Fixed: GitHub Actions tests workflow with proper file paths and dependencies
|
||||
|
||||
### 0.1.6
|
||||
|
||||
* Fixed: GitHub Actions workflows permissions for releases and wiki sync
|
||||
|
||||
### 0.1.5
|
||||
|
||||
* Fixed: Release workflow to use correct plugin directory name
|
||||
* Added: Testing setup with wp-env and Cypress
|
||||
* Added: Multisite compatibility
|
||||
* Added: npm scripts for development and testing
|
||||
|
||||
### 0.1.3
|
||||
|
||||
* Added: Improved AI IDE context recommendations in documentation
|
||||
* Enhanced: Starter Prompt with guidance on pinning .ai-assistant.md and .ai-workflows/
|
||||
* Enhanced: Starter Prompt with guidance on pinning AGENTS.md and .agents/
|
||||
* Moved: Starter Prompt to the wiki for better organization
|
||||
* Updated: README.md and readme.txt with AI IDE context recommendations
|
||||
* Improved: Documentation for AI-assisted development
|
||||
|
||||
### 0.1.2
|
||||
|
||||
* Added: STARTER-PROMPT.md with comprehensive guide for customizing the template
|
||||
* Updated: Documentation files with improved instructions
|
||||
* Added: Additional AI workflow files for better development guidance
|
||||
|
||||
### 0.1.1
|
||||
|
||||
* Updated: LICENSE file with correct GPL-2.0 text
|
||||
|
||||
### 0.1.0
|
||||
|
||||
* Initial release with basic template structure
|
||||
* Added: Core plugin architecture with OOP approach
|
||||
* Added: Admin interface components and styling
|
||||
@@ -221,4 +667,7 @@ This project is licensed under the GPL-2.0+ License - see the [LICENSE](LICENSE)
|
||||
|
||||
## Credits
|
||||
|
||||
This template is based on the experience gained from developing the ["Fix 'Plugin file does not exist' Notices"](https://github.com/wpallstars/wp-fix-plugin-does-not-exist-notices) plugin by WPALLSTARS.
|
||||
This template is based on the experience gained from developing the
|
||||
["Fix 'Plugin file does not exist' Notices"][fix-plugin-notices] plugin by WPALLSTARS.
|
||||
|
||||
[fix-plugin-notices]: https://github.com/wpallstars/wp-fix-plugin-does-not-exist-notices
|
||||
|
||||
342
WARP.md
Normal file
342
WARP.md
Normal file
@@ -0,0 +1,342 @@
|
||||
# WARP.md
|
||||
|
||||
This file provides guidance to WARP (warp.dev) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
**WordPress Plugin Starter Template** - A comprehensive starter template for WordPress plugins with best practices for AI-assisted development.
|
||||
|
||||
* **Plugin Slug**: wp-plugin-starter-template
|
||||
* **Namespace**: `WPALLSTARS\PluginStarterTemplate`
|
||||
* **Text Domain**: wp-plugin-starter-template
|
||||
* **Requirements**: WordPress 5.0+, PHP 7.4+
|
||||
* **License**: GPL-2.0+
|
||||
|
||||
## Common Development Commands
|
||||
|
||||
### Environment Setup
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
composer install
|
||||
|
||||
# Start local WordPress environment (requires Docker)
|
||||
npm run start
|
||||
|
||||
# Stop WordPress environment
|
||||
npm run stop
|
||||
|
||||
# Setup single-site test environment
|
||||
npm run setup:single
|
||||
|
||||
# Setup multisite test environment
|
||||
npm run setup:multisite
|
||||
```
|
||||
|
||||
Local WordPress site runs at: <http://localhost:8888> (admin: admin/password)
|
||||
|
||||
### Testing
|
||||
|
||||
```bash
|
||||
# PHP unit tests
|
||||
npm run test:php
|
||||
composer test
|
||||
|
||||
# E2E tests (Cypress)
|
||||
npm run test:e2e:single
|
||||
npm run test:e2e:multisite
|
||||
|
||||
# Run specific test configurations
|
||||
npm run test:single # Interactive single-site
|
||||
npm run test:multisite # Interactive multisite
|
||||
npm run test:single:headless # Headless single-site
|
||||
npm run test:multisite:headless # Headless multisite
|
||||
|
||||
# Playground tests (no Docker required)
|
||||
npm run test:playground:single
|
||||
npm run test:playground:multisite
|
||||
```
|
||||
|
||||
### Code Quality & Linting
|
||||
|
||||
```bash
|
||||
# PHP linting and fixing
|
||||
npm run lint:php # Run PHPCS
|
||||
npm run fix:php # Run PHPCBF
|
||||
composer run phpcs # Run PHPCS directly
|
||||
composer run phpcbf # Run PHPCBF directly
|
||||
|
||||
# Static analysis
|
||||
npm run lint:phpstan # PHPStan
|
||||
composer run phpstan
|
||||
|
||||
npm run lint:phpmd # PHP Mess Detector
|
||||
composer run phpmd
|
||||
|
||||
# JavaScript linting
|
||||
npm run lint:js
|
||||
|
||||
# Run all linters
|
||||
npm run lint # Runs phpcs, phpstan, phpmd
|
||||
composer run lint
|
||||
|
||||
# Run quality checks and tests
|
||||
npm run quality
|
||||
```
|
||||
|
||||
### Building & Release
|
||||
|
||||
```bash
|
||||
# Build plugin ZIP for distribution
|
||||
npm run build
|
||||
# or
|
||||
./build.sh {VERSION}
|
||||
|
||||
# Example:
|
||||
./build.sh 1.0.0
|
||||
```
|
||||
|
||||
The build script creates a deployable ZIP file in the repository root.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Plugin Initialization Flow
|
||||
|
||||
1. **Main Plugin File** (`wp-plugin-starter-template.php`):
|
||||
* Defines constants (`WP_PLUGIN_STARTER_TEMPLATE_FILE`, `_PATH`, `_URL`, `_VERSION`)
|
||||
* Registers custom autoloader for namespaced classes
|
||||
* Instantiates `Plugin` class
|
||||
* Calls `init()` method
|
||||
|
||||
2. **Autoloader**:
|
||||
* Converts namespace `WPALLSTARS\PluginStarterTemplate` to file paths
|
||||
* Looks for class files in `includes/` directory
|
||||
* Uses PSR-4 naming with class file prefix conversion
|
||||
|
||||
3. **Plugin Class** (`includes/class-plugin.php`):
|
||||
* Main orchestration class
|
||||
* Instantiates `Core` and `Admin` classes
|
||||
* Registers hooks and loads text domain
|
||||
* Provides getters for version and admin instance
|
||||
|
||||
4. **Core Class** (`includes/class-core.php`):
|
||||
* Contains core plugin functionality
|
||||
* Provides version management
|
||||
* Houses filter/action methods
|
||||
|
||||
5. **Admin Class** (`includes/Admin/class-admin.php`):
|
||||
* Manages admin-specific functionality
|
||||
* Handles admin menu, pages, and UI
|
||||
|
||||
### Directory Structure
|
||||
|
||||
```
|
||||
wp-plugin-starter-template-for-ai-coding/
|
||||
├── wp-plugin-starter-template.php # Main plugin file with headers
|
||||
├── includes/ # Core plugin classes
|
||||
│ ├── class-plugin.php # Main plugin orchestration
|
||||
│ ├── class-core.php # Core functionality
|
||||
│ ├── updater.php # Update mechanism
|
||||
│ ├── Admin/ # Admin-specific classes
|
||||
│ └── Multisite/ # Multisite-specific functionality
|
||||
├── admin/ # Admin UI resources
|
||||
│ ├── lib/ # Admin classes
|
||||
│ ├── css/ # Admin stylesheets
|
||||
│ ├── js/ # Admin JavaScript
|
||||
│ └── templates/ # Admin template files
|
||||
├── tests/ # PHPUnit and test files
|
||||
├── cypress/ # E2E tests
|
||||
├── .github/workflows/ # CI/CD workflows
|
||||
├── .agents/ # AI assistant documentation
|
||||
├── .wiki/ # Wiki documentation
|
||||
└── languages/ # Translation files
|
||||
```
|
||||
|
||||
### Key Architectural Patterns
|
||||
|
||||
* **Object-Oriented**: All functionality in namespaced classes
|
||||
* **PSR-4 Autoloading**: Automatic class loading without require statements
|
||||
* **Dependency Injection**: `Admin` receives `Core` instance via constructor
|
||||
* **Separation of Concerns**: Core functionality, admin UI, and multisite features are isolated
|
||||
* **Hook-Based**: WordPress hooks for extensibility
|
||||
|
||||
## Coding Standards
|
||||
|
||||
### PHP Standards (WordPress Coding Standards)
|
||||
|
||||
* **Indentation**: 4 spaces (project-specific override of WordPress tabs)
|
||||
* **Naming Conventions**:
|
||||
* Classes: `Class_Name`
|
||||
* Functions: `function_name`
|
||||
* Variables: `$variable_name`
|
||||
* **Documentation**: DocBlocks required for all classes, methods, and functions
|
||||
* **Internationalization**: All user-facing strings must be translatable with text domain `wp-plugin-starter-template`
|
||||
|
||||
### Markdown Standards
|
||||
|
||||
* Use asterisks (`*`) for bullet points, never hyphens (`-`)
|
||||
* Add periods to the end of all inline comments
|
||||
|
||||
### Code Quality Tools
|
||||
|
||||
The project uses several automated tools integrated via CI/CD:
|
||||
|
||||
* **PHP_CodeSniffer**: Enforces WordPress Coding Standards
|
||||
* **PHPCBF**: Auto-fixes coding standard violations
|
||||
* **PHPStan**: Static analysis (level 5)
|
||||
* **PHPMD**: Detects code complexity issues
|
||||
* **ESLint**: JavaScript linting
|
||||
* **Stylelint**: CSS linting
|
||||
* **CodeRabbit, CodeFactor, Codacy, SonarCloud**: Continuous quality monitoring
|
||||
|
||||
Always run `npm run lint` or `composer run lint` before committing.
|
||||
|
||||
## Security Requirements
|
||||
|
||||
* Validate and sanitize all inputs (use `sanitize_*()` functions)
|
||||
* Escape all outputs (use `esc_*()` functions)
|
||||
* Use nonces for form submissions
|
||||
* Check user capabilities before allowing actions
|
||||
* Never expose secrets in plain text
|
||||
|
||||
## Release Process
|
||||
|
||||
### Version Numbering
|
||||
|
||||
Follow semantic versioning (MAJOR.MINOR.PATCH):
|
||||
|
||||
* **PATCH**: Bug fixes (1.0.0 → 1.0.1)
|
||||
* **MINOR**: New features, backward-compatible (1.0.0 → 1.1.0)
|
||||
* **MAJOR**: Breaking changes (1.0.0 → 2.0.0)
|
||||
|
||||
### Release Steps
|
||||
|
||||
1. Create version branch from main: `git checkout -b v{MAJOR}.{MINOR}.{PATCH}`
|
||||
2. Update version in:
|
||||
* `wp-plugin-starter-template.php` (header and constant)
|
||||
* `readme.txt` (Stable tag and changelog)
|
||||
* `README.md` (changelog)
|
||||
* `CHANGELOG.md`
|
||||
* `languages/wp-plugin-starter-template.pot`
|
||||
3. Run code quality checks: `npm run quality`
|
||||
4. Build plugin: `./build.sh {VERSION}`
|
||||
5. Test thoroughly (single-site and multisite)
|
||||
6. Commit: `git commit -m "Version {VERSION} - [description]"`
|
||||
7. Tag: `git tag -a v{VERSION} -m "Version {VERSION}"`
|
||||
8. Tag stable: `git tag -a v{VERSION}-stable -m "Stable version {VERSION}"`
|
||||
9. Push to remotes: `git push github main --tags && git push gitea main --tags`
|
||||
|
||||
**Important**: Tags with 'v' prefix trigger GitHub Actions to build and create releases automatically.
|
||||
|
||||
## Git Updater Integration
|
||||
|
||||
This template works with the Git Updater plugin for updates from GitHub and Gitea.
|
||||
|
||||
Required headers in main plugin file:
|
||||
|
||||
```php
|
||||
* GitHub Plugin URI: wpallstars/wp-plugin-starter-template-for-ai-coding
|
||||
* GitHub Branch: main
|
||||
* Gitea Plugin URI: https://gitea.wpallstars.com/wpallstars/wp-plugin-starter-template-for-ai-coding
|
||||
* Gitea Branch: main
|
||||
```
|
||||
|
||||
Users can choose their update source (WordPress.org, GitHub, or Gitea) via plugin settings.
|
||||
|
||||
## Testing Framework
|
||||
|
||||
### WordPress Playground Testing
|
||||
|
||||
Test without Docker using WordPress Playground blueprints:
|
||||
|
||||
* Single-site: <https://playground.wordpress.net/?blueprint-url=https://raw.githubusercontent.com/wpallstars/wp-plugin-starter-template-for-ai-coding/feature/testing-framework/playground/blueprint.json>
|
||||
* Multisite: <https://playground.wordpress.net/?blueprint-url=https://raw.githubusercontent.com/wpallstars/wp-plugin-starter-template-for-ai-coding/feature/testing-framework/playground/multisite-blueprint.json>
|
||||
|
||||
### Local Testing with wp-env
|
||||
|
||||
`.wp-env.json` and `.wp-env.multisite.json` configure WordPress environments.
|
||||
|
||||
## AI-Assisted Development
|
||||
|
||||
This repository includes comprehensive AI workflow documentation in `.agents/`:
|
||||
|
||||
* `feature-development.md`: Adding new features
|
||||
* `bug-fixing.md`: Diagnosing and fixing issues
|
||||
* `release-process.md`: Creating releases
|
||||
* `code-quality-checks.md`: Running quality tools
|
||||
* `error-checking-feedback-loops.md`: Monitoring CI/CD
|
||||
* `git-workflow.md`: Git best practices
|
||||
* `wiki-documentation.md`: Maintaining documentation
|
||||
|
||||
Reference these workflows with `@.agents/{filename}` syntax.
|
||||
|
||||
## Multi-Repository Workspace Context
|
||||
|
||||
When working in a workspace with multiple repositories:
|
||||
|
||||
1. Always verify you're in the correct repository: `pwd` and `git remote -v`
|
||||
2. Never assume features from other repositories exist here
|
||||
3. Don't hallucinate functionality from other repositories in the workspace
|
||||
4. Each repository has its own specific purpose and feature set
|
||||
5. Repository-specific documentation reflects only actual features in this repository
|
||||
|
||||
## GitHub Actions Workflows
|
||||
|
||||
* `tests.yml`: PHPUnit tests
|
||||
* `phpunit.yml`: Additional PHPUnit configurations
|
||||
* `code-quality.yml`: Runs PHPCS, PHPStan, PHPMD
|
||||
* `sonarcloud.yml`: SonarCloud analysis
|
||||
* `playground-tests.yml`: Tests in WordPress Playground
|
||||
* `release.yml`: Creates releases when tags are pushed
|
||||
* `sync-wiki.yml`: Syncs `.wiki/` to GitHub wiki
|
||||
|
||||
Workflows run automatically on push and pull requests.
|
||||
|
||||
## Internationalization (i18n)
|
||||
|
||||
All user-facing strings must use translation functions:
|
||||
|
||||
```php
|
||||
// Simple strings
|
||||
__('Text', 'wp-plugin-starter-template')
|
||||
|
||||
// Echoed strings
|
||||
_e('Text', 'wp-plugin-starter-template')
|
||||
|
||||
// Escaped strings
|
||||
esc_html__('Text', 'wp-plugin-starter-template')
|
||||
|
||||
// Escaped and echoed
|
||||
esc_html_e('Text', 'wp-plugin-starter-template')
|
||||
```
|
||||
|
||||
Translation files are in `languages/` directory.
|
||||
|
||||
## Multisite Compatibility
|
||||
|
||||
Fully compatible with WordPress multisite. Multisite-specific functionality is in `includes/Multisite/`.
|
||||
|
||||
Test multisite with:
|
||||
|
||||
* `npm run setup:multisite`
|
||||
* `npm run test:e2e:multisite`
|
||||
* WordPress Playground multisite blueprint
|
||||
|
||||
## Documentation Maintenance
|
||||
|
||||
When adding features or making changes:
|
||||
|
||||
1. Update `CHANGELOG.md` and `readme.txt` changelog
|
||||
2. Update `README.md` if user-facing functionality changes
|
||||
3. Update `.wiki/` documentation (syncs to GitHub wiki)
|
||||
4. Update inline code comments and DocBlocks
|
||||
5. Follow markdown standards (asterisks for bullets, periods in comments)
|
||||
|
||||
## Reference
|
||||
|
||||
* WordPress Coding Standards: <https://developer.wordpress.org/coding-standards/>
|
||||
* Git Updater Headers: <https://git-updater.com/knowledge-base/required-headers/>
|
||||
* Testing Framework: `.wiki/Testing-Framework.md`
|
||||
* Playground Testing: `.wiki/Playground-Testing.md`
|
||||
* Code Quality Setup: `docs/code-quality-setup.md`
|
||||
@@ -11,7 +11,7 @@
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 1px 3px rgb(0 0 0 / 10%);
|
||||
}
|
||||
|
||||
.wpst-admin-header {
|
||||
@@ -98,7 +98,7 @@
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 1px 3px rgb(0 0 0 / 10%);
|
||||
}
|
||||
|
||||
.wpst-card-header {
|
||||
@@ -123,19 +123,19 @@
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* Responsive Styles */
|
||||
/* 782px is the WordPress mobile admin breakpoint. */
|
||||
@media screen and (max-width: 782px) {
|
||||
.wpst-form-table th {
|
||||
width: 100%;
|
||||
display: block;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
.wpst-form-table td {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
.wpst-form-table input[type="text"],
|
||||
.wpst-form-table input[type="number"],
|
||||
.wpst-form-table select,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
background-color: rgb(0 0 0 / 40%);
|
||||
}
|
||||
|
||||
.wpst-modal-content {
|
||||
@@ -23,7 +23,7 @@
|
||||
margin: 10% auto;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 4px 8px rgb(0 0 0 / 10%);
|
||||
width: 500px;
|
||||
max-width: 90%;
|
||||
}
|
||||
@@ -45,7 +45,7 @@
|
||||
top: 10px;
|
||||
right: 15px;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
font-weight: 700;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -108,7 +108,7 @@
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 2px solid rgba(0, 0, 0, 0.1);
|
||||
border: 2px solid rgb(0 0 0 / 10%);
|
||||
border-radius: 50%;
|
||||
border-top-color: #0073aa;
|
||||
animation: wpst-spin 1s ease-in-out infinite;
|
||||
|
||||
@@ -4,122 +4,138 @@
|
||||
* @package WPALLSTARS\PluginStarterTemplate
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
'use strict';
|
||||
(function ($) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Admin functionality
|
||||
*/
|
||||
const WPSTAdmin = {
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
init: function () {
|
||||
// Initialize components.
|
||||
this.initComponents();
|
||||
|
||||
// Bind events.
|
||||
this.bindEvents();
|
||||
},
|
||||
|
||||
/**
|
||||
* Admin functionality
|
||||
*/
|
||||
const WPSTAdmin = {
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
init: function() {
|
||||
// Initialize components
|
||||
this.initComponents();
|
||||
|
||||
// Bind events
|
||||
this.bindEvents();
|
||||
* Initialize components
|
||||
*/
|
||||
initComponents: function () {
|
||||
// Initialize any components here.
|
||||
},
|
||||
|
||||
/**
|
||||
* Bind events
|
||||
*/
|
||||
bindEvents: function () {
|
||||
// Example: Toggle sections.
|
||||
$( '.wpst-toggle-section' ).on( 'click', this.toggleSection );
|
||||
|
||||
// Example: Form submission.
|
||||
$( '#wpst-settings-form' ).on( 'submit', this.handleFormSubmit );
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle section visibility
|
||||
*
|
||||
* @param {Event} e Click event
|
||||
*/
|
||||
toggleSection: function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
const $this = $( this );
|
||||
const target = $this.data( 'target' );
|
||||
|
||||
$( target ).slideToggle( 200 );
|
||||
$this.toggleClass( 'open' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle form submission
|
||||
*
|
||||
* @param {Event} e Submit event
|
||||
*/
|
||||
handleFormSubmit: function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
const $form = $( this );
|
||||
const $submitButton = $form.find( 'input[type="submit"]' );
|
||||
const formData = $form.serialize();
|
||||
|
||||
// Disable submit button and show loading state.
|
||||
$submitButton.prop( 'disabled', true ).addClass( 'loading' );
|
||||
|
||||
// Send AJAX request.
|
||||
$.ajax(
|
||||
{
|
||||
url: wpstData.ajaxUrl,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'wpst_save_settings',
|
||||
nonce: wpstData.nonce,
|
||||
formData: formData,
|
||||
},
|
||||
success: function (response) {
|
||||
if (response.success) {
|
||||
WPSTAdmin.showNotice( 'success', response.data.message );
|
||||
} else {
|
||||
WPSTAdmin.showNotice( 'error', response.data.message );
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
WPSTAdmin.showNotice( 'error', 'An error occurred. Please try again.' );
|
||||
},
|
||||
complete: function () {
|
||||
// Re-enable submit button and remove loading state.
|
||||
$submitButton.prop( 'disabled', false ).removeClass( 'loading' );
|
||||
},
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize components
|
||||
*/
|
||||
initComponents: function() {
|
||||
// Initialize any components here
|
||||
/**
|
||||
* Show admin notice
|
||||
*
|
||||
* @param {string} type Notice type (success, error, warning)
|
||||
* @param {string} message Notice message
|
||||
*/
|
||||
showNotice: function (type, message) {
|
||||
const allowedTypes = [ 'success', 'error', 'warning' ];
|
||||
const safeType = allowedTypes.includes( type ) ? type : 'error';
|
||||
const $p = $( '<p>' );
|
||||
const $notice = $( '<div>' ).addClass( 'wpst-notice ' + safeType ).append( $p );
|
||||
|
||||
// Set message as plain text to prevent XSS.
|
||||
$p.text( message );
|
||||
|
||||
// Add notice to the page.
|
||||
$( '.wpst-notices' ).empty().append( $notice );
|
||||
|
||||
// Automatically remove notice after 5 seconds.
|
||||
setTimeout(
|
||||
function () {
|
||||
$notice.fadeOut(
|
||||
300,
|
||||
function () {
|
||||
$( this ).remove();
|
||||
},
|
||||
);
|
||||
},
|
||||
5000,
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Bind events
|
||||
*/
|
||||
bindEvents: function() {
|
||||
// Example: Toggle sections
|
||||
$('.wpst-toggle-section').on('click', this.toggleSection);
|
||||
|
||||
// Example: Form submission
|
||||
$('#wpst-settings-form').on('submit', this.handleFormSubmit);
|
||||
},
|
||||
// Initialize when document is ready.
|
||||
$( document ).ready(
|
||||
function () {
|
||||
WPSTAdmin.init();
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Toggle section visibility
|
||||
*
|
||||
* @param {Event} e Click event
|
||||
*/
|
||||
toggleSection: function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const $this = $(this);
|
||||
const target = $this.data('target');
|
||||
|
||||
$(target).slideToggle(200);
|
||||
$this.toggleClass('open');
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle form submission
|
||||
*
|
||||
* @param {Event} e Submit event
|
||||
*/
|
||||
handleFormSubmit: function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const $form = $(this);
|
||||
const $submitButton = $form.find('input[type="submit"]');
|
||||
const formData = $form.serialize();
|
||||
|
||||
// Disable submit button and show loading state
|
||||
$submitButton.prop('disabled', true).addClass('loading');
|
||||
|
||||
// Send AJAX request
|
||||
$.ajax({
|
||||
url: wpstData.ajaxUrl,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'wpst_save_settings',
|
||||
nonce: wpstData.nonce,
|
||||
formData: formData
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
WPSTAdmin.showNotice('success', response.data.message);
|
||||
} else {
|
||||
WPSTAdmin.showNotice('error', response.data.message);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
WPSTAdmin.showNotice('error', 'An error occurred. Please try again.');
|
||||
},
|
||||
complete: function() {
|
||||
// Re-enable submit button and remove loading state
|
||||
$submitButton.prop('disabled', false).removeClass('loading');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Show admin notice
|
||||
*
|
||||
* @param {string} type Notice type (success, error, warning)
|
||||
* @param {string} message Notice message
|
||||
*/
|
||||
showNotice: function(type, message) {
|
||||
const $notice = $('<div class="wpst-notice ' + type + '"><p>' + message + '</p></div>');
|
||||
|
||||
// Add notice to the page
|
||||
$('.wpst-notices').html($notice);
|
||||
|
||||
// Automatically remove notice after 5 seconds
|
||||
setTimeout(function() {
|
||||
$notice.fadeOut(300, function() {
|
||||
$(this).remove();
|
||||
});
|
||||
}, 5000);
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize when document is ready
|
||||
$(document).ready(function() {
|
||||
WPSTAdmin.init();
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
})( jQuery );
|
||||
|
||||
@@ -4,161 +4,179 @@
|
||||
* @package WPALLSTARS\PluginStarterTemplate
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
'use strict';
|
||||
(function ($) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Update Source Selector functionality
|
||||
*/
|
||||
const WPSTUpdateSourceSelector = {
|
||||
/**
|
||||
* Modal element
|
||||
*/
|
||||
$modal: null,
|
||||
|
||||
/**
|
||||
* Update Source Selector functionality
|
||||
*/
|
||||
const WPSTUpdateSourceSelector = {
|
||||
/**
|
||||
* Modal element
|
||||
*/
|
||||
$modal: null,
|
||||
* Selected source
|
||||
*/
|
||||
selectedSource: '',
|
||||
|
||||
/**
|
||||
* Selected source
|
||||
*/
|
||||
selectedSource: '',
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
init: function () {
|
||||
// Cache DOM elements.
|
||||
this.$modal = $( '#wpst-update-source-modal' );
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
init: function() {
|
||||
// Cache DOM elements
|
||||
this.$modal = $('#wpst-update-source-modal');
|
||||
|
||||
// Bind events
|
||||
this.bindEvents();
|
||||
// Bind events.
|
||||
this.bindEvents();
|
||||
},
|
||||
|
||||
/**
|
||||
* Bind events
|
||||
*/
|
||||
bindEvents: function () {
|
||||
// Open modal when clicking on the update source link.
|
||||
$( document ).on( 'click', '.wpst-update-source-selector', this.openModal.bind( this ) );
|
||||
|
||||
// Close modal when clicking on the close button or outside the modal.
|
||||
this.$modal.on( 'click', '.wpst-modal-close', this.closeModal.bind( this ) );
|
||||
$( document ).on(
|
||||
'click',
|
||||
'.wpst-modal',
|
||||
function (e) {
|
||||
if ($( e.target ).hasClass( 'wpst-modal' )) {
|
||||
WPSTUpdateSourceSelector.closeModal();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Bind events
|
||||
*/
|
||||
bindEvents: function() {
|
||||
// Open modal when clicking on the update source link
|
||||
$(document).on('click', '.wpst-update-source-selector', this.openModal.bind(this));
|
||||
|
||||
// Close modal when clicking on the close button or outside the modal
|
||||
this.$modal.on('click', '.wpst-modal-close', this.closeModal.bind(this));
|
||||
$(document).on('click', '.wpst-modal', function(e) {
|
||||
if ($(e.target).hasClass('wpst-modal')) {
|
||||
WPSTUpdateSourceSelector.closeModal();
|
||||
}
|
||||
});
|
||||
|
||||
// Select source option
|
||||
this.$modal.on('click', '.wpst-source-option', this.selectSource.bind(this));
|
||||
|
||||
// Save source selection
|
||||
this.$modal.on('click', '#wpst-save-source', this.saveSource.bind(this));
|
||||
},
|
||||
// Select source option.
|
||||
this.$modal.on( 'click', '.wpst-source-option', this.selectSource.bind( this ) );
|
||||
|
||||
/**
|
||||
* Open the modal
|
||||
*
|
||||
* @param {Event} e Click event
|
||||
*/
|
||||
openModal: function(e) {
|
||||
e.preventDefault();
|
||||
this.$modal.show();
|
||||
},
|
||||
// Save source selection.
|
||||
this.$modal.on( 'click', '#wpst-save-source', this.saveSource.bind( this ) );
|
||||
},
|
||||
|
||||
/**
|
||||
* Close the modal
|
||||
*/
|
||||
closeModal: function() {
|
||||
this.$modal.hide();
|
||||
},
|
||||
/**
|
||||
* Open the modal
|
||||
*
|
||||
* @param {Event} e Click event
|
||||
*/
|
||||
openModal: function (e) {
|
||||
e.preventDefault();
|
||||
this.$modal.show();
|
||||
},
|
||||
|
||||
/**
|
||||
* Select a source option
|
||||
*
|
||||
* @param {Event} e Click event
|
||||
*/
|
||||
selectSource: function(e) {
|
||||
const $option = $(e.currentTarget);
|
||||
|
||||
// Update selected state
|
||||
this.$modal.find('.wpst-source-option').removeClass('selected');
|
||||
$option.addClass('selected');
|
||||
|
||||
// Update radio button
|
||||
$option.find('input[type="radio"]').prop('checked', true);
|
||||
|
||||
// Store selected source
|
||||
this.selectedSource = $option.find('input[type="radio"]').val();
|
||||
},
|
||||
/**
|
||||
* Close the modal
|
||||
*/
|
||||
closeModal: function () {
|
||||
this.$modal.hide();
|
||||
},
|
||||
|
||||
/**
|
||||
* Save the selected source
|
||||
*/
|
||||
saveSource: function() {
|
||||
// Validate selection
|
||||
if (!this.selectedSource) {
|
||||
this.showMessage('error', 'Please select an update source.');
|
||||
return;
|
||||
/**
|
||||
* Select a source option
|
||||
*
|
||||
* @param {Event} e Click event
|
||||
*/
|
||||
selectSource: function (e) {
|
||||
const $option = $( e.currentTarget );
|
||||
|
||||
// Update selected state.
|
||||
this.$modal.find( '.wpst-source-option' ).removeClass( 'selected' );
|
||||
$option.addClass( 'selected' );
|
||||
|
||||
// Update radio button.
|
||||
$option.find( 'input[type="radio"]' ).prop( 'checked', true );
|
||||
|
||||
// Store selected source.
|
||||
this.selectedSource = $option.find( 'input[type="radio"]' ).val();
|
||||
},
|
||||
|
||||
/**
|
||||
* Save the selected source
|
||||
*/
|
||||
saveSource: function () {
|
||||
// Validate selection.
|
||||
if ( ! this.selectedSource) {
|
||||
this.showMessage( 'error', 'Please select an update source.' );
|
||||
return;
|
||||
}
|
||||
|
||||
// Show loading state.
|
||||
const $saveButton = $( '#wpst-save-source' );
|
||||
$saveButton.prop( 'disabled', true ).html( '<span class="wpst-loading"></span> Saving...' );
|
||||
|
||||
// Send AJAX request.
|
||||
$.ajax(
|
||||
{
|
||||
url: wpstModalData.ajaxUrl, // WordPress AJAX URL.
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'wpst_set_update_source', // AJAX action hook.
|
||||
nonce: wpstModalData.nonce, // Security nonce.
|
||||
source: this.selectedSource,
|
||||
},
|
||||
success: function (response) {
|
||||
if (response.success) {
|
||||
WPSTUpdateSourceSelector.showMessage( 'success', response.data.message );
|
||||
|
||||
// Close modal after a short delay.
|
||||
setTimeout(
|
||||
function () {
|
||||
WPSTUpdateSourceSelector.closeModal();
|
||||
},
|
||||
1500,
|
||||
);
|
||||
} else {
|
||||
WPSTUpdateSourceSelector.showMessage( 'error', response.data.message );
|
||||
}
|
||||
|
||||
// Show loading state
|
||||
const $saveButton = $('#wpst-save-source');
|
||||
$saveButton.prop('disabled', true).html('<span class="wpst-loading"></span> Saving...');
|
||||
|
||||
// Send AJAX request
|
||||
$.ajax({
|
||||
url: wpstModalData.ajaxUrl,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'wpst_set_update_source',
|
||||
nonce: wpstModalData.nonce,
|
||||
source: this.selectedSource
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
WPSTUpdateSourceSelector.showMessage('success', response.data.message);
|
||||
|
||||
// Close modal after a short delay
|
||||
setTimeout(function() {
|
||||
WPSTUpdateSourceSelector.closeModal();
|
||||
}, 1500);
|
||||
} else {
|
||||
WPSTUpdateSourceSelector.showMessage('error', response.data.message);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
WPSTUpdateSourceSelector.showMessage('error', 'An error occurred. Please try again.');
|
||||
},
|
||||
complete: function() {
|
||||
// Reset button state
|
||||
$saveButton.prop('disabled', false).text(wpstModalData.i18n.confirm);
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function () {
|
||||
WPSTUpdateSourceSelector.showMessage( 'error', 'An error occurred. Please try again.' );
|
||||
},
|
||||
complete: function () {
|
||||
// Reset button state.
|
||||
$saveButton.prop( 'disabled', false ).text( wpstModalData.i18n.confirm );
|
||||
},
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Show a message in the modal
|
||||
*
|
||||
* @param {string} type Message type (success, error)
|
||||
* @param {string} message Message text
|
||||
*/
|
||||
showMessage: function(type, message) {
|
||||
const $message = this.$modal.find('.wpst-modal-message');
|
||||
|
||||
// Set message content and type
|
||||
$message.html(message).removeClass('success error').addClass(type).show();
|
||||
|
||||
// Hide message after a delay for success messages
|
||||
if (type === 'success') {
|
||||
setTimeout(function() {
|
||||
$message.fadeOut(300);
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Show a message in the modal
|
||||
*
|
||||
* @param {string} type Message type (success, error)
|
||||
* @param {string} message Message text
|
||||
*/
|
||||
showMessage: function (type, message) {
|
||||
const $message = this.$modal.find( '.wpst-modal-message' );
|
||||
|
||||
// Initialize when document is ready
|
||||
$(document).ready(function() {
|
||||
WPSTUpdateSourceSelector.init();
|
||||
});
|
||||
// Validate type against allow-list to prevent class injection vulnerabilities.
|
||||
const allowedTypes = [ 'success', 'error' ];
|
||||
const safeType = allowedTypes.includes( type ) ? type : 'error';
|
||||
|
||||
})(jQuery);
|
||||
// Set message as plain text to prevent XSS, then apply validated type class.
|
||||
$message.text( message ).removeClass( 'success error' ).addClass( safeType ).show();
|
||||
|
||||
// Hide message after a delay for success messages.
|
||||
if (safeType === 'success') {
|
||||
setTimeout(
|
||||
function () {
|
||||
$message.fadeOut( 300 );
|
||||
},
|
||||
3000,
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Initialize when document is ready.
|
||||
$( document ).ready(
|
||||
function () {
|
||||
WPSTUpdateSourceSelector.init();
|
||||
},
|
||||
);
|
||||
|
||||
})( jQuery );
|
||||
|
||||
@@ -1 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin area specific functions.
|
||||
*
|
||||
* @package WPALLSTARS\PluginStarterTemplate\Admin\Lib
|
||||
* @file
|
||||
*/
|
||||
|
||||
@@ -1 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Modal related functions for the admin area.
|
||||
*
|
||||
* @package WPALLSTARS\PluginStarterTemplate\Admin\Lib
|
||||
*/
|
||||
|
||||
/**
|
||||
* File: modal.php
|
||||
* Description: Modal related functions for the admin area.
|
||||
* Version: 1.0
|
||||
* Author: Your Name
|
||||
* Author URI: https://yourwebsite.com
|
||||
*/
|
||||
|
||||
@@ -2,64 +2,67 @@
|
||||
/**
|
||||
* Modal Template
|
||||
*
|
||||
* @package WPALLSTARS\PluginStarterTemplate
|
||||
* @package WPALLSTARS\PluginStarterTemplate\Admin\Templates
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('WPINC')) {
|
||||
// Ensure this file is loaded within WordPress.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die;
|
||||
}
|
||||
?>
|
||||
|
||||
<!-- Update Source Modal -->
|
||||
<div id="wpst-update-source-modal" class="wpst-modal">
|
||||
<div
|
||||
id="wpst-update-source-modal"
|
||||
class="wpst-modal"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="wpst-update-source-modal-title"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div class="wpst-modal-content">
|
||||
<div class="wpst-modal-header">
|
||||
<h2 class="wpst-modal-title"><?php esc_html_e('Select Update Source', 'wp-plugin-starter-template'); ?></h2>
|
||||
<span class="wpst-modal-close">×</span>
|
||||
<h2 id="wpst-update-source-modal-title" class="wpst-modal-title"><?php esc_html_e( 'Select Update Source', 'wp-plugin-starter-template' ); ?></h2>
|
||||
<button
|
||||
type="button"
|
||||
class="wpst-modal-close"
|
||||
aria-label="<?php esc_attr_e( 'Close dialog', 'wp-plugin-starter-template' ); ?>"
|
||||
>×</button>
|
||||
</div>
|
||||
|
||||
<div class="wpst-modal-body">
|
||||
<p><?php esc_html_e('Choose your preferred source for plugin updates:', 'wp-plugin-starter-template'); ?></p>
|
||||
<p><?php esc_html_e( 'Choose your preferred source for plugin updates:', 'wp-plugin-starter-template' ); ?></p>
|
||||
|
||||
<div class="wpst-modal-message"></div>
|
||||
|
||||
<div class="wpst-source-options">
|
||||
<?php
|
||||
// Get current update source
|
||||
$current_source = get_option('wpst_update_source', 'wordpress.org');
|
||||
// Get current update source.
|
||||
$current_source = get_option( 'wpst_update_source', 'wordpress.org' );
|
||||
?>
|
||||
|
||||
<label class="wpst-source-option <?php echo $current_source === 'wordpress.org' ? 'selected' : ''; ?>">
|
||||
<input type="radio" name="update_source" value="wordpress.org" <?php checked($current_source, 'wordpress.org'); ?>>
|
||||
<span class="wpst-source-option-label"><?php esc_html_e('WordPress.org', 'wp-plugin-starter-template'); ?></span>
|
||||
<div class="wpst-source-option-description">
|
||||
<?php esc_html_e('Receive updates from the official WordPress.org repository. Recommended for most users.', 'wp-plugin-starter-template'); ?>
|
||||
</div>
|
||||
<label class="wpst-source-option <?php echo 'wordpress.org' === $current_source ? 'selected' : ''; ?>">
|
||||
<input type="radio" name="update_source" value="wordpress.org" <?php checked( $current_source, 'wordpress.org' ); ?>>
|
||||
<span class="wpst-source-option-label"><?php esc_html_e( 'WordPress.org', 'wp-plugin-starter-template' ); ?></span>
|
||||
<div class="wpst-source-option-description"><?php esc_html_e( 'Receive updates from the official WordPress.org repository. Recommended for most users.', 'wp-plugin-starter-template' ); ?></div>
|
||||
</label>
|
||||
|
||||
<label class="wpst-source-option <?php echo $current_source === 'github' ? 'selected' : ''; ?>">
|
||||
<input type="radio" name="update_source" value="github" <?php checked($current_source, 'github'); ?>>
|
||||
<span class="wpst-source-option-label"><?php esc_html_e('GitHub', 'wp-plugin-starter-template'); ?></span>
|
||||
<div class="wpst-source-option-description">
|
||||
<?php esc_html_e('Receive updates from the GitHub repository. May include pre-release versions.', 'wp-plugin-starter-template'); ?>
|
||||
</div>
|
||||
<label class="wpst-source-option <?php echo 'github' === $current_source ? 'selected' : ''; ?>">
|
||||
<input type="radio" name="update_source" value="github" <?php checked( $current_source, 'github' ); ?>>
|
||||
<span class="wpst-source-option-label"><?php esc_html_e( 'GitHub', 'wp-plugin-starter-template' ); ?></span>
|
||||
<div class="wpst-source-option-description"><?php esc_html_e( 'Receive updates from the GitHub repository. May include pre-release versions.', 'wp-plugin-starter-template' ); ?></div>
|
||||
</label>
|
||||
|
||||
<label class="wpst-source-option <?php echo $current_source === 'gitea' ? 'selected' : ''; ?>">
|
||||
<input type="radio" name="update_source" value="gitea" <?php checked($current_source, 'gitea'); ?>>
|
||||
<span class="wpst-source-option-label"><?php esc_html_e('Gitea', 'wp-plugin-starter-template'); ?></span>
|
||||
<div class="wpst-source-option-description">
|
||||
<?php esc_html_e('Receive updates from the Gitea repository. May include pre-release versions.', 'wp-plugin-starter-template'); ?>
|
||||
</div>
|
||||
<label class="wpst-source-option <?php echo 'gitea' === $current_source ? 'selected' : ''; ?>">
|
||||
<input type="radio" name="update_source" value="gitea" <?php checked( $current_source, 'gitea' ); ?>>
|
||||
<span class="wpst-source-option-label"><?php esc_html_e( 'Gitea', 'wp-plugin-starter-template' ); ?></span>
|
||||
<div class="wpst-source-option-description"><?php esc_html_e( 'Receive updates from the Gitea repository. May include pre-release versions.', 'wp-plugin-starter-template' ); ?></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wpst-modal-footer">
|
||||
<button type="button" id="wpst-save-source" class="button button-primary">
|
||||
<?php esc_html_e('Save', 'wp-plugin-starter-template'); ?>
|
||||
</button>
|
||||
<button type="button" id="wpst-save-source" class="button button-primary"><?php esc_html_e( 'Save', 'wp-plugin-starter-template' ); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
21
assets/css/admin.css
Normal file
21
assets/css/admin.css
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Admin styles for the plugin
|
||||
*/
|
||||
|
||||
.wpst-admin-container {
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
border: 1px solid #ccd0d4;
|
||||
box-shadow: 0 1px 1px rgb(0 0 0 / 4%);
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.wpst-admin-header {
|
||||
margin-bottom: 20px;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.wpst-admin-header h1 {
|
||||
margin-top: 0;
|
||||
}
|
||||
12
assets/js/admin.js
Normal file
12
assets/js/admin.js
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Admin scripts for the plugin
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
'use strict';
|
||||
|
||||
$(document).ready(function() {
|
||||
// Plugin admin functionality will go here
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
186
bin/install-wp-tests.sh
Executable file
186
bin/install-wp-tests.sh
Executable file
@@ -0,0 +1,186 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ $# -lt 3 ]; then
|
||||
echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version] [skip-database-creation] [multisite]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DB_NAME=$1
|
||||
DB_USER=$2
|
||||
DB_PASS=$3
|
||||
DB_HOST=${4-localhost}
|
||||
WP_VERSION=${5-latest}
|
||||
SKIP_DB_CREATE=${6-false}
|
||||
MULTISITE=${7-false}
|
||||
|
||||
WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib}
|
||||
WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/}
|
||||
|
||||
download() {
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -fsSL "$1" -o "$2"
|
||||
elif command -v wget >/dev/null 2>&1; then
|
||||
wget -qO "$2" "$1"
|
||||
else
|
||||
echo "Error: Neither curl nor wget is installed" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+\-(beta|RC)[0-9]+$ ]]; then
|
||||
WP_BRANCH=${WP_VERSION%\-*}
|
||||
WP_TESTS_TAG="branches/$WP_BRANCH"
|
||||
elif [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+$ ]]; then
|
||||
WP_TESTS_TAG="branches/$WP_VERSION"
|
||||
elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then
|
||||
if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then
|
||||
# version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x
|
||||
WP_TESTS_TAG="tags/${WP_VERSION%??}"
|
||||
else
|
||||
WP_TESTS_TAG="tags/$WP_VERSION"
|
||||
fi
|
||||
elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
|
||||
WP_TESTS_TAG="trunk"
|
||||
else
|
||||
# http serves a single offer, whereas https serves multiple. we only want one
|
||||
download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json
|
||||
LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//' | head -1)
|
||||
if [[ -z "$LATEST_VERSION" ]]; then
|
||||
echo "Latest WordPress version could not be found"
|
||||
exit 1
|
||||
fi
|
||||
WP_TESTS_TAG="tags/$LATEST_VERSION"
|
||||
fi
|
||||
|
||||
# Derive a git ref from WP_TESTS_TAG by stripping the SVN-style prefix.
|
||||
# WP_TESTS_TAG uses "tags/X.Y.Z", "branches/X.Y", or "trunk".
|
||||
# git clone --branch requires the bare ref name ("X.Y.Z", "X.Y", or "trunk").
|
||||
if [[ "$WP_TESTS_TAG" == tags/* ]]; then
|
||||
GIT_REF="${WP_TESTS_TAG#tags/}"
|
||||
elif [[ "$WP_TESTS_TAG" == branches/* ]]; then
|
||||
GIT_REF="${WP_TESTS_TAG#branches/}"
|
||||
else
|
||||
GIT_REF="$WP_TESTS_TAG"
|
||||
fi
|
||||
|
||||
set -ex
|
||||
|
||||
install_wp() {
|
||||
|
||||
if [ -d "$WP_CORE_DIR" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
mkdir -p "$WP_CORE_DIR"
|
||||
|
||||
if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
|
||||
mkdir -p "$WP_CORE_DIR"
|
||||
download https://wordpress.org/nightly-builds/wordpress-latest.zip "$WP_CORE_DIR/wordpress-nightly.zip"
|
||||
unzip -q "$WP_CORE_DIR/wordpress-nightly.zip" -d "$WP_CORE_DIR"
|
||||
rm "$WP_CORE_DIR/wordpress-nightly.zip"
|
||||
else
|
||||
if [ "$WP_VERSION" == 'latest' ]; then
|
||||
local ARCHIVE_NAME='latest'
|
||||
elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+ ]]; then
|
||||
download https://api.wordpress.org/core/version-check/1.7/ "$WP_CORE_DIR/wp-latest.json"
|
||||
if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then
|
||||
LATEST_VERSION=${WP_VERSION%??}
|
||||
else
|
||||
# shellcheck disable=SC2001
|
||||
VERSION_ESCAPED=$(echo "$WP_VERSION" | sed 's/\./\\\\./g')
|
||||
LATEST_VERSION=$(grep -o '"version":"'"$VERSION_ESCAPED"'[^"]*' "$WP_CORE_DIR/wp-latest.json" | sed 's/"version":"//' | head -1)
|
||||
fi
|
||||
if [[ -z "$LATEST_VERSION" ]]; then
|
||||
local ARCHIVE_NAME="wordpress-$WP_VERSION"
|
||||
else
|
||||
local ARCHIVE_NAME="wordpress-$LATEST_VERSION"
|
||||
fi
|
||||
else
|
||||
local ARCHIVE_NAME="wordpress-$WP_VERSION"
|
||||
fi
|
||||
download https://wordpress.org/"${ARCHIVE_NAME}".tar.gz "$WP_CORE_DIR/wordpress.tar.gz"
|
||||
tar --strip-components=1 -zxmf "$WP_CORE_DIR/wordpress.tar.gz" -C "$WP_CORE_DIR"
|
||||
rm "$WP_CORE_DIR/wordpress.tar.gz"
|
||||
fi
|
||||
|
||||
download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php "$WP_CORE_DIR/wp-content/db.php"
|
||||
}
|
||||
|
||||
install_test_suite() {
|
||||
# portable in-place argument for both GNU sed and Mac OSX sed
|
||||
if [[ $(uname -s) == 'Darwin' ]]; then
|
||||
local ioption='-i.bak'
|
||||
else
|
||||
local ioption='-i'
|
||||
fi
|
||||
|
||||
# set up testing suite if it doesn't yet exist
|
||||
if [ ! -d "$WP_TESTS_DIR" ]; then
|
||||
mkdir -p "$WP_TESTS_DIR"
|
||||
rm -rf /tmp/wordpress-develop
|
||||
if ! git clone --quiet --depth=1 --branch "$GIT_REF" https://github.com/WordPress/wordpress-develop.git /tmp/wordpress-develop; then
|
||||
echo "Error: Failed to clone wordpress-develop at branch/tag $GIT_REF" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ -d /tmp/wordpress-develop/tests/phpunit/includes ]; then
|
||||
if ! cp -r /tmp/wordpress-develop/tests/phpunit/includes "$WP_TESTS_DIR/"; then
|
||||
echo "Error: Failed to copy phpunit includes to $WP_TESTS_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ -d /tmp/wordpress-develop/tests/phpunit/data ]; then
|
||||
if ! cp -r /tmp/wordpress-develop/tests/phpunit/data "$WP_TESTS_DIR/"; then
|
||||
echo "Error: Failed to copy phpunit data to $WP_TESTS_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f wp-tests-config.php ]; then
|
||||
if [ -f /tmp/wordpress-develop/wp-tests-config-sample.php ]; then
|
||||
cp /tmp/wordpress-develop/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
|
||||
else
|
||||
download https://raw.githubusercontent.com/WordPress/wordpress-develop/master/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
|
||||
fi
|
||||
WP_CORE_DIR="${WP_CORE_DIR%/}"
|
||||
sed "$ioption" "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php
|
||||
sed "$ioption" "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
|
||||
sed "$ioption" "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
|
||||
sed "$ioption" "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
|
||||
sed "$ioption" "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
|
||||
|
||||
if [ "$MULTISITE" = "true" ]; then
|
||||
sed "$ioption" "s:// define( 'WP_TESTS_MULTISITE', true );:define( 'WP_TESTS_MULTISITE', true );:" "$WP_TESTS_DIR"/wp-tests-config.php
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
install_db() {
|
||||
|
||||
if [ "${SKIP_DB_CREATE}" = "true" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
local PARTS
|
||||
IFS=':' read -ra PARTS <<<"$DB_HOST"
|
||||
local DB_HOSTNAME=${PARTS[0]}
|
||||
local DB_SOCK_OR_PORT=${PARTS[1]}
|
||||
local EXTRA=""
|
||||
|
||||
if [ -n "$DB_HOSTNAME" ]; then
|
||||
if [[ $DB_SOCK_OR_PORT =~ ^[0-9]+$ ]]; then
|
||||
EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
|
||||
elif [ -n "$DB_SOCK_OR_PORT" ]; then
|
||||
EXTRA=" --socket=$DB_SOCK_OR_PORT"
|
||||
elif [ -n "$DB_HOSTNAME" ]; then
|
||||
EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
|
||||
fi
|
||||
fi
|
||||
|
||||
mysqladmin create "$DB_NAME" --user="$DB_USER" --password="$DB_PASS""$EXTRA" || true
|
||||
}
|
||||
|
||||
install_wp
|
||||
install_test_suite
|
||||
install_db
|
||||
424
bin/localwp-setup.sh
Executable file
424
bin/localwp-setup.sh
Executable file
@@ -0,0 +1,424 @@
|
||||
#!/bin/bash
|
||||
|
||||
# LocalWP Integration Script for WordPress Plugin Development
|
||||
# For use by AI coding assistants and developers
|
||||
#
|
||||
# This script manages LocalWP sites for testing the plugin.
|
||||
# Creates standardized test sites with consistent URLs.
|
||||
#
|
||||
# URL Patterns:
|
||||
# Single site: {plugin-slug}-single.local
|
||||
# Multisite: {plugin-slug}-multisite.local
|
||||
#
|
||||
# Usage:
|
||||
# ./bin/localwp-setup.sh create [--multisite]
|
||||
# ./bin/localwp-setup.sh sync
|
||||
# ./bin/localwp-setup.sh reset
|
||||
# ./bin/localwp-setup.sh info
|
||||
#
|
||||
# Examples:
|
||||
# npm run localwp:create # Create single site
|
||||
# npm run localwp:create:multisite # Create multisite
|
||||
# npm run localwp:sync # Sync plugin files
|
||||
# npm run localwp:reset # Reset to clean state
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
PLUGIN_SLUG="wp-plugin-starter-template"
|
||||
|
||||
# LocalWP paths (macOS)
|
||||
LOCAL_SITES_DIR="$HOME/Local Sites"
|
||||
LOCAL_APP="/Applications/Local.app"
|
||||
LOCAL_WP_CLI="$LOCAL_APP/Contents/Resources/extraResources/bin/wp-cli/posix/wp"
|
||||
|
||||
# Site configurations
|
||||
SINGLE_SITE_NAME="${PLUGIN_SLUG}-single"
|
||||
MULTISITE_NAME="${PLUGIN_SLUG}-multisite"
|
||||
SINGLE_SITE_DOMAIN="${SINGLE_SITE_NAME}.local"
|
||||
MULTISITE_DOMAIN="${MULTISITE_NAME}.local"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Helper functions
|
||||
log_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_step() {
|
||||
echo -e "${CYAN}[STEP]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if LocalWP is installed
|
||||
check_localwp() {
|
||||
if [ ! -d "$LOCAL_APP" ]; then
|
||||
log_error "LocalWP is not installed at $LOCAL_APP"
|
||||
log_info "Download from: https://localwp.com/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$LOCAL_WP_CLI" ]; then
|
||||
log_error "WP-CLI not found in LocalWP installation"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local version
|
||||
version=$("$LOCAL_WP_CLI" --version 2>/dev/null || echo "unknown")
|
||||
log_info "LocalWP WP-CLI version: $version"
|
||||
}
|
||||
|
||||
# Get site path
|
||||
get_site_path() {
|
||||
local site_name="$1"
|
||||
echo "$LOCAL_SITES_DIR/$site_name"
|
||||
}
|
||||
|
||||
# Get WordPress path within site
|
||||
get_wp_path() {
|
||||
local site_name="$1"
|
||||
local site_path
|
||||
site_path=$(get_site_path "$site_name")
|
||||
|
||||
# LocalWP uses app/public for WordPress files
|
||||
echo "$site_path/app/public"
|
||||
}
|
||||
|
||||
# Check if site exists
|
||||
site_exists() {
|
||||
local site_name="$1"
|
||||
local site_path
|
||||
site_path=$(get_site_path "$site_name")
|
||||
[ -d "$site_path" ]
|
||||
}
|
||||
|
||||
# Get plugin destination path
|
||||
get_plugin_path() {
|
||||
local site_name="$1"
|
||||
local wp_path
|
||||
wp_path=$(get_wp_path "$site_name")
|
||||
echo "$wp_path/wp-content/plugins/$PLUGIN_SLUG"
|
||||
}
|
||||
|
||||
# Sync plugin files to LocalWP site
|
||||
sync_plugin() {
|
||||
local site_name="$1"
|
||||
local plugin_dest
|
||||
plugin_dest=$(get_plugin_path "$site_name")
|
||||
|
||||
if ! site_exists "$site_name"; then
|
||||
log_error "Site '$site_name' does not exist"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Syncing plugin to $site_name..."
|
||||
|
||||
# Create plugin directory if it doesn't exist
|
||||
mkdir -p "$plugin_dest"
|
||||
|
||||
# Sync files using rsync (excludes dev files)
|
||||
rsync -av --delete \
|
||||
--exclude 'node_modules' \
|
||||
--exclude 'vendor' \
|
||||
--exclude '.git' \
|
||||
--exclude 'dist' \
|
||||
--exclude 'tests' \
|
||||
--exclude 'cypress' \
|
||||
--exclude '.github' \
|
||||
--exclude '.agents' \
|
||||
--exclude '.wiki' \
|
||||
--exclude 'reference-plugins' \
|
||||
--exclude '*.zip' \
|
||||
--exclude '.playground.*' \
|
||||
--exclude 'composer.lock' \
|
||||
--exclude 'package-lock.json' \
|
||||
"$PROJECT_DIR/" "$plugin_dest/"
|
||||
|
||||
log_success "Plugin synced to: $plugin_dest"
|
||||
}
|
||||
|
||||
# Create a new LocalWP site
|
||||
create_site() {
|
||||
local multisite=false
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--multisite)
|
||||
multisite=true
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
local site_name="$SINGLE_SITE_NAME"
|
||||
local domain="$SINGLE_SITE_DOMAIN"
|
||||
local mode="single site"
|
||||
|
||||
if [ "$multisite" = true ]; then
|
||||
site_name="$MULTISITE_NAME"
|
||||
domain="$MULTISITE_DOMAIN"
|
||||
mode="multisite"
|
||||
fi
|
||||
|
||||
check_localwp
|
||||
|
||||
local site_path
|
||||
site_path=$(get_site_path "$site_name")
|
||||
|
||||
if site_exists "$site_name"; then
|
||||
log_warning "Site '$site_name' already exists at: $site_path"
|
||||
log_info "Use 'npm run localwp:reset' to reset it, or 'npm run localwp:sync' to update files"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " LocalWP Site Setup ($mode)"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "This script will guide you through creating a"
|
||||
echo "LocalWP site for testing the plugin."
|
||||
echo ""
|
||||
echo "Site Details:"
|
||||
echo " Name: $site_name"
|
||||
echo " Domain: $domain"
|
||||
echo " Path: $site_path"
|
||||
echo ""
|
||||
|
||||
log_step "Creating LocalWP Site"
|
||||
echo ""
|
||||
log_info "LocalWP doesn't have a CLI for site creation."
|
||||
log_info "Please create the site manually in LocalWP:"
|
||||
echo ""
|
||||
echo "1. Open LocalWP application"
|
||||
echo "2. Click the '+' button to create a new site"
|
||||
echo "3. Use these settings:"
|
||||
echo " - Site name: ${CYAN}$site_name${NC}"
|
||||
echo " - Local site domain: ${CYAN}$domain${NC}"
|
||||
echo " - PHP version: 8.0 or higher"
|
||||
echo " - Web server: nginx (preferred)"
|
||||
echo " - MySQL version: 8.0+"
|
||||
|
||||
if [ "$multisite" = true ]; then
|
||||
echo ""
|
||||
echo "4. After site creation, convert to multisite:"
|
||||
echo " - Open Site Shell in LocalWP"
|
||||
echo " - Run: wp core multisite-convert --subdomains=0"
|
||||
echo " - Update wp-config.php if needed"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
log_info "After creating the site, run: npm run localwp:sync"
|
||||
echo ""
|
||||
|
||||
# Wait for user to create site
|
||||
read -r -p "Press Enter after you've created the site in LocalWP..."
|
||||
|
||||
if site_exists "$site_name"; then
|
||||
log_success "Site detected at: $site_path"
|
||||
sync_plugin "$site_name"
|
||||
|
||||
# Install recommended plugins
|
||||
install_recommended_plugins "$site_name"
|
||||
|
||||
show_site_info "$site_name" "$domain" "$multisite"
|
||||
else
|
||||
log_warning "Site not found at expected location"
|
||||
log_info "Expected path: $site_path"
|
||||
log_info "You can run 'npm run localwp:sync' later to sync files"
|
||||
fi
|
||||
}
|
||||
|
||||
# Install recommended plugins (matching Playground blueprint)
|
||||
install_recommended_plugins() {
|
||||
local site_name="$1"
|
||||
local wp_path
|
||||
wp_path=$(get_wp_path "$site_name")
|
||||
|
||||
log_info "Note: Install these plugins to match Playground environment:"
|
||||
echo " - Plugin Toggle (plugin-toggle)"
|
||||
echo " - Kadence Blocks (kadence-blocks)"
|
||||
echo ""
|
||||
log_info "You can install them via LocalWP's WP Admin or Site Shell"
|
||||
}
|
||||
|
||||
# Show site information
|
||||
show_site_info() {
|
||||
local site_name="$1"
|
||||
local domain="$2"
|
||||
local multisite="$3"
|
||||
|
||||
local site_path
|
||||
site_path=$(get_site_path "$site_name")
|
||||
local plugin_path
|
||||
plugin_path=$(get_plugin_path "$site_name")
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " LocalWP Site Ready"
|
||||
echo "============================================"
|
||||
echo " Site: $site_name"
|
||||
echo " URL: http://$domain"
|
||||
echo " Admin: http://$domain/wp-admin/"
|
||||
echo " Plugin Path: $plugin_path"
|
||||
echo "============================================"
|
||||
|
||||
if [ "$multisite" = true ]; then
|
||||
echo " Network Admin: http://$domain/wp-admin/network/"
|
||||
echo "============================================"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
log_info "Remember to:"
|
||||
echo " 1. Start the site in LocalWP"
|
||||
echo " 2. Activate the plugin in WordPress admin"
|
||||
echo " 3. Run 'npm run localwp:sync' after making changes"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Reset site to clean state
|
||||
reset_site() {
|
||||
local site_name="${1:-$SINGLE_SITE_NAME}"
|
||||
|
||||
if ! site_exists "$site_name"; then
|
||||
log_error "Site '$site_name' does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_warning "This will delete the plugin files and resync them."
|
||||
read -p "Continue? (y/n) " -n 1 -r
|
||||
echo
|
||||
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
local plugin_path
|
||||
plugin_path=$(get_plugin_path "$site_name")
|
||||
|
||||
log_info "Removing plugin files..."
|
||||
rm -rf "$plugin_path"
|
||||
|
||||
log_info "Resyncing plugin..."
|
||||
sync_plugin "$site_name"
|
||||
|
||||
log_success "Site reset complete"
|
||||
else
|
||||
log_info "Reset cancelled"
|
||||
fi
|
||||
}
|
||||
|
||||
# Sync all existing sites
|
||||
sync_all() {
|
||||
local synced=0
|
||||
|
||||
for site_name in "$SINGLE_SITE_NAME" "$MULTISITE_NAME"; do
|
||||
if site_exists "$site_name"; then
|
||||
sync_plugin "$site_name"
|
||||
synced=$((synced + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $synced -eq 0 ]; then
|
||||
log_warning "No LocalWP sites found for this plugin"
|
||||
log_info "Run 'npm run localwp:create' to create one"
|
||||
else
|
||||
log_success "Synced $synced site(s)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Show info about all sites
|
||||
show_info() {
|
||||
echo ""
|
||||
echo "LocalWP Sites for $PLUGIN_SLUG"
|
||||
echo "==============================="
|
||||
|
||||
for site_name in "$SINGLE_SITE_NAME" "$MULTISITE_NAME"; do
|
||||
local site_path
|
||||
site_path=$(get_site_path "$site_name")
|
||||
|
||||
if site_exists "$site_name"; then
|
||||
echo ""
|
||||
echo " ${GREEN}✓${NC} $site_name"
|
||||
echo " Path: $site_path"
|
||||
|
||||
local plugin_path
|
||||
plugin_path=$(get_plugin_path "$site_name")
|
||||
if [ -d "$plugin_path" ]; then
|
||||
echo " Plugin: ${GREEN}Installed${NC}"
|
||||
else
|
||||
echo " Plugin: ${YELLOW}Not synced${NC}"
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
echo " ${YELLOW}○${NC} $site_name (not created)"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " npm run localwp:create Create single site"
|
||||
echo " npm run localwp:create:multisite Create multisite"
|
||||
echo " npm run localwp:sync Sync plugin files"
|
||||
echo " npm run localwp:reset Reset plugin files"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Main command handler
|
||||
case "${1:-}" in
|
||||
create)
|
||||
shift
|
||||
create_site "$@"
|
||||
;;
|
||||
sync)
|
||||
sync_all
|
||||
;;
|
||||
reset)
|
||||
shift
|
||||
reset_site "$@"
|
||||
;;
|
||||
info)
|
||||
show_info
|
||||
;;
|
||||
*)
|
||||
echo "LocalWP Integration Script"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo " $0 create [--multisite] Create a new LocalWP site"
|
||||
echo " $0 sync Sync plugin files to all sites"
|
||||
echo " $0 reset [site-name] Reset site plugin to clean state"
|
||||
echo " $0 info Show info about LocalWP sites"
|
||||
echo ""
|
||||
echo "npm scripts:"
|
||||
echo " npm run localwp:create Create single site"
|
||||
echo " npm run localwp:create:multisite Create multisite"
|
||||
echo " npm run localwp:sync Sync plugin files"
|
||||
echo " npm run localwp:reset Reset plugin files"
|
||||
echo ""
|
||||
echo "URL Patterns:"
|
||||
echo " Single site: http://${PLUGIN_SLUG}-single.local"
|
||||
echo " Multisite: http://${PLUGIN_SLUG}-multisite.local"
|
||||
echo ""
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
303
bin/playground-test.sh
Executable file
303
bin/playground-test.sh
Executable file
@@ -0,0 +1,303 @@
|
||||
#!/bin/bash
|
||||
|
||||
# WordPress Playground CLI Testing Script
|
||||
# For use by AI coding assistants and developers
|
||||
#
|
||||
# This script provides a simple interface to start/stop WordPress Playground
|
||||
# for local testing with the plugin. Uses @wp-playground/cli 3.0.22+
|
||||
#
|
||||
# Usage:
|
||||
# ./bin/playground-test.sh start [--multisite] [--port PORT]
|
||||
# ./bin/playground-test.sh stop
|
||||
# ./bin/playground-test.sh status
|
||||
#
|
||||
# Examples:
|
||||
# npm run playground:start # Start single site on port 8888
|
||||
# npm run playground:start:multisite # Start multisite on port 8889
|
||||
# npm run playground:stop # Stop all playground instances
|
||||
# npm run playground:status # Check if playground is running
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
PID_FILE="$PROJECT_DIR/.playground.pid"
|
||||
DEFAULT_PORT=8888
|
||||
MULTISITE_PORT=8889
|
||||
PLUGIN_SLUG="wp-plugin-starter-template"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Helper functions
|
||||
log_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if @wp-playground/cli is installed
|
||||
check_cli() {
|
||||
if ! npx @wp-playground/cli --version > /dev/null 2>&1; then
|
||||
log_error "@wp-playground/cli is not installed"
|
||||
log_info "Run: npm install"
|
||||
exit 1
|
||||
fi
|
||||
local version=$(npx @wp-playground/cli --version 2>/dev/null)
|
||||
log_info "Using @wp-playground/cli version: $version"
|
||||
}
|
||||
|
||||
# Create plugin zip for installation
|
||||
create_plugin_zip() {
|
||||
log_info "Creating plugin zip..."
|
||||
mkdir -p "$PROJECT_DIR/dist"
|
||||
|
||||
cd "$PROJECT_DIR"
|
||||
zip -r "dist/$PLUGIN_SLUG.zip" . \
|
||||
-x "node_modules/*" \
|
||||
-x "dist/*" \
|
||||
-x ".git/*" \
|
||||
-x "vendor/*" \
|
||||
-x "tests/*" \
|
||||
-x "cypress/*" \
|
||||
-x "*.zip" \
|
||||
-x ".github/*" \
|
||||
-x ".agents/*" \
|
||||
-x ".wiki/*" \
|
||||
-x "reference-plugins/*" \
|
||||
> /dev/null 2>&1
|
||||
|
||||
log_success "Plugin zip created: dist/$PLUGIN_SLUG.zip"
|
||||
}
|
||||
|
||||
# Start WordPress Playground
|
||||
start_playground() {
|
||||
local multisite=false
|
||||
local port=$DEFAULT_PORT
|
||||
local blueprint="$PROJECT_DIR/playground/blueprint.json"
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--multisite)
|
||||
multisite=true
|
||||
port=$MULTISITE_PORT
|
||||
blueprint="$PROJECT_DIR/playground/multisite-blueprint.json"
|
||||
shift
|
||||
;;
|
||||
--port)
|
||||
port="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check if already running
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
local old_pid=$(cat "$PID_FILE")
|
||||
if kill -0 "$old_pid" 2>/dev/null; then
|
||||
log_warning "Playground is already running (PID: $old_pid)"
|
||||
log_info "Run 'npm run playground:stop' first to restart"
|
||||
exit 1
|
||||
else
|
||||
rm -f "$PID_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check port availability
|
||||
if lsof -i ":$port" > /dev/null 2>&1; then
|
||||
log_error "Port $port is already in use"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
check_cli
|
||||
create_plugin_zip
|
||||
|
||||
local mode="single site"
|
||||
if [ "$multisite" = true ]; then
|
||||
mode="multisite"
|
||||
fi
|
||||
|
||||
log_info "Starting WordPress Playground ($mode) on port $port..."
|
||||
log_info "Blueprint: $blueprint"
|
||||
|
||||
# Start the server in background
|
||||
cd "$PROJECT_DIR"
|
||||
npx @wp-playground/cli server \
|
||||
--blueprint "$blueprint" \
|
||||
--port "$port" \
|
||||
--login \
|
||||
> "$PROJECT_DIR/.playground.log" 2>&1 &
|
||||
|
||||
local server_pid=$!
|
||||
echo "$server_pid" > "$PID_FILE"
|
||||
|
||||
# Wait for server to be ready
|
||||
log_info "Waiting for server to be ready..."
|
||||
local timeout=120
|
||||
local elapsed=0
|
||||
|
||||
while ! curl -s "http://localhost:$port" > /dev/null 2>&1; do
|
||||
if [ $elapsed -ge $timeout ]; then
|
||||
log_error "Timeout waiting for WordPress Playground to start"
|
||||
log_info "Check logs: cat $PROJECT_DIR/.playground.log"
|
||||
kill "$server_pid" 2>/dev/null || true
|
||||
rm -f "$PID_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if process is still running
|
||||
if ! kill -0 "$server_pid" 2>/dev/null; then
|
||||
log_error "Server process died unexpectedly"
|
||||
log_info "Check logs: cat $PROJECT_DIR/.playground.log"
|
||||
rm -f "$PID_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 2
|
||||
elapsed=$((elapsed + 2))
|
||||
echo -ne "\r${BLUE}[INFO]${NC} Waiting... $elapsed/$timeout seconds"
|
||||
done
|
||||
|
||||
echo ""
|
||||
log_success "WordPress Playground is ready!"
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " WordPress Playground ($mode)"
|
||||
echo "============================================"
|
||||
echo " URL: http://localhost:$port"
|
||||
echo " Admin: http://localhost:$port/wp-admin/"
|
||||
echo " Login: admin / password"
|
||||
echo " PID: $server_pid"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
log_info "Run 'npm run playground:stop' to stop the server"
|
||||
log_info "Logs: $PROJECT_DIR/.playground.log"
|
||||
}
|
||||
|
||||
# Stop WordPress Playground
|
||||
stop_playground() {
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
local pid=$(cat "$PID_FILE")
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
log_info "Stopping WordPress Playground (PID: $pid)..."
|
||||
kill "$pid" 2>/dev/null || true
|
||||
|
||||
# Wait for process to stop
|
||||
local timeout=10
|
||||
local elapsed=0
|
||||
while kill -0 "$pid" 2>/dev/null && [ $elapsed -lt $timeout ]; do
|
||||
sleep 1
|
||||
elapsed=$((elapsed + 1))
|
||||
done
|
||||
|
||||
# Force kill if still running
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
log_warning "Force killing process..."
|
||||
kill -9 "$pid" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
log_success "WordPress Playground stopped"
|
||||
else
|
||||
log_warning "Process not running"
|
||||
fi
|
||||
rm -f "$PID_FILE"
|
||||
else
|
||||
log_warning "No PID file found. Playground may not be running."
|
||||
fi
|
||||
|
||||
# Clean up any orphaned processes on common ports
|
||||
for port in $DEFAULT_PORT $MULTISITE_PORT; do
|
||||
local orphan_pid=$(lsof -t -i ":$port" 2>/dev/null || true)
|
||||
if [ -n "$orphan_pid" ]; then
|
||||
log_info "Found process on port $port (PID: $orphan_pid), stopping..."
|
||||
kill "$orphan_pid" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Check status
|
||||
check_status() {
|
||||
echo ""
|
||||
echo "WordPress Playground Status"
|
||||
echo "============================"
|
||||
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
local pid=$(cat "$PID_FILE")
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
log_success "Running (PID: $pid)"
|
||||
else
|
||||
log_warning "PID file exists but process not running"
|
||||
rm -f "$PID_FILE"
|
||||
fi
|
||||
else
|
||||
log_info "Not running (no PID file)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Port Status:"
|
||||
for port in $DEFAULT_PORT $MULTISITE_PORT; do
|
||||
if lsof -i ":$port" > /dev/null 2>&1; then
|
||||
local port_pid=$(lsof -t -i ":$port" 2>/dev/null || echo "unknown")
|
||||
echo " Port $port: ${GREEN}IN USE${NC} (PID: $port_pid)"
|
||||
|
||||
# Test if it's responding
|
||||
if curl -s "http://localhost:$port" > /dev/null 2>&1; then
|
||||
echo " └─ HTTP: ${GREEN}OK${NC}"
|
||||
else
|
||||
echo " └─ HTTP: ${RED}NOT RESPONDING${NC}"
|
||||
fi
|
||||
else
|
||||
echo " Port $port: ${YELLOW}AVAILABLE${NC}"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Main command handler
|
||||
case "${1:-}" in
|
||||
start)
|
||||
shift
|
||||
start_playground "$@"
|
||||
;;
|
||||
stop)
|
||||
stop_playground
|
||||
;;
|
||||
status)
|
||||
check_status
|
||||
;;
|
||||
*)
|
||||
echo "WordPress Playground CLI Testing Script"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo " $0 start [--multisite] [--port PORT] Start WordPress Playground"
|
||||
echo " $0 stop Stop WordPress Playground"
|
||||
echo " $0 status Check playground status"
|
||||
echo ""
|
||||
echo "npm scripts:"
|
||||
echo " npm run playground:start Start single site"
|
||||
echo " npm run playground:start:multisite Start multisite"
|
||||
echo " npm run playground:stop Stop playground"
|
||||
echo " npm run playground:status Check status"
|
||||
echo ""
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
307
bin/setup-test-env.sh
Executable file
307
bin/setup-test-env.sh
Executable file
@@ -0,0 +1,307 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if environment type is provided
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 [single|multisite|playground-single|playground-multisite]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ENV_TYPE=$1
|
||||
|
||||
# Function to check if a command exists
|
||||
command_exists() {
|
||||
command -v "$1" &>/dev/null
|
||||
return $?
|
||||
}
|
||||
|
||||
# PID of the background Python HTTP server (set when started).
|
||||
PYTHON_PID=""
|
||||
|
||||
# Function to clean up resources on exit.
|
||||
cleanup() {
|
||||
if [ -n "$PYTHON_PID" ]; then
|
||||
echo "Stopping Python HTTP server (PID: $PYTHON_PID)..."
|
||||
kill "$PYTHON_PID" 2>/dev/null || true
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Trap EXIT, INT, and TERM so the server is always stopped on script exit.
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
# Function to install wp-env if needed
|
||||
install_wp_env() {
|
||||
if ! command_exists wp-env; then
|
||||
echo "wp-env is not installed. Installing..."
|
||||
npm install -g @wordpress/env
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to install wp-playground if needed
|
||||
install_wp_playground() {
|
||||
# Check if we have a local installation
|
||||
if [ ! -d "node_modules/@wp-playground" ]; then
|
||||
echo "WordPress Playground is not installed locally. Installing..."
|
||||
npm install --save-dev @wp-playground/client @wp-playground/blueprints
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$ENV_TYPE" = "single" ]; then
|
||||
echo "Setting up single site environment..."
|
||||
|
||||
# Install wp-env if needed
|
||||
install_wp_env
|
||||
|
||||
# Start the environment
|
||||
wp-env start
|
||||
|
||||
# Wait for WordPress to be ready with a timeout
|
||||
MAX_ATTEMPTS=30
|
||||
ATTEMPT=0
|
||||
echo "Waiting for WordPress to be ready..."
|
||||
until wp-env run cli wp core is-installed || [ $ATTEMPT -ge $MAX_ATTEMPTS ]; do
|
||||
ATTEMPT=$((ATTEMPT + 1))
|
||||
echo "Attempt $ATTEMPT/$MAX_ATTEMPTS..."
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ $ATTEMPT -ge $MAX_ATTEMPTS ]; then
|
||||
echo "Timed out waiting for WordPress to be ready."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Activate our plugin
|
||||
if ! wp-env run cli wp plugin activate wp-plugin-starter-template-for-ai-coding; then
|
||||
echo "Failed to activate plugin. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "WordPress Single Site environment is ready!"
|
||||
echo "Site: http://localhost:8888"
|
||||
echo "Admin login: admin / password"
|
||||
|
||||
elif [ "$ENV_TYPE" = "multisite" ]; then
|
||||
echo "Setting up multisite environment..."
|
||||
|
||||
# Install wp-env if needed
|
||||
install_wp_env
|
||||
|
||||
# Start the environment with multisite configuration
|
||||
wp-env start --config=.wp-env.multisite.json
|
||||
|
||||
# Wait for WordPress to be ready with a timeout
|
||||
MAX_ATTEMPTS=30
|
||||
ATTEMPT=0
|
||||
echo "Waiting for WordPress to be ready..."
|
||||
until wp-env run cli wp core is-installed || [ $ATTEMPT -ge $MAX_ATTEMPTS ]; do
|
||||
ATTEMPT=$((ATTEMPT + 1))
|
||||
echo "Attempt $ATTEMPT/$MAX_ATTEMPTS..."
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ $ATTEMPT -ge $MAX_ATTEMPTS ]; then
|
||||
echo "Timed out waiting for WordPress to be ready."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create a test site
|
||||
if ! wp-env run cli wp site create --slug=testsite --title="Test Site" --email=admin@example.com; then
|
||||
echo "Failed to create test site. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Network activate our plugin
|
||||
if ! wp-env run cli wp plugin activate wp-plugin-starter-template-for-ai-coding --network; then
|
||||
echo "Failed to activate plugin. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "WordPress Multisite environment is ready!"
|
||||
echo "Main site: http://localhost:8888"
|
||||
echo "Test site: http://localhost:8888/testsite"
|
||||
echo "Admin login: admin / password"
|
||||
|
||||
elif [ "$ENV_TYPE" = "playground-single" ]; then
|
||||
echo "Setting up WordPress Playground single site environment..."
|
||||
|
||||
# Install wp-playground if needed
|
||||
install_wp_playground
|
||||
|
||||
# Create plugin zip
|
||||
echo "Creating plugin zip..."
|
||||
mkdir -p dist
|
||||
zip -r dist/plugin.zip . -x "node_modules/*" "dist/*" ".git/*"
|
||||
|
||||
# Update blueprint to use local plugin
|
||||
cat >playground/blueprint.json <<EOF
|
||||
{
|
||||
"landingPage": "/wp-admin/",
|
||||
"preferredVersions": {
|
||||
"php": "8.0",
|
||||
"wp": "latest"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"step": "login",
|
||||
"username": "admin",
|
||||
"password": "password"
|
||||
},
|
||||
{
|
||||
"step": "installPlugin",
|
||||
"pluginZipFile": {
|
||||
"resource": "local",
|
||||
"path": "dist/plugin.zip"
|
||||
}
|
||||
},
|
||||
{
|
||||
"step": "activatePlugin",
|
||||
"pluginSlug": "wp-plugin-starter-template-for-ai-coding"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
# Start WordPress Playground
|
||||
echo "Starting WordPress Playground..."
|
||||
if command_exists python3; then
|
||||
python3 -m http.server 8888 --directory playground &
|
||||
PYTHON_PID=$!
|
||||
echo "Started Python HTTP server with PID: $PYTHON_PID"
|
||||
echo "Opening WordPress Playground in your browser..."
|
||||
if command_exists open; then
|
||||
open http://localhost:8888/index.html
|
||||
elif command_exists xdg-open; then
|
||||
xdg-open http://localhost:8888/index.html
|
||||
elif command_exists start; then
|
||||
start http://localhost:8888/index.html
|
||||
else
|
||||
echo "Please open http://localhost:8888/index.html in your browser"
|
||||
fi
|
||||
else
|
||||
echo "Python3 is not installed. Please open playground/index.html in your browser."
|
||||
fi
|
||||
|
||||
# Wait for WordPress Playground to be ready
|
||||
echo "Waiting for WordPress Playground to be ready..."
|
||||
sleep 5
|
||||
|
||||
echo "WordPress Playground Single Site environment is ready!"
|
||||
echo "Site: http://localhost:8888"
|
||||
echo "Admin login: admin / password"
|
||||
echo "Press Ctrl+C to stop the server when done."
|
||||
|
||||
elif [ "$ENV_TYPE" = "playground-multisite" ]; then
|
||||
echo "Setting up WordPress Playground multisite environment..."
|
||||
|
||||
# Install wp-playground if needed
|
||||
install_wp_playground
|
||||
|
||||
# Create plugin zip
|
||||
echo "Creating plugin zip..."
|
||||
mkdir -p dist
|
||||
zip -r dist/plugin.zip . -x "node_modules/*" "dist/*" ".git/*"
|
||||
|
||||
# Update blueprint to use local plugin
|
||||
# shellcheck disable=SC2154
|
||||
cat >playground/multisite-blueprint.json <<EOF
|
||||
{
|
||||
"landingPage": "/wp-admin/network/",
|
||||
"preferredVersions": {
|
||||
"php": "8.0",
|
||||
"wp": "latest"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"step": "defineWpConfig",
|
||||
"name": "WP_ALLOW_MULTISITE",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"step": "defineWpConfig",
|
||||
"name": "MULTISITE",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"step": "defineWpConfig",
|
||||
"name": "SUBDOMAIN_INSTALL",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"step": "defineWpConfig",
|
||||
"name": "DOMAIN_CURRENT_SITE",
|
||||
"value": "localhost"
|
||||
},
|
||||
{
|
||||
"step": "defineWpConfig",
|
||||
"name": "PATH_CURRENT_SITE",
|
||||
"value": "/"
|
||||
},
|
||||
{
|
||||
"step": "defineWpConfig",
|
||||
"name": "SITE_ID_CURRENT_SITE",
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"step": "defineWpConfig",
|
||||
"name": "BLOG_ID_CURRENT_SITE",
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"step": "login",
|
||||
"username": "admin",
|
||||
"password": "password"
|
||||
},
|
||||
{
|
||||
"step": "installPlugin",
|
||||
"pluginZipFile": {
|
||||
"resource": "local",
|
||||
"path": "dist/plugin.zip"
|
||||
}
|
||||
},
|
||||
{
|
||||
"step": "activatePlugin",
|
||||
"pluginSlug": "wp-plugin-starter-template-for-ai-coding",
|
||||
"networkWide": true
|
||||
},
|
||||
{
|
||||
"step": "runPHP",
|
||||
"code": "<?php\n// Create a test subsite\n$domain = 'localhost';\n$path = '/testsite/';\n$title = 'Test Subsite';\n$user_id = 1;\n\nif (!get_site_by_path($domain, $path)) {\n $blog_id = wpmu_create_blog($domain, $path, $title, $user_id);\n if (is_wp_error($blog_id)) {\n echo 'Error creating subsite: ' . $blog_id->get_error_message();\n } else {\n echo 'Created subsite with ID: ' . $blog_id;\n }\n} else {\n echo 'Subsite already exists';\n}\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
# Start WordPress Playground
|
||||
echo "Starting WordPress Playground..."
|
||||
if command_exists python3; then
|
||||
python3 -m http.server 8888 --directory playground &
|
||||
PYTHON_PID=$!
|
||||
echo "Started Python HTTP server with PID: $PYTHON_PID"
|
||||
echo "Opening WordPress Playground in your browser..."
|
||||
if command_exists open; then
|
||||
open http://localhost:8888/multisite.html
|
||||
elif command_exists xdg-open; then
|
||||
xdg-open http://localhost:8888/multisite.html
|
||||
elif command_exists start; then
|
||||
start http://localhost:8888/multisite.html
|
||||
else
|
||||
echo "Please open http://localhost:8888/multisite.html in your browser"
|
||||
fi
|
||||
else
|
||||
echo "Python3 is not installed. Please open playground/multisite.html in your browser."
|
||||
fi
|
||||
|
||||
# Wait for WordPress Playground to be ready
|
||||
echo "Waiting for WordPress Playground to be ready..."
|
||||
sleep 5
|
||||
|
||||
echo "WordPress Playground Multisite environment is ready!"
|
||||
echo "Main site: http://localhost:8888"
|
||||
echo "Test site: http://localhost:8888/testsite"
|
||||
echo "Admin login: admin / password"
|
||||
echo "Press Ctrl+C to stop the server when done."
|
||||
|
||||
else
|
||||
echo "Invalid environment type. Use 'single', 'multisite', 'playground-single', or 'playground-multisite'."
|
||||
exit 1
|
||||
fi
|
||||
100
build.sh
100
build.sh
@@ -1,13 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# WordPress Plugin Build Script
|
||||
# This script creates a clean build of the plugin for distribution
|
||||
|
||||
# Check if version is provided
|
||||
if [ -z "$1" ]; then
|
||||
echo "❌ Error: Version number is required"
|
||||
echo "Usage: ./build.sh <version>"
|
||||
exit 1
|
||||
echo "❌ Error: Version number is required"
|
||||
echo "Usage: ./build.sh <version>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION=$1
|
||||
@@ -20,78 +21,91 @@ echo "Creating build directory..."
|
||||
rm -rf "$BUILD_DIR"
|
||||
mkdir -p "$BUILD_DIR"
|
||||
|
||||
# Run code quality checks
|
||||
echo "Running code quality checks..."
|
||||
if command -v composer &>/dev/null; then
|
||||
echo "Running PHPCS..."
|
||||
composer run phpcs || { echo "⚠️ PHPCS found issues. Consider running 'composer run phpcbf' to fix them."; }
|
||||
|
||||
# Uncomment the following line to automatically fix coding standards issues
|
||||
# echo "Running PHPCBF..."
|
||||
# composer run phpcbf
|
||||
else
|
||||
echo "⚠️ Composer not found, skipping code quality checks"
|
||||
fi
|
||||
|
||||
# Install composer dependencies
|
||||
echo "Installing composer dependencies..."
|
||||
composer install --no-dev --optimize-autoloader
|
||||
|
||||
# Copy plugin files to build directory
|
||||
echo "Copying plugin files..."
|
||||
cp -R *.php "$BUILD_DIR/"
|
||||
cp -R ./*.php "$BUILD_DIR/"
|
||||
cp -R README.md LICENSE CHANGELOG.md readme.txt composer.json "$BUILD_DIR/"
|
||||
|
||||
# Copy directories
|
||||
echo "Copying directories..."
|
||||
mkdir -p "$BUILD_DIR/admin" "$BUILD_DIR/includes" "$BUILD_DIR/languages" "$BUILD_DIR/assets"
|
||||
cp -R admin/* "$BUILD_DIR/admin/"
|
||||
cp -R includes/* "$BUILD_DIR/includes/"
|
||||
cp -R languages/* "$BUILD_DIR/languages/"
|
||||
cp -R ./admin/* "$BUILD_DIR/admin/"
|
||||
cp -R ./includes/* "$BUILD_DIR/includes/"
|
||||
cp -R ./languages/* "$BUILD_DIR/languages/"
|
||||
|
||||
# Create assets directory structure
|
||||
mkdir -p "$BUILD_DIR/assets/banner" "$BUILD_DIR/assets/icon" "$BUILD_DIR/assets/screenshots"
|
||||
|
||||
# Copy assets if they exist
|
||||
if [ -d "assets/banner" ]; then
|
||||
cp -R assets/banner/* "$BUILD_DIR/assets/banner/"
|
||||
cp -R assets/banner/* "$BUILD_DIR/assets/banner/"
|
||||
fi
|
||||
|
||||
if [ -d "assets/icon" ]; then
|
||||
cp -R assets/icon/* "$BUILD_DIR/assets/icon/"
|
||||
cp -R assets/icon/* "$BUILD_DIR/assets/icon/"
|
||||
fi
|
||||
|
||||
if [ -d "assets/screenshots" ]; then
|
||||
cp -R assets/screenshots/* "$BUILD_DIR/assets/screenshots/"
|
||||
cp -R assets/screenshots/* "$BUILD_DIR/assets/screenshots/"
|
||||
fi
|
||||
|
||||
# Copy vendor directory if it exists
|
||||
if [ -d "vendor" ]; then
|
||||
cp -R vendor "$BUILD_DIR/"
|
||||
cp -R vendor "$BUILD_DIR/"
|
||||
fi
|
||||
|
||||
# Create ZIP file
|
||||
# Create ZIP file.
|
||||
echo "Creating ZIP file..."
|
||||
cd build
|
||||
zip -r "../$ZIP_FILE" "$PLUGIN_SLUG" -x "*.DS_Store" -x "*.git*" -x "*.github*"
|
||||
cd ..
|
||||
(
|
||||
cd build || exit 1
|
||||
zip -r "../$ZIP_FILE" "$PLUGIN_SLUG" -x "*.DS_Store" -x "*.git*" -x "*.github*"
|
||||
)
|
||||
|
||||
# Check if ZIP file was created successfully
|
||||
if [ -f "$ZIP_FILE" ]; then
|
||||
echo "✅ Build successful: $ZIP_FILE created"
|
||||
echo "File path: $(pwd)/$ZIP_FILE"
|
||||
|
||||
# Deploy to local WordPress installation if environment variable is set
|
||||
if [ -n "$WP_LOCAL_PLUGIN_DIR" ]; then
|
||||
echo "\nDeploying to local WordPress installation..."
|
||||
echo "Deploying to local WordPress installation..."
|
||||
|
||||
# Remove existing plugin directory
|
||||
rm -rf "$WP_LOCAL_PLUGIN_DIR/$PLUGIN_SLUG"
|
||||
|
||||
# Copy files to local WordPress installation
|
||||
rsync -av --exclude=".git" --exclude=".github" --exclude=".DS_Store" \
|
||||
"$BUILD_DIR/" "$WP_LOCAL_PLUGIN_DIR/$PLUGIN_SLUG"
|
||||
|
||||
# Clear WordPress transients if WP-CLI is available
|
||||
if command -v wp &> /dev/null; then
|
||||
echo "Clearing WordPress transients..."
|
||||
wp transient delete --all --path="$WP_LOCAL_PLUGIN_DIR/../.."
|
||||
else
|
||||
echo "⚠️ WP-CLI not found, skipping transient clearing"
|
||||
fi
|
||||
|
||||
echo "✅ Local deployment successful!"
|
||||
echo "Plugin deployed to: $WP_LOCAL_PLUGIN_DIR/$PLUGIN_SLUG"
|
||||
fi
|
||||
echo "✅ Build successful: $ZIP_FILE created"
|
||||
echo "File path: $(pwd)/$ZIP_FILE"
|
||||
|
||||
# Deploy to local WordPress installation if environment variable is set
|
||||
if [ -n "${WP_LOCAL_PLUGIN_DIR:-}" ]; then
|
||||
printf '\nDeploying to local WordPress installation...\n'
|
||||
|
||||
# Remove existing plugin directory.
|
||||
rm -rf "${WP_LOCAL_PLUGIN_DIR:?}/$PLUGIN_SLUG"
|
||||
|
||||
# Copy files to local WordPress installation
|
||||
rsync -av --exclude=".git" --exclude=".github" --exclude=".DS_Store" \
|
||||
"$BUILD_DIR/" "$WP_LOCAL_PLUGIN_DIR/$PLUGIN_SLUG"
|
||||
|
||||
# Clear WordPress transients if WP-CLI is available
|
||||
if command -v wp &>/dev/null; then
|
||||
echo "Clearing WordPress transients..."
|
||||
wp transient delete --all --path="$WP_LOCAL_PLUGIN_DIR/../.."
|
||||
else
|
||||
echo "⚠️ WP-CLI not found, skipping transient clearing"
|
||||
fi
|
||||
|
||||
echo "✅ Local deployment successful!"
|
||||
echo "Plugin deployed to: $WP_LOCAL_PLUGIN_DIR/$PLUGIN_SLUG"
|
||||
fi
|
||||
else
|
||||
echo "❌ Build failed: ZIP file was not created"
|
||||
exit 1
|
||||
echo "❌ Build failed: ZIP file was not created"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -1,36 +1,62 @@
|
||||
{
|
||||
"name": "wpallstars/wp-plugin-starter-template",
|
||||
"description": "A comprehensive starter template for WordPress plugins with best practices for AI-assisted development.",
|
||||
"name": "wpallstars/wp-plugin-starter-template-for-ai-coding",
|
||||
"description": "A starter template for WordPress plugins with AI development workflows.",
|
||||
"type": "wordpress-plugin",
|
||||
"version": "0.1.15",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"authors": [
|
||||
{
|
||||
"name": "WPALLSTARS",
|
||||
"email": "info@wpallstars.com"
|
||||
"name": "WP All Stars",
|
||||
"email": "support@wpallstars.com"
|
||||
}
|
||||
],
|
||||
"minimum-stability": "stable",
|
||||
"require": {
|
||||
"php": ">=7.0"
|
||||
"php": ">=7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.5",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"wp-coding-standards/wpcs": "^2.3"
|
||||
"phpunit/phpunit": "^9.5.0",
|
||||
"yoast/phpunit-polyfills": "^2.0",
|
||||
"10up/wp_mock": "^1.0",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
|
||||
"wp-coding-standards/wpcs": "^3.0",
|
||||
"phpcompatibility/phpcompatibility-wp": "^2.1",
|
||||
"phpstan/phpstan": "^1.10.0",
|
||||
"szepeviktor/phpstan-wordpress": "^1.3",
|
||||
"phpmd/phpmd": "^2.13.0",
|
||||
"symfony/dependency-injection": "^5.4",
|
||||
"symfony/config": "^5.4",
|
||||
"symfony/filesystem": "^5.4",
|
||||
"symfony/deprecation-contracts": "^2.5",
|
||||
"doctrine/instantiator": "^1.5.0",
|
||||
"psr/log": "^1.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"WPALLSTARS\\PluginStarterTemplate\\": "includes/"
|
||||
"WPALLSTARS\\PluginStarterTemplate\\": "includes/",
|
||||
"WP_Plugin_Starter_Template_For_AI_Coding\\": "includes/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"phpcs": "phpcs --standard=WordPress",
|
||||
"phpcbf": "phpcbf --standard=WordPress",
|
||||
"test": "phpunit"
|
||||
"autoload-dev": {
|
||||
"classmap": [
|
||||
"includes/Admin/class-admin.php",
|
||||
"tests/phpunit/"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"phpcs": "vendor/bin/phpcs --standard=phpcs.xml",
|
||||
"phpcs:simple": "vendor/bin/phpcs --standard=phpcs-simple.xml",
|
||||
"phpcbf": "vendor/bin/phpcbf --standard=phpcs.xml",
|
||||
"phpcbf:simple": "vendor/bin/phpcbf --standard=phpcs-simple.xml",
|
||||
"phpstan": "vendor/bin/phpstan analyse --level=5 .",
|
||||
"phpmd": "vendor/bin/phpmd . text phpmd.xml --exclude vendor,node_modules,tests,bin,build,dist",
|
||||
"test": "vendor/bin/phpunit",
|
||||
"lint": ["@phpcs", "@phpstan", "@phpmd"],
|
||||
"fix": ["@phpcbf"]
|
||||
}
|
||||
}
|
||||
|
||||
4060
composer.lock
generated
Normal file
4060
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
17
cypress.config.js
Normal file
17
cypress.config.js
Normal file
@@ -0,0 +1,17 @@
|
||||
/* eslint-env node, mocha */
|
||||
|
||||
const { defineConfig } = require('cypress');
|
||||
|
||||
module.exports = defineConfig({
|
||||
e2e: {
|
||||
baseUrl: 'http://localhost:8888',
|
||||
setupNodeEvents(on, config) {
|
||||
// This function can be used to register custom Cypress plugins or event listeners.
|
||||
// Currently not in use, but left for future extensibility.
|
||||
return config;
|
||||
},
|
||||
// Add configuration for WordPress Playground
|
||||
experimentalWebKitSupport: true,
|
||||
chromeWebSecurity: false,
|
||||
},
|
||||
});
|
||||
47
cypress/e2e/multisite.cy.js
Normal file
47
cypress/e2e/multisite.cy.js
Normal file
@@ -0,0 +1,47 @@
|
||||
describe('WordPress Multisite Tests', () => {
|
||||
it('Can access the main site', () => {
|
||||
cy.visit('/');
|
||||
cy.get('body').should('exist');
|
||||
cy.get('h1').should('exist');
|
||||
cy.title().should('include', 'WordPress');
|
||||
});
|
||||
|
||||
it('Can access the test subsite', () => {
|
||||
cy.visit('/testsite');
|
||||
cy.get('body').should('exist');
|
||||
cy.get('h1').should('exist');
|
||||
cy.title().should('include', 'Test Site');
|
||||
});
|
||||
|
||||
it('Can login to the admin area', () => {
|
||||
cy.loginAsAdmin();
|
||||
cy.get('#wpadminbar').should('exist');
|
||||
cy.get('#dashboard-widgets').should('exist');
|
||||
});
|
||||
|
||||
it('Can access network admin', () => {
|
||||
cy.loginAsAdmin();
|
||||
|
||||
// Go to network admin
|
||||
cy.visit('/wp-admin/network/');
|
||||
cy.get('body.network-admin').should('exist');
|
||||
});
|
||||
|
||||
it('Plugin is network activated', () => {
|
||||
// Use our custom command to check and network activate the plugin if needed
|
||||
cy.networkActivatePlugin('wp-plugin-starter-template-for-ai-coding');
|
||||
|
||||
// Verify it's network active
|
||||
cy.get('tr[data-slug="wp-plugin-starter-template-for-ai-coding"] .network_active').should('exist');
|
||||
});
|
||||
|
||||
it('Network settings page loads correctly', () => {
|
||||
cy.loginAsAdmin();
|
||||
|
||||
// Navigate to the network settings page (if it exists)
|
||||
cy.visit('/wp-admin/network/settings.php');
|
||||
|
||||
// This is a basic check for the network settings page
|
||||
cy.get('h1').should('contain', 'Network Settings');
|
||||
});
|
||||
});
|
||||
43
cypress/e2e/playground-multisite.cy.js
Normal file
43
cypress/e2e/playground-multisite.cy.js
Normal file
@@ -0,0 +1,43 @@
|
||||
/* eslint-env mocha, jquery, cypress */
|
||||
describe('WordPress Playground Multisite Tests', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/', { timeout: 30000 });
|
||||
});
|
||||
|
||||
it('Can access the site', () => {
|
||||
cy.get('body', { timeout: 15000 }).should('exist');
|
||||
});
|
||||
|
||||
it('Can access the network admin area', () => {
|
||||
cy.loginAsAdmin();
|
||||
cy.visit('/wp-admin/network/', { timeout: 30000 });
|
||||
cy.get('#wpadminbar', { timeout: 15000 }).should('exist');
|
||||
cy.get('#wpbody-content').should('exist');
|
||||
});
|
||||
|
||||
it('Plugin is network activated', () => {
|
||||
cy.loginAsAdmin();
|
||||
cy.visit('/wp-admin/network/plugins.php', { timeout: 30000 });
|
||||
|
||||
cy.get('body', { timeout: 15000 }).then(($body) => {
|
||||
if ($body.text().includes('Plugin Toggle')) {
|
||||
cy.contains('tr', 'Plugin Toggle').should('exist');
|
||||
cy.contains('tr', 'Plugin Toggle').find('.network_active, .deactivate').should('exist');
|
||||
} else {
|
||||
cy.log('Plugin Toggle not found, skipping check');
|
||||
}
|
||||
|
||||
if ($body.text().includes('Kadence Blocks')) {
|
||||
cy.contains('tr', 'Kadence Blocks').find('.network_active, .deactivate').should('exist');
|
||||
} else {
|
||||
cy.log('Kadence Blocks plugin not found, skipping check');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('Network settings page loads correctly', () => {
|
||||
cy.loginAsAdmin();
|
||||
cy.visit('/wp-admin/network/settings.php', { timeout: 30000 });
|
||||
cy.get('#wpbody-content', { timeout: 15000 }).should('exist');
|
||||
});
|
||||
});
|
||||
56
cypress/e2e/playground-single-site.cy.js
Normal file
56
cypress/e2e/playground-single-site.cy.js
Normal file
@@ -0,0 +1,56 @@
|
||||
/* eslint-env mocha, jquery, cypress */
|
||||
describe('WordPress Playground Single Site Tests', {
|
||||
retries: {
|
||||
runMode: 2,
|
||||
openMode: 0,
|
||||
},
|
||||
}, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/', { timeout: 30000 });
|
||||
});
|
||||
|
||||
it('Can access the site', () => {
|
||||
cy.get('body', { timeout: 15000 }).should('exist');
|
||||
});
|
||||
|
||||
it('Can access the admin area', () => {
|
||||
cy.loginAsAdmin();
|
||||
cy.get('#wpadminbar', { timeout: 15000 }).should('exist');
|
||||
});
|
||||
|
||||
it('Plugin is activated', () => {
|
||||
cy.loginAsAdmin();
|
||||
cy.visit('/wp-admin/plugins.php', { timeout: 30000 });
|
||||
|
||||
cy.get('body', { timeout: 15000 }).then(($body) => {
|
||||
const hasPluginToggle = $body.text().includes('Plugin Toggle');
|
||||
const hasKadenceBlocks = $body.text().includes('Kadence Blocks');
|
||||
|
||||
expect(
|
||||
hasPluginToggle || hasKadenceBlocks,
|
||||
'At least one blueprint plugin should be present in the plugins table',
|
||||
).to.be.true;
|
||||
|
||||
if (hasPluginToggle) {
|
||||
cy.contains('tr', 'Plugin Toggle').should('exist');
|
||||
cy.contains('tr', 'Plugin Toggle').find('.deactivate').should('exist');
|
||||
} else {
|
||||
cy.log('Plugin Toggle not found, skipping check');
|
||||
}
|
||||
|
||||
if (hasKadenceBlocks) {
|
||||
cy.contains('tr', 'Kadence Blocks').find('.deactivate').should('exist');
|
||||
} else {
|
||||
cy.log('Kadence Blocks plugin not found, skipping check');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('Plugin settings page loads correctly', () => {
|
||||
cy.loginAsAdmin();
|
||||
cy.visit('/wp-admin/options-general.php', { timeout: 30000 });
|
||||
cy.get('#wpbody-content', { timeout: 15000 }).should('exist');
|
||||
cy.get('h1').should('be.visible');
|
||||
cy.title().should('include', 'Settings');
|
||||
});
|
||||
});
|
||||
75
cypress/e2e/single-site.cy.js
Normal file
75
cypress/e2e/single-site.cy.js
Normal file
@@ -0,0 +1,75 @@
|
||||
/* eslint-env mocha, jquery, cypress */
|
||||
describe( 'WordPress Single Site Tests', () => {
|
||||
it( 'Can access the site', () => {
|
||||
cy.visit( '/' );
|
||||
cy.get( 'body' ).should( 'exist' );
|
||||
} );
|
||||
|
||||
it( 'Can login to the admin area', () => {
|
||||
cy.loginAsAdmin();
|
||||
cy.get( '#wpadminbar' ).should( 'exist' );
|
||||
cy.get( '#dashboard-widgets' ).should( 'exist' );
|
||||
} );
|
||||
|
||||
it( 'Plugin is activated', () => {
|
||||
// Use our custom command to check and activate the plugin if needed.
|
||||
cy.activatePlugin( 'wp-plugin-starter-template-for-ai-coding' );
|
||||
|
||||
// Verify it's active.
|
||||
cy.get( 'tr[data-slug="wp-plugin-starter-template-for-ai-coding"] .deactivate' ).should( 'exist' );
|
||||
} );
|
||||
|
||||
it( 'Plugin row is visible on the plugins page', () => {
|
||||
cy.loginAsAdmin();
|
||||
cy.visit( '/wp-admin/plugins.php' );
|
||||
|
||||
// Verify the plugin row exists with the correct slug.
|
||||
cy.get( 'tr[data-slug="wp-plugin-starter-template-for-ai-coding"]' ).should( 'exist' );
|
||||
|
||||
// Verify the plugin name is displayed.
|
||||
cy.get( 'tr[data-slug="wp-plugin-starter-template-for-ai-coding"] .plugin-title strong' )
|
||||
.should( 'contain', 'WordPress Plugin Starter Template' );
|
||||
} );
|
||||
|
||||
it( 'Update source selector link is present in the plugin row', () => {
|
||||
cy.loginAsAdmin();
|
||||
cy.visit( '/wp-admin/plugins.php' );
|
||||
|
||||
// The update source selector link should be rendered in the plugin row.
|
||||
cy.get( 'tr[data-slug="wp-plugin-starter-template-for-ai-coding"]' )
|
||||
.find( '.wpst-update-source-selector' )
|
||||
.should( 'exist' );
|
||||
} );
|
||||
|
||||
it( 'Update source modal opens and displays source options', () => {
|
||||
cy.loginAsAdmin();
|
||||
cy.visit( '/wp-admin/plugins.php' );
|
||||
|
||||
// Click the update source selector link to open the modal.
|
||||
cy.get( '.wpst-update-source-selector' ).first().click();
|
||||
|
||||
// Modal should be visible.
|
||||
cy.get( '#wpst-update-source-modal' ).should( 'be.visible' );
|
||||
|
||||
// Modal should contain the three update source options.
|
||||
cy.get( '#wpst-update-source-modal input[name="update_source"][value="wordpress.org"]' ).should( 'exist' );
|
||||
cy.get( '#wpst-update-source-modal input[name="update_source"][value="github"]' ).should( 'exist' );
|
||||
cy.get( '#wpst-update-source-modal input[name="update_source"][value="gitea"]' ).should( 'exist' );
|
||||
|
||||
// Save button should be present.
|
||||
cy.get( '#wpst-save-source' ).should( 'exist' );
|
||||
} );
|
||||
|
||||
it( 'Update source modal can be closed', () => {
|
||||
cy.loginAsAdmin();
|
||||
cy.visit( '/wp-admin/plugins.php' );
|
||||
|
||||
// Open the modal.
|
||||
cy.get( '.wpst-update-source-selector' ).first().click();
|
||||
cy.get( '#wpst-update-source-modal' ).should( 'be.visible' );
|
||||
|
||||
// Close the modal via the close button.
|
||||
cy.get( '#wpst-update-source-modal .wpst-modal-close' ).click();
|
||||
cy.get( '#wpst-update-source-modal' ).should( 'not.be.visible' );
|
||||
} );
|
||||
} );
|
||||
74
cypress/support/commands.js
Normal file
74
cypress/support/commands.js
Normal file
@@ -0,0 +1,74 @@
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
|
||||
/**
|
||||
* Custom command to login as admin
|
||||
*/
|
||||
Cypress.Commands.add('loginAsAdmin', () => {
|
||||
cy.visit('/wp-admin', { timeout: 30000 });
|
||||
|
||||
cy.get('body', { timeout: 15000 }).then(($body) => {
|
||||
if ($body.find('#wpadminbar').length > 0) {
|
||||
cy.log('Already logged in as admin');
|
||||
return;
|
||||
}
|
||||
|
||||
if ($body.find('#user_login').length > 0) {
|
||||
cy.get('#user_login').should('be.visible').type('admin');
|
||||
cy.get('#user_pass').should('be.visible').type('password');
|
||||
cy.get('#wp-submit').should('be.visible').click();
|
||||
cy.get('#wpadminbar', { timeout: 15000 }).should('exist');
|
||||
} else {
|
||||
cy.log('Login form not found, assuming already logged in');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Custom command to activate plugin
|
||||
*/
|
||||
Cypress.Commands.add('activatePlugin', (pluginSlug) => {
|
||||
cy.loginAsAdmin();
|
||||
cy.visit('/wp-admin/plugins.php');
|
||||
|
||||
// Check if plugin is already active
|
||||
cy.contains('tr', pluginSlug).then(($tr) => {
|
||||
if ($tr.find('.deactivate').length > 0) {
|
||||
// Plugin is already active
|
||||
cy.log(`Plugin ${pluginSlug} is already active`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Activate the plugin
|
||||
cy.contains('tr', pluginSlug).find('.activate a').click();
|
||||
cy.contains('tr', pluginSlug).find('.deactivate').should('exist');
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Custom command to network activate plugin
|
||||
*/
|
||||
Cypress.Commands.add('networkActivatePlugin', (pluginSlug) => {
|
||||
cy.loginAsAdmin();
|
||||
cy.visit('/wp-admin/network/plugins.php');
|
||||
|
||||
// Check if plugin is already network active
|
||||
cy.contains('tr', pluginSlug).then(($tr) => {
|
||||
if ($tr.find('.network_active').length > 0) {
|
||||
// Plugin is already network active
|
||||
cy.log(`Plugin ${pluginSlug} is already network active`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Network activate the plugin
|
||||
cy.contains('tr', pluginSlug).find('.activate a').click();
|
||||
cy.contains('tr', pluginSlug).find('.network_active').should('exist');
|
||||
});
|
||||
});
|
||||
17
cypress/support/e2e.js
Normal file
17
cypress/support/e2e.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// ***********************************************************
|
||||
// This example support/e2e.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands';
|
||||
107
docs/code-quality-setup.md
Normal file
107
docs/code-quality-setup.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# Code Quality Tools Setup
|
||||
|
||||
This document explains how to set up and use the code quality tools for this project.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* PHP 7.4 or higher
|
||||
* Composer
|
||||
|
||||
## Installation
|
||||
|
||||
1. Clone the repository:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding.git
|
||||
cd wp-plugin-starter-template-for-ai-coding
|
||||
```
|
||||
|
||||
2. Install dependencies:
|
||||
|
||||
```bash
|
||||
composer install
|
||||
```
|
||||
|
||||
## Available Tools
|
||||
|
||||
### PHP CodeSniffer (PHPCS)
|
||||
|
||||
PHPCS checks your code against the WordPress Coding Standards.
|
||||
|
||||
```bash
|
||||
# Run PHPCS
|
||||
composer phpcs
|
||||
|
||||
# Run PHPCS with a simplified ruleset
|
||||
composer phpcs:simple
|
||||
```
|
||||
|
||||
### PHP Code Beautifier and Fixer (PHPCBF)
|
||||
|
||||
PHPCBF automatically fixes coding standard violations.
|
||||
|
||||
```bash
|
||||
# Run PHPCBF to fix coding standard violations
|
||||
composer phpcbf
|
||||
|
||||
# Run PHPCBF with a simplified ruleset
|
||||
composer phpcbf:simple
|
||||
```
|
||||
|
||||
### PHPStan
|
||||
|
||||
PHPStan performs static analysis to find bugs in your code.
|
||||
|
||||
```bash
|
||||
# Run PHPStan
|
||||
composer phpstan
|
||||
```
|
||||
|
||||
### PHP Mess Detector (PHPMD)
|
||||
|
||||
PHPMD detects potential problems in your code.
|
||||
|
||||
```bash
|
||||
# Run PHPMD
|
||||
composer phpmd
|
||||
```
|
||||
|
||||
### Running All Linters
|
||||
|
||||
```bash
|
||||
# Run all linters (PHPCS, PHPStan, PHPMD)
|
||||
composer lint
|
||||
```
|
||||
|
||||
### Running All Fixers
|
||||
|
||||
```bash
|
||||
# Run all fixers (PHPCBF)
|
||||
composer fix
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
For SonarCloud and Codacy integration, you need to set up the following environment variables:
|
||||
|
||||
### SonarCloud
|
||||
|
||||
```bash
|
||||
export SONAR_TOKEN=your_sonar_token
|
||||
```
|
||||
|
||||
### Codacy
|
||||
|
||||
```bash
|
||||
export CODACY_PROJECT_TOKEN=your_codacy_token
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
The project includes GitHub Actions workflows for running these tools automatically on each push and pull request. See the `.github/workflows/code-quality.yml` file for details.
|
||||
|
||||
## Customization
|
||||
|
||||
* PHPCS rules can be customized in `phpcs.xml`
|
||||
* PHPStan configuration is in `phpstan.neon`
|
||||
* SonarCloud configuration is in `sonar-project.properties`
|
||||
121
includes/Admin/class-admin.php
Normal file
121
includes/Admin/class-admin.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin area functionality for the plugin.
|
||||
*
|
||||
* @package WPALLSTARS\PluginStarterTemplate\Admin
|
||||
*/
|
||||
|
||||
namespace WPALLSTARS\PluginStarterTemplate\Admin;
|
||||
|
||||
use WPALLSTARS\PluginStarterTemplate\Core;
|
||||
|
||||
/**
|
||||
* Admin class responsible for admin-specific hooks and functionality.
|
||||
*/
|
||||
class Admin {
|
||||
|
||||
/**
|
||||
* Core plugin class instance.
|
||||
*
|
||||
* @var Core
|
||||
*/
|
||||
private Core $core;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Core $core Core instance.
|
||||
*/
|
||||
public function __construct( Core $core ) {
|
||||
$this->core = $core;
|
||||
$this->initialize_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes WordPress hooks.
|
||||
*/
|
||||
private function initialize_hooks(): void {
|
||||
\add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues admin-specific scripts and styles.
|
||||
*
|
||||
* This method is hooked into 'admin_enqueue_scripts'. It checks if the current
|
||||
* screen is relevant to the plugin before enqueueing assets.
|
||||
*/
|
||||
public function enqueue_admin_assets(): void {
|
||||
|
||||
// @phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||
// @phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||
// For production, use filter_input.
|
||||
$page = '';
|
||||
if ( defined( 'PHPUNIT_RUNNING' ) && PHPUNIT_RUNNING ) {
|
||||
// For testing, use $_GET directly.
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- We're sanitizing with wp_unslash and validating later
|
||||
$page = isset( $_GET['page'] ) ? \wp_unslash( $_GET['page'] ) : '';
|
||||
}
|
||||
|
||||
// Use filter_input for production environment.
|
||||
if ( empty( $page ) ) {
|
||||
$page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
|
||||
}
|
||||
|
||||
if ( ! $page || 'wp_plugin_starter_template_settings' !== $page ) {
|
||||
return;
|
||||
}
|
||||
// @phpcs:enable
|
||||
|
||||
// Get the plugin version.
|
||||
$plugin_version = $this->core->get_plugin_version();
|
||||
|
||||
$plugin_url = $this->get_plugin_base_url();
|
||||
|
||||
// Enqueue styles.
|
||||
\wp_enqueue_style(
|
||||
'wpst-admin-styles',
|
||||
$plugin_url . 'admin/css/admin-styles.css',
|
||||
array(), // Dependencies.
|
||||
$plugin_version // Version.
|
||||
);
|
||||
|
||||
// Enqueue admin scripts.
|
||||
\wp_enqueue_script(
|
||||
'wpst-admin-script',
|
||||
$plugin_url . 'admin/js/admin-scripts.js',
|
||||
array( 'jquery' ),
|
||||
$plugin_version, // Version.
|
||||
true
|
||||
);
|
||||
|
||||
// Prepare data for localization.
|
||||
$data = array(
|
||||
'ajax_url' => \admin_url( 'admin-ajax.php' ),
|
||||
'nonce' => \wp_create_nonce( 'wpst_admin_nonce' ),
|
||||
);
|
||||
|
||||
// Localize the script with the data.
|
||||
\wp_localize_script(
|
||||
'wpst-admin-script',
|
||||
'wpst_admin_data',
|
||||
$data
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plugin base URL.
|
||||
*
|
||||
* @return string Plugin base URL with trailing slash.
|
||||
*/
|
||||
private function get_plugin_base_url(): string {
|
||||
if ( defined( 'WP_PLUGIN_STARTER_TEMPLATE_URL' ) ) {
|
||||
return WP_PLUGIN_STARTER_TEMPLATE_URL;
|
||||
}
|
||||
|
||||
if ( defined( 'WPST_PLUGIN_URL' ) ) {
|
||||
return WPST_PLUGIN_URL;
|
||||
}
|
||||
|
||||
return \plugin_dir_url( dirname( __DIR__, 2 ) );
|
||||
}
|
||||
}
|
||||
29
includes/Multisite/README.md
Normal file
29
includes/Multisite/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Multisite Support
|
||||
|
||||
This directory contains placeholder files for multisite-specific functionality.
|
||||
|
||||
When developing a plugin based on this template, you can extend these files.
|
||||
|
||||
Create additional classes in this directory to implement multisite features.
|
||||
|
||||
## Usage
|
||||
|
||||
To implement multisite-specific functionality:
|
||||
|
||||
1. Create your multisite-specific classes in this directory
|
||||
2. Load and initialize these classes in your main plugin file when in a multisite environment:
|
||||
|
||||
```php
|
||||
// Load multisite support classes if in multisite environment
|
||||
if ( is_multisite() ) {
|
||||
require_once WP_PLUGIN_STARTER_TEMPLATE_PATH . 'includes/Multisite/class-multisite.php';
|
||||
|
||||
// Initialize multisite support
|
||||
$multisite = new WPALLSTARS\PluginStarterTemplate\Multisite\Multisite();
|
||||
}
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
For information on testing your plugin in a multisite environment, see the
|
||||
[Testing Framework](../../.wiki/Testing.md) documentation.
|
||||
68
includes/Multisite/class-multisite.php
Normal file
68
includes/Multisite/class-multisite.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* Multisite Class
|
||||
*
|
||||
* This is a placeholder file for multisite-specific functionality.
|
||||
* Extend this file or create additional classes in this directory
|
||||
* to implement multisite features for your plugin.
|
||||
*
|
||||
* @package WPALLSTARS\PluginStarterTemplate
|
||||
*/
|
||||
|
||||
namespace WPALLSTARS\PluginStarterTemplate\Multisite;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Multisite
|
||||
*
|
||||
* Base class for multisite-specific functionality.
|
||||
*/
|
||||
class Multisite {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
// This is just a placeholder class.
|
||||
// Add your multisite-specific initialization here.
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize hooks.
|
||||
*/
|
||||
public function initialize_hooks() {
|
||||
add_action( 'network_admin_menu', array( $this, 'add_network_menu' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add network admin menu.
|
||||
*/
|
||||
public function add_network_menu() {
|
||||
// This is a placeholder method.
|
||||
// In a real implementation, you would add network admin menu items here.
|
||||
}
|
||||
|
||||
/**
|
||||
* Example method for multisite functionality.
|
||||
*
|
||||
* @return bool Always returns true.
|
||||
*/
|
||||
public function is_multisite_compatible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Example method to get all sites in the network.
|
||||
*
|
||||
* @return array An array of sites or an empty array if not in multisite.
|
||||
*/
|
||||
public function get_network_sites() {
|
||||
// This is just a placeholder method.
|
||||
// In a real implementation, you might use get_sites() or a custom query.
|
||||
return function_exists( 'get_sites' ) ? get_sites( array( 'public' => 1 ) ) : array();
|
||||
}
|
||||
}
|
||||
50
includes/class-core.php
Normal file
50
includes/class-core.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* Core functionality for the plugin
|
||||
*
|
||||
* @package WPALLSTARS\PluginStarterTemplate
|
||||
*/
|
||||
|
||||
namespace WPALLSTARS\PluginStarterTemplate;
|
||||
|
||||
/**
|
||||
* Core class
|
||||
*/
|
||||
class Core {
|
||||
|
||||
/**
|
||||
* Plugin version
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private string $version;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $version Plugin version.
|
||||
*/
|
||||
public function __construct( string $version = '' ) {
|
||||
// Initialize hooks.
|
||||
$this->version = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Example method to filter content
|
||||
*
|
||||
* @param string $content The content to filter.
|
||||
* @return string The filtered content.
|
||||
*/
|
||||
public function filter_content( string $content ): string {
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin version
|
||||
*
|
||||
* @return string The plugin version.
|
||||
*/
|
||||
public function get_plugin_version(): string {
|
||||
return $this->version;
|
||||
}
|
||||
}
|
||||
98
includes/class-plugin.php
Normal file
98
includes/class-plugin.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
/**
|
||||
* Main plugin class
|
||||
*
|
||||
* @package WPALLSTARS\PluginStarterTemplate
|
||||
*/
|
||||
|
||||
namespace WPALLSTARS\PluginStarterTemplate;
|
||||
|
||||
use WPALLSTARS\PluginStarterTemplate\Admin\Admin;
|
||||
|
||||
/**
|
||||
* Plugin class
|
||||
*/
|
||||
class Plugin {
|
||||
|
||||
/**
|
||||
* Core instance
|
||||
*
|
||||
* @var Core
|
||||
*/
|
||||
private Core $core;
|
||||
|
||||
/**
|
||||
* Admin instance
|
||||
*
|
||||
* @var Admin
|
||||
*/
|
||||
private Admin $admin;
|
||||
|
||||
/**
|
||||
* Plugin file path
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private string $pluginFile;
|
||||
|
||||
/**
|
||||
* Plugin version
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private string $version;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $pluginFile Main plugin file path.
|
||||
* @param string $version Plugin version.
|
||||
*/
|
||||
public function __construct( string $pluginFile, string $version ) {
|
||||
$this->pluginFile = $pluginFile;
|
||||
$this->version = $version;
|
||||
$this->core = new Core( $version );
|
||||
$this->admin = new Admin( $this->core );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the plugin
|
||||
*/
|
||||
public function init(): void {
|
||||
// Register hooks and filters.
|
||||
add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
|
||||
|
||||
// Initialize any other plugin functionality.
|
||||
}
|
||||
|
||||
/**
|
||||
* Load plugin textdomain.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function load_textdomain(): void {
|
||||
load_plugin_textdomain(
|
||||
'wp-plugin-starter-template',
|
||||
false,
|
||||
dirname( plugin_basename( $this->pluginFile ) ) . '/languages/'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin version.
|
||||
*
|
||||
* @return string The plugin version.
|
||||
*/
|
||||
public function get_version(): string {
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the admin instance.
|
||||
*
|
||||
* @return Admin The admin instance.
|
||||
*/
|
||||
public function get_admin(): Admin {
|
||||
return $this->admin;
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
<?php
|
||||
@@ -1 +0,0 @@
|
||||
<?php
|
||||
@@ -1 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* File: updater.php
|
||||
* Description: Placeholder for potential updater logic.
|
||||
*
|
||||
* @package WPALLSTARS\PluginStarterTemplate
|
||||
*/
|
||||
|
||||
60
mu-plugins/multisite-setup.php
Normal file
60
mu-plugins/multisite-setup.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: Multisite Setup Helper
|
||||
* Description: Helper plugin to set up multisite testing environment
|
||||
* Version: 1.0.0
|
||||
* Author: WPALLSTARS
|
||||
* License: GPL-2.0-or-later
|
||||
*
|
||||
* @package WP_Plugin_Starter_Template_For_AI_Coding
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a filter to allow subdirectory multisite on localhost
|
||||
*/
|
||||
add_filter( 'allow_subdirectory_install', '__return_true' );
|
||||
|
||||
/**
|
||||
* Add a filter to skip domain verification for multisite
|
||||
*/
|
||||
add_filter( 'multisite_domain_check', '__return_true' );
|
||||
|
||||
/**
|
||||
* Add a filter to allow wildcard subdomains
|
||||
*/
|
||||
add_filter( 'wp_is_large_network', '__return_false' );
|
||||
|
||||
/**
|
||||
* Add a filter to allow domain mapping
|
||||
*/
|
||||
add_filter( 'domain_mapping_warning', '__return_false' );
|
||||
|
||||
/**
|
||||
* Helper function to check if we're in a multisite environment.
|
||||
*
|
||||
* @return bool True if multisite is enabled, false otherwise.
|
||||
*/
|
||||
function wpst_is_multisite() {
|
||||
return defined( 'MULTISITE' ) && MULTISITE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get all sites in the network.
|
||||
*
|
||||
* @return array Array of site objects.
|
||||
*/
|
||||
function wpst_get_network_sites() {
|
||||
if ( ! wpst_is_multisite() ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return get_sites( array( 'public' => 1 ) );
|
||||
}
|
||||
|
||||
// Add a filter to enable multisite testing in PHPUnit.
|
||||
add_filter( 'wpst_is_multisite_compatible', '__return_true' );
|
||||
7827
package-lock.json
generated
Normal file
7827
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
73
package.json
Normal file
73
package.json
Normal file
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"name": "wp-plugin-starter-template-for-ai-coding",
|
||||
"version": "0.1.15",
|
||||
"description": "A comprehensive starter template for WordPress plugins with best practices for AI-assisted development.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "wp-env start",
|
||||
"stop": "wp-env stop",
|
||||
"wp-env": "wp-env",
|
||||
"setup:single": "bash bin/setup-test-env.sh single",
|
||||
"setup:multisite": "bash bin/setup-test-env.sh multisite",
|
||||
"test:single": "cypress open --config specPattern=cypress/e2e/single-site.cy.js",
|
||||
"test:single:headless": "cypress run --config specPattern=cypress/e2e/single-site.cy.js",
|
||||
"test:multisite": "cypress open --config specPattern=cypress/e2e/multisite.cy.js",
|
||||
"test:multisite:headless": "cypress run --config specPattern=cypress/e2e/multisite.cy.js",
|
||||
"test:e2e:single": "npm run setup:single && sleep 5 && npm run test:single:headless",
|
||||
"test:e2e:multisite": "npm run setup:multisite && sleep 5 && npm run test:multisite:headless",
|
||||
"test:playground:single": "cypress run --spec cypress/e2e/playground-single-site.cy.js",
|
||||
"test:playground:multisite": "cypress run --spec cypress/e2e/playground-multisite.cy.js",
|
||||
"playground:start": "bash bin/playground-test.sh start",
|
||||
"playground:start:multisite": "bash bin/playground-test.sh start --multisite",
|
||||
"playground:stop": "bash bin/playground-test.sh stop",
|
||||
"playground:status": "bash bin/playground-test.sh status",
|
||||
"localwp:create": "bash bin/localwp-setup.sh create",
|
||||
"localwp:create:multisite": "bash bin/localwp-setup.sh create --multisite",
|
||||
"localwp:sync": "bash bin/localwp-setup.sh sync",
|
||||
"localwp:reset": "bash bin/localwp-setup.sh reset",
|
||||
"test:phpunit": "composer test",
|
||||
"test:phpunit:multisite": "WP_MULTISITE=1 composer test",
|
||||
"build": "./build.sh",
|
||||
"lint:js": "eslint cypress/ cypress.config.js",
|
||||
"lint:css": "stylelint \"**/*.css\" --allow-empty-input",
|
||||
"lint:php": "composer run-script phpcs",
|
||||
"lint:php:simple": "composer run-script phpcs:simple",
|
||||
"lint:phpstan": "composer run-script phpstan",
|
||||
"lint:phpmd": "composer run-script phpmd",
|
||||
"fix:php": "composer run-script phpcbf",
|
||||
"fix:php:simple": "composer run-script phpcbf:simple",
|
||||
"test:php": "composer run-script test",
|
||||
"lint:php-all": "composer run-script lint",
|
||||
"lint": "npm run lint:php-all && npm run lint:js && npm run lint:css",
|
||||
"fix": "composer run-script fix",
|
||||
"quality": "npm run lint && npm run test:php"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding.git"
|
||||
},
|
||||
"keywords": [
|
||||
"wordpress",
|
||||
"plugin",
|
||||
"template",
|
||||
"ai",
|
||||
"coding"
|
||||
],
|
||||
"author": "WPALLSTARS",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"bugs": {
|
||||
"url": "https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding/issues"
|
||||
},
|
||||
"homepage": "https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding#readme",
|
||||
"devDependencies": {
|
||||
"@wordpress/env": "^8.12.0",
|
||||
"@wp-playground/blueprints": "^3.0.22",
|
||||
"@wp-playground/cli": "^3.0.22",
|
||||
"@wp-playground/client": "^3.0.22",
|
||||
"cypress": "^13.17.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-cypress": "^6.2.0",
|
||||
"stylelint": "^16.0.0",
|
||||
"stylelint-config-standard": "^36.0.0"
|
||||
}
|
||||
}
|
||||
57
phpcs-simple.xml
Normal file
57
phpcs-simple.xml
Normal file
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset name="WordPress Plugin Starter Template Simple">
|
||||
<description>A simplified ruleset for WordPress Plugin Starter Template.</description>
|
||||
|
||||
<!-- Check all PHP files in directory tree by default. -->
|
||||
<file>.</file>
|
||||
|
||||
<!-- Exclude paths -->
|
||||
<exclude-pattern>*/vendor/*</exclude-pattern>
|
||||
<exclude-pattern>*/node_modules/*</exclude-pattern>
|
||||
<exclude-pattern>*/bin/*</exclude-pattern>
|
||||
<exclude-pattern>*/.github/*</exclude-pattern>
|
||||
<exclude-pattern>*/tests/*</exclude-pattern>
|
||||
<exclude-pattern>*/build/*</exclude-pattern>
|
||||
<exclude-pattern>*/dist/*</exclude-pattern>
|
||||
|
||||
<!-- Command line arguments: combined short flags (-s shows sniff codes, -p shows progress) -->
|
||||
<arg value="sp"/>
|
||||
<arg name="extensions" value="php"/>
|
||||
<arg name="basepath" value="."/>
|
||||
<arg name="parallel" value="8"/>
|
||||
|
||||
<!-- Configs -->
|
||||
<config name="minimum_supported_wp_version" value="5.0"/>
|
||||
<config name="testVersion" value="7.0-"/>
|
||||
|
||||
<!-- Rules -->
|
||||
<rule ref="WordPress">
|
||||
<!-- Exclude rules that are too strict for this project -->
|
||||
<exclude name="WordPress.Files.FileName.InvalidClassFileName"/>
|
||||
<exclude name="WordPress.Files.FileName.NotHyphenatedLowercase"/>
|
||||
</rule>
|
||||
|
||||
<!-- Additional rules for better code quality -->
|
||||
<rule ref="Generic.Formatting.MultipleStatementAlignment">
|
||||
<properties>
|
||||
<property name="maxPadding" value="1"/>
|
||||
<property name="error" value="false"/>
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
<!-- Use spaces for indentation -->
|
||||
<rule ref="Generic.WhiteSpace.ScopeIndent">
|
||||
<properties>
|
||||
<property name="indent" value="4"/>
|
||||
<property name="tabIndent" value="false"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="Generic.WhiteSpace.DisallowTabIndent"/>
|
||||
|
||||
<!-- Enforce proper line endings -->
|
||||
<rule ref="Generic.Files.LineEndings">
|
||||
<properties>
|
||||
<property name="eolChar" value="\n"/>
|
||||
</properties>
|
||||
</rule>
|
||||
</ruleset>
|
||||
66
phpcs.xml
Normal file
66
phpcs.xml
Normal file
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset name="WordPress Coding Standards">
|
||||
<description>WordPress dev PHP_CodeSniffer ruleset.</description>
|
||||
|
||||
<!-- Check all PHP files in directory tree by default. -->
|
||||
<file>.</file>
|
||||
|
||||
<exclude-pattern>*/vendor/*</exclude-pattern>
|
||||
<exclude-pattern>*/node_modules/*</exclude-pattern>
|
||||
<exclude-pattern>*/bin/*</exclude-pattern>
|
||||
<exclude-pattern>*/.github/*</exclude-pattern>
|
||||
<exclude-pattern>*/tests/*</exclude-pattern>
|
||||
<exclude-pattern>libs/</exclude-pattern>
|
||||
|
||||
<arg name="extensions" value="php" />
|
||||
<arg name="basepath" value="." />
|
||||
<arg name="parallel" value="8" />
|
||||
|
||||
<!-- Configs -->
|
||||
<config name="minimum_supported_wp_version" value="5.2" />
|
||||
|
||||
<!-- Rules -->
|
||||
<rule ref="WordPress">
|
||||
<exclude name="WordPress.NamingConventions.ValidVariableName" />
|
||||
<exclude name="WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition" />
|
||||
|
||||
<!-- Disable Strict comparison in array check. Not applicable in the majority of cases. -->
|
||||
<exclude name="WordPress.PHP.StrictInArray" />
|
||||
|
||||
<exclude name="WordPress.WP.I18n" />
|
||||
|
||||
<exclude name="WordPress.Files.FileName.InvalidClassFileName" />
|
||||
<exclude name="WordPress.DB.DirectDatabaseQuery.NoCaching" />
|
||||
|
||||
<!-- Universal sniffs are commented out until the dependencies are properly installed -->
|
||||
<!-- <exclude name="Universal.ControlStructures.DisallowAlternativeSyntax.FoundIfWithInlineHTML" /> -->
|
||||
<!-- <exclude name="Universal.ControlStructures.DisallowAlternativeSyntax.FoundForeachWithInlineHTML" /> -->
|
||||
<!-- <exclude name="Universal.ControlStructures.DisallowAlternativeSyntax.FoundIf" /> -->
|
||||
<!-- <exclude name="Universal.ControlStructures.IfElseDeclaration.NoNewLine" /> -->
|
||||
<!-- <exclude name="Universal.Classes.RequireFinalClass.NonFinalClassFound" /> -->
|
||||
<!-- <exclude name="Universal.Namespaces.EnforceCurlyBraceSyntax.Forbidden" /> -->
|
||||
|
||||
<exclude name="Generic.Commenting.Todo" />
|
||||
<exclude name="Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition" />
|
||||
<exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedCatch" />
|
||||
<exclude name="Generic.WhiteSpace.DisallowSpaceIndent" />
|
||||
<exclude name="WordPress.WP.CapitalPDangit.Misspelled" />
|
||||
</rule>
|
||||
|
||||
<rule ref="Generic.WhiteSpace.ScopeIndent">
|
||||
<properties>
|
||||
<property name="indent" value="4"/>
|
||||
<property name="tabIndent" value="false"/>
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
<rule ref="Generic.WhiteSpace.DisallowTabIndent" />
|
||||
|
||||
<rule ref="Generic.Formatting.MultipleStatementAlignment">
|
||||
<properties>
|
||||
<property name="maxPadding" value="1" />
|
||||
<property name="error" value="false" />
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
</ruleset>
|
||||
27
phpmd.xml
Normal file
27
phpmd.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset name="WordPress PHPMD Ruleset"
|
||||
xmlns="http://pmd.sf.net/ruleset/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
|
||||
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
|
||||
<description>Custom PHPMD ruleset for WordPress plugin development</description>
|
||||
|
||||
<!-- Import rulesets -->
|
||||
<rule ref="rulesets/cleancode.xml">
|
||||
<exclude name="StaticAccess" />
|
||||
</rule>
|
||||
<rule ref="rulesets/codesize.xml" />
|
||||
<rule ref="rulesets/controversial.xml">
|
||||
<exclude name="CamelCaseMethodName" />
|
||||
<exclude name="CamelCaseParameterName" />
|
||||
<exclude name="CamelCaseVariableName" />
|
||||
<!-- WordPress plugins use filter_input() for production and $_GET for testing; Superglobals rule is not applicable. -->
|
||||
<exclude name="Superglobals" />
|
||||
</rule>
|
||||
<rule ref="rulesets/design.xml" />
|
||||
<rule ref="rulesets/naming.xml">
|
||||
<exclude name="ShortVariable" />
|
||||
<exclude name="LongVariable" />
|
||||
</rule>
|
||||
<rule ref="rulesets/unusedcode.xml" />
|
||||
</ruleset>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user