@ai-kits/wp-ag-kit 1.0.2 → 1.0.3

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 (28) hide show
  1. package/README.md +12 -8
  2. package/STRUCTURE.md +9 -7
  3. package/agents/woocommerce-expert.md +32 -0
  4. package/agents/wordpress-expert.md +4 -2
  5. package/package.json +5 -3
  6. package/skills/woocommerce/SKILL.md +54 -0
  7. package/skills/woocommerce/references/backend-dev-guide.md +44 -0
  8. package/skills/woocommerce/references/code-entities.md +186 -0
  9. package/skills/woocommerce/references/code-quality.md +273 -0
  10. package/skills/woocommerce/references/code-review-guide.md +71 -0
  11. package/skills/woocommerce/references/coding-conventions.md +182 -0
  12. package/skills/woocommerce/references/copy-guidelines-guide.md +17 -0
  13. package/skills/woocommerce/references/data-integrity.md +164 -0
  14. package/skills/woocommerce/references/dependency-injection.md +102 -0
  15. package/skills/woocommerce/references/dev-cycle-guide.md +32 -0
  16. package/skills/woocommerce/references/file-entities.md +73 -0
  17. package/skills/woocommerce/references/hooks.md +87 -0
  18. package/skills/woocommerce/references/js-i18n-patterns.md +298 -0
  19. package/skills/woocommerce/references/markdown-guide.md +358 -0
  20. package/skills/woocommerce/references/markdown-linting.md +202 -0
  21. package/skills/woocommerce/references/php-i18n-patterns.md +83 -0
  22. package/skills/woocommerce/references/php-linting-patterns.md +304 -0
  23. package/skills/woocommerce/references/running-tests.md +249 -0
  24. package/skills/woocommerce/references/security-patterns.md +109 -0
  25. package/skills/woocommerce/references/sentence-case.md +177 -0
  26. package/skills/woocommerce/references/type-annotations.md +161 -0
  27. package/skills/woocommerce/references/unit-tests.md +362 -0
  28. package/skills/woocommerce/references/woocommerce-global-objects.md +89 -0
@@ -0,0 +1,304 @@
1
+ # PHP Linting Patterns and Common Issues
2
+
3
+ ## Table of Contents
4
+
5
+ - [Critical Rule: Lint Only Specific Files](#critical-rule-lint-only-specific-files)
6
+ - [Common PHP Linting Issues & Fixes](#common-php-linting-issues--fixes)
7
+ - [Translators Comment Placement](#translators-comment-placement)
8
+ - [PSR-12 File Header Order](#psr-12-file-header-order)
9
+ - [Mock Classes with Intentional Violations](#mock-classes-with-intentional-violations)
10
+ - [Multi-line Condition Alignment](#multi-line-condition-alignment)
11
+ - [Unused Closure Parameters](#unused-closure-parameters)
12
+ - [Array and Operator Alignment](#array-and-operator-alignment)
13
+ - [Indentation Rules](#indentation-rules)
14
+ - [Workflow for Fixing PHP Linting Issues](#workflow-for-fixing-php-linting-issues)
15
+ - [Quick Command Reference](#quick-command-reference)
16
+
17
+ ## Critical Rule: Lint Only Specific Files
18
+
19
+ **NEVER run linting on the entire codebase.** Always lint specific files, changed files or staged files only.
20
+
21
+ ```bash
22
+ # ✅ CORRECT: Check only changed files at the branch level
23
+ pnpm lint:php:changes
24
+
25
+ # ✅ CORRECT: Check only changed files that are staged
26
+ pnpm lint:php:changes:staged
27
+
28
+ # ✅ CORRECT: Lint specific file
29
+ pnpm lint:php -- path/to/file.php
30
+ pnpm lint:php:fix -- path/to/file.php
31
+
32
+ # ❌ WRONG: Lints entire codebase
33
+ pnpm lint:php
34
+ pnpm lint:php:fix
35
+ ```
36
+
37
+ ## Common PHP Linting Issues & Fixes
38
+
39
+ ### Quick Reference Table
40
+
41
+ | Issue | Wrong | Correct |
42
+ |-------|-------|---------|
43
+ | **Translators comment** | Before return | Before function call |
44
+ | **File docblock (PSR-12)** | After `declare()` | Before `declare()` |
45
+ | **Indentation** | Spaces | Tabs only |
46
+ | **Array alignment** | Inconsistent | Align `=>` with context |
47
+ | **Equals alignment** | Inconsistent | Match surrounding style |
48
+
49
+ ## Translators Comment Placement
50
+
51
+ Translators comments must be placed **immediately before the translation function call**, not before the return statement.
52
+
53
+ ### Wrong - Comment Before Return
54
+
55
+ ```php
56
+ /* translators: %s: Gateway name. */
57
+ return sprintf(
58
+ esc_html__( '%s is not supported.', 'woocommerce' ),
59
+ 'Gateway'
60
+ );
61
+ ```
62
+
63
+ ### Correct - Comment Before Translation Function
64
+
65
+ ```php
66
+ return sprintf(
67
+ /* translators: %s: Gateway name. */
68
+ esc_html__( '%s is not supported.', 'woocommerce' ),
69
+ 'Gateway'
70
+ );
71
+ ```
72
+
73
+ ### Multiple Parameters
74
+
75
+ ```php
76
+ return sprintf(
77
+ /* translators: 1: Gateway name, 2: Country code. */
78
+ esc_html__( '%1$s is not available in %2$s.', 'woocommerce' ),
79
+ $gateway_name,
80
+ $country_code
81
+ );
82
+ ```
83
+
84
+ ## PSR-12 File Header Order
85
+
86
+ File docblocks must come **before** the `declare()` statement, not after.
87
+
88
+ ### Wrong - Docblock After declare()
89
+
90
+ ```php
91
+ <?php
92
+ declare( strict_types=1 );
93
+
94
+ /**
95
+ * File docblock
96
+ *
97
+ * @package WooCommerce
98
+ */
99
+ ```
100
+
101
+ ### Correct - Docblock Before declare()
102
+
103
+ ```php
104
+ <?php
105
+ /**
106
+ * File docblock
107
+ *
108
+ * @package WooCommerce
109
+ */
110
+
111
+ declare( strict_types=1 );
112
+ ```
113
+
114
+ ## Mock Classes with Intentional Violations
115
+
116
+ When creating mock classes that must match external class names, use phpcs:disable comments:
117
+
118
+ ```php
119
+ if ( ! class_exists( 'WC_Payments_Utils' ) ) {
120
+ /**
121
+ * Mock class for testing.
122
+ *
123
+ * phpcs:disable Squiz.Classes.ClassFileName.NoMatch
124
+ * phpcs:disable Suin.Classes.PSR4.IncorrectClassName
125
+ * phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
126
+ */
127
+ class WC_Payments_Utils {
128
+ /**
129
+ * Mock implementation.
130
+ */
131
+ public static function supported_countries() {
132
+ return array( 'US', 'GB' );
133
+ }
134
+ }
135
+ }
136
+ ```
137
+
138
+ ## Multi-line Condition Alignment
139
+
140
+ Use tabs for continuation lines in multi-line conditions:
141
+
142
+ ```php
143
+ // Correct - tabs for continuation
144
+ if ( class_exists( '\WC_Payments_Utils' ) &&
145
+ is_callable( '\WC_Payments_Utils::supported_countries' ) ) {
146
+ // code
147
+ }
148
+
149
+ // Also correct - align with opening parenthesis
150
+ if ( class_exists( '\WC_Payments_Utils' ) &&
151
+ is_callable( '\WC_Payments_Utils::supported_countries' ) ) {
152
+ // code
153
+ }
154
+ ```
155
+
156
+ ## Unused Closure Parameters
157
+
158
+ When creating closures with parameters required by signature but unused, use `unset()` to avoid PHPCS errors:
159
+
160
+ ### The Problem
161
+
162
+ ```php
163
+ // ❌ WRONG - PHPCS error: Generic.CodeAnalysis.UnusedFunctionParameter
164
+ 'callback' => function ( string $return_url ) {
165
+ return array( 'success' => true );
166
+ },
167
+ ```
168
+
169
+ ### The Solution
170
+
171
+ ```php
172
+ // ✅ CORRECT - unset unused parameters
173
+ 'callback' => function ( string $return_url ) {
174
+ unset( $return_url ); // Avoid parameter not used PHPCS errors.
175
+ return array( 'success' => true );
176
+ },
177
+ ```
178
+
179
+ ### Multiple Unused Parameters
180
+
181
+ ```php
182
+ 'callback' => function ( $arg1, $arg2, $arg3 ) {
183
+ unset( $arg1, $arg2 ); // Avoid parameter not used PHPCS errors.
184
+ return $arg3;
185
+ },
186
+ ```
187
+
188
+ ### Common Scenarios
189
+
190
+ - Mock method callbacks in PHPUnit tests
191
+ - Array/filter callbacks where signature is fixed
192
+ - Interface implementations with unused parameters
193
+
194
+ **Reference:** `tests/php/src/Internal/Admin/Settings/PaymentsRestControllerIntegrationTest.php:1647-1655`
195
+
196
+ ## Array and Operator Alignment
197
+
198
+ ### Array Arrow Alignment
199
+
200
+ Align `=>` arrows consistently within each array context:
201
+
202
+ ```php
203
+ // Correct - aligned arrows
204
+ $options = array(
205
+ 'gateway_id' => 'stripe',
206
+ 'enabled' => true,
207
+ 'country_code' => 'US',
208
+ );
209
+
210
+ // Also correct - no alignment for short arrays
211
+ $small = array(
212
+ 'id' => 123,
213
+ 'name' => 'Test',
214
+ );
215
+ ```
216
+
217
+ ### Assignment Operator Alignment
218
+
219
+ Match the surrounding code style:
220
+
221
+ ```php
222
+ // When surrounding code aligns, align:
223
+ $gateway_id = 'stripe';
224
+ $enabled = true;
225
+ $country_code = 'US';
226
+
227
+ // When surrounding code doesn't align, don't align:
228
+ $gateway_id = 'stripe';
229
+ $enabled = true;
230
+ $country_code = 'US';
231
+ ```
232
+
233
+ ## Indentation Rules
234
+
235
+ **Always use tabs, never spaces, for indentation.**
236
+
237
+ ```php
238
+ // ✅ Correct - tabs for indentation
239
+ public function process_payment( $order_id ) {
240
+ → $order = wc_get_order( $order_id );
241
+
242
+ → if ( ! $order ) {
243
+ → → return false;
244
+ → }
245
+
246
+ → return true;
247
+ }
248
+
249
+ // ❌ Wrong - spaces for indentation
250
+ public function process_payment( $order_id ) {
251
+ $order = wc_get_order( $order_id );
252
+
253
+ if ( ! $order ) {
254
+ return false;
255
+ }
256
+
257
+ return true;
258
+ }
259
+ ```
260
+
261
+ ## Workflow for Fixing PHP Linting Issues
262
+
263
+ 1. **Run linting on changed files:**
264
+
265
+ ```bash
266
+ pnpm lint:php:changes
267
+ ```
268
+
269
+ 2. **Auto-fix what you can:**
270
+
271
+ ```bash
272
+ pnpm lint:php:fix -- path/to/file.php
273
+ ```
274
+
275
+ 3. **Review remaining errors** - Common issues that require manual fixing:
276
+ - Translators comment placement
277
+ - File docblock order (PSR-12)
278
+ - Unused closure parameters (add `unset()`)
279
+
280
+ 4. **Address remaining issues manually**
281
+
282
+ 5. **Verify the output is clean:**
283
+
284
+ ```bash
285
+ pnpm lint:php -- path/to/file.php
286
+ ```
287
+
288
+ 6. **Commit**
289
+
290
+ ## Quick Command Reference
291
+
292
+ ```bash
293
+ # Check changed files
294
+ pnpm lint:php:changes
295
+
296
+ # Check specific file
297
+ pnpm lint:php -- src/Internal/Admin/ClassName.php
298
+
299
+ # Fix specific file
300
+ pnpm lint:php:fix -- src/Internal/Admin/ClassName.php
301
+
302
+ # Check with error details
303
+ vendor/bin/phpcs -s path/to/file.php
304
+ ```
@@ -0,0 +1,249 @@
1
+ # Running Tests
2
+
3
+ ## Table of Contents
4
+
5
+ - [PHP Unit Tests](#php-unit-tests)
6
+ - [Basic Test Commands](#basic-test-commands)
7
+ - [Examples](#examples)
8
+ - [Common Test Commands](#common-test-commands)
9
+ - [Test Environment](#test-environment)
10
+ - [Troubleshooting Tests](#troubleshooting-tests)
11
+ - [Interpreting Test Output](#interpreting-test-output)
12
+ - [Best Practices](#best-practices)
13
+ - [Test Configuration](#test-configuration)
14
+ - [JavaScript/Jest Tests](#javascriptjest-tests)
15
+ - [Notes](#notes)
16
+
17
+ ## PHP Unit Tests
18
+
19
+ To run PHP unit tests in the WooCommerce plugin directory, use the following commands:
20
+
21
+ ### Basic Test Commands
22
+
23
+ ```bash
24
+ # Run all PHP unit tests
25
+ pnpm run test:php:env
26
+
27
+ # Run specific test class
28
+ pnpm run test:php:env -- --filter TestClassName
29
+
30
+ # Run specific test method
31
+ pnpm run test:php:env -- --filter TestClassName::test_method_name
32
+
33
+ # Run tests with verbose output
34
+ pnpm run test:php:env -- --verbose --filter TestClassName
35
+ ```
36
+
37
+ ### Examples
38
+
39
+ ```bash
40
+ # Run payment extension suggestions tests
41
+ pnpm run test:php:env -- --filter PaymentsExtensionSuggestionsTest
42
+
43
+ # Run specific test method
44
+ pnpm run test:php:env -- --filter PaymentsExtensionSuggestionsTest::test_get_country_extensions_count_with_merchant_selling_online
45
+ ```
46
+
47
+ ## Common Test Commands
48
+
49
+ ### Run Tests for a Directory
50
+
51
+ ```bash
52
+ # Run all tests in a directory
53
+ pnpm run test:php:env -- tests/php/src/Internal/Admin/
54
+ ```
55
+
56
+ ### Run Tests Matching a Pattern
57
+
58
+ ```bash
59
+ # Run all Admin tests
60
+ pnpm run test:php:env -- --filter "Admin.*Test"
61
+
62
+ # Run all tests with "Payment" in the name
63
+ pnpm run test:php:env -- --filter "Payment"
64
+ ```
65
+
66
+ ### Stop on First Failure
67
+
68
+ ```bash
69
+ # Useful during development to quickly identify issues
70
+ pnpm run test:php:env -- --stop-on-failure
71
+ ```
72
+
73
+ ### Get Test Coverage
74
+
75
+ ```bash
76
+ # Get coverage report (if configured)
77
+ pnpm run test:php:env -- --coverage-text
78
+ ```
79
+
80
+ ## Test Environment
81
+
82
+ ### How It Works
83
+
84
+ Tests run in Docker via `wp-env` with auto-configured WordPress/WooCommerce (PHPUnit 9.6.24, PHP 8.1).
85
+
86
+ ### Environment Setup
87
+
88
+ The test environment is managed automatically, but you can control it if needed:
89
+
90
+ ```bash
91
+ # Start the test environment
92
+ wp-env start
93
+
94
+ # Stop the test environment
95
+ wp-env stop
96
+
97
+ # Restart the test environment
98
+ wp-env restart
99
+
100
+ # Destroy and recreate the environment
101
+ wp-env destroy
102
+ wp-env start
103
+ ```
104
+
105
+ ## Troubleshooting Tests
106
+
107
+ | Problem | Solution |
108
+ |---------|----------|
109
+ | "Class not found" errors | Run `pnpm install` |
110
+ | Tests hang/fail to start | `wp-env stop && wp-env start` or `wp-env destroy && wp-env start` |
111
+ | Permission errors | Check Docker permissions |
112
+ | Xdebug warnings | Ignore (don't affect results) |
113
+
114
+ ## Interpreting Test Output
115
+
116
+ ### Successful Test Run
117
+
118
+ ```text
119
+ PHPUnit 9.6.24
120
+
121
+ .................................................. 50 / 100 ( 50%)
122
+ .................................................. 100 / 100 (100%)
123
+
124
+ Time: 00:02.345, Memory: 24.00 MB
125
+
126
+ OK (100 tests, 250 assertions)
127
+ ```
128
+
129
+ ### Failed Test
130
+
131
+ ```text
132
+ PHPUnit 9.6.24
133
+
134
+ .....F................................................. 50 / 100 ( 50%)
135
+ .................................................. 100 / 100 (100%)
136
+
137
+ Time: 00:02.345, Memory: 24.00 MB
138
+
139
+ There was 1 failure:
140
+
141
+ 1) PaymentsExtensionSuggestionsTest::test_get_country_extensions_count_for_online_merchants with data set "United States" ('US', 5)
142
+ Expected 5 extensions for online merchant in US
143
+ Failed asserting that 4 matches expected 5.
144
+
145
+ /path/to/test/file.php:123
146
+
147
+ FAILURES!
148
+ Tests: 100, Assertions: 250, Failures: 1.
149
+ ```
150
+
151
+ ### Understanding Failures
152
+
153
+ Test failures provide:
154
+
155
+ - **Which test failed:** Test class and method name
156
+ - **Test data:** Data set used (if using data providers)
157
+ - **Expected vs actual:** What was expected and what was received
158
+ - **Location:** File and line number where assertion failed
159
+
160
+ ## Best Practices
161
+
162
+ ### During Development
163
+
164
+ 1. **Run specific tests** for the code you're changing:
165
+
166
+ ```bash
167
+ pnpm run test:php:env -- --filter YourTestClass
168
+ ```
169
+
170
+ 2. **Use verbose mode** when debugging:
171
+
172
+ ```bash
173
+ pnpm run test:php:env -- --verbose --filter YourTestClass
174
+ ```
175
+
176
+ 3. **Stop on first failure** to focus on one issue at a time:
177
+
178
+ ```bash
179
+ pnpm run test:php:env -- --stop-on-failure --filter YourTestClass
180
+ ```
181
+
182
+ ### Before Committing
183
+
184
+ 1. **Run all affected tests:**
185
+
186
+ ```bash
187
+ pnpm run test:php:env -- tests/php/src/Internal/YourFeature/
188
+ ```
189
+
190
+ 2. **Ensure all tests pass** before committing
191
+
192
+ 3. **Check code quality** (see code-quality.md)
193
+
194
+ ## Test Configuration
195
+
196
+ Test configuration file: `plugins/woocommerce/phpunit.xml`
197
+
198
+ This file contains:
199
+
200
+ - Test suite definitions
201
+ - Bootstrap files
202
+ - Coverage settings
203
+ - Logging configuration
204
+
205
+ ## JavaScript/Jest Tests
206
+
207
+ ### Running JavaScript Tests
208
+
209
+ To run JavaScript tests for the admin client, navigate to the `client/admin` directory:
210
+
211
+ ```bash
212
+ # Navigate to client/admin directory first
213
+ cd client/admin
214
+
215
+ # Run all JavaScript tests
216
+ pnpm test:js
217
+
218
+ # Run tests in watch mode
219
+ pnpm test:js -- --watch
220
+
221
+ # Run a specific test file
222
+ pnpm test:js -- status-badge.test.tsx
223
+
224
+ # Run tests with coverage
225
+ pnpm test:js -- --coverage
226
+ ```
227
+
228
+ ### Test File Locations
229
+
230
+ - JavaScript/Jest tests: `client/admin/client/**/*.test.tsx` or `*.test.ts`
231
+ - Jest configuration: `client/admin/jest.config.js`
232
+
233
+ ### Troubleshooting JavaScript Tests
234
+
235
+ For detailed Jest configuration and testing patterns, see `client/admin/CLAUDE.md`.
236
+
237
+ Common issues:
238
+
239
+ - **Tests not found**: Ensure you're in the `client/admin` directory
240
+ - **Module resolution errors**: Run `pnpm install` in the `client/admin` directory
241
+ - **Cache issues**: Try `pnpm test:js -- --clearCache`
242
+
243
+ ## Notes
244
+
245
+ - The test environment handles WordPress/WooCommerce setup automatically
246
+ - Extension counts in payment tests must match the actual implementation exactly
247
+ - Test data providers are useful for testing multiple scenarios
248
+ - Always check test output for helpful error messages
249
+ - For React/TypeScript testing patterns, refer to `client/admin/CLAUDE.md`
@@ -0,0 +1,109 @@
1
+ # Security Patterns for WooCommerce
2
+
3
+ This guide covers security best practices for WooCommerce development, focusing on data sanitization, validation, and escaping.
4
+
5
+ ## Data Sanitization (Inputs)
6
+
7
+ Always sanitize user input before using it in logic or saving to the database.
8
+
9
+ | Type | Function |
10
+ |------|----------|
11
+ | Text | `sanitize_text_field()` |
12
+ | Email | `sanitize_email()` |
13
+ | URL | `esc_url_raw()` |
14
+ | Key/Slug | `sanitize_key()` |
15
+ | Array | `array_map( 'sanitize_text_field', $array )` |
16
+
17
+ ```php
18
+ $product_name = sanitize_text_field( $_POST['product_name'] ?? '' );
19
+ ```
20
+
21
+ ## Data Validation
22
+
23
+ Verify data before processing it.
24
+
25
+ ```php
26
+ if ( ! is_numeric( $order_id ) ) {
27
+ return;
28
+ }
29
+
30
+ if ( ! is_email( $user_email ) ) {
31
+ throw new Exception( 'Invalid email' );
32
+ }
33
+ ```
34
+
35
+ ## Data Escaping (Outputs)
36
+
37
+ Always escape data right before echoing it. This is the last line of defense against XSS.
38
+
39
+ | Type | Function |
40
+ |------|----------|
41
+ | HTML Content | `esc_html()` |
42
+ | HTML Attributes | `esc_attr()` |
43
+ | URLs | `esc_url()` |
44
+ | JavaScript | `esc_js()` |
45
+ | textarea | `esc_textarea()` |
46
+
47
+ ```php
48
+ echo '<div class="name">' . esc_html( $name ) . '</div>';
49
+ echo '<input value="' . esc_attr( $value ) . '">';
50
+ ```
51
+
52
+ ## Nonces
53
+
54
+ Always use nonces to protect against CSRF attacks in forms and AJAX requests.
55
+
56
+ ### Form Verification
57
+
58
+ ```php
59
+ // In the form
60
+ wp_nonce_field( 'my_plugin_action', 'my_plugin_nonce' );
61
+
62
+ // In the processing logic
63
+ if ( ! isset( $_POST['my_plugin_nonce'] ) || ! wp_verify_nonce( $_POST['my_plugin_nonce'], 'my_plugin_action' ) ) {
64
+ wp_die( 'Security check failed' );
65
+ }
66
+ ```
67
+
68
+ ### URL/AJAX Verification
69
+
70
+ ```php
71
+ // Creating link
72
+ $url = wp_nonce_url( admin_url( 'admin-post.php?action=my_action' ), 'my_action_nonce' );
73
+
74
+ // Verification
75
+ check_admin_referer( 'my_action_nonce' );
76
+ ```
77
+
78
+ ## Database Safety
79
+
80
+ Use `$wpdb->prepare()` for custom SQL queries to prevent SQL injection.
81
+
82
+ ```php
83
+ global $wpdb;
84
+ $id = 123;
85
+ $results = $wpdb->get_results( $wpdb->prepare(
86
+ "SELECT * FROM {$wpdb->prefix}posts WHERE ID = %d",
87
+ $id
88
+ ) );
89
+ ```
90
+
91
+ ## Capabilities and Permissions
92
+
93
+ Always check if the current user has the authority to perform an action.
94
+
95
+ ```php
96
+ if ( ! current_user_can( 'manage_woocommerce' ) ) {
97
+ return;
98
+ }
99
+
100
+ if ( ! $order->get_customer_id() === get_current_user_id() ) {
101
+ return;
102
+ }
103
+ ```
104
+
105
+ ## WooCommerce Specific Security
106
+
107
+ - Use `WC_Validation` class for common e-commerce validation (postcodes, phone numbers).
108
+ - Use `WC_Data` getters and setters which perform some internal checks.
109
+ - Be careful with `WC_Checkout::process_checkout` and related hooks.