* fix: address WordPress.org plugin review feedback
- Prefix the session transaction queue transient with the plugin's
graphql_woocommerce_ namespace instead of the generic "woo_" word, to
avoid collisions (Plugin Directory: prefix data storage).
- Declare the WooCommerce dependency via the "Requires Plugins: woocommerce"
plugin header.
- Bump README.txt "Tested up to" to 7.0.
- Ship composer.json in the distributed plugin (drop it, and composer.lock,
from composer archive excludes) so the build is reproducible/reviewable.
* chore: rename plugin to "GraphQL for eCommerce" for trademark compliance
The WordPress.org plugin review flagged the display name/slug for beginning
with the "WPGraphQL" trademark (and the "WooGraphQL" portmanteau of the
WooCommerce mark), which can imply official affiliation.
- Display name (plugin header + readme title) -> "GraphQL for eCommerce".
- Slug/text domain -> "graphql-for-ecommerce" (header, all i18n string
literals, and the PHPCS WordPress.WP.I18n text_domain config).
- Update user-facing notices/errors that named the old plugin.
"WooGraphQL" remains the project's informal nickname (repo, docs, community),
just not in the WordPress.org directory's official name/slug. Internal file
names and GitHub URLs are unchanged.
* fix: keep test-only dev deps out of the committed composer.json
The committed manifest mirrors develop (lint/stan dev deps only); CI adds the
test suite deps at runtime via `composer installTestEnv`. A previous commit
captured the installTestEnv-modified composer.json, desyncing it from
composer.lock and breaking `composer install` in CI.
* chore: regenerate composer.lock (refresh dev dependencies)
Regenerate the lock from the manifest so it is in sync (fixes the CI
`composer install` failure) and refresh dependencies in the process —
firebase/php-jwt v7.0.4 -> v7.1.0 plus 11 others, with vendor-prefixed
re-strauss'd to match. Full wpunit suite passes against the updated deps
(305 tests, 835 assertions).
* chore: rename text domain in createdVia/attribution strings from #1018#1018 (createdVia + order attribution) merged into develop after the rename
commit was authored, so its new i18n strings still used the old
'wp-graphql-woocommerce' text domain. Update them to 'graphql-for-ecommerce'
to match the rename.
* fix: session secret key, cart session persistence, null variation attributes
- Use wp_salt() as fallback secret key instead of hardcoded 24-byte string
to satisfy php-jwt v7's HS256 minimum key length requirement (Closes#1009)
- Call get_cart_from_session() after wc_load_cart() in
initialize_session_and_cart() to prevent cart queries from clearing
persisted session data (Closes#1010)
- Guard against null $attrs in variation_attributes_to_data_array()
to prevent PHP warnings when variations have no attributes (Closes#1011)
- Return empty array instead of null for product attribute options
when no terms exist
* chore: Linter compliances met
* fix: Elementor breaks transfer-session endpoint with 500 error
Elementor's LandingPages module creates a WP_Query during `init` which
fires `pre_get_posts` before WooCommerce session is initialized. Our
resolve_request handler ran on this early query and called
WC()->session->get_customer_id() on null, causing a fatal error.
Fix: Guard resolve_request to only run on the main front-end query and
bail if WC session is not yet initialized. Also add Elementor to the
test environment and add functional tests that reproduce the issue.
Closes#945
* chore: Add @param docblock for resolve_request $query parameter
* devops: Remove unused resolvers and add session transaction manager tests
Remove Coupon_Connection_Resolver and Customer_Connection_Resolver
which had 0% coverage and were never instantiated.
Add SessionTransactionManagerTest covering did_transaction_expire
edge cases and next_transaction invalid/expired queue handling.
* feat: WC Settings API, compatibility refactor, HPOS fix, CI improvements
WC Settings GraphQL API:
- Add WCSetting interface with common fields and type-safe resolveType
- Add concrete types: WCStringSetting, WCArraySetting, WCRelativeDateSetting,
WCImageWidthSetting with typed value/default fields
- Add WCSettingGroup type with nested settings field
- Add wcSettingGroups and wcSettings root query fields (admin only)
- Add updateWCSetting and updateWCSettings mutations
- Dynamic WCSettingTypeEnum collected from registered WC settings
- Filters: graphql_woocommerce_setting_type_map, graphql_woocommerce_setting_types
- Register WC admin settings for GraphQL requests via Compatibility class
Compatibility refactor:
- Consolidate ACF, JWT Auth, and QL Search filters into Compatibility class
- Remove class-acf-schema-filters.php, class-jwt-auth-schema-filters.php, functions.php
HPOS compatibility fix:
- Replace hardcoded directory name check with dirname(__DIR__) === WP_PLUGIN_DIR
- Works with any plugin folder name while still skipping nested vendor installs
CI improvements:
- Remove STRIPE_API_PUBLISHABLE_KEY restriction from coverage job
- Add HPOS to coverage matrix entries
- Sort type registry and includes alphabetically
Other fixes:
- Fix Settings_Mutation::validate_setting_checkbox_field to be static
- Update ShippingZone settings field type to WCStringSetting
Closes#864, closes#969
* refactor: Rename and split core classes, add order cursor pagination tests
Class renames:
- WooCommerce_Filters → WooCommerce (class-woocommerce.php), setup() → init()
- Core_Schema_Filters → Post_Types (class-post-types.php)
Class split:
- Extract taxonomy registration from Core_Schema_Filters into Taxonomies (class-taxonomies.php)
Access functions:
- Add wc_graphql_resolve_product_type() for interface resolveType callbacks
- Add wc_graphql_is_session_handler_disabled()
- Add wc_graphql_enabled_authorizing_url_fields()
- Add wc_graphql_get_authorizing_url_nonce_param_name()
- Replace direct class references with global functions in type-registry,
compatibility, protected-router, and all product interface files
Stripe gateway compatibility:
- Move woographql_stripe_gateway_args from WooCommerce to Compatibility class
- Rename to woocommerce_gateway_stripe_args
Tests:
- Add OrderCursorPaginationTest (6 tests) covering COT cursor-based
pagination: forward/backward, date ordering ASC/DESC, cursor integrity
* fix: Use proper expectedField/expectedNode assertions in cursor pagination tests
Replace empty assertQuerySuccessful([]) calls and manual lodashGet
assertions with expectedField, expectedNode, and not()->expectedNode()
for proper GraphQL response validation.
* feat: add authenticated download URLs for headless frontends
- Add downloadNonce and downloadUrl fields to DownloadableItem type
using the existing Protected Router session transfer pattern
- Add preAuthDownloadUrl field (toggleable via settings) that generates
tokenized download URLs for direct file access without cookie auth
- Add download_url nonce handling to Protected_Router
- Add enable_pre_auth_download_urls and download_url_nonce_param settings
- Add GraphQLE2E helpers for checkout and account shortcode pages
- Rewrite ProtectedRouterCest to test redirect flow without JS-dependent
page content assertions, add account and payment method URL tests
- Add DownloadableItemAuthCest with 5 e2e tests covering both options
* fix: test suite stability and code coverage collection
- Add WC_Unit_Tests_Bootstrap stub to wpunit bootstrap to bypass
wc_get_product_visibility_term_ids static cache between suites
- Add setWooGraphQLSetting helper to GraphQLE2E for safe individual
field updates to woographql_settings option with proper defaults
- Update all functional tests to use setWooGraphQLSetting instead of
replacing the entire woographql_settings option
- Fix createRelated factory to use explicit shared category instead
of relying on default Uncategorized category
- Add download_url to ProtectedRouterTest nonce names assertion
- Remove debug logs from ProductQueriesTest and ProductsQueriesTest
- Fix CI workflow to run suites separately and aggregate coverage
via phpcov merge
- Wire c3.php into WordPress index.php for remote coverage collection
- Update .coveralls.yml service_name to github-actions
- Clean up Xdebug 2 settings in Dockerfile
* chore: Linter compliances met
* fix: ensure tests/_output is writable for c3.php coverage collection
* devops: .env.docker removed from setup
* devops: split CI into separate jobs per suite with retry and coverage aggregation
* devops: add +Coverage indicator to CI job names
* devops: add --fail-fast to first run, fix retry to mark job as passing on retry success
* fix: improve i18n compatibility for WPML, Polylang, and non-latin character support
- Add Label::get_safe_enum_name() utility with optional transliteration
for non-latin tax class/attribute/taxonomy names (#637, #409)
- Add "Transliterate non-latin characters" admin setting
- Replace get_page_by_path() with WP_Query for product slug resolution
so WPML/Polylang can hook into the standard query pipeline (#403, #368)
- Split product connections: `products` (toType: Product) and
`productsWithVariations` (toType: ProductUnion) so i18n plugins can
register language where args on the standard type name (#811, #952)
- Add ProductTypesWithVariationsEnum for the ProductUnion connection
- Add i18n compatibility tests
* chore: Linter compliances met
Adds a new "Session Transfer Behavior" setting to the WooGraphQL
settings page that controls how cart/session data is handled when
a user logs in with an existing session from another device:
- keep_new_fallback_old (default): keeps current guest session data,
falls back to previously saved user session if guest data is empty
- keep_new: always keeps the current guest session data
- keep_old: restores the previously saved user session data
* fix: resolve REQUEST_URI fatal error and JWT key length issues in CI
QLSessionHandlerTest::tearDown() was calling unset($_SERVER) which
destroyed the entire superglobal. WordPress cron.php then fataled on
shutdown when accessing $_SERVER['REQUEST_URI']. Changed to only unset
the specific HTTP_WOOCOMMERCE_SESSION key.
Also updated JWT secret keys to meet firebase/php-jwt v7's minimum
32-byte requirement for HS256 in both test config and Docker entrypoint.
* fix: the rest of the files added
* devops: php7.4 removed from matrix
* chore: Linter compliances met
* devops: More broken test updated
* devops: Tests updated for CI
* fix: QLSessionHandlerCest fixed
* fix: QLSessionHandlerCest fixed
* devops: CI fixed
* feat: Add Store API Cart-Token compatibility and session handler improvements
* chore: Linter compliances met
* chore: linter compliances met
* chore: linter compliances met
* feat: QL Session Handler functionality expanded to support cookies on non-GraphQL requests
* chore: Linter and PHPStan compliance met
* devops: QLSessionHandlerTest patched for suite testing
* chore: Linter and PHPStan compliance met
* fix: More cart session save triggered implemented
* fix: More cart session save triggered implemented
* chore: Linter compliance met
* chore: Linter compliance met
* feat: forgetSession mutation added
* feat: forgetSession mutation added
* dev!: namespace Composer dependencies with strauss
* chore: include vendor-prefixed when stanning
* Strauss configurations properly applied. Contribution docs restored.
* Linter and PHPStan compliance met
* `platform` removed from `composer.json`
* devops: PHP7.3 removed from CI matrix
---------
Co-authored-by: Geoff Taylor <geoff@axistaylor.com>
* chore: avoid magic constants [PHPCS]
* chore: change ruleset to wp-graphql-cs and lint
* devops: HPOS added back to CI with the release of WC 3.9
---------
Co-authored-by: Geoff Taylor <geoff@axistaylor.com>
* Added noop for set_customer_session_cookie.
* fixup! Added noop for set_customer_session_cookie.
---------
Co-authored-by: Andres A <andres@Andress-MBP.home>
There are instances where a stale transaction stays around do to an error in the mutation. As a result, the recursive update_transaction_queue method will continue to run over and over, causing an inifinte loop and potentially crashing the server.
This attempts to add a timestamp once the transaction is validated when checking via the timestamp and will remove it from the queue.
The customer id is stored in the the session_handler instance. As a result the same transient was getting set for all users, which was causing errors when a hanging transaction was left.