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,193 @@
1
+ # Form Factory Pattern (v1.2.0) - Auto-Wired Validation
2
+
3
+ ## Contents
4
+
5
+ - [Creating Forms with Auto-Validation](#creating-forms-with-auto-validation)
6
+ - [Auto-Wiring Field Functions](#auto-wiring-field-functions)
7
+ - [Extending with Custom Validation](#extending-with-custom-validation)
8
+ - [Form Wrapper Functions](#form-wrapper-functions)
9
+ - [Security Chokepoint Pattern](#security-chokepoint-pattern)
10
+
11
+ ---
12
+
13
+ ## Creating Forms with Auto-Validation
14
+
15
+ The form factory pattern uses function composition to automatically wire validators to field types:
16
+
17
+ ```php
18
+ // Create form with auto-wired validation
19
+ ['render' => $render, 'validate' => $validate] = ima_forms_create_form(
20
+ 'contact-form', // Form ID
21
+ function($register) use ($data, $errors) {
22
+ // Use auto-wiring field functions
23
+ ima_forms_email($register, [
24
+ 'name' => 'email',
25
+ 'label' => 'Email Address',
26
+ 'required' => true,
27
+ 'value' => $data['email'] ?? '',
28
+ 'error' => $errors['email'] ?? '',
29
+ ]);
30
+
31
+ ima_forms_phone($register, [
32
+ 'name' => 'phone',
33
+ 'label' => 'Phone Number',
34
+ 'required' => true,
35
+ 'value' => $data['phone'] ?? '',
36
+ 'error' => $errors['phone'] ?? '',
37
+ ]);
38
+
39
+ ima_forms_textarea($register, [
40
+ 'name' => 'message',
41
+ 'label' => 'Message',
42
+ 'required' => true,
43
+ 'value' => $data['message'] ?? '',
44
+ 'error' => $errors['message'] ?? '',
45
+ ]);
46
+ }
47
+ );
48
+
49
+ // Render form
50
+ $render();
51
+
52
+ // Validate (in AJAX handler)
53
+ $validation = $validate($sanitized_data);
54
+ if (!$validation['valid']) {
55
+ wp_send_json_error(['errors' => $validation['errors']]);
56
+ }
57
+ ```
58
+
59
+ ## Auto-Wiring Field Functions
60
+
61
+ **Available auto-wiring functions** (automatically attach validators):
62
+
63
+ | Function | Validator |
64
+ |----------|-----------|
65
+ | `ima_forms_text($register, $args)` | Required validator |
66
+ | `ima_forms_email($register, $args)` | Format + enhanced validation |
67
+ | `ima_forms_phone($register, $args)` | Format validation |
68
+ | `ima_forms_url($register, $args)` | Format validation |
69
+ | `ima_forms_textarea($register, $args)` | Required validator |
70
+ | `ima_forms_select($register, $args)` | Required validator |
71
+ | `ima_forms_checkbox($register, $args)` | Required validator |
72
+ | `ima_forms_checkbox_group_field($register, $args)` | Required (array) |
73
+
74
+ ## Extending with Custom Validation
75
+
76
+ ```php
77
+ // Compose auto-wired + custom validators
78
+ $combined = ima_forms_compose_validators(
79
+ $validate, // Auto-wired from form factory
80
+ function($data) {
81
+ $errors = [];
82
+ // Your custom validation
83
+ if ($data['password'] !== $data['password_confirm']) {
84
+ $errors['password_confirm'] = 'Passwords must match.';
85
+ }
86
+ return ['valid' => empty($errors), 'errors' => $errors];
87
+ }
88
+ );
89
+ ```
90
+
91
+ ## Form Wrapper Functions
92
+
93
+ ### Standardized Form Container
94
+
95
+ ```php
96
+ ima_forms_form([
97
+ 'id' => 'my-form',
98
+ 'action' => 'my_ajax_action', // AJAX action name
99
+ 'method' => 'post',
100
+ 'class' => 'ima-form w-100', // Default: full width
101
+ 'nonce_action' => 'my_form_submit',
102
+ 'nonce_name' => 'nonce',
103
+ 'enqueue_base' => true, // Auto-enqueue ima-forms-base.js
104
+ ], function() {
105
+ // Form fields here
106
+ ima_forms_text_field([...]);
107
+ ima_forms_email_field([...]);
108
+
109
+ // Standardized submit button
110
+ ima_forms_submit_button([
111
+ 'text' => 'Submit Form',
112
+ 'processing_text' => 'Submitting...',
113
+ 'class' => 'btn btn-primary',
114
+ 'show_spinner' => true,
115
+ ]);
116
+ });
117
+ ```
118
+
119
+ ### Benefits
120
+
121
+ - **Automatic error container**: `.ima-form-errors` populated by JavaScript
122
+ - **Automatic success container**: `.ima-form-success` for success messages
123
+ - **AJAX-ready**: `data-action` attribute for JavaScript handler
124
+ - **Nonce included**: WordPress nonce field automatically added
125
+ - **Loading states**: Submit button shows spinner and disables during submission
126
+
127
+ ## Security Chokepoint Pattern
128
+
129
+ ### AJAX Handler Factory (Classic Approach)
130
+
131
+ ```php
132
+ // Create secure AJAX handler
133
+ $handler = ima_forms_create_ajax_handler(
134
+ 'listing_application', // Form ID
135
+ 'ima_form_listing_application', // Nonce action
136
+ 'ima_listing_sanitize', // Sanitization function
137
+ 'ima_listing_validate', // Validation function
138
+ 'ima_listing_process' // Processing function
139
+ );
140
+
141
+ // Register AJAX hooks
142
+ add_action('wp_ajax_ima_listing_submit', $handler);
143
+ add_action('wp_ajax_nopriv_ima_listing_submit', $handler);
144
+ ```
145
+
146
+ **Security layers** (automatic):
147
+ 1. **Nonce verification**: CSRF protection
148
+ 2. **Sanitization**: Context-appropriate cleaning
149
+ 3. **Validation**: Business rules enforcement
150
+ 4. **Processing**: Controlled side effects
151
+
152
+ **Rate limiting**: Handled by infrastructure (WordFence, Akismet, WP Armour)
153
+
154
+ ### Modern Approach with Validation Engine
155
+
156
+ ```php
157
+ function my_form_ajax_handler() {
158
+ // Security: Nonce verification
159
+ if (!wp_verify_nonce($_POST['nonce'], 'my_form_submit')) {
160
+ wp_send_json_error(['message' => 'Security check failed.'], 403);
161
+ }
162
+
163
+ // Validate + Sanitize (automatic via template)
164
+ $result = ima_forms_validate_form(
165
+ 'templates/forms/my-form',
166
+ $_POST,
167
+ 'my-form'
168
+ );
169
+
170
+ if (!$result['valid']) {
171
+ wp_send_json_error([
172
+ 'message' => 'Please correct the errors.',
173
+ 'errors' => $result['errors']
174
+ ], 400);
175
+ }
176
+
177
+ // Process validated data
178
+ $data = $result['sanitized'];
179
+ // ... your processing logic
180
+
181
+ wp_send_json_success(['message' => 'Success!']);
182
+ }
183
+
184
+ add_action('wp_ajax_my_form_submit', 'my_form_ajax_handler');
185
+ ```
186
+
187
+ ### When to Use Which Pattern
188
+
189
+ | Pattern | Use When |
190
+ |---------|----------|
191
+ | **Validation Engine** (v1.3.0) | Simple forms, standard validation needs |
192
+ | **Form Factory** (v1.2.0) | Programmatic field generation, dynamic forms |
193
+ | **Classic AJAX Handler** | Legacy code, complex multi-step processing |
@@ -0,0 +1,153 @@
1
+ # Quick Reference
2
+
3
+ ## Contents
4
+
5
+ - [Field Components](#field-components-auto-registration)
6
+ - [Container Components](#container-components)
7
+ - [Validation Engine (v1.4.0)](#validation-engine-v140)
8
+ - [Registry Functions](#registry-functions)
9
+ - [Validators](#validators)
10
+ - [Sanitizers](#sanitizers)
11
+ - [Core Functions](#core-functions)
12
+ - [Version Features](#version-features)
13
+ - [Filters](#filters)
14
+
15
+ ---
16
+
17
+ ## Field Components (Auto-Registration)
18
+
19
+ | Function | Purpose |
20
+ |----------|---------|
21
+ | `ima_forms_text_field()` | Text input with validation |
22
+ | `ima_forms_email_field()` | Email with enhanced validation |
23
+ | `ima_forms_password_field()` | Password input |
24
+ | `ima_forms_hidden_field()` | Hidden field |
25
+ | `ima_forms_textarea_field()` | Multi-line text |
26
+ | `ima_forms_select_field()` | Dropdown select |
27
+ | `ima_forms_state_select_field()` | US states dropdown |
28
+ | `ima_forms_checkbox_field()` | Single checkbox |
29
+ | `ima_forms_checkbox_group()` | Multiple checkboxes |
30
+ | `ima_forms_phone_field()` | Phone with format validation |
31
+ | `ima_forms_url_field()` | URL with format validation |
32
+ | `ima_forms_address_fieldset()` | Composite address fields |
33
+ | `ima_forms_consent_agreement_field()` | Scrollable agreement + signature |
34
+
35
+ ## Container Components
36
+
37
+ | Function | Purpose |
38
+ |----------|---------|
39
+ | `ima_forms_form()` | Complete form wrapper with AJAX |
40
+ | `ima_forms_submit_button()` | Standardized submit button |
41
+ | `ima_forms_card()` | Bootstrap card wrapper |
42
+ | `ima_forms_section()` | Section with heading |
43
+ | `ima_forms_column_layout()` | Responsive columns |
44
+ | `ima_forms_fieldset()` | Semantic fieldset |
45
+ | `ima_forms_repeater()` | Dynamic row repeater |
46
+
47
+ ## Validation Engine (v1.4.0)
48
+
49
+ | Function | Purpose |
50
+ |----------|---------|
51
+ | `ima_forms_validate_form($template, $data, $form_id, $args)` | Main validation entry |
52
+ | `ima_forms_validate_against_specs($specs, $data)` | Validate data against specs |
53
+ | `ima_forms_run_validators($specs, $sanitized)` | Run stored validators |
54
+ | `ima_forms_sanitize_against_specs($specs, $data)` | Sanitize using specs |
55
+ | `ima_forms_debug_validation_summary($specs)` | Debug: validation preview |
56
+
57
+ ## Registry Functions
58
+
59
+ | Function | Purpose |
60
+ |----------|---------|
61
+ | `ima_forms_register_field_spec($name, $spec)` | Register field spec + validators |
62
+ | `ima_forms_get_field_specs()` | Get all registered specs |
63
+ | `ima_forms_clear_field_specs()` | Clear registry |
64
+ | `ima_forms_has_field_spec($name)` | Check if field registered |
65
+ | `ima_forms_get_field_spec($name)` | Get single spec |
66
+ | `ima_forms_get_field_spec_count()` | Count registered specs |
67
+ | `ima_forms_debug_field_specs()` | Human-readable spec dump |
68
+
69
+ ## Validators
70
+
71
+ | Function | Purpose |
72
+ |----------|---------|
73
+ | `ima_forms_validate_required($value, $label)` | Required check |
74
+ | `ima_forms_validate_email($email, $label)` | Basic RFC 5322 |
75
+ | `ima_forms_validate_email_enhanced($email, $label, $enhanced)` | Full email validation |
76
+ | `ima_forms_validate_phone($phone, $label)` | Phone format |
77
+ | `ima_forms_validate_url($url, $label)` | URL format |
78
+ | `ima_forms_validate_min_length($value, $min, $label)` | Min length |
79
+ | `ima_forms_validate_max_length($value, $max, $label)` | Max length |
80
+ | `ima_forms_validate_array_required($array, $label)` | Array not empty |
81
+ | `ima_forms_validate_numeric($value, $label)` | Numeric check |
82
+ | `ima_forms_validate_range($value, $min, $max, $label)` | Range check |
83
+ | `ima_forms_create_email_validator($domains, $typos)` | Pre-compiled validator |
84
+
85
+ ## Sanitizers
86
+
87
+ | Function | Purpose |
88
+ |----------|---------|
89
+ | `ima_forms_sanitize_field($type, $value)` | Single field |
90
+ | `ima_forms_sanitize_data($data, $field_map)` | Multiple fields |
91
+ | `ima_forms_sanitize_repeater($rows, $field_map)` | Repeater rows |
92
+ | `ima_forms_sanitize_against_specs($specs, $data)` | Using specs (auto) |
93
+
94
+ ## Core Functions
95
+
96
+ | Function | Purpose |
97
+ |----------|---------|
98
+ | `ima_forms_create_ajax_handler()` | Security chokepoint |
99
+ | `ima_forms_create_renderer()` | Template rendering |
100
+ | `ima_forms_load_field_template()` | Template hierarchy |
101
+ | `ima_forms_get_us_states()` | US states data |
102
+
103
+ ## Version Features
104
+
105
+ ### v1.4.0 (Validators at Registration)
106
+ - Validators built as closures at field registration
107
+ - `spec['validators']` stores closure array
108
+ - `ima_forms_run_validators()` just iterates and runs
109
+ - No type switching in engine
110
+
111
+ ### v1.3.0 (Validation Engine)
112
+ - Template-driven validation
113
+ - Field spec registry
114
+ - Automatic sanitization from specs
115
+ - `ima_forms_validate_form()` as primary API
116
+
117
+ ### v1.2.0 (Form Factory)
118
+ - Auto-wired validation via function composition
119
+ - `ima_forms_create_form()` factory
120
+ - `ima_forms_form()` and `ima_forms_submit_button()` wrappers
121
+ - Password and hidden field types
122
+ - Consent agreement component
123
+ - Enhanced email validation with disposable domains
124
+
125
+ ### v1.1.0 (Container Components)
126
+ - Card, section, column layout, fieldset components
127
+ - Repeater with auto-enqueuing
128
+ - Template override system
129
+
130
+ ### v1.0.0 (Foundation)
131
+ - Basic field components
132
+ - Pure validators and sanitizers
133
+ - Security chokepoint pattern
134
+ - Bootstrap 5 integration
135
+
136
+ ## Filters
137
+
138
+ | Filter | Purpose |
139
+ |--------|---------|
140
+ | `ima_forms_validate_{form-id}` | Custom validation (cross-field, business rules) |
141
+ | `ima_forms_bad_email_domains` | Add blocked email domains |
142
+ | `ima_forms_email_typo_corrections` | Add typo corrections |
143
+
144
+ ## Default Nonce
145
+
146
+ The default nonce action for `ima_forms_form()` is: `ima_forms_ajax`
147
+
148
+ ```php
149
+ // In AJAX handler:
150
+ if (!wp_verify_nonce($_POST['nonce'], 'ima_forms_ajax')) {
151
+ wp_send_json_error(['message' => 'Security check failed.'], 403);
152
+ }
153
+ ```
@@ -0,0 +1,336 @@
1
+ # Validation Engine - Validators-at-Registration Architecture
2
+
3
+ ## Contents
4
+
5
+ - [Architecture Overview (v1.4.0)](#architecture-overview-v140)
6
+ - [How Field Registration Works](#how-field-registration-works)
7
+ - [Validation Flow](#validation-flow)
8
+ - [Field Spec Structure](#field-spec-structure)
9
+ - [Custom Validation via Filters](#custom-validation-via-filters)
10
+ - [Pure Validators](#pure-validators)
11
+ - [Enhanced Email Validator](#enhanced-email-validator)
12
+ - [Function Factory for Performance](#function-factory-for-performance)
13
+ - [Sanitization Patterns](#sanitization-patterns)
14
+ - [Debug Helpers](#debug-helpers)
15
+
16
+ ---
17
+
18
+ ## Architecture Overview (v1.4.0)
19
+
20
+ **Core concept**: Validators are built as closures at field registration time, not by the engine via type-switching.
21
+
22
+ ### Old Architecture (v1.3.0)
23
+ ```php
24
+ // Field registered spec with type metadata
25
+ ima_forms_register_field_spec('email', ['type' => 'email', 'required' => true, ...]);
26
+
27
+ // Engine rebuilt validators based on type switching
28
+ switch ($spec['type']) {
29
+ case 'email':
30
+ $error = ima_forms_validate_email_enhanced($value, ...);
31
+ // etc.
32
+ }
33
+ ```
34
+
35
+ ### New Architecture (v1.4.0)
36
+ ```php
37
+ // Field builds validators at registration time
38
+ $validators = [];
39
+ $validators[] = fn($v) => ima_forms_validate_required($v, $label);
40
+ $validators[] = fn($v) => empty($v) ? null : ima_forms_validate_email_enhanced($v, $label, true);
41
+
42
+ ima_forms_register_field_spec('email', [
43
+ 'type' => 'email',
44
+ 'validators' => $validators, // Closures stored directly!
45
+ ]);
46
+
47
+ // Engine simply iterates and runs
48
+ foreach ($spec['validators'] as $validator) {
49
+ $error = $validator($value);
50
+ if ($error !== null) break;
51
+ }
52
+ ```
53
+
54
+ **Benefits**:
55
+ - **Single source of truth**: Field function defines validation once
56
+ - **No type switching**: Validators are closures, just iterate and run
57
+ - **Testable**: Validators are pure functions captured at registration time
58
+ - **Extensible**: Easy to add field-specific validators without touching engine
59
+
60
+ ---
61
+
62
+ ## How Field Registration Works
63
+
64
+ Each field function has a `_register()` function that builds validators:
65
+
66
+ ```php
67
+ function ima_forms_text_field_register(array $args): void {
68
+ $name = $args['name'] ?? '';
69
+ $label = $args['label'] ?? $name;
70
+ $required = $args['required'] ?? false;
71
+ $minlength = $args['minlength'] ?? null;
72
+ $maxlength = $args['maxlength'] ?? null;
73
+
74
+ // Build validators at registration time
75
+ $validators = [];
76
+
77
+ if ($required) {
78
+ $validators[] = fn($v) => ima_forms_validate_required($v, $label);
79
+ }
80
+
81
+ if ($minlength !== null) {
82
+ $validators[] = function($v) use ($label, $minlength) {
83
+ if (empty($v)) return null;
84
+ return ima_forms_validate_min_length((string) $v, (int) $minlength, $label);
85
+ };
86
+ }
87
+
88
+ if ($maxlength !== null) {
89
+ $validators[] = function($v) use ($label, $maxlength) {
90
+ if (empty($v)) return null;
91
+ return ima_forms_validate_max_length((string) $v, (int) $maxlength, $label);
92
+ };
93
+ }
94
+
95
+ ima_forms_register_field_spec($name, [
96
+ 'type' => 'text',
97
+ 'label' => $label,
98
+ 'required' => $required,
99
+ 'validators' => $validators,
100
+ 'sanitize_type' => 'text',
101
+ ]);
102
+ }
103
+ ```
104
+
105
+ **Key insight**: The `$validators` array contains closures that capture the field's label and constraints via `use`. When the engine runs them, it just calls each closure with the value.
106
+
107
+ ---
108
+
109
+ ## Validation Flow
110
+
111
+ ```php
112
+ // 1. Include template → field functions register specs + validators
113
+ ima_forms_validate_form('templates/forms/my-form', $_POST, 'my-form');
114
+
115
+ // Inside ima_forms_validate_form():
116
+ // a) Clear registry (clean state)
117
+ ima_forms_clear_field_specs();
118
+
119
+ // b) Include template (fields register their specs + validators)
120
+ ob_start();
121
+ get_template_part($template_path, null, $template_args);
122
+ ob_end_clean();
123
+
124
+ // c) Get collected specs (with validators already built)
125
+ $specs = ima_forms_get_field_specs();
126
+
127
+ // d) Sanitize data based on specs
128
+ $sanitized = ima_forms_sanitize_against_specs($specs, $data);
129
+
130
+ // e) Run validators (simple iteration!)
131
+ $errors = ima_forms_run_validators($specs, $sanitized);
132
+
133
+ // f) Run custom validation filter
134
+ $errors = apply_filters("ima_forms_validate_{$form_id}", $errors, $sanitized, $specs);
135
+
136
+ // g) Return result
137
+ return ['valid' => empty($errors), 'errors' => $errors, 'sanitized' => $sanitized];
138
+ ```
139
+
140
+ ---
141
+
142
+ ## Field Spec Structure
143
+
144
+ ```php
145
+ [
146
+ 'type' => 'email', // Field type (for sanitization fallback)
147
+ 'label' => 'Email Address', // For error messages
148
+ 'required' => true, // Whether field is required
149
+ 'enhanced_validation' => true, // Email-specific: domain checking
150
+ 'sanitize_type' => 'email', // Sanitization type
151
+ 'validators' => [ // Array of closures!
152
+ fn($v) => ima_forms_validate_required($v, 'Email Address'),
153
+ fn($v) => empty($v) ? null : ima_forms_validate_email_enhanced($v, 'Email Address', true),
154
+ ],
155
+ ]
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Custom Validation via Filters
161
+
162
+ ```php
163
+ // Add custom validation logic (runs after field validators)
164
+ add_filter('ima_forms_validate_my-form', function($errors, $sanitized, $specs) {
165
+ // Cross-field validation
166
+ if ($sanitized['password'] !== $sanitized['password_confirm']) {
167
+ $errors['password_confirm'] = 'Passwords must match.';
168
+ }
169
+
170
+ // Business rules
171
+ if (!empty($sanitized['age']) && $sanitized['age'] < 18) {
172
+ $errors['age'] = 'Must be 18 or older.';
173
+ }
174
+
175
+ return $errors;
176
+ }, 10, 3);
177
+ ```
178
+
179
+ ---
180
+
181
+ ## Pure Validators
182
+
183
+ All validators return `null` for valid, error string for invalid:
184
+
185
+ ```php
186
+ function ima_forms_validate_required($value, string $label): ?string {
187
+ if (empty($value) && $value !== '0') {
188
+ return "{$label} is required.";
189
+ }
190
+ return null;
191
+ }
192
+ ```
193
+
194
+ **Available validators**:
195
+ - `ima_forms_validate_required($value, $label)`
196
+ - `ima_forms_validate_email($email, $label)` - Basic RFC 5322
197
+ - `ima_forms_validate_email_enhanced($email, $label, $enhanced)` - With domain/typo checking
198
+ - `ima_forms_validate_url($url, $label)`
199
+ - `ima_forms_validate_phone($phone, $label)` - 10-15 digits, allows formatting
200
+ - `ima_forms_validate_min_length($value, $min, $label)`
201
+ - `ima_forms_validate_max_length($value, $max, $label)`
202
+ - `ima_forms_validate_array_required($array, $label)`
203
+ - `ima_forms_validate_numeric($value, $label)`
204
+ - `ima_forms_validate_range($value, $min, $max, $label)`
205
+
206
+ ---
207
+
208
+ ## Enhanced Email Validator
209
+
210
+ ```php
211
+ $error = ima_forms_validate_email_enhanced(
212
+ 'user@gmial.com', // Input
213
+ 'Email Address', // Label for error message
214
+ true // Enable enhanced checks
215
+ );
216
+ // Returns: "Did you mean user@gmail.com? Please check your email address."
217
+ ```
218
+
219
+ **Features**:
220
+ - RFC 5322 format validation
221
+ - Disposable domain blocking (20+ domains: mailinator, tempmail, etc.)
222
+ - Common typo detection (gmial.com → gmail.com)
223
+
224
+ **Customize blocked domains**:
225
+ ```php
226
+ add_filter('ima_forms_bad_email_domains', function($domains) {
227
+ $domains[] = 'example-spam.com';
228
+ return $domains;
229
+ });
230
+ ```
231
+
232
+ **Customize typo corrections**:
233
+ ```php
234
+ add_filter('ima_forms_email_typo_corrections', function($corrections) {
235
+ $corrections['customemail.co'] = 'customemail.com';
236
+ return $corrections;
237
+ });
238
+ ```
239
+
240
+ ---
241
+
242
+ ## Function Factory for Performance
243
+
244
+ **Pre-compile email validator** for repeated validations (2-5x faster in bulk operations):
245
+
246
+ ```php
247
+ // Create validator once with configuration
248
+ $validator = ima_forms_create_email_validator(
249
+ ['spam.com', 'tempmail.com'], // Bad domains
250
+ ['gmial.com' => 'gmail.com'] // Typo corrections
251
+ );
252
+
253
+ // Use for multiple emails (hot path optimization)
254
+ foreach ($emails as $email) {
255
+ $error = $validator($email, 'Email');
256
+ }
257
+ ```
258
+
259
+ ---
260
+
261
+ ## Sanitization Patterns
262
+
263
+ ### Automatic Sanitization
264
+
265
+ When using the Validation Engine, sanitization is automatic:
266
+
267
+ ```php
268
+ $result = ima_forms_validate_form(...);
269
+ // $result['sanitized'] contains sanitized data
270
+ ```
271
+
272
+ ### Sanitization Type Mapping
273
+
274
+ ```php
275
+ function ima_forms_get_sanitize_type_for_field(array $spec): string {
276
+ return match ($spec['type']) {
277
+ 'email' => 'email',
278
+ 'url' => 'url',
279
+ 'textarea' => 'textarea',
280
+ 'checkbox' => 'boolean',
281
+ 'checkbox_group' => 'checkbox_array',
282
+ 'phone' => 'phone',
283
+ default => 'text',
284
+ };
285
+ }
286
+ ```
287
+
288
+ ### Repeater Sanitization
289
+
290
+ ```php
291
+ $sanitized_locations = ima_forms_sanitize_repeater(
292
+ $_POST['additional_locations'] ?? [],
293
+ ['location_name' => 'text', 'contact_email' => 'email']
294
+ );
295
+ ```
296
+
297
+ ---
298
+
299
+ ## Debug Helpers
300
+
301
+ ### See Registered Specs
302
+
303
+ ```php
304
+ echo ima_forms_debug_field_specs();
305
+ // Output:
306
+ // Registered Field Specs (4):
307
+ // - name: text [REQUIRED]
308
+ // - email: email [REQUIRED]
309
+ // - phone: phone
310
+ // - message: textarea [REQUIRED]
311
+ ```
312
+
313
+ ### See Validation Summary
314
+
315
+ ```php
316
+ $specs = ima_forms_get_field_specs();
317
+ echo ima_forms_debug_validation_summary($specs);
318
+ // Output:
319
+ // Validation Summary (4 fields):
320
+ // name (text, REQUIRED): [2 validator(s)]
321
+ // email (email, REQUIRED): [2 validator(s)]
322
+ // phone (phone, optional): [1 validator(s)]
323
+ // message (textarea, REQUIRED): [1 validator(s)]
324
+ ```
325
+
326
+ ### Registry Functions
327
+
328
+ | Function | Purpose |
329
+ |----------|---------|
330
+ | `ima_forms_register_field_spec($name, $spec)` | Register a field spec |
331
+ | `ima_forms_get_field_specs()` | Get all registered specs |
332
+ | `ima_forms_clear_field_specs()` | Clear registry (used by engine) |
333
+ | `ima_forms_has_field_spec($name)` | Check if field registered |
334
+ | `ima_forms_get_field_spec($name)` | Get single spec |
335
+ | `ima_forms_get_field_spec_count()` | Count registered specs |
336
+ | `ima_forms_debug_field_specs()` | Human-readable spec dump |