Skip to content

Make Fbp::$randomNumber private and add the missing native types - #25

Merged
loevgaard merged 1 commit into
2.xfrom
native-types-and-private-random-number
Sep 21, 2026
Merged

loevgaard merged 1 commit into
2.xfrom
native-types-and-private-random-number

Conversation

@loevgaard

Copy link
Copy Markdown
Member

Summary

The last two cleanups from the list in #16 and #24. After this, nothing in src/ is untyped, and the cookie value objects are fully immutable.

  • Fbp::$randomNumber is private. It was the only public, mutable property on the otherwise immutable Fb/Fbc/Fbp value objects, so $fbp->randomNumber = 1 bypassed withRandomNumber(). The getter and the wither already existed.
  • User::$fbc and User::$fbp are natively typed, as Fbc|string|null and Fbp|string|null. They were untyped with only a docblock, so anything could be assigned.
  • Fb::withCreationTime() takes int|\DateTimeInterface natively, instead of accepting anything and checking it with an assertion at runtime.
  • withSubdomainIndex(), withCreationTime() and withAppendix() declare static as their return type, replacing the @return static docblocks.
  • The private Parameters::normalize() helper gets mixed and a native return type.

Backwards compatibility

Intentional breaks, documented in a new section of UPGRADE-2.0.md:

  • Reading or writing $fbp->randomNumber no longer works; use getRandomNumber() / withRandomNumber().
  • Assigning anything but an Fbc/Fbp, a string or null to User::$fbc / $fbp throws a \TypeError.
  • Passing a wrong type to withCreationTime() throws a \TypeError, where it used to throw an InvalidArgumentException. The upgrade guide notes that a \TypeError is PHP's own error for a programming mistake and does not implement ExceptionInterface.

The Roave BC job is red by design.

Tests

  • Removed FbTest::it_rejects_a_creation_time_that_is_neither_an_integer_nor_a_datetime. It passed a string with a @phpstan-ignore, and only made sense for an untyped parameter; the type system enforces this now.
  • Added UserTest::it_accepts_the_cookies_as_value_objects_and_as_strings: both properties default to null, and accept value objects as well as strings, with the expected payload each time.
  • 166 tests, 100 % line coverage; PHPStan (level max), ECS, dependency analyser green; Infection MSI 95 % / covered 95 %, no new escaped mutants.

Not in this PR

Issue #20, one failing pixel stopping delivery to the rest, is still open. It was deferred on purpose and needs design decisions of its own.

The last two cleanups planned for 2.0:

- Fbp::$randomNumber was the only public, mutable property on the
  otherwise immutable cookie value objects. It is private now;
  getRandomNumber() and withRandomNumber() already existed.
- User::$fbc and User::$fbp were untyped, so anything could be assigned.
  They are Fbc|string|null and Fbp|string|null natively.
- Fb::withCreationTime() takes int|\DateTimeInterface natively instead
  of checking an untyped parameter at runtime, so a wrong type is a
  TypeError instead of an InvalidArgumentException.
- withSubdomainIndex(), withCreationTime() and withAppendix() declare
  static as their return type instead of documenting it.

The private Parameters::normalize() helper is typed as well. See
UPGRADE-2.0.md.
@loevgaard
loevgaard merged commit 9bdda98 into 2.x Sep 21, 2026
27 of 28 checks passed
@loevgaard
loevgaard deleted the native-types-and-private-random-number branch September 21, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant