Because cats have 9 lives, but servers don't - so they need backup-restore! Complete backup solution with S3/MinIO support. - Full WordPress backup (files + database) - S3 / MinIO / S3-compatible storage backends - Scheduled automatic backups - Disaster recovery / one-click restore - Backup integrity validation - Cat-themed admin interface Includes build.sh and .distignore for WordPress-installable release ZIPs.
11 KiB
11 KiB
Development Guide - TigerStyle Life9
🛠️ Development Environment Setup
Prerequisites
- WordPress: Local development environment (Local by Flywheel, XAMPP, Docker)
- Node.js: 18+ for Astro frontend development
- PHP: 7.4+ with required extensions
- Composer: For PHP dependency management
Quick Setup
# Clone to WordPress plugins directory
cd /path/to/wordpress/wp-content/plugins/
git clone https://github.com/tigerstyle/life9.git tigerstyle-life9
cd tigerstyle-life9
# Install dependencies
npm install
composer install
# Build frontend (optional - fallbacks work without build)
npm run build
# Activate in WordPress admin
🏗️ Project Architecture
Directory Structure
tigerstyle-life9/
├── 📄 tigerstyle-life9.php # Main plugin file (singleton pattern)
├── 📁 includes/ # Core PHP classes
│ ├── 🛡️ class-security.php # Security management layer
│ ├── 🔒 class-encryption.php # AES-256-GCM encryption
│ ├── 🧹 class-sanitizer.php # Input sanitization
│ ├── ✅ class-validator.php # Data validation
│ ├── 📦 class-backup-engine.php # Backup orchestration
│ ├── 🗄️ class-database-backup.php # MySQL export
│ ├── 📁 class-file-scanner.php # File discovery
│ ├── 💾 class-storage-manager.php # Storage abstraction
│ ├── 🌐 class-rest-endpoints.php # REST API
│ ├── 🎨 class-admin.php # WordPress admin integration
│ └── 📁 storage/ # Storage backend implementations
├── 📁 src/astro/ # Modern frontend
│ ├── 📁 pages/ # Admin interface pages
│ │ ├── backup.astro # Backup creation interface
│ │ ├── restore.astro # Restore wizard
│ │ ├── settings.astro # Configuration panel
│ │ └── admin-dashboard.astro # Main dashboard
│ ├── 📁 components/ # Reusable UI components
│ │ └── FileBrowser.astro # File selection component
│ └── 📁 layouts/ # Page layouts
│ └── WordPressAdmin.astro # WordPress admin wrapper
├── 📁 admin/assets/ # Compiled frontend assets
│ ├── 📁 css/ # Stylesheets
│ └── 📁 dist/ # Built Astro output
├── 📁 build-tools/ # Development utilities
├── 🔧 astro.config.mjs # Astro build configuration
├── 📋 package.json # Node.js dependencies
├── 📋 composer.json # PHP dependencies
└── 📚 Documentation files
Design Patterns Used
1. Singleton Pattern (Main Plugin)
final class TigerStyle_Life9 {
private static $instance = null;
public static function instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
}
2. Abstract Factory (Storage Backends)
abstract class TigerStyle_Life9_Storage_Backend {
abstract public function store($file_path, $config = []);
abstract public function retrieve($remote_path, $local_path, $config = []);
abstract public function delete($remote_path, $config = []);
}
3. Strategy Pattern (Backup Types)
class TigerStyle_Life9_Backup_Engine {
private $strategies = [];
public function add_strategy($type, $strategy) {
$this->strategies[$type] = $strategy;
}
public function execute_backup($type, $config) {
return $this->strategies[$type]->backup($config);
}
}
4. Observer Pattern (Progress Tracking)
// Server-Sent Events for real-time updates
class TigerStyle_Life9_Progress_Tracker {
private $observers = [];
public function notify_progress($backup_id, $progress) {
foreach ($this->observers as $observer) {
$observer->update($backup_id, $progress);
}
}
}
🧩 Component Development
Creating New Astro Components
- Create component file:
---
// src/astro/components/NewComponent.astro
interface Props {
title: string;
data?: any[];
}
const { title, data = [] } = Astro.props;
---
<div class="new-component" x-data="newComponent()">
<h3>{title}</h3>
<div class="component-content">
<!-- Component HTML -->
</div>
</div>
<script>
function newComponent() {
return {
// Alpine.js reactive data
items: [],
loading: false,
// Methods
async loadData() {
this.loading = true;
try {
const response = await this.$wp.ajax('get_component_data');
this.items = response.data;
} finally {
this.loading = false;
}
}
};
}
</script>
- Add styles in
admin/assets/css/admin.css:
.new-component {
padding: var(--tigerstyle-spacing-lg);
border: 1px solid var(--tigerstyle-gray-200);
border-radius: var(--tigerstyle-radius-lg);
}
Creating PHP Backend Classes
- Follow WordPress coding standards:
<?php
/**
* New Feature Class
*
* Description of what this class does
*
* @package TigerStyleLife9
* @since 1.0.0
*/
// Exit if accessed directly
if (!defined('ABSPATH')) {
exit;
}
/**
* New feature implementation
*
* @since 1.0.0
*/
class TigerStyle_Life9_New_Feature {
/**
* Security instance
*
* @var TigerStyle_Life9_Security
*/
private $security;
/**
* Constructor
*/
public function __construct() {
$this->security = tigerstyle_life9()->get_security();
$this->init_hooks();
}
/**
* Initialize WordPress hooks
*/
private function init_hooks() {
add_action('wp_ajax_tigerstyle_life9_new_action', [$this, 'handle_ajax']);
}
/**
* Handle AJAX request
*/
public function handle_ajax() {
// Security checks
check_ajax_referer('tigerstyle_life9_ajax', '_wpnonce');
if (!current_user_can('manage_options')) {
wp_send_json_error('Insufficient permissions');
}
// Input validation
$input = $this->security->sanitize_input($_POST);
// Business logic
$result = $this->process_request($input);
wp_send_json_success($result);
}
}
🧪 Testing Framework
PHP Unit Tests
// tests/test-backup-engine.php
class Test_Backup_Engine extends WP_UnitTestCase {
private $backup_engine;
public function setUp(): void {
parent::setUp();
$this->backup_engine = new TigerStyle_Life9_Backup_Engine(tigerstyle_life9());
}
public function test_backup_creation() {
$config = [
'include_files' => true,
'include_database' => true
];
$result = $this->backup_engine->create_backup($config);
$this->assertIsArray($result);
$this->assertArrayHasKey('backup_id', $result);
$this->assertTrue($result['success']);
}
public function test_security_validation() {
// Test path traversal prevention
$malicious_path = '../../wp-config.php';
$is_valid = $this->backup_engine->validate_backup_path($malicious_path);
$this->assertFalse($is_valid);
}
}
Frontend Testing
// tests/backup-interface.test.js
import { test, expect } from '@playwright/test';
test('backup interface loads correctly', async ({ page }) => {
await page.goto('/wp-admin/admin.php?page=tigerstyle-life9-backup');
// Check for main elements
await expect(page.locator('h1')).toContainText('Create Backup');
await expect(page.locator('.backup-type-grid')).toBeVisible();
// Test backup configuration
await page.check('[x-model="config.includeFiles"]');
await page.check('[x-model="config.includeDatabase"]');
await expect(page.locator('button[type="submit"]')).toBeEnabled();
});
🔧 Build Process
Development Workflow
# Start development
npm run dev # Astro dev server with hot reload
npm run watch # Watch for changes and rebuild
# Build for production
npm run build # Build optimized Astro assets
npm run build:wp # WordPress-specific build
# Testing
npm run test # Run all tests
npm run test:unit # PHP unit tests
npm run test:e2e # End-to-end tests
npm run test:security # Security scans
# Code quality
npm run lint # ESLint + Prettier
composer run phpcs # PHP CodeSniffer
composer run psalm # Static analysis
Custom Build Scripts
// build-tools/wordpress-integration.js
export async function buildForWordPress() {
// Convert Astro pages to WordPress-compatible format
// Generate asset manifest for PHP integration
// Optimize for WordPress admin environment
}
🎨 Styling System
CSS Architecture
/* CSS Custom Properties for theming */
:root {
--tigerstyle-primary: #1e40af;
--tigerstyle-spacing-md: 1rem;
--tigerstyle-radius-lg: 0.5rem;
}
/* Component-scoped styles */
.tigerstyle-backup-interface {
/* Styles scoped to prevent WordPress conflicts */
}
/* Utility classes */
.tigerstyle-card { /* Reusable card component */ }
.tigerstyle-button-primary { /* Primary button styling */ }
Alpine.js Integration
// Global Alpine.js helpers
document.addEventListener('alpine:init', () => {
Alpine.magic('wp', () => ({
ajax: async (action, data = {}) => {
// WordPress AJAX wrapper with security
},
nonce: tigerStyleLife9.nonce,
capabilities: tigerStyleLife9.capabilities
}));
});
🚀 Deployment
Production Checklist
- Run security scans (
composer audit,npm audit) - Execute full test suite
- Build optimized assets (
npm run build) - Verify PHP compatibility (7.4+)
- Test on clean WordPress installation
- Review security configuration
- Update version numbers
- Generate changelog
Release Process
- Version bump in
tigerstyle-life9.phpandpackage.json - Build assets with
npm run build - Run tests with
npm run test - Security scan with
composer audit - Create release on GitHub with changelog
- Submit to WordPress.org plugin repository
🐛 Debugging
Debug Mode
// Enable debug mode
define('TIGERSTYLE_LIFE9_DEBUG', true);
define('WP_DEBUG_LOG', true);
// Custom logging
tigerstyle_life9_log('Debug message', $data);
Common Issues
- Astro build fails: Check Node.js version and dependencies
- Backup permissions: Verify WordPress file permissions
- Memory limits: Increase PHP memory_limit for large sites
- Progress tracking: Check Server-Sent Events support
Happy coding! Build something awesome! 🚀