ima-claude 2.9.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.
Files changed (182) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +463 -0
  3. package/dist/cli.js +1064 -0
  4. package/package.json +49 -0
  5. package/platforms/claude/adapter.ts +115 -0
  6. package/platforms/junie/adapter.ts +254 -0
  7. package/platforms/junie/agents-template.md +113 -0
  8. package/platforms/junie/hook-translations.md +84 -0
  9. package/platforms/shared/detector.ts +27 -0
  10. package/platforms/shared/installer.ts +202 -0
  11. package/platforms/shared/types.ts +78 -0
  12. package/plugins/ima-claude/.claude-plugin/plugin.json +25 -0
  13. package/plugins/ima-claude/agents/explorer.md +30 -0
  14. package/plugins/ima-claude/agents/implementer.md +30 -0
  15. package/plugins/ima-claude/agents/memory.md +42 -0
  16. package/plugins/ima-claude/agents/reviewer.md +53 -0
  17. package/plugins/ima-claude/agents/tester.md +33 -0
  18. package/plugins/ima-claude/agents/wp-developer.md +46 -0
  19. package/plugins/ima-claude/hooks/README.md +145 -0
  20. package/plugins/ima-claude/hooks/atlassian_prereqs.py +112 -0
  21. package/plugins/ima-claude/hooks/block_sed_edits.py +59 -0
  22. package/plugins/ima-claude/hooks/bootstrap.sh +90 -0
  23. package/plugins/ima-claude/hooks/bootstrap_utility_check.py +94 -0
  24. package/plugins/ima-claude/hooks/composer_autoload_check.py +70 -0
  25. package/plugins/ima-claude/hooks/docs_organization.py +104 -0
  26. package/plugins/ima-claude/hooks/enforce_rg_over_grep.py +56 -0
  27. package/plugins/ima-claude/hooks/fp_utility_check.py +90 -0
  28. package/plugins/ima-claude/hooks/hook_logger.py +69 -0
  29. package/plugins/ima-claude/hooks/hooks.json +239 -0
  30. package/plugins/ima-claude/hooks/jira_issue_fetch.py +79 -0
  31. package/plugins/ima-claude/hooks/jquery_in_wordpress.py +92 -0
  32. package/plugins/ima-claude/hooks/memory_bootstrap.py +79 -0
  33. package/plugins/ima-claude/hooks/memory_store_reminder.py +75 -0
  34. package/plugins/ima-claude/hooks/prompt_coach.py +125 -0
  35. package/plugins/ima-claude/hooks/prompt_coach_digest.md +48 -0
  36. package/plugins/ima-claude/hooks/prompt_coach_system.md +30 -0
  37. package/plugins/ima-claude/hooks/sequential_thinking_check.py +81 -0
  38. package/plugins/ima-claude/hooks/serena_over_grep.py +96 -0
  39. package/plugins/ima-claude/hooks/serena_over_read.py +66 -0
  40. package/plugins/ima-claude/hooks/serena_project_check.py +133 -0
  41. package/plugins/ima-claude/hooks/sql_injection_check.py +73 -0
  42. package/plugins/ima-claude/hooks/task_master_after_plan.py +31 -0
  43. package/plugins/ima-claude/hooks/task_master_before_impl.py +93 -0
  44. package/plugins/ima-claude/hooks/tavily_extract_advanced.py +48 -0
  45. package/plugins/ima-claude/hooks/vestige_before_external.py +86 -0
  46. package/plugins/ima-claude/hooks/webfetch_to_tavily.py +42 -0
  47. package/plugins/ima-claude/hooks/websearch_to_tavily.py +41 -0
  48. package/plugins/ima-claude/hooks/wp_security_check.py +150 -0
  49. package/plugins/ima-claude/personalities/README.md +45 -0
  50. package/plugins/ima-claude/personalities/enable-40k.md +69 -0
  51. package/plugins/ima-claude/personalities/enable-templars.md +69 -0
  52. package/plugins/ima-claude/skills/.research-summary.md +340 -0
  53. package/plugins/ima-claude/skills/architect/SKILL.md +304 -0
  54. package/plugins/ima-claude/skills/compound-bridge/SKILL.md +200 -0
  55. package/plugins/ima-claude/skills/discourse/SKILL.md +440 -0
  56. package/plugins/ima-claude/skills/discourse-admin/SKILL.md +192 -0
  57. package/plugins/ima-claude/skills/discourse-admin/references/api-endpoints.md +441 -0
  58. package/plugins/ima-claude/skills/discourse-admin/references/gotchas.md +107 -0
  59. package/plugins/ima-claude/skills/discourse-admin/references/staging-defaults.md +98 -0
  60. package/plugins/ima-claude/skills/discourse-admin/scripts/discourse-admin.py +319 -0
  61. package/plugins/ima-claude/skills/docs-organize/SKILL.md +254 -0
  62. package/plugins/ima-claude/skills/docs-organize/templates/active-README.md +50 -0
  63. package/plugins/ima-claude/skills/docs-organize/templates/archive-README.md +57 -0
  64. package/plugins/ima-claude/skills/docs-organize/templates/docs-README.md +43 -0
  65. package/plugins/ima-claude/skills/docs-organize/templates/phase-archive-README.md +83 -0
  66. package/plugins/ima-claude/skills/docs-organize/templates/section-README.md +48 -0
  67. package/plugins/ima-claude/skills/docs-organize/templates/transient-README.md +79 -0
  68. package/plugins/ima-claude/skills/docs-organize/templates/transient-gitignore +9 -0
  69. package/plugins/ima-claude/skills/ember-discourse/SKILL.md +496 -0
  70. package/plugins/ima-claude/skills/functional-programmer/SKILL.md +258 -0
  71. package/plugins/ima-claude/skills/ima-bootstrap/SKILL.md +278 -0
  72. package/plugins/ima-claude/skills/ima-bootstrap/references/bootstrap-patterns.md +356 -0
  73. package/plugins/ima-claude/skills/ima-bootstrap/references/ima-brand.md +273 -0
  74. package/plugins/ima-claude/skills/ima-bootstrap/references/theme-integration.md +212 -0
  75. package/plugins/ima-claude/skills/ima-brand/SKILL.md +108 -0
  76. package/plugins/ima-claude/skills/ima-brand/references/brand-identity.md +140 -0
  77. package/plugins/ima-claude/skills/ima-brand/references/digital-standards.md +180 -0
  78. package/plugins/ima-claude/skills/ima-brand/references/visual-system.md +173 -0
  79. package/plugins/ima-claude/skills/ima-forms-expert/SKILL.md +175 -0
  80. package/plugins/ima-claude/skills/ima-forms-expert/references/container-components.md +154 -0
  81. package/plugins/ima-claude/skills/ima-forms-expert/references/examples.md +328 -0
  82. package/plugins/ima-claude/skills/ima-forms-expert/references/field-components.md +298 -0
  83. package/plugins/ima-claude/skills/ima-forms-expert/references/form-factory.md +193 -0
  84. package/plugins/ima-claude/skills/ima-forms-expert/references/quick-reference.md +153 -0
  85. package/plugins/ima-claude/skills/ima-forms-expert/references/validation-engine.md +336 -0
  86. package/plugins/ima-claude/skills/jira-checkpoint/SKILL.md +178 -0
  87. package/plugins/ima-claude/skills/jquery/SKILL.md +413 -0
  88. package/plugins/ima-claude/skills/js-fp/SKILL.md +463 -0
  89. package/plugins/ima-claude/skills/js-fp/core-principles.md +487 -0
  90. package/plugins/ima-claude/skills/js-fp/examples/pure-functions.js +260 -0
  91. package/plugins/ima-claude/skills/js-fp/examples/tests/pure-functions.test.js +262 -0
  92. package/plugins/ima-claude/skills/js-fp/references/anti-patterns.md +120 -0
  93. package/plugins/ima-claude/skills/js-fp/references/performance-patterns.md +116 -0
  94. package/plugins/ima-claude/skills/js-fp/references/testing-patterns.md +134 -0
  95. package/plugins/ima-claude/skills/js-fp-api/SKILL.md +280 -0
  96. package/plugins/ima-claude/skills/js-fp-api/examples/crud-endpoint.js +258 -0
  97. package/plugins/ima-claude/skills/js-fp-api/references/middleware-patterns.md +134 -0
  98. package/plugins/ima-claude/skills/js-fp-api/references/security-sql.md +110 -0
  99. package/plugins/ima-claude/skills/js-fp-api/references/validation-patterns.md +165 -0
  100. package/plugins/ima-claude/skills/js-fp-react/SKILL.md +447 -0
  101. package/plugins/ima-claude/skills/js-fp-react/examples/ProductCard.tsx +65 -0
  102. package/plugins/ima-claude/skills/js-fp-react/references/hooks-advanced.md +136 -0
  103. package/plugins/ima-claude/skills/js-fp-react/references/performance-patterns.md +175 -0
  104. package/plugins/ima-claude/skills/js-fp-vue/SKILL.md +322 -0
  105. package/plugins/ima-claude/skills/js-fp-vue/references/complete-examples.md +397 -0
  106. package/plugins/ima-claude/skills/js-fp-vue/references/composables-advanced.md +282 -0
  107. package/plugins/ima-claude/skills/js-fp-vue/references/reactivity-patterns.md +348 -0
  108. package/plugins/ima-claude/skills/js-fp-vue/references/testing.md +314 -0
  109. package/plugins/ima-claude/skills/js-fp-wordpress/SKILL.md +301 -0
  110. package/plugins/ima-claude/skills/js-fp-wordpress/references/ajax-patterns.md +192 -0
  111. package/plugins/ima-claude/skills/js-fp-wordpress/references/event-patterns.md +136 -0
  112. package/plugins/ima-claude/skills/js-fp-wordpress/references/wp-integration.md +248 -0
  113. package/plugins/ima-claude/skills/livecanvas/SKILL.md +209 -0
  114. package/plugins/ima-claude/skills/livecanvas/references/livecanvas-features.md +311 -0
  115. package/plugins/ima-claude/skills/livecanvas/references/loops-and-logic.md +730 -0
  116. package/plugins/ima-claude/skills/livecanvas/references/picostrap.md +227 -0
  117. package/plugins/ima-claude/skills/mcp-atlassian/SKILL.md +339 -0
  118. package/plugins/ima-claude/skills/mcp-context7/SKILL.md +109 -0
  119. package/plugins/ima-claude/skills/mcp-memory/SKILL.md +182 -0
  120. package/plugins/ima-claude/skills/mcp-qdrant/SKILL.md +233 -0
  121. package/plugins/ima-claude/skills/mcp-sequential/SKILL.md +149 -0
  122. package/plugins/ima-claude/skills/mcp-serena/SKILL.md +174 -0
  123. package/plugins/ima-claude/skills/mcp-tavily/SKILL.md +118 -0
  124. package/plugins/ima-claude/skills/mcp-vestige/SKILL.md +259 -0
  125. package/plugins/ima-claude/skills/php-authnet/SKILL.md +275 -0
  126. package/plugins/ima-claude/skills/php-authnet/references/api-reference.md +624 -0
  127. package/plugins/ima-claude/skills/php-authnet/references/sandbox-testing.md +424 -0
  128. package/plugins/ima-claude/skills/php-fp/SKILL.md +333 -0
  129. package/plugins/ima-claude/skills/php-fp/examples/pure-functions.php +403 -0
  130. package/plugins/ima-claude/skills/php-fp/examples/tests/PureFunctionsTest.php +515 -0
  131. package/plugins/ima-claude/skills/php-fp/references/core-principles.md +277 -0
  132. package/plugins/ima-claude/skills/php-fp/references/testing-patterns.md +374 -0
  133. package/plugins/ima-claude/skills/php-fp-wordpress/SKILL.md +216 -0
  134. package/plugins/ima-claude/skills/php-fp-wordpress/references/fp-patterns.md +275 -0
  135. package/plugins/ima-claude/skills/php-fp-wordpress/references/plugin-architecture.md +295 -0
  136. package/plugins/ima-claude/skills/php-fp-wordpress/references/security-examples.md +203 -0
  137. package/plugins/ima-claude/skills/php-fp-wordpress/references/testing-strategy.md +259 -0
  138. package/plugins/ima-claude/skills/phpunit-wp/SKILL.md +716 -0
  139. package/plugins/ima-claude/skills/playwright/SKILL.md +434 -0
  140. package/plugins/ima-claude/skills/playwright/references/accessibility-testing.md +153 -0
  141. package/plugins/ima-claude/skills/playwright/references/ci-cd.md +268 -0
  142. package/plugins/ima-claude/skills/playwright/references/network-mocking.md +270 -0
  143. package/plugins/ima-claude/skills/playwright/references/visual-regression.md +215 -0
  144. package/plugins/ima-claude/skills/py-fp/SKILL.md +663 -0
  145. package/plugins/ima-claude/skills/py-fp/examples/pure-functions.py +185 -0
  146. package/plugins/ima-claude/skills/py-fp/examples/tests/test_pure_functions.py +244 -0
  147. package/plugins/ima-claude/skills/py-fp/references/core-principles.md +381 -0
  148. package/plugins/ima-claude/skills/py-fp/references/testing-patterns.md +283 -0
  149. package/plugins/ima-claude/skills/quasar-fp/SKILL.md +327 -0
  150. package/plugins/ima-claude/skills/quasar-fp/metadata.json +85 -0
  151. package/plugins/ima-claude/skills/quasar-fp/references/component-patterns.md +257 -0
  152. package/plugins/ima-claude/skills/quasar-fp/references/theme-integration.md +233 -0
  153. package/plugins/ima-claude/skills/quasar-fp/references/utility-classes.md +237 -0
  154. package/plugins/ima-claude/skills/quickstart/SKILL.md +129 -0
  155. package/plugins/ima-claude/skills/rails/SKILL.md +359 -0
  156. package/plugins/ima-claude/skills/resume-session/SKILL.md +68 -0
  157. package/plugins/ima-claude/skills/rg/SKILL.md +205 -0
  158. package/plugins/ima-claude/skills/ruby-fp/SKILL.md +336 -0
  159. package/plugins/ima-claude/skills/save-session/SKILL.md +81 -0
  160. package/plugins/ima-claude/skills/scorecard/SKILL.md +96 -0
  161. package/plugins/ima-claude/skills/skill-analyzer/SKILL.md +127 -0
  162. package/plugins/ima-claude/skills/skill-analyzer/references/advanced-checklist.md +44 -0
  163. package/plugins/ima-claude/skills/skill-analyzer/references/core-checklist.md +60 -0
  164. package/plugins/ima-claude/skills/skill-analyzer/scripts/analyze_skill.py +418 -0
  165. package/plugins/ima-claude/skills/skill-creator/LICENSE.txt +202 -0
  166. package/plugins/ima-claude/skills/skill-creator/SKILL.md +343 -0
  167. package/plugins/ima-claude/skills/skill-creator/references/output-patterns.md +82 -0
  168. package/plugins/ima-claude/skills/skill-creator/references/workflows.md +28 -0
  169. package/plugins/ima-claude/skills/skill-creator/scripts/init_skill.py +303 -0
  170. package/plugins/ima-claude/skills/skill-creator/scripts/package_skill.py +110 -0
  171. package/plugins/ima-claude/skills/skill-creator/scripts/quick_validate.py +103 -0
  172. package/plugins/ima-claude/skills/task-master/SKILL.md +51 -0
  173. package/plugins/ima-claude/skills/task-planner/SKILL.md +228 -0
  174. package/plugins/ima-claude/skills/task-runner/SKILL.md +192 -0
  175. package/plugins/ima-claude/skills/unit-testing/SKILL.md +198 -0
  176. package/plugins/ima-claude/skills/unit-testing/references/mock-patterns.md +181 -0
  177. package/plugins/ima-claude/skills/unit-testing/references/tdd-workflow.md +177 -0
  178. package/plugins/ima-claude/skills/unit-testing/references/test-strategy.md +126 -0
  179. package/plugins/ima-claude/skills/wp-local/SKILL.md +246 -0
  180. package/plugins/ima-claude/skills/wp-local/references/configuration.md +198 -0
  181. package/plugins/ima-claude/skills/wp-local/references/wp-cli-reference.md +406 -0
  182. package/plugins/ima-claude/skills/wp-local/scripts/wp-local.sh +61 -0
@@ -0,0 +1,295 @@
1
+ # Plugin Complexity Patterns
2
+
3
+ ## Table of Contents
4
+ 1. [Complexity Decision Guide](#complexity-decision-guide)
5
+ 2. [Simple Plugin (<500 lines)](#simple-plugin-500-lines)
6
+ 3. [Medium Plugin (500-2000 lines)](#medium-plugin-500-2000-lines)
7
+ 4. [Complex Plugin (2000+ lines)](#complex-plugin-2000-lines)
8
+ 5. [File Organization](#file-organization)
9
+
10
+ ---
11
+
12
+ ## Complexity Decision Guide
13
+
14
+ | Plugin Size | Lines | Pattern | When to Use |
15
+ |-------------|-------|---------|-------------|
16
+ | Simple | <500 | Namespaced functions | Single feature, few hooks |
17
+ | Medium | 500-2000 | Classes + pure functions | Multiple features, some state |
18
+ | Complex | 2000+ | DI Container + Services | Many features, shared dependencies |
19
+
20
+ **Rule**: Start simple, add complexity only when needed.
21
+
22
+ ---
23
+
24
+ ## Simple Plugin (<500 lines)
25
+
26
+ **Use**: Namespaced functions with direct hook usage.
27
+
28
+ ```php
29
+ <?php
30
+ /**
31
+ * Plugin Name: Simple Analytics Tracker
32
+ */
33
+
34
+ namespace SimpleAnalytics;
35
+
36
+ // Pure function - testable without WordPress
37
+ function calculate_page_views(array $logs): int {
38
+ return count(array_filter($logs, fn($log) => $log['type'] === 'page_view'));
39
+ }
40
+
41
+ function format_analytics_data(array $logs): array {
42
+ return [
43
+ 'page_views' => calculate_page_views($logs),
44
+ 'unique_visitors' => count(array_unique(array_column($logs, 'visitor_id'))),
45
+ 'last_updated' => date('Y-m-d H:i:s')
46
+ ];
47
+ }
48
+
49
+ // WordPress integration with security
50
+ add_action('wp_footer', function() {
51
+ if (!current_user_can('edit_posts')) return;
52
+
53
+ $logs = get_option('analytics_logs', []);
54
+ $data = format_analytics_data($logs);
55
+
56
+ echo '<div id="analytics">' . esc_html($data['page_views']) . ' page views</div>';
57
+ });
58
+
59
+ add_action('wp_ajax_get_analytics', function() {
60
+ if (!current_user_can('manage_options')) {
61
+ wp_send_json_error('Unauthorized', 403);
62
+ }
63
+ check_ajax_referer('analytics_nonce');
64
+
65
+ $logs = get_option('analytics_logs', []);
66
+ wp_send_json_success(format_analytics_data($logs));
67
+ });
68
+ ```
69
+
70
+ ---
71
+
72
+ ## Medium Plugin (500-2000 lines)
73
+
74
+ **Use**: Classes for features + pure functions for logic.
75
+
76
+ ```php
77
+ <?php
78
+ namespace MediumPlugin;
79
+
80
+ // Pure functions in separate file (includes/functions.php)
81
+ function calculate_shipping_cost(float $weight, string $zone): float {
82
+ $rates = ['domestic' => 5.00, 'international' => 15.00];
83
+ $base = $rates[$zone] ?? 10.00;
84
+ return $base + ($weight * 0.50);
85
+ }
86
+
87
+ function validate_shipping_address(array $address): array {
88
+ $errors = [];
89
+ if (empty($address['street'])) $errors[] = 'Street required';
90
+ if (empty($address['city'])) $errors[] = 'City required';
91
+ if (empty($address['zip'])) $errors[] = 'ZIP required';
92
+
93
+ return empty($errors)
94
+ ? ['valid' => true]
95
+ : ['valid' => false, 'errors' => $errors];
96
+ }
97
+
98
+ // Class for WordPress integration
99
+ class ShippingCalculator {
100
+ public function __construct() {
101
+ add_filter('woocommerce_shipping_cost', [$this, 'apply_calculation'], 10, 2);
102
+ add_action('wp_ajax_validate_address', [$this, 'handle_validation']);
103
+ }
104
+
105
+ public function apply_calculation($cost, $package) {
106
+ $weight = $package['contents_weight'];
107
+ $zone = $package['destination']['country'] === 'US' ? 'domestic' : 'international';
108
+
109
+ return calculate_shipping_cost($weight, $zone);
110
+ }
111
+
112
+ public function handle_validation() {
113
+ if (!current_user_can('edit_shop_orders')) {
114
+ wp_send_json_error('Unauthorized', 403);
115
+ }
116
+ check_ajax_referer('shipping_nonce');
117
+
118
+ $address = array_map('sanitize_text_field', $_POST['address']);
119
+ $result = validate_shipping_address($address);
120
+
121
+ if ($result['valid']) {
122
+ wp_send_json_success('Address valid');
123
+ } else {
124
+ wp_send_json_error($result['errors']);
125
+ }
126
+ }
127
+ }
128
+
129
+ // Initialize
130
+ new ShippingCalculator();
131
+ ```
132
+
133
+ ---
134
+
135
+ ## Complex Plugin (2000+ lines)
136
+
137
+ **Use**: Dependency Injection Container + Service Architecture.
138
+
139
+ ### DI Container
140
+
141
+ ```php
142
+ <?php
143
+ namespace ComplexPlugin;
144
+
145
+ class Container {
146
+ private array $services = [];
147
+ private array $resolved = [];
148
+
149
+ public function register(string $name, callable $resolver): void {
150
+ $this->services[$name] = $resolver;
151
+ }
152
+
153
+ public function get(string $name) {
154
+ if (!isset($this->resolved[$name])) {
155
+ $this->resolved[$name] = ($this->services[$name])($this);
156
+ }
157
+ return $this->resolved[$name];
158
+ }
159
+ }
160
+ ```
161
+
162
+ ### Service Classes
163
+
164
+ ```php
165
+ <?php
166
+ namespace ComplexPlugin\Services;
167
+
168
+ class OrderService {
169
+ private PaymentService $payment;
170
+
171
+ public function __construct(PaymentService $payment) {
172
+ $this->payment = $payment;
173
+ }
174
+
175
+ public function process(array $order_data): array {
176
+ // Use pure function for calculation
177
+ $total = \ComplexPlugin\BusinessLogic\calculate_order_total(
178
+ $order_data['items'],
179
+ $order_data['discounts']
180
+ );
181
+
182
+ // Side effect: process payment
183
+ $payment_result = $this->payment->charge($total);
184
+
185
+ return [
186
+ 'order_id' => uniqid('order_'),
187
+ 'total' => $total,
188
+ 'payment' => $payment_result
189
+ ];
190
+ }
191
+ }
192
+
193
+ class PaymentService {
194
+ public function charge(float $amount): array {
195
+ // Payment gateway integration
196
+ return ['success' => true, 'transaction_id' => uniqid('txn_')];
197
+ }
198
+ }
199
+ ```
200
+
201
+ ### Main Plugin Class
202
+
203
+ ```php
204
+ <?php
205
+ namespace ComplexPlugin;
206
+
207
+ class Plugin {
208
+ private Container $container;
209
+
210
+ public function __construct() {
211
+ $this->container = new Container();
212
+ $this->setup_services();
213
+ $this->init_hooks();
214
+ }
215
+
216
+ private function setup_services(): void {
217
+ $this->container->register('payment', fn($c) =>
218
+ new Services\PaymentService()
219
+ );
220
+ $this->container->register('order', fn($c) =>
221
+ new Services\OrderService($c->get('payment'))
222
+ );
223
+ }
224
+
225
+ private function init_hooks(): void {
226
+ add_action('wp_ajax_process_order', [$this, 'handle_order']);
227
+ }
228
+
229
+ public function handle_order(): void {
230
+ // Security
231
+ if (!current_user_can('edit_shop_orders')) {
232
+ wp_send_json_error('Unauthorized', 403);
233
+ }
234
+ check_ajax_referer('process_order');
235
+
236
+ // Sanitize
237
+ $order_data = [
238
+ 'items' => array_map(function($item) {
239
+ return [
240
+ 'id' => absint($item['id']),
241
+ 'price' => floatval($item['price']),
242
+ 'quantity' => absint($item['quantity'])
243
+ ];
244
+ }, $_POST['items']),
245
+ 'discounts' => []
246
+ ];
247
+
248
+ // Process via service
249
+ $result = $this->container->get('order')->process($order_data);
250
+
251
+ wp_send_json_success($result);
252
+ }
253
+ }
254
+ ```
255
+
256
+ ---
257
+
258
+ ## File Organization
259
+
260
+ ### Simple Plugin
261
+ ```
262
+ simple-plugin/
263
+ ├── simple-plugin.php # Everything in one file
264
+ └── readme.txt
265
+ ```
266
+
267
+ ### Medium Plugin
268
+ ```
269
+ medium-plugin/
270
+ ├── medium-plugin.php # Bootstrap, hooks
271
+ ├── includes/
272
+ │ ├── functions.php # Pure business logic
273
+ │ └── class-feature.php # WordPress integration
274
+ └── tests/
275
+ └── test-functions.php
276
+ ```
277
+
278
+ ### Complex Plugin
279
+ ```
280
+ complex-plugin/
281
+ ├── complex-plugin.php
282
+ ├── includes/
283
+ │ ├── class-container.php
284
+ │ ├── class-plugin.php
285
+ │ └── functions.php # Pure business logic
286
+ ├── services/
287
+ │ ├── class-order-service.php
288
+ │ └── class-payment-service.php
289
+ ├── admin/
290
+ │ ├── settings.php
291
+ │ └── ajax-handlers.php
292
+ └── tests/
293
+ ├── unit/ # Pure function tests
294
+ └── integration/ # WordPress tests
295
+ ```
@@ -0,0 +1,203 @@
1
+ # WordPress Security Patterns - Detailed Examples
2
+
3
+ ## Table of Contents
4
+ 1. [Capability Checks](#1-capability-checks)
5
+ 2. [Nonce Verification](#2-nonce-verification)
6
+ 3. [Input Sanitization](#3-input-sanitization)
7
+ 4. [Output Escaping](#4-output-escaping)
8
+ 5. [Prepared SQL Statements](#5-prepared-sql-statements)
9
+ 6. [Security Function Reference](#security-function-reference)
10
+
11
+ ---
12
+
13
+ ## 1. Capability Checks
14
+
15
+ **Prevents 53% of XSS vulnerabilities.**
16
+
17
+ ```php
18
+ <?php
19
+ // ALWAYS check permissions FIRST
20
+ add_action('wp_ajax_delete_user_data', 'handle_delete_user_data');
21
+ function handle_delete_user_data() {
22
+ // Check capability before ANY operation
23
+ if (!current_user_can('delete_users')) {
24
+ wp_send_json_error('Insufficient permissions', 403);
25
+ return;
26
+ }
27
+
28
+ // Then proceed
29
+ delete_user_data($_POST['user_id']);
30
+ }
31
+
32
+ // NEVER allow operations without capability check
33
+ function delete_user_data_UNSAFE() {
34
+ wp_delete_user($_POST['user_id']); // Any authenticated user can delete!
35
+ }
36
+ ```
37
+
38
+ ### Common Capabilities
39
+ | Capability | Use For |
40
+ |------------|---------|
41
+ | `manage_options` | Plugin settings, admin-only operations |
42
+ | `edit_posts` | Content creation |
43
+ | `delete_users` | User management |
44
+ | `upload_files` | File uploads |
45
+
46
+ ---
47
+
48
+ ## 2. Nonce Verification
49
+
50
+ **Prevents 15-17% CSRF attacks.**
51
+
52
+ ```php
53
+ <?php
54
+ // ALWAYS verify nonces
55
+ add_action('admin_post_save_settings', 'save_plugin_settings');
56
+ function save_plugin_settings() {
57
+ // Verify nonce before processing
58
+ if (!isset($_POST['settings_nonce']) ||
59
+ !wp_verify_nonce($_POST['settings_nonce'], 'save_settings_action')) {
60
+ wp_die('Security check failed');
61
+ }
62
+
63
+ // Then save
64
+ update_option('plugin_settings', $_POST['settings']);
65
+ }
66
+
67
+ // NEVER process forms without nonce
68
+ function save_settings_UNSAFE() {
69
+ update_option('plugin_settings', $_POST['settings']); // CSRF vulnerable!
70
+ }
71
+ ```
72
+
73
+ ### Nonce Functions
74
+ | Function | Purpose |
75
+ |----------|---------|
76
+ | `wp_nonce_field('action', 'field_name')` | Generate hidden form field |
77
+ | `wp_verify_nonce($_POST['field'], 'action')` | Verify form submission |
78
+ | `check_ajax_referer('action', 'nonce')` | Verify AJAX nonce |
79
+ | `wp_create_nonce('action')` | Create nonce for JS |
80
+
81
+ ---
82
+
83
+ ## 3. Input Sanitization
84
+
85
+ **Required for ALL user input.**
86
+
87
+ ```php
88
+ <?php
89
+ // ALWAYS sanitize based on data type
90
+ function process_form_submission() {
91
+ $name = sanitize_text_field($_POST['name']);
92
+ $email = sanitize_email($_POST['email']);
93
+ $content = wp_kses_post($_POST['content']); // Allow safe HTML
94
+ $url = esc_url_raw($_POST['website']);
95
+ $number = absint($_POST['count']);
96
+
97
+ save_to_database($name, $email, $content, $url, $number);
98
+ }
99
+
100
+ // NEVER use raw input
101
+ function process_form_UNSAFE() {
102
+ save_to_database($_POST['name'], $_POST['email']); // Injection risk!
103
+ }
104
+ ```
105
+
106
+ ### Sanitization Functions
107
+ | Function | Use For |
108
+ |----------|---------|
109
+ | `sanitize_text_field()` | Plain text, single line |
110
+ | `sanitize_textarea_field()` | Multi-line text |
111
+ | `sanitize_email()` | Email addresses |
112
+ | `absint()` | Positive integers |
113
+ | `wp_kses_post()` | HTML (post content allowed tags) |
114
+ | `esc_url_raw()` | URLs for database storage |
115
+
116
+ ---
117
+
118
+ ## 4. Output Escaping
119
+
120
+ **Context-specific escaping required.**
121
+
122
+ ```php
123
+ <?php
124
+ // ALWAYS escape based on context
125
+ function render_user_profile($user) {
126
+ // HTML context
127
+ echo '<h2>' . esc_html($user->name) . '</h2>';
128
+
129
+ // Attribute context
130
+ echo '<img src="' . esc_url($user->avatar) . '" alt="' . esc_attr($user->name) . '">';
131
+
132
+ // JavaScript context
133
+ echo '<script>var userName = ' . wp_json_encode($user->name) . ';</script>';
134
+
135
+ // URL context
136
+ echo '<a href="' . esc_url($user->website) . '">Website</a>';
137
+ }
138
+
139
+ // NEVER output unescaped data
140
+ function render_profile_UNSAFE($user) {
141
+ echo '<h1>' . $user->name . '</h1>'; // XSS if name contains <script>
142
+ }
143
+ ```
144
+
145
+ ### Escaping Functions
146
+ | Function | Context |
147
+ |----------|---------|
148
+ | `esc_html()` | HTML body text |
149
+ | `esc_attr()` | HTML attributes |
150
+ | `esc_url()` | URLs in href/src |
151
+ | `esc_js()` | Inline JavaScript strings |
152
+ | `wp_json_encode()` | JSON data in scripts |
153
+
154
+ ---
155
+
156
+ ## 5. Prepared SQL Statements
157
+
158
+ **Prevents SQL injection.**
159
+
160
+ ```php
161
+ <?php
162
+ // ALWAYS use prepared statements
163
+ function get_user_posts($user_id) {
164
+ global $wpdb;
165
+
166
+ $posts = $wpdb->get_results($wpdb->prepare(
167
+ "SELECT * FROM {$wpdb->posts} WHERE post_author = %d AND post_status = %s",
168
+ $user_id,
169
+ 'publish'
170
+ ));
171
+
172
+ return $posts;
173
+ }
174
+
175
+ // NEVER use string concatenation
176
+ function get_posts_UNSAFE($user_id) {
177
+ global $wpdb;
178
+ return $wpdb->get_results("SELECT * FROM {$wpdb->posts} WHERE post_author = $user_id");
179
+ }
180
+ ```
181
+
182
+ ### Prepared Statement Placeholders
183
+ | Placeholder | Type |
184
+ |-------------|------|
185
+ | `%d` | Integer |
186
+ | `%f` | Float |
187
+ | `%s` | String |
188
+
189
+ ---
190
+
191
+ ## Security Function Reference
192
+
193
+ ### Quick Lookup Table
194
+
195
+ | Input Type | Sanitize | Escape (Output) |
196
+ |------------|----------|-----------------|
197
+ | Plain text | `sanitize_text_field()` | `esc_html()` |
198
+ | HTML content | `wp_kses_post()` | Already safe |
199
+ | Email | `sanitize_email()` | `esc_html()` |
200
+ | URL | `esc_url_raw()` | `esc_url()` |
201
+ | Integer | `absint()` | `absint()` |
202
+ | Filename | `sanitize_file_name()` | `esc_html()` |
203
+ | SQL | `$wpdb->prepare()` | N/A |