+
Skip to content

Conversation

alongosz
Copy link
Member

@alongosz alongosz commented Jun 10, 2025

🎫 Issue IBX-9727

Related PRs:

Description:

TL;DR;

There are two interfaces with translatable contracts:

  • \Ibexa\Core\Base\Translatable
  • \Ibexa\Contracts\Core\Repository\Translatable
    fixed strict types there and aligned code extending them. Mostly: exceptions and validation errors.

Interesting parts

After adding strict types I've stumbled upon two "gems" spotted by PHPStan (see: 37833d8):

  • We were not instantiating ValidationError correctly inside of the BinaryBase::validateValidatorConfiguration method (binary field types), passing target as the part of $values argument instead of $target argument. It's used by strtr so the bug was harmless and invisible - superfluous value with index 0 was ignored. However if you'd placed literal '0' anywhere in the message, it would get replaced :-)
  • We passed an array to $values's value, which accepts only scalars. BlockingLimitationType would crash with Array to string conversion error in such case. This Limitation is not used anymore in the system, so it was also invisible.

The second thing spotted by PHPStan was the fact that we allow for UnauthorizedException properties which values are non-strings, but also: other scalars, Stringables (hypothetical case tbh), and nulls. This was my mistake, which was fixed and squashed into ac9304c.

While investigating those issues, I've created 2 unit test cases for easier debugging of "things" - ValidationErrorTest and UnauthorizedExceptionTest. Added them here for the future reference of how these "things" work.

Minor out of scope change: it's recommended in PHP 8 to use

get_debug_type($var)

instead of e.g.:

is_object($var) ? get_class($var) : gettype($var),

That looks more compact, however it's not 1:1, as e.g.: "integer" becomes "int". Aligned the existing test case with that change.

For QA:

Vast scope. Regression run needs to be enough.

@alongosz alongosz force-pushed the ibx-9727-translatable-strict-types branch from 2c28150 to f954065 Compare June 10, 2025 21:48
@alongosz alongosz marked this pull request as ready for review June 10, 2025 22:16
Copy link
Member Author

@alongosz alongosz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Below you can find some comments to the changes:

null,
[
'value' => $limitationValue->limitationValues,
'identifier' => $limitationValue->getIdentifier(),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

This is my best guess of what the Author meant to place here. At least it makes the most sense.

$this->setParameters(['%module%' => $module, '%function%' => $function]);

if ($properties) {
if (!empty($properties)) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Actually needs to behave the same for [] and null (discovered by test coverage).

if (!is_int($parameters['maxFileSize']) && $parameters['maxFileSize'] !== null) {
$validationErrors[] = new ValidationError(
'Validator %validator% expects parameter %parameter% to be of %type%.',
'Validator %validator% expects parameter %parameter% to be of %type% type.',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

The message actually is not grammatically correct without the type at the end (see the unit test coverage). Hopefully 🤞 it's not covered literally by behat anywhere. Are those in xliff files somewhere though?


if (count($groups) !== 1) {
throw new Exception\TypeGroupNotFound($groupId);
throw new Exception\TypeGroupNotFound((string)$groupId);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

We're using that one with both numeric IDs and string identifiers. I prefer this way instead of doing int|string on the exception class argument type.

Comment on lines +18 to +39
final class ContentFieldValidationExceptionTest extends TestCase
{
/**
* @see \Ibexa\Core\Base\Exceptions\ContentFieldValidationException::MAX_MESSAGES_NUMBER
*/
private const int MAX_MESSAGES_NUMBER = 32;

public function testTranslatableMessageValidationErrorLimit(): void
{
$errors = [];
for ($fieldId = 1; $fieldId <= self::MAX_MESSAGES_NUMBER + 1; ++$fieldId) {
$errors[$fieldId] = [
'eng-GB' => [new ValidationError("Field $fieldId error message")],
];
}
$exception = ContentFieldValidationException::createNewWithMultiline($errors);
self::assertStringEndsWith(
sprintf('- Limit of %d validation errors has been exceeded.', self::MAX_MESSAGES_NUMBER),
$exception->getMessage()
);
}
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Needed to fix ContentFieldValidationException so validation messages overflow error is an instance of ValidationError too (previously was a string), for the type consistency in the array. Hence the test double checking the logic.

],
'Expected an instance of "Ibexa\Contracts\Core\Repository\Values\Filter\FilteringSortClause", ' .
'got "integer" at position 1',
'got "int" at position 1',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

The mentioned side-effect of using get_debug_type

@alongosz alongosz force-pushed the ibx-9727-translatable-strict-types branch from 578764c to ee563bf Compare June 10, 2025 22:43
@alongosz alongosz requested a review from a team June 11, 2025 07:47
@ezrobot ezrobot requested review from Steveb-p, ViniTou, adamwojs, barw4, ciastektk, mikadamczyk and wiewiurdp and removed request for a team June 11, 2025 07:48
@alongosz alongosz force-pushed the ibx-9727-translatable-strict-types branch from 9377fb4 to b3f3870 Compare June 13, 2025 11:20
@adamwojs
Copy link
Member

@alongosz Do we need to adapt code base in other repositories, before the merge ?

@alongosz
Copy link
Member Author

@alongosz Do we need to adapt code base in other repositories, before the merge ?

@adamwojs regressions are clear, but given we like to extend things from core we shouldn't, maybe I'll run PHPStan against this branch on all repos. Just occurred to me now 😅

@alongosz alongosz force-pushed the ibx-9727-translatable-strict-types branch from b3f3870 to 19ab54a Compare June 16, 2025 11:47
Copy link

@alongosz alongosz merged commit be546a9 into main Jun 17, 2025
16 checks passed
@alongosz alongosz deleted the ibx-9727-translatable-strict-types branch June 17, 2025 16:35
alongosz added a commit to ibexa/fieldtype-richtext that referenced this pull request Jun 24, 2025
adamwojs pushed a commit to ibexa/fieldtype-richtext that referenced this pull request Jun 25, 2025
* [Tests] Fixed strict types after ibexa/core#590 changes
* [PHPStan] Removed resolved issues from the baseline
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.

8 participants

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载