Skip to content

[12.x] Add whenJson/whenNotJson methods #55581

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 24 additions & 0 deletions src/Illuminate/Support/Stringable.php
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,30 @@ public function whenIsAscii($callback, $default = null)
return $this->when($this->isAscii(), $callback, $default);
}

/**
* Execute the given callback if the string is a valid JSON string.
*
* @param callable $callback
* @param callable|null $default
* @return static
*/
public function whenJson($callback, $default = null)
{
return $this->when($this->isJson(), $callback, $default);
Copy link
Contributor

Choose a reason for hiding this comment

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

To allow for the higher order functions that the when method is capable of, I suggest changing this to:

return $this->when($this->isJson(), ...func_get_args());

This allows the func_num_args() call in when to properly pick up $callback or $default being used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I'm not quite following what you're trying to say. The method parameters and parameters passed to the when function are the same as whenEmpty and whenNotEmpty.

Copy link
Contributor

Choose a reason for hiding this comment

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

Nevermind. I didn't realize the rest of Stringable is doing the same as you suggested...

Copy link
Contributor

@AndrewMast AndrewMast Apr 28, 2025

Choose a reason for hiding this comment

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

@tomirons Considering the rest of the Stringable class, you should discard what I was saying. But to clarify what I meant:

When only one method is provided to the when (the condition, in this case, $this->isJson()), a HigherOrderWhenProxy instance is returned. This allows for method calls such as $conditionableObject->when(true)->prepend('key.')->unless(false)->append('.key'); or something like that. It also allows for $object->when()->methodThatReturnsTrue()->doThis(); (also with properties).

When doing $this->when($this->isJson(), $callback, $default);, it forces 3 arguments no matter what, even if nothing is provided for $default in whenJson. So this would mean that when would never be able to be a higher order method in this case. But also considering the $callback method is required, it's best to keep it as-is.

}

/**
* Execute the given callback if the string is not a valid JSON string.
*
* @param callable $callback
* @param callable|null $default
* @return static
*/
public function whenNotJson($callback, $default = null)
{
return $this->when(! $this->isJson(), $callback, $default);
}

/**
* Execute the given callback if the string is a valid UUID.
*
Expand Down
26 changes: 26 additions & 0 deletions tests/Support/SupportStringableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,32 @@ public function testWhenIsAscii()
}));
}

public function testWhenJson()
{
$this->assertSame('JSON: 1', (string) $this->stringable('1')->whenJson(function ($stringable) {
return $stringable->prepend('JSON: ');
}, function ($stringable) {
return $stringable->prepend('Not JSON: ');
}));

$this->assertSame('Not JSON: 1,', (string) $this->stringable('1,')->whenJson(function ($stringable) {
return $stringable->prepend('JSON: ');
}, function ($stringable) {
return $stringable->prepend('Not JSON: ');
}));
}

public function testWhenNotJson()
{
$this->assertSame('[1,2,3]', (string) $this->stringable('[1,2,3]')->whenNotJson(function ($stringable) {
return $stringable.' JSON';
}));

$this->assertSame('Not JSON', (string) $this->stringable('Not')->whenNotJson(function ($stringable) {
return $stringable.' JSON';
}));
}

public function testWhenIsUuid()
{
$this->assertSame('Uuid: 2cdc7039-65a6-4ac7-8e5d-d554a98e7b15', (string) $this->stringable('2cdc7039-65a6-4ac7-8e5d-d554a98e7b15')->whenIsUuid(function ($stringable) {
Expand Down