Support for multiple `send` key items for controllers
Closed this issue · 10 comments
Synopsis:
Allow specifying multiple items for the send
key to send multiple notifications.
Proposed Syntax:
Ticket:
resource: all
store:
validate: title, content
save: ticket
send:
- TicketReceived to:ticket.customer with:ticket
- NewTicket to:ticket.staff with:ticket
dispatch: SyncMedia with:ticket
fire: NewTicket with:ticket
flash: ticket.id
redirect: ticket.index
Expected Behavior:
The proposed syntax should generate multiple lines.
Notification::send($ticket->customer, new TicketReceived($ticket));
Notification::send($ticket->staff, new NewTicket($ticket));
I think the way to do this would be:
send: TicketReceived to:ticket.customer with:ticket
send: NewTicket to:ticket.staff with:ticket
Same amount of keystrokes really. But let me know if that doesn't work.
That currently fails since duplicate keys are not supported in YAML nor JSON.
php artisan blueprint:build
Symfony\Component\Yaml\Exception\ParseException
Duplicate key "send" detected at line 538 (near "send: A to:ticket.author with:ticket").
at vendor/symfony/yaml/Parser.php:348
344▕ // But overwriting is allowed when a merge node is used in current block.
345▕ if ($allowOverwrite || !isset($data[$key])) {
346▕ $data[$key] = $value;
347▕ } else {
➜ 348▕ throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), $this->getRealCurrentLineNb() + 1, $this->currentLine);
349▕ }
350▕ }
351▕ if ($isRef) {
352▕ $this->refs[$isRef] = $data[$key];
Ah, lame YAML. I have reopened this for the community to implement.
Will take a look in the next days and see if I can figure out where to get the additional parsing working 👀
I'd probably look at the Statement "lexer". I believe there is where you could check and handle if the value is an array, if so, register multiple SendStatement
. The rest should just work.
Just had a cursory look and due to how the parser seems to work it results in something like this for a send
array
"store" => array:7 [
"validate" => "title, content"
"save" => "ticket"
"send" => "ReviewNotification to:ticket.author with:ticket ReviewNotification to:ticket.author with:ticket"
"dispatch" => "SyncMedia with:ticket"
"fire" => "NewTicket with:ticket"
"flash" => "ticket.id"
"redirect" => "ticket.index"
]
I'll have a proper look when I'm at my machine.
Edit:
This is happening due to this part.
if ($strip_dashes) {
$content = preg_replace('/^(\s*)-\s*/m', '\1', $content);
}
Removing gets the array working.
@jasonmccreary what was the problem that required strip_dashes
? This effectively makes it impossible to use arrays in the draft.yml
file since those array items are usually denoted by a leading dash. An alternative would be to use the []
syntax, see https://www.w3schools.io/file/yaml-arrays/.
Ticket:
resource: all
store:
validate: title, content
save: ticket
send: [
TicketReceived to:ticket.customer with:ticket,
NewTicket to:ticket.staff with:ticket
]
dispatch: SyncMedia with:ticket
fire: NewTicket with:ticket
flash: ticket.id
redirect: ticket.index
Try with just an indent, no brackets, no dashes.
Doesn't work like that since that isn't valid YAML. Summary from what I've gathered so far:
- The
$strip_dashes
flag makes the most common way of declaring arrays impossible. - The
ControllerGenerator
class would need to be modified but to handle arrays but this can be easily handled by addingforeach (Arr::wrap($statement) as $statement)
. - The same applies to the
StatementLexer
class.
Closed by #623.