@mytechtoday/augment-extensions 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/augment-extensions/domain-rules/wordpress/README.md +163 -0
- package/augment-extensions/domain-rules/wordpress/module.json +32 -0
- package/augment-extensions/domain-rules/wordpress/rules/coding-standards.md +617 -0
- package/augment-extensions/domain-rules/wordpress/rules/directory-structure.md +270 -0
- package/augment-extensions/domain-rules/wordpress/rules/file-patterns.md +423 -0
- package/augment-extensions/domain-rules/wordpress/rules/gutenberg-blocks.md +493 -0
- package/augment-extensions/domain-rules/wordpress/rules/performance.md +568 -0
- package/augment-extensions/domain-rules/wordpress/rules/plugin-development.md +510 -0
- package/augment-extensions/domain-rules/wordpress/rules/project-detection.md +251 -0
- package/augment-extensions/domain-rules/wordpress/rules/rest-api.md +501 -0
- package/augment-extensions/domain-rules/wordpress/rules/security.md +564 -0
- package/augment-extensions/domain-rules/wordpress/rules/theme-development.md +388 -0
- package/augment-extensions/domain-rules/wordpress/rules/woocommerce.md +441 -0
- package/augment-extensions/domain-rules/wordpress-plugin/README.md +139 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/ajax-plugin.md +1599 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/custom-post-type-plugin.md +1727 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/gutenberg-block-plugin.md +428 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/gutenberg-block.md +422 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/mvc-plugin.md +1623 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/object-oriented-plugin.md +1343 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/rest-endpoint.md +734 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/settings-page-plugin.md +1350 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/simple-procedural-plugin.md +503 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/singleton-plugin.md +971 -0
- package/augment-extensions/domain-rules/wordpress-plugin/module.json +53 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/activation-hooks.md +770 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/admin-interface.md +874 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/ajax-handlers.md +629 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/asset-management.md +559 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/context-providers.md +709 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/cron-jobs.md +736 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/database-management.md +1057 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/documentation-standards.md +463 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/frontend-functionality.md +478 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/gutenberg-blocks.md +818 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/internationalization.md +416 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/migration.md +667 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/performance-optimization.md +878 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/plugin-architecture.md +693 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/plugin-structure.md +352 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/rest-api.md +818 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/scaffolding-workflow.md +624 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/security-best-practices.md +866 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/testing-patterns.md +1165 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/testing.md +414 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/vscode-integration.md +751 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/woocommerce-integration.md +949 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/wordpress-org-submission.md +458 -0
- package/augment-extensions/examples/gutenberg-block-plugin/README.md +101 -0
- package/augment-extensions/examples/gutenberg-block-plugin/examples/testimonial-block.md +428 -0
- package/augment-extensions/examples/gutenberg-block-plugin/module.json +40 -0
- package/augment-extensions/examples/rest-api-plugin/README.md +98 -0
- package/augment-extensions/examples/rest-api-plugin/examples/task-manager-api.md +1299 -0
- package/augment-extensions/examples/rest-api-plugin/module.json +40 -0
- package/augment-extensions/examples/woocommerce-extension/README.md +98 -0
- package/augment-extensions/examples/woocommerce-extension/examples/product-customizer.md +763 -0
- package/augment-extensions/examples/woocommerce-extension/module.json +40 -0
- package/augment-extensions/workflows/wordpress-plugin/README.md +232 -0
- package/augment-extensions/workflows/wordpress-plugin/ai-prompts.md +839 -0
- package/augment-extensions/workflows/wordpress-plugin/bead-decomposition-patterns.md +854 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/complete-plugin-example.md +540 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/custom-post-type-example.md +1083 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/feature-addition-workflow.md +669 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/plugin-creation-workflow.md +597 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/secure-form-handler-example.md +925 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/security-audit-workflow.md +752 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/wordpress-org-submission-workflow.md +773 -0
- package/augment-extensions/workflows/wordpress-plugin/module.json +49 -0
- package/augment-extensions/workflows/wordpress-plugin/rules/best-practices.md +942 -0
- package/augment-extensions/workflows/wordpress-plugin/rules/development-workflow.md +702 -0
- package/augment-extensions/workflows/wordpress-plugin/rules/submission-workflow.md +728 -0
- package/augment-extensions/workflows/wordpress-plugin/rules/testing-workflow.md +775 -0
- package/cli/dist/cli.js +5 -1
- package/cli/dist/cli.js.map +1 -1
- package/cli/dist/commands/show.d.ts.map +1 -1
- package/cli/dist/commands/show.js +41 -0
- package/cli/dist/commands/show.js.map +1 -1
- package/modules.md +52 -0
- package/package.json +1 -1
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
# Complete WordPress Plugin Example
|
|
2
|
+
|
|
3
|
+
This example shows a complete WordPress plugin development workflow from start to finish using OpenSpec and Beads.
|
|
4
|
+
|
|
5
|
+
## Scenario
|
|
6
|
+
|
|
7
|
+
Building a "Simple Contact Form" WordPress plugin that allows users to submit contact messages through a form on the frontend, with admin management capabilities.
|
|
8
|
+
|
|
9
|
+
## Plugin Requirements
|
|
10
|
+
|
|
11
|
+
- **Plugin Name**: Simple Contact Form
|
|
12
|
+
- **Plugin Slug**: simple-contact-form
|
|
13
|
+
- **Text Domain**: simple-contact-form
|
|
14
|
+
- **Minimum WordPress**: 6.0
|
|
15
|
+
- **PHP Version**: 7.4+
|
|
16
|
+
- **Features**:
|
|
17
|
+
- Frontend contact form with name, email, subject, message fields
|
|
18
|
+
- Admin page to view submitted messages
|
|
19
|
+
- Email notifications to site admin
|
|
20
|
+
- AJAX form submission
|
|
21
|
+
- Security: nonces, sanitization, escaping, capability checks
|
|
22
|
+
|
|
23
|
+
## Directory Structure
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
simple-contact-form/
|
|
27
|
+
├── simple-contact-form.php # Main plugin file
|
|
28
|
+
├── readme.txt # WordPress.org readme
|
|
29
|
+
├── uninstall.php # Cleanup on uninstall
|
|
30
|
+
├── includes/
|
|
31
|
+
│ ├── class-contact-form.php # Core form logic
|
|
32
|
+
│ ├── class-contact-message.php # Message model
|
|
33
|
+
│ └── class-email-handler.php # Email sending
|
|
34
|
+
├── admin/
|
|
35
|
+
│ ├── class-admin.php # Admin interface
|
|
36
|
+
│ ├── css/
|
|
37
|
+
│ │ └── admin.css
|
|
38
|
+
│ └── js/
|
|
39
|
+
│ └── admin.js
|
|
40
|
+
├── public/
|
|
41
|
+
│ ├── class-public.php # Frontend display
|
|
42
|
+
│ ├── css/
|
|
43
|
+
│ │ └── public.css
|
|
44
|
+
│ └── js/
|
|
45
|
+
│ └── public.js
|
|
46
|
+
├── tests/
|
|
47
|
+
│ ├── bootstrap.php
|
|
48
|
+
│ ├── test-contact-form.php
|
|
49
|
+
│ └── test-email-handler.php
|
|
50
|
+
└── languages/
|
|
51
|
+
└── simple-contact-form.pot
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Step 1: Initialize OpenSpec
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Create OpenSpec directory structure
|
|
58
|
+
mkdir -p openspec/specs/plugin-features
|
|
59
|
+
mkdir -p openspec/changes
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Step 2: Create OpenSpec Specification
|
|
63
|
+
|
|
64
|
+
**File**: `openspec/specs/plugin-features/contact-form.md`
|
|
65
|
+
|
|
66
|
+
```markdown
|
|
67
|
+
---
|
|
68
|
+
id: plugin-features/contact-form
|
|
69
|
+
status: active
|
|
70
|
+
relatedTasks: []
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
# Simple Contact Form Plugin
|
|
74
|
+
|
|
75
|
+
## Overview
|
|
76
|
+
A WordPress plugin that provides a simple contact form with admin management.
|
|
77
|
+
|
|
78
|
+
## Requirements
|
|
79
|
+
|
|
80
|
+
### Functional Requirements
|
|
81
|
+
- Display contact form via shortcode `[simple_contact_form]`
|
|
82
|
+
- Collect: name, email, subject, message
|
|
83
|
+
- Store submissions in custom database table
|
|
84
|
+
- Send email notification to admin on submission
|
|
85
|
+
- Admin page to view/delete submissions
|
|
86
|
+
- AJAX form submission with loading state
|
|
87
|
+
|
|
88
|
+
### Security Requirements
|
|
89
|
+
- Nonce verification for form submission
|
|
90
|
+
- Capability check: `manage_options` for admin page
|
|
91
|
+
- Sanitize all inputs using WordPress functions
|
|
92
|
+
- Escape all outputs
|
|
93
|
+
- Validate email addresses
|
|
94
|
+
- Rate limiting: max 3 submissions per IP per hour
|
|
95
|
+
|
|
96
|
+
### Performance Requirements
|
|
97
|
+
- Database queries optimized with indexes
|
|
98
|
+
- AJAX for form submission (no page reload)
|
|
99
|
+
- Conditional asset loading (only load on pages with shortcode)
|
|
100
|
+
|
|
101
|
+
## User Stories
|
|
102
|
+
|
|
103
|
+
**As a** site visitor
|
|
104
|
+
**I want** to submit a contact message
|
|
105
|
+
**So that** I can communicate with the site owner
|
|
106
|
+
|
|
107
|
+
**As a** site admin
|
|
108
|
+
**I want** to view submitted messages
|
|
109
|
+
**So that** I can respond to inquiries
|
|
110
|
+
|
|
111
|
+
## Technical Approach
|
|
112
|
+
|
|
113
|
+
### Database Schema
|
|
114
|
+
Custom table: `wp_simple_contact_messages`
|
|
115
|
+
- id (bigint, primary key, auto_increment)
|
|
116
|
+
- name (varchar 255)
|
|
117
|
+
- email (varchar 255)
|
|
118
|
+
- subject (varchar 255)
|
|
119
|
+
- message (text)
|
|
120
|
+
- ip_address (varchar 45)
|
|
121
|
+
- submitted_at (datetime)
|
|
122
|
+
- status (varchar 20, default 'unread')
|
|
123
|
+
|
|
124
|
+
### WordPress Integration
|
|
125
|
+
- Shortcode: `simple_contact_form`
|
|
126
|
+
- Admin menu: Tools > Contact Messages
|
|
127
|
+
- AJAX action: `simple_contact_form_submit`
|
|
128
|
+
- Activation hook: create database table
|
|
129
|
+
- Uninstall hook: remove database table and options
|
|
130
|
+
|
|
131
|
+
### Files to Create
|
|
132
|
+
- Main plugin file with header
|
|
133
|
+
- Core classes for form, message, email
|
|
134
|
+
- Admin interface class
|
|
135
|
+
- Frontend display class
|
|
136
|
+
- CSS/JS assets
|
|
137
|
+
- Unit tests
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Step 3: Create Beads Epic and Tasks
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Create epic
|
|
144
|
+
bd create "Build Simple Contact Form Plugin" -p 0 --type epic --label wordpress --label plugin
|
|
145
|
+
# Returns: bd-scf
|
|
146
|
+
|
|
147
|
+
# Database setup
|
|
148
|
+
bd create "Create database schema" -p 0 --parent bd-scf --label database
|
|
149
|
+
# Returns: bd-scf.1
|
|
150
|
+
|
|
151
|
+
# Core implementation
|
|
152
|
+
bd create "Create ContactForm core class" -p 1 --parent bd-scf --label implementation
|
|
153
|
+
# Returns: bd-scf.2
|
|
154
|
+
|
|
155
|
+
bd create "Create ContactMessage model class" -p 1 --parent bd-scf --label implementation
|
|
156
|
+
# Returns: bd-scf.3
|
|
157
|
+
|
|
158
|
+
bd create "Create EmailHandler class" -p 1 --parent bd-scf --label implementation
|
|
159
|
+
# Returns: bd-scf.4
|
|
160
|
+
|
|
161
|
+
# Admin interface
|
|
162
|
+
bd create "Create admin interface" -p 1 --parent bd-scf --label admin
|
|
163
|
+
# Returns: bd-scf.5
|
|
164
|
+
|
|
165
|
+
bd create "Add admin CSS/JS" -p 1 --parent bd-scf --label admin
|
|
166
|
+
# Returns: bd-scf.6
|
|
167
|
+
|
|
168
|
+
# Frontend
|
|
169
|
+
bd create "Create frontend form display" -p 1 --parent bd-scf --label frontend
|
|
170
|
+
# Returns: bd-scf.7
|
|
171
|
+
|
|
172
|
+
bd create "Add AJAX form submission" -p 1 --parent bd-scf --label frontend --label ajax
|
|
173
|
+
# Returns: bd-scf.8
|
|
174
|
+
|
|
175
|
+
bd create "Add frontend CSS/JS" -p 1 --parent bd-scf --label frontend
|
|
176
|
+
# Returns: bd-scf.9
|
|
177
|
+
|
|
178
|
+
# Security
|
|
179
|
+
bd create "Add nonce verification" -p 1 --parent bd-scf --label security
|
|
180
|
+
# Returns: bd-scf.10
|
|
181
|
+
|
|
182
|
+
bd create "Add input sanitization" -p 1 --parent bd-scf --label security
|
|
183
|
+
# Returns: bd-scf.11
|
|
184
|
+
|
|
185
|
+
bd create "Add output escaping" -p 1 --parent bd-scf --label security
|
|
186
|
+
# Returns: bd-scf.12
|
|
187
|
+
|
|
188
|
+
bd create "Add rate limiting" -p 1 --parent bd-scf --label security
|
|
189
|
+
# Returns: bd-scf.13
|
|
190
|
+
|
|
191
|
+
# Testing
|
|
192
|
+
bd create "Write unit tests" -p 1 --parent bd-scf --label testing
|
|
193
|
+
# Returns: bd-scf.14
|
|
194
|
+
|
|
195
|
+
bd create "Manual testing in WordPress" -p 2 --parent bd-scf --label testing
|
|
196
|
+
# Returns: bd-scf.15
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Step 4: Add Task Dependencies
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# Core classes depend on database
|
|
203
|
+
bd dep add bd-scf.2 bd-scf.1
|
|
204
|
+
bd dep add bd-scf.3 bd-scf.1
|
|
205
|
+
bd dep add bd-scf.4 bd-scf.1
|
|
206
|
+
|
|
207
|
+
# Admin depends on core classes
|
|
208
|
+
bd dep add bd-scf.5 bd-scf.3
|
|
209
|
+
bd dep add bd-scf.6 bd-scf.5
|
|
210
|
+
|
|
211
|
+
# Frontend depends on core classes
|
|
212
|
+
bd dep add bd-scf.7 bd-scf.2
|
|
213
|
+
bd dep add bd-scf.8 bd-scf.7
|
|
214
|
+
bd dep add bd-scf.9 bd-scf.7
|
|
215
|
+
|
|
216
|
+
# Security tasks depend on implementation
|
|
217
|
+
bd dep add bd-scf.10 bd-scf.8
|
|
218
|
+
bd dep add bd-scf.11 bd-scf.2
|
|
219
|
+
bd dep add bd-scf.12 bd-scf.5
|
|
220
|
+
bd dep add bd-scf.13 bd-scf.8
|
|
221
|
+
|
|
222
|
+
# Testing depends on everything
|
|
223
|
+
bd dep add bd-scf.14 bd-scf.13
|
|
224
|
+
bd dep add bd-scf.15 bd-scf.14
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Step 5: Implementation Workflow
|
|
228
|
+
|
|
229
|
+
### Task bd-scf.1: Create Database Schema
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
bd update bd-scf.1 --status in_progress
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**File**: `includes/class-contact-message.php` (database setup)
|
|
236
|
+
|
|
237
|
+
```php
|
|
238
|
+
<?php
|
|
239
|
+
class Simple_Contact_Message {
|
|
240
|
+
public static function create_table() {
|
|
241
|
+
global $wpdb;
|
|
242
|
+
$table_name = $wpdb->prefix . 'simple_contact_messages';
|
|
243
|
+
$charset_collate = $wpdb->get_charset_collate();
|
|
244
|
+
|
|
245
|
+
$sql = "CREATE TABLE $table_name (
|
|
246
|
+
id bigint(20) NOT NULL AUTO_INCREMENT,
|
|
247
|
+
name varchar(255) NOT NULL,
|
|
248
|
+
email varchar(255) NOT NULL,
|
|
249
|
+
subject varchar(255) NOT NULL,
|
|
250
|
+
message text NOT NULL,
|
|
251
|
+
ip_address varchar(45) NOT NULL,
|
|
252
|
+
submitted_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
|
253
|
+
status varchar(20) DEFAULT 'unread' NOT NULL,
|
|
254
|
+
PRIMARY KEY (id),
|
|
255
|
+
KEY email (email),
|
|
256
|
+
KEY submitted_at (submitted_at),
|
|
257
|
+
KEY status (status)
|
|
258
|
+
) $charset_collate;";
|
|
259
|
+
|
|
260
|
+
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
|
261
|
+
dbDelta($sql);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
public static function drop_table() {
|
|
265
|
+
global $wpdb;
|
|
266
|
+
$table_name = $wpdb->prefix . 'simple_contact_messages';
|
|
267
|
+
$wpdb->query("DROP TABLE IF EXISTS $table_name");
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**File**: `simple-contact-form.php` (activation hook)
|
|
273
|
+
|
|
274
|
+
```php
|
|
275
|
+
<?php
|
|
276
|
+
/**
|
|
277
|
+
* Plugin Name: Simple Contact Form
|
|
278
|
+
* Description: A simple contact form with admin management
|
|
279
|
+
* Version: 1.0.0
|
|
280
|
+
* Author: Your Name
|
|
281
|
+
* License: GPL-2.0+
|
|
282
|
+
* Text Domain: simple-contact-form
|
|
283
|
+
*/
|
|
284
|
+
|
|
285
|
+
if (!defined('ABSPATH')) {
|
|
286
|
+
exit;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
define('SIMPLE_CONTACT_FORM_VERSION', '1.0.0');
|
|
290
|
+
define('SIMPLE_CONTACT_FORM_PATH', plugin_dir_path(__FILE__));
|
|
291
|
+
|
|
292
|
+
// Activation hook
|
|
293
|
+
register_activation_hook(__FILE__, 'simple_contact_form_activate');
|
|
294
|
+
function simple_contact_form_activate() {
|
|
295
|
+
require_once SIMPLE_CONTACT_FORM_PATH . 'includes/class-contact-message.php';
|
|
296
|
+
Simple_Contact_Message::create_table();
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Deactivation hook
|
|
300
|
+
register_deactivation_hook(__FILE__, 'simple_contact_form_deactivate');
|
|
301
|
+
function simple_contact_form_deactivate() {
|
|
302
|
+
// Cleanup if needed
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**File**: `uninstall.php`
|
|
307
|
+
|
|
308
|
+
```php
|
|
309
|
+
<?php
|
|
310
|
+
if (!defined('WP_UNINSTALL_PLUGIN')) {
|
|
311
|
+
exit;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
require_once plugin_dir_path(__FILE__) . 'includes/class-contact-message.php';
|
|
315
|
+
Simple_Contact_Message::drop_table();
|
|
316
|
+
|
|
317
|
+
// Delete options
|
|
318
|
+
delete_option('simple_contact_form_version');
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
bd comment bd-scf.1 "Created database schema with indexes for performance"
|
|
323
|
+
bd close bd-scf.1
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Task bd-scf.2: Create ContactForm Core Class
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
bd ready # Shows bd-scf.2, bd-scf.3, bd-scf.4 are ready
|
|
330
|
+
bd update bd-scf.2 --status in_progress
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
**File**: `includes/class-contact-form.php`
|
|
334
|
+
|
|
335
|
+
```php
|
|
336
|
+
<?php
|
|
337
|
+
class Simple_Contact_Form {
|
|
338
|
+
private $message_model;
|
|
339
|
+
private $email_handler;
|
|
340
|
+
|
|
341
|
+
public function __construct() {
|
|
342
|
+
$this->message_model = new Simple_Contact_Message();
|
|
343
|
+
$this->email_handler = new Simple_Contact_Email_Handler();
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
public function init() {
|
|
347
|
+
add_shortcode('simple_contact_form', array($this, 'render_form'));
|
|
348
|
+
add_action('wp_ajax_simple_contact_form_submit', array($this, 'handle_submission'));
|
|
349
|
+
add_action('wp_ajax_nopriv_simple_contact_form_submit', array($this, 'handle_submission'));
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
public function render_form($atts) {
|
|
353
|
+
ob_start();
|
|
354
|
+
include SIMPLE_CONTACT_FORM_PATH . 'public/partials/contact-form.php';
|
|
355
|
+
return ob_get_clean();
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
public function handle_submission() {
|
|
359
|
+
// Verify nonce
|
|
360
|
+
if (!check_ajax_referer('simple_contact_form_nonce', 'nonce', false)) {
|
|
361
|
+
wp_send_json_error(array('message' => 'Security check failed'));
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Rate limiting check
|
|
365
|
+
if (!$this->check_rate_limit()) {
|
|
366
|
+
wp_send_json_error(array('message' => 'Too many submissions. Please try again later.'));
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Sanitize inputs
|
|
370
|
+
$name = sanitize_text_field($_POST['name']);
|
|
371
|
+
$email = sanitize_email($_POST['email']);
|
|
372
|
+
$subject = sanitize_text_field($_POST['subject']);
|
|
373
|
+
$message = sanitize_textarea_field($_POST['message']);
|
|
374
|
+
|
|
375
|
+
// Validate
|
|
376
|
+
if (empty($name) || empty($email) || empty($subject) || empty($message)) {
|
|
377
|
+
wp_send_json_error(array('message' => 'All fields are required'));
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if (!is_email($email)) {
|
|
381
|
+
wp_send_json_error(array('message' => 'Invalid email address'));
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Save to database
|
|
385
|
+
$message_id = $this->message_model->save(array(
|
|
386
|
+
'name' => $name,
|
|
387
|
+
'email' => $email,
|
|
388
|
+
'subject' => $subject,
|
|
389
|
+
'message' => $message,
|
|
390
|
+
'ip_address' => $this->get_client_ip()
|
|
391
|
+
));
|
|
392
|
+
|
|
393
|
+
if ($message_id) {
|
|
394
|
+
// Send email notification
|
|
395
|
+
$this->email_handler->send_notification($message_id);
|
|
396
|
+
wp_send_json_success(array('message' => 'Thank you! Your message has been sent.'));
|
|
397
|
+
} else {
|
|
398
|
+
wp_send_json_error(array('message' => 'Failed to save message. Please try again.'));
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
private function check_rate_limit() {
|
|
403
|
+
$ip = $this->get_client_ip();
|
|
404
|
+
$count = $this->message_model->count_recent_by_ip($ip, 1); // 1 hour
|
|
405
|
+
return $count < 3; // Max 3 per hour
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
private function get_client_ip() {
|
|
409
|
+
$ip = '';
|
|
410
|
+
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
|
|
411
|
+
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
|
412
|
+
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
|
413
|
+
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
|
414
|
+
} else {
|
|
415
|
+
$ip = $_SERVER['REMOTE_ADDR'];
|
|
416
|
+
}
|
|
417
|
+
return sanitize_text_field($ip);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
```bash
|
|
423
|
+
bd comment bd-scf.2 "Created ContactForm class with AJAX handler and rate limiting"
|
|
424
|
+
bd close bd-scf.2
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
## Step 6: Continue Implementation
|
|
428
|
+
|
|
429
|
+
Following the same pattern, implement remaining tasks:
|
|
430
|
+
|
|
431
|
+
- **bd-scf.3**: ContactMessage model with CRUD operations
|
|
432
|
+
- **bd-scf.4**: EmailHandler for sending notifications
|
|
433
|
+
- **bd-scf.5**: Admin interface to view/delete messages
|
|
434
|
+
- **bd-scf.6**: Admin CSS/JS for styling and interactions
|
|
435
|
+
- **bd-scf.7**: Frontend form template
|
|
436
|
+
- **bd-scf.8**: AJAX form submission JavaScript
|
|
437
|
+
- **bd-scf.9**: Frontend CSS for form styling
|
|
438
|
+
- **bd-scf.10-13**: Security hardening
|
|
439
|
+
- **bd-scf.14**: Unit tests with PHPUnit
|
|
440
|
+
- **bd-scf.15**: Manual testing
|
|
441
|
+
|
|
442
|
+
## Step 7: Testing
|
|
443
|
+
|
|
444
|
+
```bash
|
|
445
|
+
# Run unit tests
|
|
446
|
+
cd wp-content/plugins/simple-contact-form
|
|
447
|
+
./vendor/bin/phpunit
|
|
448
|
+
|
|
449
|
+
# Manual testing checklist
|
|
450
|
+
bd comment bd-scf.15 "Testing checklist:
|
|
451
|
+
- ✓ Form displays correctly via shortcode
|
|
452
|
+
- ✓ AJAX submission works without page reload
|
|
453
|
+
- ✓ Email notifications sent to admin
|
|
454
|
+
- ✓ Messages saved to database
|
|
455
|
+
- ✓ Admin page displays messages
|
|
456
|
+
- ✓ Rate limiting prevents spam
|
|
457
|
+
- ✓ Security: nonces verified
|
|
458
|
+
- ✓ Security: inputs sanitized
|
|
459
|
+
- ✓ Security: outputs escaped
|
|
460
|
+
- ✓ Works with different themes
|
|
461
|
+
- ✓ Works on mobile devices"
|
|
462
|
+
|
|
463
|
+
bd close bd-scf.15
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
## Step 8: Close Epic
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
bd close bd-scf
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
## Final Plugin Structure
|
|
473
|
+
|
|
474
|
+
```
|
|
475
|
+
simple-contact-form/
|
|
476
|
+
├── simple-contact-form.php ✓ Created
|
|
477
|
+
├── readme.txt ✓ Created
|
|
478
|
+
├── uninstall.php ✓ Created
|
|
479
|
+
├── includes/
|
|
480
|
+
│ ├── class-contact-form.php ✓ Created
|
|
481
|
+
│ ├── class-contact-message.php ✓ Created
|
|
482
|
+
│ └── class-email-handler.php ✓ Created
|
|
483
|
+
├── admin/
|
|
484
|
+
│ ├── class-admin.php ✓ Created
|
|
485
|
+
│ ├── css/admin.css ✓ Created
|
|
486
|
+
│ └── js/admin.js ✓ Created
|
|
487
|
+
├── public/
|
|
488
|
+
│ ├── class-public.php ✓ Created
|
|
489
|
+
│ ├── partials/contact-form.php ✓ Created
|
|
490
|
+
│ ├── css/public.css ✓ Created
|
|
491
|
+
│ └── js/public.js ✓ Created
|
|
492
|
+
├── tests/
|
|
493
|
+
│ ├── bootstrap.php ✓ Created
|
|
494
|
+
│ ├── test-contact-form.php ✓ Created
|
|
495
|
+
│ └── test-email-handler.php ✓ Created
|
|
496
|
+
└── languages/
|
|
497
|
+
└── simple-contact-form.pot ✓ Created
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
## AI Agent Workflow Summary
|
|
501
|
+
|
|
502
|
+
### Creating the Plugin
|
|
503
|
+
|
|
504
|
+
```
|
|
505
|
+
Create a WordPress plugin called "Simple Contact Form" that allows users to submit contact messages.
|
|
506
|
+
|
|
507
|
+
Requirements:
|
|
508
|
+
- Plugin slug: simple-contact-form
|
|
509
|
+
- Text domain: simple-contact-form
|
|
510
|
+
- Minimum WordPress version: 6.0
|
|
511
|
+
- PHP version: 7.4+
|
|
512
|
+
|
|
513
|
+
Features:
|
|
514
|
+
- Frontend contact form (name, email, subject, message)
|
|
515
|
+
- Admin page to view submissions
|
|
516
|
+
- Email notifications
|
|
517
|
+
- AJAX submission
|
|
518
|
+
- Rate limiting (3 per hour per IP)
|
|
519
|
+
|
|
520
|
+
Use object-oriented architecture with separate classes for form, message model, and email handling.
|
|
521
|
+
Follow WordPress security best practices: nonces, sanitization, escaping, capability checks.
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### Implementation Approach
|
|
525
|
+
|
|
526
|
+
1. **Create OpenSpec spec** defining requirements
|
|
527
|
+
2. **Break down into Beads tasks** with dependencies
|
|
528
|
+
3. **Implement incrementally** following task order
|
|
529
|
+
4. **Test thoroughly** with unit and manual tests
|
|
530
|
+
5. **Document progress** in Beads comments
|
|
531
|
+
6. **Close tasks** as completed
|
|
532
|
+
|
|
533
|
+
## Key Takeaways
|
|
534
|
+
|
|
535
|
+
- **OpenSpec** provides clear requirements and technical approach
|
|
536
|
+
- **Beads** tracks implementation progress with dependencies
|
|
537
|
+
- **Security-first** approach with WordPress best practices
|
|
538
|
+
- **Incremental development** with testable milestones
|
|
539
|
+
- **Complete documentation** through Beads comments and OpenSpec specs
|
|
540
|
+
|