Skip to content

Commit

Permalink
ENH allow stacked messages on FormMessage
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewandante committed Oct 4, 2023
1 parent 44b1700 commit e90de56
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/Forms/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ public function loadMessagesFrom($result)
$owner = $this;
}

$owner->setMessage($message['message'], $message['messageType'], $message['messageCast']);
$owner->appendMessage($message['message'], $message['messageType'], $message['messageCast'], true);
}
return $this;
}
Expand Down
52 changes: 51 additions & 1 deletion src/Forms/FormMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ trait FormMessage
*/
protected $messageCast = null;


/**
* Returns the field message, used by form validation.
*
Expand Down Expand Up @@ -92,6 +91,57 @@ public function setMessage(
return $this;
}

/**
* Appends a message to the existing message if the types match, overrides if not
*
* @param string $message Message string
* @param string $messageType Message type
* @param string $messageCast
* @param bool $force Whether or not to override the existing message if appending is invalid
* @throws InvalidArgumentException
* @return $this
*/
public function appendMessage(
string $message,
string $messageType = ValidationResult::TYPE_ERROR,
string $messageCast = ValidationResult::CAST_TEXT,
bool $force = false,
): static {
if (empty($this->message)) {
return $this->setMessage($message, $messageType, $messageCast);
}
$canBeMerged = ($messageType === $this->getMessageType() && $messageCast === $this->getMessageCast());

if (!$canBeMerged && $force === false) {
throw new InvalidArgumentException(
sprintf(
"Couldn't append message of type %s and cast %s to existing message of type %s and cast %s",
$messageType,
$messageCast,
$this->getMessageType(),
$this->getMessageCast(),
)
);
}

// Checks that the exact message string is not already contained before appending
$messageContainsString = strpos($this->message, $message) !== false;
if ($canBeMerged && $messageContainsString) {
return $this;
}

if ($canBeMerged) {
$message = sprintf(
'%s%s%s',
$this->message,
$messageCast === ValidationResult::CAST_HTML ? '<br />' : PHP_EOL,
$message
);
}

return $this->setMessage($message, $messageType, $messageCast);
}

/**
* Get casting helper for message cast, or null if not known
*
Expand Down
50 changes: 50 additions & 0 deletions tests/php/Forms/FormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,56 @@ public function testFieldMessageEscapeHtml()
);
}

public function testFieldMessageAppend()
{
$form = $this->getStubForm();
$form->appendMessage('Just a string');
$parser = new CSSContentParser($form->forTemplate());
$messageEls = $parser->getBySelector('.message');
$this->assertStringContainsString('Just a string', $messageEls[0]->asXML());

$form = $this->getStubForm();
$form->appendMessage('Just a string');
$form->appendMessage('Certainly different');
$parser = new CSSContentParser($form->forTemplate());
$messageEls = $parser->getBySelector('.message');
$this->assertStringContainsString('Just a string', $messageEls[0]->asXML());
$this->assertStringContainsString('Certainly different', $messageEls[0]->asXML());

$form = $this->getStubForm();
$form->appendMessage('Just a string');
$form->appendMessage('Certainly different');
$form->appendMessage('Just a string');
$parser = new CSSContentParser($form->forTemplate());
$messageEls = $parser->getBySelector('.message');
$this->assertStringContainsString('Just a string', $messageEls[0]->asXML());
$this->assertStringContainsString('Certainly different', $messageEls[0]->asXML());
$this->assertEquals(1, substr_count($messageEls[0]->asXML(), 'Just a string'), 'Should not append if already present');
}

public function testFieldMessageAppendExceptions()
{
$form = $this->getStubForm();
$form->appendMessage('Just a string');
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage("Couldn't append message of type good and cast text to existing message of type error and cast text");
$form->appendMessage('This is a good message', ValidationResult::TYPE_GOOD);

$form = $this->getStubForm();
$form->appendMessage('This is a good message', ValidationResult::TYPE_GOOD);
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage("Couldn't append message of type good and cast html to existing message of type good and cast text");
$form->appendMessage('HTML is the future of the web', ValidationResult::TYPE_GOOD, ValidationResult::CAST_HTML);

$form = $this->getStubForm();
$form->appendMessage('This is a good message', ValidationResult::TYPE_GOOD);
$form->appendMessage('HTML is the future of the web', ValidationResult::TYPE_GOOD, ValidationResult::CAST_HTML, true);
$parser = new CSSContentParser($form->forTemplate());
$messageEls = $parser->getBySelector('.message');
$this->assertStringContainsString('HTML is the future of the web', $messageEls[0]->asXML());
$this->assertStringNotContainsString('This is a good message', $messageEls[0]->asXML());
}

public function testGetExtraFields()
{
$form = new FormTest\ExtraFieldsForm(
Expand Down

0 comments on commit e90de56

Please sign in to comment.