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,403 @@
1
+ <?php
2
+ declare(strict_types=1);
3
+
4
+ namespace PhpFp\Examples;
5
+
6
+ /**
7
+ * Pure function examples demonstrating PHP FP patterns
8
+ *
9
+ * Key principles:
10
+ * - Strict types enabled
11
+ * - Pure functions (no side effects, deterministic)
12
+ * - Native PHP array functions over loops
13
+ * - Explicit dependencies via parameters
14
+ * - Immutable data handling
15
+ */
16
+
17
+ // ───────────────────────────────────────────────────────
18
+ // Basic Pure Functions
19
+ // ───────────────────────────────────────────────────────
20
+
21
+ /**
22
+ * Calculate user discount based on tier and loyalty
23
+ * @pure - No side effects, deterministic
24
+ */
25
+ function calculateDiscount(float $price, string $tier, int $daysAsMember): float
26
+ {
27
+ $tierMultipliers = [
28
+ 'bronze' => 0.05,
29
+ 'silver' => 0.10,
30
+ 'gold' => 0.15,
31
+ 'platinum' => 0.20
32
+ ];
33
+
34
+ $baseDiscount = $tierMultipliers[$tier] ?? 0.0;
35
+ $loyaltyBonus = min($daysAsMember / 365 * 0.02, 0.05); // Max 5%
36
+ $totalDiscount = min($baseDiscount + $loyaltyBonus, 0.25); // Max 25%
37
+
38
+ return round($price * (1 - $totalDiscount), 2);
39
+ }
40
+
41
+ /**
42
+ * Validate email format
43
+ * @pure - Returns validation result without side effects
44
+ */
45
+ function validateEmail(string $email): array
46
+ {
47
+ $isValid = filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
48
+
49
+ return [
50
+ 'valid' => $isValid,
51
+ 'error' => $isValid ? null : 'Invalid email format'
52
+ ];
53
+ }
54
+
55
+ /**
56
+ * Format user display name
57
+ * @pure - String transformation only
58
+ */
59
+ function formatDisplayName(array $user): string
60
+ {
61
+ $firstName = trim($user['first_name'] ?? '');
62
+ $lastName = trim($user['last_name'] ?? '');
63
+
64
+ if ($firstName && $lastName) {
65
+ return "{$firstName} {$lastName}";
66
+ }
67
+
68
+ return $firstName ?: $lastName ?: 'Anonymous';
69
+ }
70
+
71
+ // ───────────────────────────────────────────────────────
72
+ // Configuration Pre-Compilation (Performance Pattern)
73
+ // ───────────────────────────────────────────────────────
74
+
75
+ /**
76
+ * Pre-compile validation rules to avoid O(n²) complexity
77
+ *
78
+ * ❌ BAD: Configuration inside loop
79
+ * foreach ($users as $user) {
80
+ * $rules = ['email' => 'required', 'age' => 'numeric']; // Created N times!
81
+ * validate($user, $rules);
82
+ * }
83
+ *
84
+ * ✅ GOOD: Pre-compile configuration
85
+ * $validator = createValidator(['email' => 'required', 'age' => 'numeric']);
86
+ * foreach ($users as $user) {
87
+ * $validator($user); // Uses pre-compiled rules
88
+ * }
89
+ */
90
+ function createValidator(array $rules): callable
91
+ {
92
+ // Pre-compile rules once (expensive operation)
93
+ $compiledRules = array_map(function($rule) {
94
+ return match($rule) {
95
+ 'required' => fn($value) => !empty($value),
96
+ 'numeric' => fn($value) => is_numeric($value),
97
+ 'email' => fn($value) => filter_var($value, FILTER_VALIDATE_EMAIL) !== false,
98
+ default => fn($value) => true
99
+ };
100
+ }, $rules);
101
+
102
+ // Return validator function that uses pre-compiled rules
103
+ return function(array $data) use ($compiledRules): array {
104
+ $errors = [];
105
+
106
+ foreach ($compiledRules as $field => $validator) {
107
+ $value = $data[$field] ?? null;
108
+ if (!$validator($value)) {
109
+ $errors[$field] = "Validation failed for {$field}";
110
+ }
111
+ }
112
+
113
+ return [
114
+ 'valid' => empty($errors),
115
+ 'errors' => $errors
116
+ ];
117
+ };
118
+ }
119
+
120
+ /**
121
+ * Pre-compile field transformer configuration
122
+ */
123
+ function createFieldTransformer(array $fieldConfig): callable
124
+ {
125
+ // Pre-compile transformation functions
126
+ $transformers = array_map(function($transform) {
127
+ return match($transform) {
128
+ 'trim' => fn($v) => trim($v),
129
+ 'lowercase' => fn($v) => strtolower($v),
130
+ 'uppercase' => fn($v) => strtoupper($v),
131
+ 'capitalize' => fn($v) => ucfirst($v),
132
+ default => fn($v) => $v
133
+ };
134
+ }, $fieldConfig);
135
+
136
+ return function(array $data) use ($transformers): array {
137
+ $transformed = $data;
138
+
139
+ foreach ($transformers as $field => $transform) {
140
+ if (isset($transformed[$field])) {
141
+ $transformed[$field] = $transform($transformed[$field]);
142
+ }
143
+ }
144
+
145
+ return $transformed;
146
+ };
147
+ }
148
+
149
+ // ───────────────────────────────────────────────────────
150
+ // Composition with Native PHP Functions
151
+ // ───────────────────────────────────────────────────────
152
+
153
+ /**
154
+ * Process users with native array functions
155
+ * Demonstrates composition without pipe/compose utilities
156
+ */
157
+ function processActiveUsers(array $users, int $limit = 10): array
158
+ {
159
+ return array_slice(
160
+ array_map(
161
+ fn($user) => [
162
+ ...$user,
163
+ 'display_name' => formatDisplayName($user),
164
+ 'account_age' => calculateAccountAge($user['created_at'])
165
+ ],
166
+ array_filter(
167
+ $users,
168
+ fn($user) => $user['active'] ?? false
169
+ )
170
+ ),
171
+ 0,
172
+ $limit
173
+ );
174
+ }
175
+
176
+ /**
177
+ * Calculate account age in days
178
+ * @pure - Date calculation only
179
+ */
180
+ function calculateAccountAge(string $createdAt): int
181
+ {
182
+ $created = strtotime($createdAt);
183
+ $now = time();
184
+
185
+ return (int) (($now - $created) / (60 * 60 * 24));
186
+ }
187
+
188
+ /**
189
+ * Group items by field value
190
+ * @pure - Array transformation
191
+ */
192
+ function groupBy(array $items, string $field): array
193
+ {
194
+ return array_reduce(
195
+ $items,
196
+ function($groups, $item) use ($field) {
197
+ $key = $item[$field] ?? 'unknown';
198
+ $groups[$key][] = $item;
199
+ return $groups;
200
+ },
201
+ []
202
+ );
203
+ }
204
+
205
+ // ───────────────────────────────────────────────────────
206
+ // Immutability Patterns (PHP-Specific)
207
+ // ───────────────────────────────────────────────────────
208
+
209
+ /**
210
+ * Update user without mutation
211
+ * PHP arrays are copy-on-write, but we make it explicit
212
+ */
213
+ function updateUser(array $user, array $updates): array
214
+ {
215
+ // Create new array instead of mutating
216
+ return array_merge($user, $updates, [
217
+ 'updated_at' => date('Y-m-d H:i:s')
218
+ ]);
219
+ }
220
+
221
+ /**
222
+ * Add item to collection immutably
223
+ */
224
+ function addItem(array $collection, array $item): array
225
+ {
226
+ // array_merge creates new array
227
+ return array_merge($collection, [$item]);
228
+ }
229
+
230
+ /**
231
+ * Remove item from collection immutably
232
+ */
233
+ function removeItem(array $collection, string $id): array
234
+ {
235
+ // array_filter creates new array
236
+ return array_values(
237
+ array_filter(
238
+ $collection,
239
+ fn($item) => $item['id'] !== $id
240
+ )
241
+ );
242
+ }
243
+
244
+ // ───────────────────────────────────────────────────────
245
+ // Result Type Pattern (Error Handling)
246
+ // ───────────────────────────────────────────────────────
247
+
248
+ /**
249
+ * Parse and validate user data
250
+ * @pure - Returns result, throws no exceptions
251
+ */
252
+ function parseUserData(array $data): array
253
+ {
254
+ // Validate required fields
255
+ $requiredFields = ['email', 'name'];
256
+ $missingFields = array_filter(
257
+ $requiredFields,
258
+ fn($field) => empty($data[$field])
259
+ );
260
+
261
+ if (!empty($missingFields)) {
262
+ return [
263
+ 'success' => false,
264
+ 'error' => 'Missing required fields: ' . implode(', ', $missingFields),
265
+ 'data' => null
266
+ ];
267
+ }
268
+
269
+ // Validate email
270
+ $emailValidation = validateEmail($data['email']);
271
+ if (!$emailValidation['valid']) {
272
+ return [
273
+ 'success' => false,
274
+ 'error' => $emailValidation['error'],
275
+ 'data' => null
276
+ ];
277
+ }
278
+
279
+ // Success - return parsed data
280
+ return [
281
+ 'success' => true,
282
+ 'error' => null,
283
+ 'data' => [
284
+ 'email' => strtolower(trim($data['email'])),
285
+ 'name' => trim($data['name']),
286
+ 'age' => isset($data['age']) ? (int) $data['age'] : null
287
+ ]
288
+ ];
289
+ }
290
+
291
+ /**
292
+ * Calculate shipping cost with error handling
293
+ * @pure - Returns result type
294
+ */
295
+ function calculateShipping(float $weight, string $zone): array
296
+ {
297
+ $validZones = ['domestic', 'international', 'express'];
298
+
299
+ if (!in_array($zone, $validZones)) {
300
+ return [
301
+ 'success' => false,
302
+ 'error' => "Invalid zone: {$zone}",
303
+ 'data' => null
304
+ ];
305
+ }
306
+
307
+ if ($weight <= 0) {
308
+ return [
309
+ 'success' => false,
310
+ 'error' => 'Weight must be positive',
311
+ 'data' => null
312
+ ];
313
+ }
314
+
315
+ $rates = [
316
+ 'domestic' => 5.00,
317
+ 'international' => 15.00,
318
+ 'express' => 25.00
319
+ ];
320
+
321
+ $cost = $rates[$zone] + ($weight * 0.50);
322
+
323
+ return [
324
+ 'success' => true,
325
+ 'error' => null,
326
+ 'data' => round($cost, 2)
327
+ ];
328
+ }
329
+
330
+ // ───────────────────────────────────────────────────────
331
+ // Dependency Injection Examples
332
+ // ───────────────────────────────────────────────────────
333
+
334
+ /**
335
+ * Process order with injected dependencies
336
+ * @pure - All dependencies passed as parameters
337
+ */
338
+ function processOrder(
339
+ array $order,
340
+ callable $calculateTax,
341
+ callable $calculateShipping,
342
+ callable $applyDiscount
343
+ ): array {
344
+ $subtotal = array_sum(array_column($order['items'], 'price'));
345
+ $tax = $calculateTax($subtotal, $order['tax_zone']);
346
+ $shipping = $calculateShipping($order['weight'], $order['shipping_zone']);
347
+ $discount = $applyDiscount($subtotal, $order['discount_code'] ?? null);
348
+
349
+ return [
350
+ 'subtotal' => $subtotal,
351
+ 'tax' => $tax,
352
+ 'shipping' => $shipping,
353
+ 'discount' => $discount,
354
+ 'total' => $subtotal + $tax + $shipping - $discount
355
+ ];
356
+ }
357
+
358
+ /**
359
+ * Calculate tax based on zone
360
+ * @pure - Tax calculation only
361
+ */
362
+ function calculateTax(float $amount, string $zone): float
363
+ {
364
+ $rates = [
365
+ 'CA' => 0.0725,
366
+ 'NY' => 0.08875,
367
+ 'TX' => 0.0625
368
+ ];
369
+
370
+ $rate = $rates[$zone] ?? 0.0;
371
+ return round($amount * $rate, 2);
372
+ }
373
+
374
+ /**
375
+ * Calculate shipping cost
376
+ * @pure - Shipping calculation only
377
+ */
378
+ function calculateShippingCost(float $weight, string $zone): float
379
+ {
380
+ $baseRates = [
381
+ 'domestic' => 5.00,
382
+ 'international' => 15.00
383
+ ];
384
+
385
+ $base = $baseRates[$zone] ?? 10.00;
386
+ return round($base + ($weight * 0.50), 2);
387
+ }
388
+
389
+ /**
390
+ * Apply discount code
391
+ * @pure - Discount calculation only
392
+ */
393
+ function applyDiscountCode(float $amount, ?string $code): float
394
+ {
395
+ $discounts = [
396
+ 'SAVE10' => 0.10,
397
+ 'SAVE20' => 0.20,
398
+ 'SAVE30' => 0.30
399
+ ];
400
+
401
+ $rate = $discounts[$code ?? ''] ?? 0.0;
402
+ return round($amount * $rate, 2);
403
+ }