Skip to content

Releases: phpnomad/wordpress-integration

4.3.3

12 Jun 14:05
bce8152

Choose a tag to compare

Follow-up to 4.3.2: the derived permission_callback no longer runs middleware for controllers whose HTTP method doesn't match the dispatching request. The Allow-header pass (rest_send_allow_header) checks every method registered on a route; running a sibling verb's middleware against a wrong-shaped request fired validations with null parameters — PHP warnings and unbound-placeholder database errors under WP_DEBUG. Method-mismatched checks now return true without executing the chain; real requests of that verb still run their own middleware. All consumers of 4.3.x should upgrade.

4.3.2

12 Jun 12:34

Choose a tag to compare

Fixes the derived REST permission_callback fataling requests on repeat invocation.

WordPress calls a route's permission callbacks more than once per request — at dispatch, then again for every method on the matched route while rest_send_allow_header builds the Allow header, all against the same WP_REST_Request. 4.3.1 re-ran the controller middleware chain on each call; non-idempotent middleware (e.g. ConvertCsvMiddleware) threw on the second pass and the resulting TypeError escaped catch (Exception), killing the request after the route callback had already produced a correct response. Symptom: HTTP 200 with an empty body on every middleware-bearing GET endpoint.

  • Middleware outcomes memoized per (request, controller class); repeat permission checks return the stored answer without re-running the chain
  • Per-controller keying prevents the Allow-header pass over sibling methods from clobbering the matched controller's outcome
  • catch \Throwable so middleware engine errors become a 500 WP_Error instead of a fatal

Four new regression tests. All consumers of 4.3.0/4.3.1 should upgrade.

4.3.1

12 Jun 10:58

Choose a tag to compare

Packaging hygiene: tests, CI, and tool configs are now excluded from dist archives (export-ignore); LICENSE metadata ensured. No code changes.

4.3.0

12 Jun 10:35

Choose a tag to compare

Security & hardening

  • REST permission callbacks derived from controller middleware — routes are no longer registered with permission_callback => '__return_true'. The permission gate runs the controller's own middleware chain (no contract change): 401/403 rejections surface as WP_Error, validation/existence failures keep the legacy error payload shape, and the chain runs exactly once per request. Controllers without middleware remain public. (#31, PR #38)
  • Exception messages no longer leak SQL or $wpdb->last_error — database failure messages are stable; diagnostic detail is recorded server-side via error_log at the point of failure. RecordNotFound control-flow exceptions stripped without logging. (#32, PR #37)

Requires PHP 8.0+ (WeakMap).

4.2.0

11 Jun 15:08

Choose a tag to compare

Security hardening

  • AdminScreenResolver: the four raw $_REQUEST reads now go through sanitize_key(wp_unslash(...)) via a shared helper; non-string values resolve to null. (#34, PR #35)
  • Table strategies: all table/column identifiers now use $wpdb->prepare() with the %i identifier placeholder; INFORMATION_SCHEMA's TABLE_NAME comparison is a proper %s value placeholder; removed a zero-argument prepare() call that fired _doing_it_wrong on every column sync. (#33, PR #36)

Requires WordPress 6.2+ (for the %i placeholder).

4.1.0

27 May 19:38

Choose a tag to compare

Wires WordPress to the phpnomad/chrono catalog.

What's new

WordPressClockStrategy now implements the cluster of chrono interfaces that WordPress core functions naturally fulfill:

  • ClockStrategycurrent_datetime()
  • HasTimezonewp_timezone()
  • HasLocaledetermine_locale()
  • CanFormatLocalizedDatewp_date()
  • CanFormatRelativeTimehuman_time_diff() wrapped in __('%s ago') for past instants and __('in %s') for future instants

WordPressInitializer binds the single concrete against all five interfaces via the existing array-binding pattern used by DatabaseDateAdapter.

What's not implemented (deliberately)

Stdlib-backed chrono capabilities (predicates, arithmetic, calendar boundaries, diff, parsing, non-localized format) are left to other integrations or consumer code. WordPress core has no platform-specific implementation for these, so wrapping native PHP behavior here would add no value. Pair with phpnomad/carbon-integration if you want the rest of the catalog covered — its CarbonChronoStrategy consumes the HasTimezone and HasLocale bindings this package provides.

New dependency

  • phpnomad/chrono ^1.0

Tests

WordPressClockStrategyTest covers interface membership, value passthrough, argument delegation to WordPress core functions, return shape, and directional branching in relative(). Full suite: 59 tests, 98 assertions, all green.

4.0.2

16 Apr 04:30
bf38396

Choose a tag to compare

Summary

  • use wpdb->last_error directly when get_results() returns null
  • enrich record-not-found exceptions with the actual query or update identity context
  • improve support visibility for hidden WordPress datastore failures

Included

Why

This patch came out of the Siren obligation investigation. The WordPress query layer was discarding the most useful wpdb error text and throwing unhelpful not-found exceptions in the exact places support needed more context.

4.0.1

31 Mar 15:31

Choose a tag to compare

Allow phpnomad/loader ^2.0 and phpnomad/framework ^3.0 for phpnomad/di v2.0 compatibility.

v4.0.0

31 Mar 11:32

Choose a tag to compare

Breaking Changes

  • TranslationStrategy updated for phpnomad/translate v2.0.0
    • Old: translate(string $translate, ?string $language, $context): string
    • New: translate(string $text, ?string $context = null): string and translatePlural(string $singular, string $plural, int $count, ?string $context = null): string
  • HasLanguage removed from constructor — WordPress manages locale via its own globals
  • Requires phpnomad/translate ^2.0

Bug Fixes

  • Fixed _x() call — was passing domain as context argument instead of the actual context

3.0.2

12 Jan 15:02
f49d08a

Choose a tag to compare

What's Changed

Full Changelog: 3.0.1...3.0.2