407 lines
9.7 KiB
Markdown
407 lines
9.7 KiB
Markdown
# PSR-4 WordPress Plugin Template
|
|
|
|
This is a modern PSR-4 autoloading pattern for WordPress plugins using Composer. Best for large, complex plugins that need professional architecture with namespaces and autoloading.
|
|
|
|
## Features
|
|
|
|
✅ PSR-4 autoloading with Composer
|
|
✅ Namespace organization (MyPSR4Plugin\*)
|
|
✅ Singleton pattern
|
|
✅ Modular class structure by domain
|
|
✅ Custom post type with meta boxes
|
|
✅ Custom taxonomy
|
|
✅ Admin settings using Settings API
|
|
✅ REST API endpoints (GET, POST)
|
|
✅ Asset management (admin + frontend)
|
|
✅ Proper activation/deactivation hooks
|
|
✅ Uninstall script for cleanup
|
|
✅ Internationalization ready
|
|
✅ WordPress Coding Standards ready (PHPCS)
|
|
✅ Security best practices
|
|
|
|
## Installation
|
|
|
|
1. Copy this folder to `wp-content/plugins/`
|
|
2. Rename folder and files to match your plugin name
|
|
3. Find and replace the following:
|
|
- `MyPSR4Plugin` → YourPluginNamespace
|
|
- `My PSR-4 Plugin` → Your plugin name
|
|
- `my-psr4-plugin` → your-plugin-slug
|
|
- `mypp_` → yourprefix_
|
|
- `MYPP_` → YOURPREFIX_
|
|
- `yourname/my-psr4-plugin` → your-composer/package-name
|
|
- `https://example.com` → Your website
|
|
- `Your Name` → Your name
|
|
4. Run `composer install` in the plugin directory
|
|
5. Activate in WordPress admin
|
|
|
|
## Structure
|
|
|
|
```
|
|
my-psr4-plugin/
|
|
├── my-psr4-plugin.php # Main plugin file (bootstrapper)
|
|
├── composer.json # Composer dependencies and autoloading
|
|
├── uninstall.php # Cleanup on uninstall
|
|
├── README.md # This file
|
|
├── src/ # Source code (PSR-4 autoloaded)
|
|
│ ├── Plugin.php # Main plugin class
|
|
│ ├── PostTypes/ # Custom post types
|
|
│ │ └── Book.php
|
|
│ ├── Taxonomies/ # Taxonomies
|
|
│ │ └── Genre.php
|
|
│ ├── Admin/ # Admin functionality
|
|
│ │ └── Settings.php
|
|
│ ├── Frontend/ # Frontend functionality
|
|
│ │ └── Assets.php
|
|
│ └── API/ # REST API endpoints
|
|
│ └── BookEndpoints.php
|
|
├── assets/ # CSS/JS files (create as needed)
|
|
│ ├── css/
|
|
│ │ ├── admin-style.css
|
|
│ │ └── style.css
|
|
│ └── js/
|
|
│ ├── admin-script.js
|
|
│ └── script.js
|
|
├── languages/ # Translation files (create as needed)
|
|
└── vendor/ # Composer dependencies (auto-generated)
|
|
```
|
|
|
|
## Composer Setup
|
|
|
|
### Install Dependencies
|
|
|
|
```bash
|
|
cd wp-content/plugins/my-psr4-plugin
|
|
composer install
|
|
```
|
|
|
|
### Development Dependencies
|
|
|
|
The template includes WordPress Coding Standards (WPCS) for code quality:
|
|
|
|
```bash
|
|
# Check code standards
|
|
composer phpcs
|
|
|
|
# Fix code standards automatically
|
|
composer phpcbf
|
|
```
|
|
|
|
### Update Dependencies
|
|
|
|
```bash
|
|
composer update
|
|
```
|
|
|
|
## Namespaces
|
|
|
|
The plugin uses the following namespace structure:
|
|
|
|
- `MyPSR4Plugin\` - Root namespace
|
|
- `MyPSR4Plugin\PostTypes\` - Custom post types
|
|
- `MyPSR4Plugin\Taxonomies\` - Taxonomies
|
|
- `MyPSR4Plugin\Admin\` - Admin functionality
|
|
- `MyPSR4Plugin\Frontend\` - Frontend functionality
|
|
- `MyPSR4Plugin\API\` - REST API endpoints
|
|
|
|
## Included Examples
|
|
|
|
### Custom Post Type (src/PostTypes/Book.php)
|
|
- "Books" post type with Gutenberg support
|
|
- Meta boxes for ISBN, Author, Publication Year
|
|
- Nonce verification and sanitization
|
|
|
|
### Taxonomy (src/Taxonomies/Genre.php)
|
|
- "Genres" hierarchical taxonomy
|
|
- Linked to Books post type
|
|
|
|
### Admin Settings (src/Admin/Settings.php)
|
|
- Located in Settings → PSR-4 Plugin
|
|
- Uses WordPress Settings API
|
|
- Multiple field types with validation
|
|
|
|
### REST API (src/API/BookEndpoints.php)
|
|
- `GET /wp-json/mypp/v1/books` - List all books
|
|
- `GET /wp-json/mypp/v1/books/{id}` - Get single book
|
|
- `POST /wp-json/mypp/v1/books` - Create book
|
|
- Permission callbacks and validation
|
|
|
|
### Assets (src/Frontend/Assets.php)
|
|
- Conditional loading (admin + frontend)
|
|
- Localized script data
|
|
|
|
## Adding New Classes
|
|
|
|
### 1. Create Class File
|
|
|
|
Create `src/YourNamespace/YourClass.php`:
|
|
|
|
```php
|
|
<?php
|
|
namespace MyPSR4Plugin\YourNamespace;
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
class YourClass {
|
|
private static $instance = null;
|
|
|
|
public static function get_instance() {
|
|
if ( null === self::$instance ) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
private function __construct() {
|
|
// Initialize
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2. Initialize in Plugin.php
|
|
|
|
Add to `src/Plugin.php` in the `init()` method:
|
|
|
|
```php
|
|
YourNamespace\YourClass::get_instance();
|
|
```
|
|
|
|
### 3. Composer Will Auto-Load
|
|
|
|
No need to manually require files! Composer's PSR-4 autoloader handles it.
|
|
|
|
## Security Checklist
|
|
|
|
- [x] ABSPATH check in every file
|
|
- [x] Namespaces prevent naming conflicts
|
|
- [x] Private constructors (singletons)
|
|
- [x] Nonces for all forms
|
|
- [x] Capability checks (current_user_can)
|
|
- [x] Input sanitization (sanitize_text_field, absint)
|
|
- [x] Output escaping (esc_html, esc_attr)
|
|
- [x] REST API permission callbacks
|
|
- [x] REST API argument validation
|
|
- [x] Conditional asset loading
|
|
- [x] Composer autoloader check
|
|
|
|
## Advantages of PSR-4 Pattern
|
|
|
|
✅ **Professional** - Industry-standard autoloading
|
|
✅ **No manual requires** - Composer handles class loading
|
|
✅ **Organized** - Classes grouped by domain/functionality
|
|
✅ **Scalable** - Easy to add new features
|
|
✅ **Testable** - Each class is independently testable
|
|
✅ **Standards** - Compatible with modern PHP tooling
|
|
✅ **Namespaces** - Prevents naming conflicts
|
|
✅ **Version control** - Clean git diffs (no huge files)
|
|
|
|
## When to Use PSR-4
|
|
|
|
**Use PSR-4 when**:
|
|
- Plugin has 20+ classes
|
|
- Multiple developers
|
|
- Need professional architecture
|
|
- Plan to add many features over time
|
|
- Want to use Composer packages
|
|
- Need unit testing
|
|
- Building a commercial plugin
|
|
|
|
**Use OOP when**:
|
|
- Plugin has 10-20 classes
|
|
- Single developer
|
|
- Don't need Composer dependencies
|
|
|
|
**Use Simple when**:
|
|
- Plugin has <10 classes
|
|
- Quick, focused functionality
|
|
|
|
## Development Workflow
|
|
|
|
### 1. Create New Feature Class
|
|
|
|
```bash
|
|
# Example: Create a new AJAX handler
|
|
touch src/AJAX/BookActions.php
|
|
```
|
|
|
|
### 2. Write Class with Namespace
|
|
|
|
```php
|
|
<?php
|
|
namespace MyPSR4Plugin\AJAX;
|
|
|
|
class BookActions {
|
|
// Your code
|
|
}
|
|
```
|
|
|
|
### 3. Initialize in Plugin.php
|
|
|
|
```php
|
|
AJAX\BookActions::get_instance();
|
|
```
|
|
|
|
### 4. Test
|
|
|
|
No need to run `composer dump-autoload` - PSR-4 discovers classes automatically!
|
|
|
|
## Code Quality
|
|
|
|
### Check Code Standards
|
|
|
|
```bash
|
|
composer phpcs
|
|
```
|
|
|
|
### Fix Code Standards
|
|
|
|
```bash
|
|
composer phpcbf
|
|
```
|
|
|
|
### Add Custom Rules
|
|
|
|
Edit `composer.json` scripts:
|
|
|
|
```json
|
|
"scripts": {
|
|
"phpcs": "phpcs --standard=WordPress --extensions=php src/",
|
|
"phpcbf": "phpcbf --standard=WordPress --extensions=php src/"
|
|
}
|
|
```
|
|
|
|
## Distribution & Auto-Updates
|
|
|
|
### Enabling GitHub Auto-Updates
|
|
|
|
You can provide automatic updates from GitHub without submitting to WordPress.org:
|
|
|
|
**1. Install Plugin Update Checker via Composer:**
|
|
|
|
```bash
|
|
composer require yahnis-elsts/plugin-update-checker
|
|
```
|
|
|
|
Or as git submodule:
|
|
|
|
```bash
|
|
git submodule add https://github.com/YahnisElsts/plugin-update-checker.git
|
|
```
|
|
|
|
**2. Create Updater class:**
|
|
|
|
Create `src/Updater.php`:
|
|
|
|
```php
|
|
<?php
|
|
namespace MyPSR4Plugin;
|
|
|
|
use YahnisElsts\PluginUpdateChecker\v5\PucFactory;
|
|
|
|
class Updater {
|
|
private static $instance = null;
|
|
private $updateChecker;
|
|
|
|
public static function get_instance() {
|
|
if ( null === self::$instance ) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
private function __construct() {
|
|
$this->init_updater();
|
|
}
|
|
|
|
private function init_updater() {
|
|
$updater_path = plugin_dir_path( __DIR__ ) . 'vendor/yahnis-elsts/plugin-update-checker/plugin-update-checker.php';
|
|
|
|
if ( ! file_exists( $updater_path ) ) {
|
|
return;
|
|
}
|
|
|
|
require $updater_path;
|
|
|
|
$this->updateChecker = PucFactory::buildUpdateChecker(
|
|
'https://github.com/yourusername/your-plugin/',
|
|
plugin_dir_path( __DIR__ ) . 'my-psr4-plugin.php',
|
|
'your-plugin-slug'
|
|
);
|
|
|
|
$this->updateChecker->setBranch( 'main' );
|
|
$this->updateChecker->getVcsApi()->enableReleaseAssets();
|
|
|
|
// Private repo authentication
|
|
if ( defined( 'MYPP_GITHUB_TOKEN' ) ) {
|
|
$this->updateChecker->setAuthentication( MYPP_GITHUB_TOKEN );
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**3. Initialize in Plugin.php:**
|
|
|
|
Add to `src/Plugin.php` `init()` method:
|
|
|
|
```php
|
|
Updater::get_instance();
|
|
```
|
|
|
|
**4. For private repos, add token to wp-config.php:**
|
|
|
|
```php
|
|
define( 'MYPP_GITHUB_TOKEN', 'ghp_xxxxxxxxxxxxx' );
|
|
```
|
|
|
|
**5. Create releases:**
|
|
|
|
```bash
|
|
# Update version in plugin header
|
|
git add my-psr4-plugin.php
|
|
git commit -m "Bump version to 1.0.1"
|
|
git tag 1.0.1
|
|
git push origin main
|
|
git push origin 1.0.1
|
|
|
|
# Create GitHub Release with pre-built ZIP
|
|
```
|
|
|
|
**6. Build release ZIP:**
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# build-release.sh
|
|
|
|
VERSION="1.0.1"
|
|
PLUGIN_SLUG="my-psr4-plugin"
|
|
|
|
# Install dependencies (no dev packages)
|
|
composer install --no-dev --optimize-autoloader
|
|
|
|
# Create ZIP
|
|
zip -r "${PLUGIN_SLUG}-${VERSION}.zip" \
|
|
"${PLUGIN_SLUG}/" \
|
|
-x "*.git*" "*.github/*" "tests/*" "node_modules/*"
|
|
|
|
echo "Built: ${PLUGIN_SLUG}-${VERSION}.zip"
|
|
```
|
|
|
|
### Resources
|
|
|
|
- **Complete Guide**: See `references/github-auto-updates.md`
|
|
- **Implementation Examples**: See `examples/github-updater.php`
|
|
- **Plugin Update Checker**: https://github.com/YahnisElsts/plugin-update-checker
|
|
|
|
## Resources
|
|
|
|
- [WordPress Plugin Handbook](https://developer.wordpress.org/plugins/)
|
|
- [PSR-4 Autoloading](https://www.php-fig.org/psr/psr-4/)
|
|
- [Composer Documentation](https://getcomposer.org/doc/)
|
|
- [WordPress Coding Standards](https://developer.wordpress.org/coding-standards/)
|
|
|
|
## License
|
|
|
|
GPL v2 or later
|