Is this a good approach for validating user input in a chatbot? I am writing an autoposter telegram bot in PHP using the php-telegram-bot library (by Longman). I have a Task class that stores information about the task (repetition period, message data, etc.).
class Task
{
#[ORM\Id]
#[ORM\Column(type: 'integer')]
#[ORM\GeneratedValue]
private int|null $id;
#[ORM\Column(type: 'boolean')]
private bool $isOn;
#[ORM\Column(type: 'time')]
private DateTime $startAt;
#[ORM\Column(type: 'integer')]
private int $repeatIntervalSeconds;
#[ORM\Column(type: 'datetime')]
private DateTime $endAt;
#[ORM\Column(type: 'simple_array')]
private array $chats = [];
#[ORM\Column(type: 'integer')]
private int $messageChatId;
#[ORM\Column(type: 'integer')]
private int $messageId;
//...
}
I also have a command /taskcreate that consistently asks questions like "Send the date and time when the message replay will be disabled." and waits for the user's response. The problem is that I also have commands like /taskchangerepetition or /taskchangemessage that need to duplicate the user input validation code. The question is: what is the best way to implement this validation, should I create a static validator class or should I do the validation in the Task class itself? Or there are other ways. Currently I am using this:
// TaskcreateCommand.php
// State machine
// Every time a step is achieved the state is updated
// ...
case 3:
if ($text === '' || !TaskValidator::validateEndAt($text)) {
$notes['state'] = 3;
$this->conversation->update();
$data['text'] = 'π Send the date and time when the message replay will be disabled.' . PHP_EOL . PHP_EOL .
'β You must specify the date in the format dd/mm/yy hh:mm' . PHP_EOL . 'Example: 15/08/23 02:59';
if ($text !== '') {
$data['text'] = 'β οΈ Invalid format';
}
$result = Request::sendMessage($data);
break;
}
$notes['end_at'] = $text;
$text = '';
// TaskValidator.php
public static function validateEndAt($input): bool {
$dateObj = DateTime::createFromFormat('d.m.Y H:i', $input);
$now = new DateTime('now');
return $dateObj !== false && $dateObj > $now;
}
1 Answer 1
I think the best option is to implement the validate function inside task class. It should be a behaviour of the task class.
And why don't you use polymorphism here? You have Task
class but you have at least 3 types of Task
here: CreateCommnad, ChangeRepetition, ChangeMessage
You can have a called basic validate
function in Task class and extend or change the implementation in subclasses to fit the expected input.
Assuming you know about OOP, that's one way we can use to eliminate code duplication and avoid switch/case condition. Then you can use Factory pattern to create Task
php
orm
andtelegram
, but then say you're trying to validate input, which is entirely independent of all 4 tags you've listed \$\endgroup\$momento
pattern.Validation
is typically done with aChain of responsibility
. \$\endgroup\$