Ran into an issue...user wants to put a timestamp in their body text like [12:57] - this is being seen as a token by smart_trim and all other modules that look for tokens, but long story short my error:

"smart_trim_tokens(): Argument #1 ($type) must be of type string, int given"

I went to that function which is using HOOK_tokens and see the $type is expecting a string, but if I look at the core HOOK_tokens, the $type argument is not hinted. If we remove this hint, my error goes away. All other contrib modules I looked at are not type-hinting this argument either, so I say we follow the core example which is:

function hook_tokens($type, $tokens, array $data, array $options, \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata) {}

Looks like smart_trim is hinting the $tokens argument as well, so we could remove that as well.

Issue fork smart_trim-3479519

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

porchlight created an issue. See original summary.

porchlight’s picture

Status: Active » Needs review
StatusFileSize
new591 bytes

Patch attached

dpovshed’s picture

The fix looks good!

mstrelan’s picture

Related core issue. Probably string is correct but the regex is finding ints.

mstrelan’s picture

Version: 2.2.0 » 2.x-dev

Created MR that applies to 2.x-dev branch and 2.3.1 release.

lostcarpark’s picture

Although it pains me to remove strong typing, it does seem to be necessary in this case.

I note composer is failing for "next major". I think that is probably due to Drupal 12 development, and should probably be resolved in a separate issue.

mstrelan’s picture

Trust me, I agree. You could maybe opt to use a union type of int|string|float. Also, I think D12 is broken due to drush incompatibility with Symfony 8.

csakiistvan’s picture

Assigned: Unassigned » csakiistvan

Environment

  • Drupal: 11.4.1
  • PHP: 8.5.5
  • Database: MariaDB 10.11.16
  • DDEV: v1.25.2
  • smart_trim: 2.x-dev (MR !126, branch 3479519-incorrect-type-hinting)
  • Browser: Chrome

Prerequisites

  • smart_trim and its dependency token enabled.
  • The module file declares strict_types=1, so the parameter type mismatch is enforced at call time.

Root cause

Core's token scanner returns the token type as an int when it is numeric (a token such as [12:57] yields type 12, because PHP casts numeric array keys to integers). The hook_tokens() implementation type-hinted string $type (and array $tokens), which does not match core's own hook_tokens() signature (unhinted). Under a strict caller this throws TypeError: Argument #1 ($type) must be of type string, int given.

Steps

  1. Apply the fix from MR !126: remove the string hint from $type and the array hint from $tokens in the hook_tokens() implementation, matching core's unhinted signature.
  2. Rebuild caches: ddev drush cr
  3. Trigger token generation for a text that contains a numeric token type, e.g. [12:57], so the token type reaches the hook as an integer.
  4. Observe that token generation completes without a TypeError.

Expected results

  • A numeric token type (int) is accepted by the hook_tokens() implementation.
  • Token generation completes with no TypeError.
  • Normal [entity:field-smart-trim] token replacement continues to work.

Actual results

Before the fix, passing the scanned numeric token type (int 12) into the type-hinted string $type parameter under strict_types=1 raised TypeError: Drupal\smart_trim\Hook\SmartTrimTokenHooks::tokens(): Argument #1 ($type) must be of type string, int given. After removing the $type and $tokens hints, the same numeric token type is accepted and token generation completes without error, while existing smart-trim token replacement is unaffected.


Testing produced with the assistance of an LLM.

csakiistvan’s picture

Status: Needs review » Reviewed & tested by the community
markie’s picture

Status: Reviewed & tested by the community » Needs review

Still needs community review

csakiistvan’s picture

Assigned: csakiistvan » Unassigned

ultimike made their first commit to this issue’s fork.

ultimike’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

I went ahead and updated the issue fork with latest from 2.x (we do not have a `smart_trim.tokens.inc` anymore.)

I usually prefer to type hint all method/function arguments, but since we're following an established pattern from Drupal core, I guess I'll have to get over it.

I am moving this back to "Needs work" for two reasons:

  1. This change triggers a test failure in Drupal\Tests\smart_trim\Kernel\TokenTest::testSummaryFieldTokens ("Token value for [node:body-smart-trim] was not generated.")
  2. All changes to Smart Trim require tests. So, we'll need a test to demonstrate that stuff like `[12:57] ` in the text to be smart trimmed doesn't fly off the rails due to code thinking that is a token.

-mike

peri22 made their first commit to this issue’s fork.

peri22’s picture

Status: Needs work » Needs review

I added two fixes on top of #13:

  1. Restored #[Hook('tokens')]: Without it, the hook was no longer registered, which is what broke TokenTest::testSummaryFieldTokens.
  2. Removed type hints from smart_trim_tokens(): I also removed them in smart_trim.module, because that file uses strict_types=1 and contains the function from the original bug report.

I also added a new test: TokenTest::testNumericTokenType(). It calls the hook implementations directly. This is necessary because Drupal core dispatches hooks from non-strict code (where integers are coerced into strings). By calling it directly, we can correctly reproduce and test the reported error ("TypeError: smart_trim_tokens(): Argument #1 ($type) must be of type string, int given").

Pipeline is green!

  • ultimike committed 623e2788 on 2.x authored by mstrelan
    fix: #3479519 Incorrect type hinting in the smart_trim_tokens function...
ultimike’s picture

Status: Needs review » Fixed

Thanks everybody - merged!

-mike

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.