Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
77247a8
Update packages
ahegyes Nov 12, 2026
5a2aa9d
Test that a creator's existing order survives a refused child
ahegyes Nov 12, 2026
22274aa
Refuse a creator's order that is the parent or already linked
ahegyes Nov 12, 2026
9d73321
Test that a link whose child is not saved leaves no half link
ahegyes Nov 12, 2026
0d2b654
Save a link's child first and its parent only once it reads back
ahegyes Nov 12, 2026
3573638
Test that a tree walk stops at an order it has visited
ahegyes Nov 12, 2026
57cba3b
Stop each tree walk at an order it has visited
ahegyes Nov 12, 2026
1209548
Test that an order deleted for good leaves its children as roots
ahegyes Nov 12, 2026
b2cedaf
Make the children of an order deleted for good roots of their trees
ahegyes Nov 12, 2026
c286e9b
Test that an update repairs the links v1 left inconsistent
ahegyes Nov 12, 2026
48a696c
Repair v1's orphaned and half links in a batched migration step
ahegyes Nov 12, 2026
bce1061
Test that a child is created only by a user who may edit that order
ahegyes Nov 12, 2026
390d5ec
Check the order's own edit capability before creating its child
ahegyes Nov 12, 2026
159ba71
Test that rows read their own links and completion passes once
ahegyes Nov 12, 2026
a839ea1
Read each row's own links and complete each order once per pass
ahegyes Nov 12, 2026
466203d
Test that new-tab links announce it and the depth filter is named
ahegyes Nov 12, 2026
dbdc437
Announce new-tab links and name the depth filter
ahegyes Nov 12, 2026
a7caa2d
Test the admin copy that says what changed and why
ahegyes Nov 12, 2026
639f6ef
Say why a child cannot be created and which filter the list shows
ahegyes Nov 12, 2026
a7e2d90
Test the v1 behaviors the port changed without a ruling
ahegyes Nov 12, 2026
700aa02
Restore the v1 behaviors the port changed without a ruling
ahegyes Nov 12, 2026
3e22ec7
Test that the plugin row keeps v1's link keys and labels
ahegyes Nov 12, 2026
1badd8b
Key and label the plugin row's links as v1 did
ahegyes Nov 12, 2026
f4bedb4
Test that a v1 field's own id names its option
ahegyes Nov 12, 2026
d620258
Keep a v1 field's own id in the get_group_fields bridge
ahegyes Nov 12, 2026
b08b0c2
Die through an exception a redirect cannot raise in the nonce row
ahegyes Nov 12, 2026
471b34f
Give the Integration suite WordPress's admin memory ceiling
ahegyes Nov 12, 2026
9bc6d4e
Share the test harness each class copied
ahegyes Nov 12, 2026
0c93d30
Restore the shared site in finally after each destructive row
ahegyes Nov 12, 2026
780103d
Cover other order types, the asset gate and the allowed depth
ahegyes Nov 12, 2026
7e80911
Check that v1 hook listeners hand their values to the v2 names
ahegyes Nov 12, 2026
fcc0559
Pin the WooCommerce floor in the readme's prose
ahegyes Nov 12, 2026
e0e73f6
Wait for the child's own editor and set the depth the spec reads
ahegyes Nov 12, 2026
84f4a1c
Keep only the types PHPStan needs in the order-number fixtures
ahegyes Nov 12, 2026
58623cd
Bring Linked Orders' layout and idioms to the ruled forms
ahegyes Nov 12, 2026
e782b5f
Cut Linked Orders' docblock summaries to their roles
ahegyes Nov 12, 2026
7a7f2c4
Name the link meta keys and the add-child action as constants
ahegyes Nov 12, 2026
e416d8e
Keep the settings section's id inside its class
ahegyes Nov 12, 2026
800596f
Record the v1 breaks the changelog and readme left out
ahegyes Nov 12, 2026
70416f7
Fit Linked Orders' docs to the plugin they describe
ahegyes Nov 12, 2026
730f774
Query a link key on either storage through one helper
ahegyes Nov 12, 2026
b6d83ee
Fire the runner's hook before checking the stored revision
ahegyes Nov 12, 2026
58f9e2b
Audit only Linked Orders' depth filter in the list's axe pass
ahegyes Nov 12, 2026
9068fed
Test wording that fits every order type Linked Orders links
ahegyes Nov 12, 2026
a963705
Word the admin for whichever order type is linked
ahegyes Nov 12, 2026
559b18f
Start the revision row from the revision before the batched step
ahegyes Nov 12, 2026
4307177
Keep one label key and word the autocompletion note truly
ahegyes Nov 12, 2026
b5d9610
Name the plugin in the autocompletion note, not an ancestor
ahegyes Nov 12, 2026
4bbc634
Test v1's hook-tag builders and numbering without v1's edge cases
ahegyes Nov 12, 2026
fe270b7
Drop v1 edge-case reproduction and single-use constants
ahegyes Nov 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"name": "ahegyes/wordpress-plugins",
"description": "Plugins built on the wp-framework packages are developed side by side here, so a change that crosses plugins lands and is tested in one place, while each plugin still ships from a mirror of its own.",
Expand All @@ -23,7 +23,7 @@
"php": ">=8.5"
},
"require-dev": {
"wp-plugin/woocommerce": "^11.2"
"wp-plugin/woocommerce": "^11.3"
},

"minimum-stability": "dev",
Expand Down
12 changes: 6 additions & 6 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions plugins/internal-comments/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@
"johnpbloch/wordpress-core": "^7.1",
"laravel/serializable-closure": "^2.2",
"php-di/php-di": "^7.1.1",
"php-stubs/woocommerce-stubs": "^11.2",
"php-stubs/woocommerce-stubs": "^11.3",
"phpunit/phpunit": "^13",
"pronamic/changelog-md-to-wordpress-plugin-readme-txt": "^1.0",
"wp-plugin/woocommerce": "^11.2"
"wp-plugin/woocommerce": "^11.3"
},

"minimum-stability": "dev",
Expand Down
47 changes: 25 additions & 22 deletions plugins/internal-comments/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions plugins/internal-comments/internal-comments.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
* Version: 2.0.0
* Requires at least: 7.1
* Requires PHP: 8.5
* WC requires at least: 11.2
* WC tested up to: 11.2
* WC requires at least: 11.3
* WC tested up to: 11.3
* Author: Contributors
* Author URI: https://github.com/ahegyes
* License: GPL-3.0-or-later
Expand Down
2 changes: 1 addition & 1 deletion plugins/internal-comments/readme.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
=== Internal Comments ===

Check notice on line 1 in plugins/internal-comments/readme.txt

View workflow job for this annotation

GitHub Actions / readme.txt lint (internal-comments)

[donate-link] Consider adding a donate link to support the plugin
Contributors: ahegyes, deepwebsolutions
Tags: internal comments, private comments
Tested up to: 7.1
Expand Down Expand Up @@ -27,7 +27,7 @@

== Installation ==

There are no prerequisites other than the minimum WordPress and PHP versions. Internal comments on WooCommerce orders need WooCommerce 11.2 or newer.
There are no prerequisites other than the minimum WordPress and PHP versions. Internal comments on WooCommerce orders need WooCommerce 11.3 or newer.

### INSTALL FROM WITHIN WORDPRESS

Expand Down
24 changes: 12 additions & 12 deletions plugins/linked-orders-for-woocommerce/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ src/ the composition root and its components only
├── MetaBox.php the parent, children and add-child button beside an order's editor, on either storage
├── ListTable.php the orders list's depth column, filters and row actions, on either storage
├── Autocompletion.php completes an order's descendants when it completes, where the setting is on
├── OrderDeletion.php makes the children of an order deleted for good the roots of their trees
└── Integration/ SequentialOrderNumbersPro, gated on wc_seq_order_number_pro()
models/DWS_Order_Node.php v1's global node class on the classmap, reading and saving the _dws_lo_ order meta
includes/ hook-free code as dws_lowc_ functions and DWS_LOWC_ constants, loaded in name order, _-prefixed files skipped
├── safeguards.php restrictions that hold whenever the plugin cannot boot; loaded by the entry before the floor check
├── safeguards.php an empty slot for restrictions that hold whenever the plugin cannot boot; loaded by the entry before the floor check
├── capabilities.php v1's four capabilities and the roles CapabilityGrants gives them
├── options.php v1's option keys, their defaults and the depth validator
├── settings.php v1's settings API: the raw, validated and validating reads, by v1 field id and group
Expand All @@ -45,7 +46,7 @@ composer test:integration:multisite # starts .wp-env.multisite.json, then runs
composer quality-check # manifest and changelog validation, PHPCS (both profiles), PHPStan (both profiles), Unit and Integration
composer changelog:add # stages an entry in changelog/, which the release step in the monorepo's CONTRIBUTING.md writes
npm run setup # both installs, the scripts' build, then the development site
npm run build # the orders list's assets through the local wp-scripts; npm run start watches them in a POSIX shell
npm run build # the orders list's assets through the local wp-scripts; npm run start watches them
npm run lint:scripts # ESLint, beside lint:styles (Stylelint) and lint:types (tsc)
npm run test:e2e # Playwright on .wp-env.tests.json, starting it if needed; the scripts must be built
```
Expand All @@ -63,19 +64,18 @@ Each runs PHP 8.5 with WooCommerce from `vendor/` and its order tables on; CI ru
## Conventions

1. **Placement.** `src/` holds only the composition root and its components. Code that registers no hooks, such as keys, readers, v1's helper API, the footprint, migration steps and asset registrars, is `dws_lowc_` functions and `DWS_LOWC_` constants in `includes/`, which parses on PHP 7.4: no `mixed` or union types, typed constants, `match`, nullsafe calls or first-class callables there. `DWS_Order_Node` keeps v1's global name in `models/`, outside that limit. Container definitions are composition and stay in `Plugin::get_definitions()`.
2. **Variants.** A component that exists only in one build variant is a child in a branch of its parent's `get_child_component_classes()`, never a second entry in `COMPONENTS`.
3. **Request context.** `is_admin()` is false on REST requests and true in admin-ajax ones, so an admin-only feature decides the request context in its callbacks, never in `should_load()`.
4. **Add-ons.** An add-on extends a base plugin only through the base plugin's documented hooks. It reads a template-built base plugin's slug, name and version only through that plugin's `{prefix}_get_plugin_*()` getters, from `plugins_loaded` on, since the add-on may load first, and behind `function_exists()`, since a base plugin below its floors or with a partial build may stay active without defining them.
5. **Request reads.** An integer or boolean is read as `filter_var( wp_unslash( $_POST['key'] ?? '' ), FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE ) ?? $default` (`FILTER_VALIDATE_BOOL` for a boolean, where an absent key reads false, as an unchecked checkbox posts nothing), and a string through an `is_string()` guard and the field's sanitizer; never `filter_input()`, the `default` filter option or a cast on request input.
6. **Options and data.** A setting is read through v1's API in `includes/settings.php`, whose validation is each setting's one typed read and whose reads apply v1's filters, safeguards excepted. v1's settings keep their `dws-lowc_` keys and its order links their `_dws_lo_` meta; anything new lives under `dws_lowc_`, or `_dws_lowc_` for hidden meta. The footprint covers those prefixes and v1's other rows by name.
7. **Order storage.** Order code goes through WC CRUD, `get_edit_order_url()` and WooCommerce's screen ids and list hooks, never the posts table, and every Integration row whose outcome the order storage can change runs on all four storages through `OrderStorageTrait`: posts and the order tables, each with the sync on and off. Rows that check only the order of hooks, or a stand-in plugin, use one.
8. **v1 hooks.** A hook v1 fired keeps its v1 literal, fired first through `apply_filters_deprecated()` or `do_action_deprecated()` with `'2.0.0'` and the v2 name, then the v2 name, and `DeprecatedHooksTest` names the pair.
9. **Safeguards** live in `includes/safeguards.php`, call only WordPress and that file, and relax only through their own filter, through `dws_lowc_is_relaxed()` (the template's recipes). The entry loads them before the floor check, so they parse on PHP 7.4 and call only WordPress APIs present at the oldest WordPress the bootstrap package runs on, or guard them, which `phpstan.safeguards.neon` checks.
10. **Migrations** are append-only: a step converges from any partial state, verifies its writes and throws when one fails.
2. **Request context.** `is_admin()` is false on REST requests and true in admin-ajax ones, so an admin-only feature decides the request context in its callbacks, never in `should_load()`.
3. **Add-ons.** An add-on extends a base plugin only through the base plugin's documented hooks. It reads a template-built base plugin's slug, name and version only through that plugin's `{prefix}_get_plugin_*()` getters, from `plugins_loaded` on, since the add-on may load first, and behind `function_exists()`, since a base plugin below its floors or with a partial build may stay active without defining them.
4. **Request reads.** An integer or boolean is read as `filter_var( wp_unslash( $_POST['key'] ?? '' ), FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE ) ?? $default` (`FILTER_VALIDATE_BOOL` for a boolean, where an absent key reads false, as an unchecked checkbox posts nothing), and a string through an `is_string()` guard and the field's sanitizer; never `filter_input()`, the `default` filter option or a cast on request input.
5. **Options and data.** A setting is read through v1's API in `includes/settings.php`, whose validation is each setting's one typed read and whose reads apply v1's filters, safeguards excepted. v1's settings keep their `dws-lowc_` keys and its order links their `_dws_lo_` meta; anything new lives under `dws_lowc_`, or `_dws_lowc_` for hidden meta. The footprint covers those prefixes and v1's other rows by name.
6. **Order storage.** Order code goes through WC CRUD, `get_edit_order_url()` and WooCommerce's screen ids and list hooks, never the posts table, and every Integration row whose outcome the order storage can change runs on all four storages through `OrderStorageTrait`: posts and the order tables, each with the sync on and off. Rows that check only the order of hooks, or a stand-in plugin, use one.
7. **v1 hooks.** A hook v1 fired keeps its v1 literal, fired first through `apply_filters_deprecated()` or `do_action_deprecated()` with `'2.0.0'` and the v2 name, then the v2 name, and `DeprecatedHooksTest` names the pair.
8. **Safeguards.** `includes/safeguards.php` holds none yet. A safeguard added there follows the template's safeguard recipe: the entry loads the file before the floor check, so it parses on PHP 7.4 and calls only what its hook hands it, WordPress APIs present at the oldest WordPress the bootstrap package runs on and WooCommerce APIs present since 3.6, guarding anything newer, which `phpstan.safeguards.neon` checks for WordPress. A safeguard that calls WooCommerce is hooked from the file's one `woocommerce_loaded` callback, and it relaxes only through its own filter, with an explicit `false`, after `dws_lowc/boot/succeeded`.
9. **Migrations** are append-only: a step converges from any partial state, verifies its writes and throws when one fails.

## Contract

The plugin's contract is the elements tagged `@api`, the hooks it fires, and its option, meta and capability names and REST routes; breaking it ships as the next major. Every other function, constant and class, `src/` included, is internal and changes in any release.
The plugin's contract is the elements tagged `@api`, the hooks it fires, its option, meta and capability names and REST routes, and the `linked_orders_for_woocommerce_add_new_child` label an order type sets for it; breaking it ships as the next major. Every other function, constant and class, `src/` included, is internal and changes in any release.

## Style

Expand Down
2 changes: 1 addition & 1 deletion plugins/linked-orders-for-woocommerce/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Pending entries live in [`changelog/`](./changelog) — add via `composer change
## 2.0.0 - unreleased

### Changed
- Rebuilt on the v2 framework, which boots the plugin only where its floors and WooCommerce are met and otherwise shows a notice.
- Rebuilt on the v2 framework, which boots the plugin only where its floors and WooCommerce are met and otherwise shows a notice. The plugin grants its capabilities by itself, so v1's install and update notice and its AJAX actions are gone.

## 1.2.2 - 2022-07-12

Expand Down
Loading
Loading