8000 Prep trunk for 8.6 cycle by github-actions[bot] · Pull Request #1 · alexmigf/woocommerce · GitHub
[go: up one dir, main page]

Skip to content

Prep trunk for 8.6 cycle - #1

Open
github-actions[bot] wants to merge 1 commit into
trunkfrom
prep/trunk-for-next-dev-cycle-8.6
Open

github-actions[bot] wants to merge 1 commit into
trunkfrom
prep/trunk-for-next-dev-cycle-8.6

Conversation

@github-actions
Copy link
Copy Markdown

This PR updates the versions in trunk to 8.6.0-dev.

alexmigf pushed a commit that referenced this pull request Nov 22, 2024
This works fine:

```
curl -u bor0:asdf -X OPTIONS "localhost:8080/wp-json/wc/store/v1/products?_unstable_tax_asdf_operator=1" | jq
```

However, this causes a fatal error `PHP Fatal error:  Uncaught TypeError: str_starts_with(): Argument #1 ($haystack) must be of type string, int given`:

```
curl -u bor0:asdf -X OPTIONS "localhost:8080/wp-json/wc/store/v1/products?1=2" | jq
```
alexmigf pushed a commit that referenced this pull request Jun 4, 2026
* Add ambiguous provider match notice to tracking number lookup form

* Add changefile(s) from automation for the following project(s): woocommerce, woocommerce/client/admin

* Add tests

* Add accessibility to fulfillment drawer - part 1

* Fix input focus issues, remove duplicate speaks, replace HTML button with React component, add action button descriptions, fix tests and styling

* Add changefile(s) from automation for the following project(s): woocommerce, woocommerce/client/admin

* Fix linter

* Fix another linter error

* Fix error created after merge conflict resolution

* Add changefile(s) from automation for the following project(s): woocommerce, woocommerce/client/admin

* Fix fulfillment drawer accessibility issues (WOOPLUG-5066)

- Use useInstanceId for unique ARIA IDs on action buttons
- Remove redundant aria-label that overrides visible button text (WCAG 2.5.3)
- Move screen-reader-text spans outside Button to prevent double naming
- Remove aria-live from item selector count div (speak() handles announcements)
- Replace setTimeout with double requestAnimationFrame for focus management
- Add focus trapping and focus restoration tests for the drawer
- Add speak() announcement tests for item-selector and shipment-tracking-number-form

* Fix lint errors in fulfillment test files

- Fix prettier formatting on toMatch() calls
- Use ownerDocument.activeElement instead of document.activeElement

* Address code review feedback for fulfillment accessibility

- Use useRef instead of createRef in CustomerNotificationBox
- Wrap close button aria-label in __() for i18n
- Replace :focus with :focus-visible for WCAG 2.4.7 compliance
- Remove redundant aria-live on role="alert" error container
- Remove aria-live="polite" from fulfill button to avoid double announcements
- Add requestAnimationFrame cleanup in drawer and editor useEffects
- Replace hardcoded IDs with useInstanceId in ShipmentTrackingNumberForm
- Guard focus restoration with isConnected check

* Remove aria-label override on fulfillment header and fix decorative image alt

- Remove aria-label from fulfillment editor expand/collapse header so the
  accessible name comes from the heading text (e.g., "Fulfillment #1"),
  giving screen readers fulfillment-specific context. aria-expanded already
  conveys the expand/collapse state.
- Use empty alt on decorative provider icon that is already aria-hidden.

* Fix focus trap escape on Shift+Tab and add fallback aria-label to drawer

- Include drawer panel element in Shift+Tab boundary check so focus
  wraps to the last element instead of escaping the trap
- Add fallback aria-label for the dialog so it has an accessible name
  while the header component is loading (aria-labelledby takes
  precedence once the referenced element exists)

* Use WordPress admin button focus style (box-shadow) instead of outline

Match the standard WordPress admin focus convention: box-shadow with
--wp-admin-border-width-focus and --wp-admin-theme-color, applied via
:focus:not(:disabled). Also fix the 4th instance in card.scss that was
still suppressing focus indicators.

* Revert card.scss focus style change (out of scope)

* Address code review feedback

- Switch :focus:not(:disabled) to :focus-visible for keyboard-only focus rings
- Remove dead aria-label from drawer panel (aria-labelledby takes precedence)
- Replace ariaDescription DOM mutation with aria-describedby for universal support
- Filter disabled elements from focus trap selector to prevent trapping on unfocusable elements
- Add console.error in tracking number lookup catch block for debuggability

* Update drawer accessibility test for aria-label removal

---------

Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: woocommercebot <woocommercebot@users.noreply.github.com>
alexmigf pushed a commit that referenced this pull request Jun 4, 2026
… alongside existing product-data (woocommerce#63208)

* Add woocommerce/product-context store alongside existing product-data

Introduce a new iAPI store that uses direct state hydration via
wp_interactivity_state() instead of reading from block context. This is
purely additive - the old product-data store remains untouched and all
existing consumers continue using it.

New store provides computed getters (product, variation, selectedProduct)
that look up full product data from the woocommerce/products store,
and actions (setProductId, setVariationId) for state mutations.

Server-side hydration is added in SingleProductTemplate and
AddToCartWithOptions alongside the existing product-data hydration.

* Add changefile(s) from automation for the following project(s): woocommerce

* Fix prettier formatting in product-context store files

* Remove ProductsStoreTest — will be added in a separate PR

* Add tearDown to reset ProductsStore static state between tests

* Rename product-context getters for clarity

- product → parentProduct (specifically the parent, for variation matching)
- variation → selectedVariation (the variation the shopper picked)
- selectedProduct → product (the resolved active product, most common use case)

* Rename product getter to currentProduct for clarity

* Fix grouped products batch update missing cart item key

The update-item endpoint requires `key` to identify the cart item, but
Preact's reactive proxy filters `key` from property enumeration since
it's a reserved prop. This caused JSON.stringify to omit the key when
serializing the proxy object as the request body, resulting in "Cart
item does not exist" errors when adding grouped products a second time
without reloading.

Explicitly construct the body with `key` and `quantity` instead of
passing the proxy object directly. Also adds an e2e test that exercises
the add-twice-without-reload scenario.

* Revert "Fix grouped products batch update missing cart item key"

This reverts commit 9d39197.

* Simplify product-context store API based on review feedback

Remove actions and old getters. The store now exposes plain writable
state (productId, variationId) and two computed getters (currentProduct,
parentProduct). Consumers write state directly instead of calling actions.

* Remove consent string test from ProductContextStoreTest

* Fix prettier formatting in product-context store and tests

* Rename currentProduct/parentProduct to product/selectedVariation

The previous getter names were confusing — parentProduct returned the
variable product (not intuitive) and currentProduct changed identity
depending on whether a variation was selected.

The new API is clearer:
- product: always the main product, never a variation
- selectedVariation: the variation if one is selected, null otherwise

Also renames test file to .test.ts for jest discovery.

* Remove non-existent ProductContextState re-export

* Pass empty object when referencing products store

The products store already initializes its own state in products.ts.
The store() call in product-context.ts is just grabbing a reference,
so re-declaring the initial state was unnecessary duplication.

* Simplify context productId resolution to use || instead of !== undefined

* Read variationId from block context with fallback to store state

Same pattern as productId — context takes precedence so each product
in a loop can have its own variation selection.

* Fix prettier formatting for productId and variationId assignments

* Fix formatting via prettier

* Remove ProductContextStore class, add derived state closures to SingleProductTemplate

Replace the ProductContextStore PHP class with inline derived state
closures in SingleProductTemplate. The closures mirror the JS getters
for state.product and state.selectedVariation so that directives
referencing these properties resolve during server-side rendering.

This also removes the global state side-effect from load_context,
which was problematic for nested product contexts. Nested blocks
should set data-wp-context directly instead.

* Keep product-data store hydrated alongside new product-context store

Existing consumers (add-to-cart-with-options, variation-selector) still
read from woocommerce/product-data templateState. Without it, productId
resolved to undefined, disabling all variation selectors and breaking
add-to-cart. The product-data hydration will be removed when consumers
are migrated to product-context in the follow-up PR.

* Use explicit namespace for getContext, return null consistently

Address review feedback:
- Pass 'woocommerce/single-product' namespace to getContext() calls so
  the store reads context from the correct namespace (matching the
  pattern in product-data.ts)
- Return null instead of undefined from the product getter for
  consistency with the PHP closures and selectedVariation getter

* Adapt unit tests

* Fix logic context vs state

* Adapt unit tests to the context changes

* Use lock in products store

* Fix context logic in the server

---------

Co-authored-by: woocommercebot <woocommercebot@users.noreply.github.com>
Co-authored-by: Mario Santos <34552881+SantosGuillamot@users.noreply.github.com>
Co-authored-by: David Arenas <david.arenas@automattic.com>
alexmigf pushed a commit that referenced this pull request Jun 4, 2026
* Create woocommerce-core-dev agent documentation

* Revise woocommerce-core-dev agent description and examples

Updated the description for the woocommerce-core-dev agent to provide clearer guidance on its use and examples of context for user queries. Removed the Agent Memory section to streamline the document.

* Update description formatting in woocommerce-core-dev.md

* Initial plan

* feat: add EmailLogger class for transactional email logging

Agent-Logs-Url: https://github.com/jonathanbossenger/woocommerce/sessions/7aa95d05-2ba2-4c49-94e7-a9a1904aec90

Co-authored-by: jonathanbossenger <180629+jonathanbossenger@users.noreply.github.com>

* test: use explicit expects() in EmailLoggerTest mock setup

Agent-Logs-Url: https://github.com/jonathanbossenger/woocommerce/sessions/7aa95d05-2ba2-4c49-94e7-a9a1904aec90

Co-authored-by: jonathanbossenger <180629+jonathanbossenger@users.noreply.github.com>

* test: clean up WC_Order after test to prevent database pollution

Agent-Logs-Url: https://github.com/jonathanbossenger/woocommerce/sessions/7aa95d05-2ba2-4c49-94e7-a9a1904aec90

Co-authored-by: jonathanbossenger <180629+jonathanbossenger@users.noreply.github.com>

* refactor: address review feedback on EmailLogger and EmailLoggerTest

- EmailLogger: add woocommerce_email_log_enabled and woocommerce_email_log_context
  filters; normalize object_type via instanceof; use wp_hash() instead of md5();
  drop trigger_time; add :void to register(); remove duplicate @internal; switch
  to logger->log() for LoggerSpyTrait compatibility; simplify array_merge
- EmailLoggerTest: swap hand-rolled fake logger for LoggerSpyTrait; add @Covers;
  move hook teardown to tearDown(); replace real WC_Order with createMock();
  add tests for empty recipient, normalized object types, and both new filters

Agent-Logs-Url: https://github.com/jonathanbossenger/woocommerce/sessions/1be4692b-e694-4131-8c3f-48a2cd24492f

Co-authored-by: jonathanbossenger <180629+jonathanbossenger@users.noreply.github.com>

* fix: update changelog, align log source to transactional-emails, note untranslated message

- Update changelog entry: remove stale "trigger time" reference, update source name
- Change LOG_SOURCE from 'email-log' to 'transactional-emails' to align with
  existing convention in class-wc-emails.php:225
- Add comment on intentionally untranslated log message (consistent with class-wc-emails.php)
- Update test assertion source value to match new constant

Agent-Logs-Url: https://github.com/jonathanbossenger/woocommerce/sessions/3822e0af-859f-4ea4-8b39-c17d5a04567f

Co-authored-by: jonathanbossenger <180629+jonathanbossenger@users.noreply.github.com>

* fix: resolve PHPCS violations in EmailLogger and EmailLoggerTest

- Fix Squiz.Commenting.FunctionComment.SpacingAfterParamType in all @PARAM
  docblocks (both files): reduce type+spaces to 9 chars total (5/3/1 pattern
  for bool/string/WC_Email; 4/3/1 for array/string/WC_Email; 1/1/2 for
  string/string/mixed)
- Move intentional-non-translation comment above $status/$message pair so
  both assignments are in the same MultipleStatementAlignment block; double
  space in '$status  =' is now correct alignment
- Rename $object parameter to $wc_object in get_object_context() and
  create_mock_email() to clear
  Universal.NamingConventions.NoReservedKeywordParameterNames.objectFound

Agent-Logs-Url: https://github.com/jonathanbossenger/woocommerce/sessions/c8c6dfd8-5bfc-4f28-aadc-d5a6c0207fcd

Co-authored-by: jonathanbossenger <180629+jonathanbossenger@users.noreply.github.com>

* improve EmailLogger output and fix test-email send context

- Message now reads naturally: `Email "new_order" for order #29 sent`
- Failure messages include the PHPMailer reason via wp_mail_failed hook
- Recipient stored as plain address instead of hashed value
- Object context collapsed to a single typed key: `order: 29`, `user: 3`
- `email_id` context key renamed to `email_type` for clarity
- Fix EmailPreviewRestController to send via the actual WC_Email instance
  so email_type and recipient are populated correctly in test-email logs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: align EmailLoggerTest to new schema and update changelog

- EmailLoggerTest.php: update all assertions to match a9aa887 schema
  - email_id -> email_type context key
  - recipient_hash -> plain recipient (test_recipient_is_hashed removed,
    test_recipient_is_stored_plain + test_empty_recipient_produces_empty_string added)
  - object_type/object_id -> single typed key (e.g. 'order' => 42)
  - test_object_context_omitted_when_no_object checks for order/product/user keys
  - test_register_adds_hook now also asserts wp_mail_failed hook
  - tearDown removes wp_mail_failed hook to prevent bleed
  - Add test_failure_message_includes_error_reason for wp_mail_failed capture path
  - Add test_success_message_has_no_error_reason
- Changelog: drop "hashed recipient", note failure-reason capture from wp_mail_failed
- EmailLogger.php: add code comment on wp_mail_failed cross-contamination window
- EmailPreviewRestController.php: add comment explaining $email->recipient mutation

Agent-Logs-Url: https://github.com/jonathanbossenger/woocommerce/sessions/9e16277a-cb44-4552-a753-0bb2f579
9F4D
3362

Co-authored-by: jonathanbossenger <180629+jonathanbossenger@users.noreply.github.com>

* refactor: resolve recipient to username or guest instead of plain email

Avoids storing plain email addresses in the transactional email log while
still giving support teams a useful identifier. Registered users are logged
by WordPress username; addresses with no associated account log as 'guest'.
Multi-recipient strings (comma-separated) are resolved address by address.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Initial plan

* feat: track email disabled/skipped outcomes and add EmailLogger handlers

Add send_notification() protected method to WC_Email base class that
fires woocommerce_email_disabled when is_enabled() returns false, and
woocommerce_email_skipped (with reason) when no recipient is available.

Update all 16 standard trigger() methods to call send_notification()
instead of the inline is_enabled()/send() pattern. Add the already_sent
skip action to WC_Email_New_Order's duplicate-send guard.

Update EmailLogger to register and handle the two new action hooks,
logging INFO entries for disabled and skipped outcomes with the same
source, email_type, recipient, and object context as the existing
woocommerce_email_sent handler.

Add 12 new tests covering disabled/skipped log entries, status fields,
reason fields, object context, and the log_enabled filter suppression."

Agent-Logs-Url: https://github.com/jonathanbossenger/woocommerce/sessions/149fe54c-1e70-4459-a560-da1f88ffe27c

Co-authored-by: jonathanbossenger <180629+jonathanbossenger@users.noreply.github.com>

* PR fixes

* fix: rename changelog to match upstream PR number 64477

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: address review feedback on email outcome tracking

#1: Extract log_non_send_outcome() private helper in EmailLogger — both
handle_woocommerce_email_disabled() and handle_woocommerce_email_skipped()
now delegate to a single method, keeping the context schema defined in
one place.

#2: Cache get_recipient() into a local variable in send_notification() and
send_if_recipient() so the filter-running method is called only once.

#3: Add WC_Email::SKIP_REASON_NO_RECIPIENT and SKIP_REASON_ALREADY_SENT
public constants; use them in send_notification(), WC_Email_New_Order, and
all tests instead of bare strings.

#4: Extend changelog to document the restore_locale() locale-leak fix and
the instanceof WC_Order defensive guard that were bundled in the first commit.

#5: Close the manual-trigger coverage gap — add send_if_recipient() protected
helper to WC_Email that fires woocommerce_email_skipped/no_recipient without
checking is_enabled(); update WC_Email_Customer_Invoice,
WC_Email_Customer_POS_Completed_Order, and WC_Email_Customer_POS_Refunded_Order
to use it in place of the raw if(get_recipient()){send()} guards.

#6: Add unit tests for send_notification() (disabled → action fires + returns
false, no recipient → skipped action fires + returns false, both pass → send()
called with cached recipient) and for send_if_recipient() (no recipient →
skipped fires, is_enabled() false → send() still called).

#7: Tighten hook-priority assertions to assertSame(10, has_action(...)).

Agent-Logs-Url: https://github.com/jonathanbossenger/woocommerce/sessions/3a30fb52-595f-4c7f-a165-c5e6ebaeebba

Co-authored-by: jonathanbossenger <180629+jonathanbossenger@users.noreply.github.com>

* fix: PHP 7.4 compat, tearDown closure leak, split changelog entry

- Convert all five create_testable_email() call sites from named
  arguments (PHP 8.0+) to positional arguments so the test suite
  continues to pass on the PHP 7.4 CI job.

- Replace per-handler remove_action() calls in tearDown() with
  remove_all_actions() for woocommerce_email_disabled and
  woocommerce_email_skipped so that test-registered closures are
  cleaned up between tests and cannot bleed into subsequent tests.

- Split the single changelog file into two: the existing
  rsm-353-capture-email-outcomes (Type: enhancement) now covers only
  the outcome-tracking feature and the defensive instanceof guard;
  a new rsm-353-new-order-restore-locale-fix (Type: fix, Significance:
  patch) covers the restore_locale() locale-leak fix.

Agent-Logs-Url: https://github.com/jonathanbossenger/woocommerce/sessions/f6a0db0c-64a1-4fb9-8d74-66ec38bff467

Co-authored-by: jonathanbossenger <180629+jonathanbossenger@users.noreply.github.com>

* tweak: log disabled/skipped email outcomes at NOTICE

Distinguish "normal but significant" non-send outcomes from routine successful sends. Admins scanning the transactional-emails log can now filter past disabled/skipped rows without losing them in the noise of every successful send.

failed remains WARNING; sent remains INFO.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* refactor: remove already_sent skip-reason from new order duplicate guard

The duplicate-send guard in WC_Email_New_Order::trigger() intentionally
blocks a second send when resend is not allowed. Firing
woocommerce_email_skipped on that path implied the outcome was
observable and controllable the same way as a no_recipient skip, but
the underlying behaviour (silently blocking a manual resend action) is
not a scenario that should be surfaced as a loggable skip reason.

Changes:
- Remove `do_action( 'woocommerce_email_skipped', SKIP_REASON_ALREADY_SENT ... )`
  from WC_Email_New_Order::trigger() — restore_locale() stays on that
  path to keep the locale-leak fix.
- Remove the SKIP_REASON_ALREADY_SENT public constant from WC_Email.
- Update the woocommerce_email_skipped docblock in class-wc-email.php to
  remove the SKIP_REASON_ALREADY_SENT bullet point.
- Update EmailLogger::handle_woocommerce_email_skipped() docblock.
- Update two EmailLoggerTest assertions that used SKIP_REASON_ALREADY_SENT
  to use SKIP_REASON_NO_RECIPIENT instead (they were testing the handler
  behaviour with any valid reason, not the new_order path specifically).
- Update changelog entry to drop "already sent" from the skip-reason list.

Agent-Logs-Url: https://github.com/jonathanbossenger/woocommerce/sessions/68d31c0c-97c7-4bea-9ec9-397d5185dfb3

Co-authored-by: jonathanbossenger <180629+jonathanbossenger@users.noreply.github.com>

* Mark test emails in the transactional email log

Tag log entries from the email preview send-test flow with `is_test: true`
in the log context and prefix the message with "Test email" so store owners
can distinguish test sends from real transactional email attempts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Ensure temporary log filter is always removed

* Address review: bump @SInCE to 10.9.0 and drop duplicate changelog

- Update five @SInCE tags in WC_Email (SKIP_REASON_NO_RECIPIENT,
  send_notification, woocommerce_email_disabled, woocommerce_email_skipped,
  send_if_recipient) from 10.8.0 to 10.9.0 to match the actual target version.
- Remove plugins/woocommerce/changelog/64477, which duplicated the already-
  shipped entry from woocommerce#64491. This PR's specific changes are covered by the
  three rsm-353-* changelog files.

* Fix CI: stale PHPStan baseline + missing PHPCS docblocks

- phpstan-baseline.neon: drop two stale class-wc-email-new-order.php ignores
  (save / update_meta_data on WC_Order|WC_Order_Refund|false). The defensive
  instanceof guard added in rsm-353-capture-email-outcomes resolved both.
- class-wc-email.php: full docblock with @SInCE 10.9.0 on the
  woocommerce_email_skipped do_action() call inside send_if_recipient(); the
  shorthand "documented in..." form failed WooCommerce.Commenting.CommentHooks.
- EmailLogger.php: same treatment for the two "documented in..." references to
  woocommerce_email_log_enabled and woocommerce_email_log_context inside
  log_non_send_outcome().
- EmailLoggerTest.php: add docblocks + tighten property type spacing on the
  anonymous WC_Email test double helper.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jonathanbossenger <180629+jonathanbossenger@users.noreply.github.com>
Co-authored-by: Job <8783673+jobthomas@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants

0