Commit 3e7907620e5 for woocommerce

commit 3e7907620e51c5e470cf8380f1fa6d3e53024cda
Author: Vlad Olaru <vlad.olaru@automattic.com>
Date:   Thu Aug 20 18:12:26 2026 +0300

    Clarify what get_all() returns on the product and order enums (#67889)

    * docs(enums): Clarify what get_all() returns on the product and order enums

    get_all() returns every constant on its class, which for four of these enums is
    a strictly larger set than the values a product or order can actually take:
    ProductStockStatus includes lowstock, a derived reporting state that is never
    stored; ProductType includes variation, a child post type rather than a
    selectable type; ProductStatus and OrderStatus include WordPress-managed states
    such as auto-draft, trash, future and checkout-draft.

    The docblocks read as the authoritative list ("Returns all product stock status
    values"), which invites using them to populate filters or validate input. Two
    places in the codebase already work around the gap instead of trusting it — the
    Analytics stock report merges 'lowstock' in alongside
    wc_get_product_stock_status_options(), and OrderAbilityTrait merges get_all()
    with wc_get_order_statuses() — which is the boundary being rediscovered rather
    than documented.

    Say so in the docblocks and name the canonical helper where one exists. Those
    helpers are filterable, so they also reflect values an extension registered,
    which a static enum cannot.

    No behaviour change; every current caller of get_all() is correct for its
    purpose.

    * docs(enums): Correct the get_all() docblocks after review

    The first pass organised these around whether a value could be "assigned",
    which does not survive contact with the setters:

    - WC_Product::set_status() does not validate at all, and core assigns
      auto-draft and trash itself, so every ProductStatus value is assignable. The
      real distinction is who chooses the status, not whether it can be set.
    - WC_Abstract_Order::set_status() exempts auto-draft and trash from its own
      validation, so wc_get_order_statuses() is not the assignable set either.
    - Variations are creatable products whose get_type() returns 'variation'. They
      are absent from wc_get_product_types() because that lists top-level choices,
      not because they are not a real type.
    - checkout-draft was grouped with trash and auto-draft as a post-level state,
      but WooCommerce adds it to wc_get_order_statuses() through the
      wc_order_statuses filter and the Store API assigns it to live orders. It is
      the opposite of an exception to that helper.
    - Saying a stock filter should offer only the persisted statuses overreached:
      the Analytics stock report deliberately offers lowstock.

    Reframe around what each list actually is — the complete static enum versus the
    filterable, labelled set WooCommerce registers — and scope each claim to what
    was verified.

    Also record the shape mismatch the first pass omitted. get_all() returns a flat
    unprefixed string[]; all three helpers return value => label maps, and
    wc_get_order_statuses() keys on the wc- prefix, so its keys never compare equal
    to these constants without OrderUtil::remove_status_prefix(). Recommending a
    helper without that caveat invites a silent in_array() failure.

    * docs(enums): Extend the get_all() scope notes to the remaining affected enums

    Splitting these off was justified as keeping the diff tight, which is a weak
    argument for a docs-only change with no behavioural risk. Shipping four of six
    leaves the rest reading exactly as misleadingly as the ones just corrected, and
    implies the corrected four are somehow special.

    CatalogVisibility is the subtler case: get_all() returns the same four values as
    wc_get_product_visibility_options() today, so they look interchangeable. But
    that helper is filterable, returns a value => label map, and is what
    set_catalog_visibility() validates against, so a site can accept a visibility
    the enum does not list.

    OrderInternalStatus has a concrete in-core gap rather than a theoretical one: it
    has no wc-checkout-draft constant, yet WooCommerce registers that status through
    the wc_order_statuses filter and the Store API assigns it to live orders.

    WeightUnit and DimensionUnit are still left alone, now for a substantive reason
    rather than diff size. They have no companion helper, and their
    woocommerce_weight_units and woocommerce_dimension_units filters are applied at
    a single call site in the V4 settings controller. Documenting them as an
    extension point on the enum would imply a general contract that does not exist.

    * docs(enums): Qualify the OrderStatus comparison as the default status map

    wc_get_order_statuses() applies the wc_order_statuses filter, so what it returns
    is site-specific. Saying the enum carries statuses the helper "does not" read as
    an invariant, which the next sentence in the same DocBlock immediately disproves
    by noting WooCommerce adds checkout-draft through that very filter.

    Say "does not return by default" instead.

    * docs(enums): Tighten the get_all() notes and correct two claims

    Editorial pass over all six DocBlocks. Two were wrong on the facts:

    - ProductStockStatus said lowstock is "derived from stock quantity rather than
      persisted, so a query filtering the stock_status column can never match it".
      The conclusion held but the reasoning was vague and the "never" overclaimed a
      filterable surface. WC_Product::set_stock_status() actually validates against
      wc_get_product_stock_status_options() and coerces anything outside it to
      instock, which is the concrete mechanism. Better still, the Analytics low
      stock query selects rows whose stock_status is already instock, so a low-stock
      product stores instock. Say that instead.

    - ProductStatus said get_post_statuses() "omits self::FUTURE". True but
      misleadingly partial: it lists only draft, pending, private and publish, so it
      omits auto-draft and trash as well. State what it returns.

    The rest is compression. Dropped hedges that carried no information --
    "happen to", "today", "legitimately", "remains a legitimate choice" -- replaced
    "never compare equal" with the action a caller actually needs, split two
    run-on paragraphs, and cut the circular clause that explained the Analytics
    report by referring back to itself.

diff --git a/plugins/woocommerce/changelog/docs-enum-get-all-scope b/plugins/woocommerce/changelog/docs-enum-get-all-scope
new file mode 100644
index 00000000000..2def543241a
--- /dev/null
+++ b/plugins/woocommerce/changelog/docs-enum-get-all-scope
@@ -0,0 +1,4 @@
+Significance: patch
+Type: dev
+
+Document what Enums get_all() returns compared with the filterable wc_get_*() helpers, including the differing return shapes and the wc- prefix on order statuses.
diff --git a/plugins/woocommerce/src/Enums/CatalogVisibility.php b/plugins/woocommerce/src/Enums/CatalogVisibility.php
index d9c1dff8a62..aaa2e0e7d2e 100644
--- a/plugins/woocommerce/src/Enums/CatalogVisibility.php
+++ b/plugins/woocommerce/src/Enums/CatalogVisibility.php
@@ -31,7 +31,14 @@ final class CatalogVisibility {
 	public const HIDDEN = 'hidden';

 	/**
-	 * Returns all catalog visibility values.
+	 * Returns every catalog visibility value defined by this enum, as a flat list.
+	 *
+	 * These are the same four values wc_get_product_visibility_options() returns by default, which
+	 * makes the two look interchangeable. They are not. That helper returns a value => label map,
+	 * it is filterable, and WC_Product::set_catalog_visibility() validates against it, so a site can
+	 * accept a visibility this list does not contain.
+	 *
+	 * Use wc_get_product_visibility_options() wherever you validate or present a choice.
 	 *
 	 * @since 10.9.0
 	 *
diff --git a/plugins/woocommerce/src/Enums/OrderInternalStatus.php b/plugins/woocommerce/src/Enums/OrderInternalStatus.php
index fa445fd7fa9..ce0af5ad46c 100644
--- a/plugins/woocommerce/src/Enums/OrderInternalStatus.php
+++ b/plugins/woocommerce/src/Enums/OrderInternalStatus.php
@@ -59,7 +59,17 @@ final class OrderInternalStatus {
 	public const FAILED = 'wc-failed';

 	/**
-	 * Returns all internal order status values.
+	 * Returns every internal order status value defined by this enum, as a flat list of `wc-`
+	 * prefixed slugs.
+	 *
+	 * These are the seven core statuses, which is narrower than the set an order can hold. The enum
+	 * has no `wc-checkout-draft`, a status WooCommerce registers through the `wc_order_statuses`
+	 * filter and the Store API assigns to live orders during checkout. It cannot carry statuses an
+	 * extension registers either.
+	 *
+	 * For the registered statuses, use wc_get_order_statuses(), which returns a value => label map
+	 * on these same prefixed keys. OrderStatus lists a wider set of unprefixed slugs, including
+	 * WordPress post statuses such as trash and auto-draft.
 	 *
 	 * @since 10.9.0
 	 *
diff --git a/plugins/woocommerce/src/Enums/OrderStatus.php b/plugins/woocommerce/src/Enums/OrderStatus.php
index bc596091a0c..7ad84c29881 100644
--- a/plugins/woocommerce/src/Enums/OrderStatus.php
+++ b/plugins/woocommerce/src/Enums/OrderStatus.php
@@ -108,7 +108,21 @@ final class OrderStatus {
 	);

 	/**
-	 * Returns all order status values defined in this class.
+	 * Returns every order status value defined by this enum, as a flat list of unprefixed slugs.
+	 *
+	 * It differs from the statuses WooCommerce registers in both directions. It carries
+	 * self::TRASH, self::NEW, self::AUTO_DRAFT and self::DRAFT, which wc_get_order_statuses() does
+	 * not return by default, and it cannot carry statuses an extension registers.
+	 * WC_Abstract_Order::set_status() accepts self::TRASH and self::AUTO_DRAFT even so, exempting
+	 * them from its own validation.
+	 *
+	 * self::CHECKOUT_DRAFT sits on the helper's side of that line: WooCommerce adds it through the
+	 * `wc_order_statuses` filter, and the Store API assigns it to live orders during checkout.
+	 *
+	 * For the registered statuses, use wc_get_order_statuses(). It returns a value => label map
+	 * keyed on the `wc-` prefixed slug, so comparing its keys with this enum's values needs
+	 * OrderUtil::remove_status_prefix(). OrderInternalStatus lists the seven core statuses in
+	 * prefixed form.
 	 *
 	 * @since 10.9.0
 	 *
diff --git a/plugins/woocommerce/src/Enums/ProductStatus.php b/plugins/woocommerce/src/Enums/ProductStatus.php
index fa0a627e72c..7059d5838cf 100644
--- a/plugins/woocommerce/src/Enums/ProductStatus.php
+++ b/plugins/woocommerce/src/Enums/ProductStatus.php
@@ -58,7 +58,15 @@ final class ProductStatus {
 	public const FUTURE = 'future';

 	/**
-	 * Returns all product status values.
+	 * Returns every product status value defined by this enum, as a flat list.
+	 *
+	 * A product can hold any of them: WC_Product::set_status() does not validate, and core assigns
+	 * self::AUTO_DRAFT and self::TRASH itself. What separates them is who decides. WordPress sets
+	 * self::AUTO_DRAFT, self::TRASH and self::FUTURE; an author chooses the rest.
+	 *
+	 * WooCommerce has no narrower helper, and get_post_statuses() is not one: it is unfiltered and
+	 * lists only draft, pending, private and publish. Narrow this list yourself for a particular
+	 * editor or REST schema.
 	 *
 	 * @since 10.9.0
 	 *
diff --git a/plugins/woocommerce/src/Enums/ProductStockStatus.php b/plugins/woocommerce/src/Enums/ProductStockStatus.php
index 065e80a397c..b24afeef82d 100644
--- a/plugins/woocommerce/src/Enums/ProductStockStatus.php
+++ b/plugins/woocommerce/src/Enums/ProductStockStatus.php
@@ -37,7 +37,17 @@ final class ProductStockStatus {
 	public const LOW_STOCK = 'lowstock';

 	/**
-	 * Returns all product stock status values.
+	 * Returns every stock status value defined by this enum, as a flat list.
+	 *
+	 * It is wider than the set of statuses products store. self::LOW_STOCK is a reporting
+	 * aggregate: the Analytics stock report counts in-stock products whose quantity has fallen to
+	 * their low-stock threshold, so a low-stock product stores self::IN_STOCK. That report adds
+	 * self::LOW_STOCK to its own enum for exactly that reason.
+	 *
+	 * WC_Product::set_stock_status() coerces anything outside wc_get_product_stock_status_options()
+	 * to self::IN_STOCK, so use that helper for values you intend to store or filter on. It returns
+	 * a value => label map rather than a list, and being filterable it also carries statuses an
+	 * extension added.
 	 *
 	 * @since 10.9.0
 	 *
diff --git a/plugins/woocommerce/src/Enums/ProductType.php b/plugins/woocommerce/src/Enums/ProductType.php
index a46489f0254..52ab813c7a5 100644
--- a/plugins/woocommerce/src/Enums/ProductType.php
+++ b/plugins/woocommerce/src/Enums/ProductType.php
@@ -44,7 +44,15 @@ final class ProductType {
 	public const VARIATION = 'variation';

 	/**
-	 * Returns all product type values.
+	 * Returns every product type value defined by this enum, as a flat list.
+	 *
+	 * It includes self::VARIATION. Variations are real, creatable products, and
+	 * WC_Product_Variation::get_type() returns this value, but each belongs to a parent rather than
+	 * standing on its own.
+	 *
+	 * For the top-level types a merchant can pick, use wc_get_product_types(). It returns a
+	 * value => label map rather than a list, and being filterable it also carries types an
+	 * extension registered.
 	 *
 	 * @since 10.9.0
 	 *