Automated PHP stubs for Woo extensions

WooCommerce uses PHPStan along with a number of other tools for testing, linting, and static analysis. However code that interacts with other extensions can be skipped or baselined when their classes and methods aren’t available to the analyzer.

To ensure that any integration between Woo plugins is proper and doesn’t break with future changes, PHPStan needs to know the shape of classes and methods. Otherwise, you end up with class.notFound errors and no way to verify it works as it should. Enter PHP stubs.

We’re introducing woocommerce/php-stubs, a new package that auto-generates PHP stubs for Woo extensions, both from the WooCommerce Marketplace and WordPress.org, so PHPStan can check calls into other extensions instead of skipping them. The stubs are public on GitHub and Packagist.

If you develop a plugin or theme that integrates with Woo extensions, you can use the same stubs to check those integrations without installing every extension in your analysis environment.

Why we built it

Even though we’re making this widely available to developers building on Woo, the truth is, we needed it for ourselves.

  • Integration code had no checks. PHPStan can’t check a call to a class it doesn’t know, so the code was skipped or baselined.
  • Hand-written stubs go stale. A number of extensions each had their own, but they were stale against the latest versions.
  • Version matters. Checks need to be against the minimum version requirement, not the latest release, otherwise it can call a method that older sites don’t have.

What’s included

The public package includes the first release of each of the newest 10 minor versions (x.y.0) and the newest release. A patch release stays only while it’s the newest.

  • Woo-owned paid plugins from the WooCommerce Marketplace.
  • Free Woo-owned WordPress.org plugins.
  • Third-party Marketplace extensions whose developers opt in to public stubs.
  • A supplement for WooCommerce internals that php-stubs/woocommerce-stubs skips. It picks the supplement matching your installed WooCommerce stubs automatically.

The stubs are generated from each extension’s release using php-stubs/generator: functions, classes, interfaces, traits, enums, and constants. New releases are published automatically – paid plugins within an hour, free plugins daily.

How to use it in your repo

Require the public package next to the WooCommerce stubs:

composer require --dev woocommerce/php-stubs:dev-trunk php-stubs/woocommerce-stubs

Include the plugins you integrate with in phpstan.neon.dist. Pin the minimum version you support, always an x.y.0 release. Use latest.neon when you don’t declare a minimum.

includes:
    # Minimum supported version: move the pin together with the minimum.
    - vendor/woocommerce/php-stubs/stubs/woocommerce-bookings/3.10.0.neon
    # No minimum declared: newest release.
    - vendor/woocommerce/php-stubs/stubs/woocommerce-subscriptions/latest.neon
    # WooCommerce internals: matches your installed stubs automatically.
    - vendor/woocommerce/php-stubs/supplements/woocommerce-internal.php

If your code checks plugin versions, add each plugin’s version constant to PHPStan’s dynamicConstantNames. A stub defines it with one release’s value, which would otherwise make version_compare() guards look constant.

The stubs are plain PHP, so Phan, Psalm, and IDEs can read them too. The package README explains which files to load.

Add stubs for your extension

Marketplace extension developers can opt in by adding this line to the main plugin file header in their next release:

 * Woo Stubs: public

That release’s stubs will then be generated and published. If you need stubs for another WordPress.org plugin, open an issue in the repository with information about the plugin and integration you want to check.

I’d like to see this used across more repos, as this can catch cross-plugin integration bugs that might otherwise go unnoticed. If you need help setting this up, open an issue.


Leave a Reply

Your email address will not be published. Required fields are marked *