Skip to content
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

Support multiple emails in one connection #153

Merged
merged 5 commits into from
Jan 19, 2025
Merged
Changes from 1 commit
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
Prev Previous commit
test(smtp): fix psalm issues
roxblnfk committed Jan 19, 2025
commit 7f6ad5b22075fae38bc11c4844d1fff759894a2c
26 changes: 14 additions & 12 deletions src/Sender/MailToFileSender.php
Original file line number Diff line number Diff line change
@@ -47,30 +47,32 @@ public function send(iterable $frames): void
/**
* Get normalized email address for file or directory name.
*
* @return non-empty-string
* @return non-empty-string|null
*/
private static function normalizeEmail(string $email): string
private static function normalizeEmail(?string $email): ?string
{
return \preg_replace(
$normalized = \preg_replace(
['/[^a-z0-9.\\- @]/i', '/\s+/'],
['!', '_'],
$email,
(string) $email,
);

return $normalized === '' ? null : $normalized;
}

/**
* @return list<non-empty-string>
*/
private static function fetchDirectories(Message\Smtp $message): array
{
return
\array_filter(
\array_unique(
\array_map(
static fn(Contact $c) => self::normalizeEmail($c->email),
\array_merge($message->getBcc(), $message->getTo()),
),
return \array_values(\array_filter(
\array_unique(
\array_map(
static fn(Contact $c): ?string => self::normalizeEmail($c->email),
\array_merge($message->getBcc(), $message->getTo()),
),
);
),
static fn(?string $dir): bool => $dir !== null,
));
}
}
27 changes: 14 additions & 13 deletions src/Traffic/Message/Smtp.php
Original file line number Diff line number Diff line change
@@ -133,23 +133,23 @@
{
$addrs = \array_unique(\array_merge((array) ($this->protocol['FROM'] ?? []), $this->getHeader('From')));

return \array_map([$this, 'parseContact'], $addrs);
return \array_map(self::parseContact(...), $addrs);

Check warning on line 136 in src/Traffic/Message/Smtp.php

Codecov / codecov/patch

src/Traffic/Message/Smtp.php#L136

Added line #L136 was not covered by tests
}

/**
* @return Contact[]
*/
public function getTo(): array
{
return $this->normalizeAddressList($this->getHeader('To'));
return self::normalizeAddressList($this->getHeader('To'));
}

/**
* @return Contact[]
*/
public function getCc(): array
{
return $this->normalizeAddressList($this->getHeader('Cc'));
return self::normalizeAddressList($this->getHeader('Cc'));
}

/**
@@ -160,15 +160,15 @@
*/
public function getBcc(): array
{
return $this->normalizeAddressList($this->protocol['BCC'] ?? []);
return self::normalizeAddressList($this->protocol['BCC'] ?? []);
}

/**
* @return Contact[]
*/
public function getReplyTo(): array
{
return $this->normalizeAddressList($this->getHeader('Reply-To'));
return self::normalizeAddressList($this->getHeader('Reply-To'));
}

public function getSubject(): string
@@ -187,7 +187,7 @@
return null;
}

private function parseContact(string $line): Contact
private static function parseContact(string $line): Contact
{
if (\preg_match('/^\s*+(?<name>.*?)\s*<(?<email>.*)>\s*$/', $line, $matches) === 1) {
$name = match (true) {
@@ -206,26 +206,27 @@
}

/**
* @return array<Contact>
* @return list<Contact>
*/
private function parseDestinationAddress(string $line): array
private static function parseDestinationAddress(string $line): array
{
// if this is a group recipient
if (\preg_match('/^[^"]+:(.*);$/', $line, $matches) === 1) {
$line = $matches[1];
}

$emailList = \array_map('trim', \explode(',', $line));
return \array_map([$this, 'parseContact'], $emailList);
$emailList = \array_map(\trim(...), \explode(',', $line));
return \array_map(self::parseContact(...), $emailList);
}

/**
* @return array<Contact>
* @param list<string> $param
* @return list<Contact>
*/
private function normalizeAddressList(array $param): array
private static function normalizeAddressList(array $param): array
{
return \array_merge(
...\array_map([$this, 'parseDestinationAddress'], $param),
...\array_map(self::parseDestinationAddress(...), $param),
);
}
}

Unchanged files with check annotations Beta

<?php

Check failure on line 1 in src/Application.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Ignored error pattern #^Parameter \$clientInflector of static method Buggregator\\Trap\\Socket\\Server\:\:init\(\) expects \(Closure\(Buggregator\\Trap\\Socket\\Client, int\)\: void\)\|null, Closure\(Buggregator\\Trap\\Socket\\Client, int\)\: Buggregator\\Trap\\Socket\\Client given\.$# in path /home/runner/work/trap/trap/src/Application.php was not matched in reported errors.

Check failure on line 1 in src/Application.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Ignored error pattern #^Parameter \$clientInflector of static method Buggregator\\Trap\\Socket\\Server\:\:init\(\) expects \(Closure\(Buggregator\\Trap\\Socket\\Client, int\)\: void\)\|null, Closure\(Buggregator\\Trap\\Socket\\Client, int\)\: Buggregator\\Trap\\Socket\\Client given\.$# in path /home/runner/work/trap/trap/src/Application.php was not matched in reported errors.
declare(strict_types=1);
<?php

Check failure on line 1 in src/Command/Run.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Ignored error pattern #^Short ternary operator is not allowed\. Use null coalesce operator if applicable or consider using long ternary\.$# in path /home/runner/work/trap/trap/src/Command/Run.php was not matched in reported errors.

Check failure on line 1 in src/Command/Run.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Ignored error pattern #^Short ternary operator is not allowed\. Use null coalesce operator if applicable or consider using long ternary\.$# in path /home/runner/work/trap/trap/src/Command/Run.php was not matched in reported errors.
declare(strict_types=1);
}
/** @var XHProfMessage $payload */
$payload = \json_decode((string) $request->getBody(), true, 96, \JSON_THROW_ON_ERROR);

Check failure on line 71 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

PHPDoc tag @var for variable $payload has no value type specified in iterable type array.

Check failure on line 71 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

PHPDoc tag @var for variable $payload has no value type specified in iterable type array.

Check failure on line 71 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

PHPDoc tag @var for variable $payload has no value type specified in iterable type array.

Check failure on line 71 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

PHPDoc tag @var for variable $payload has no value type specified in iterable type array.
\is_array($payload['profile'] ?? null) && \is_array($payload['tags'] ?? null)

Check failure on line 73 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Call to function is_array() with array will always evaluate to true.

Check failure on line 73 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Call to function is_array() with array will always evaluate to true.

Check failure on line 73 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Offset 'profile' on array{profile: array, tags: array, app_name: string, hostname: string, date: int<1, max>} on left side of ?? always exists and is not nullable.

Check failure on line 73 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Offset 'tags' on array{profile: array, tags: array, app_name: string, hostname: string, date: int<1, max>} on left side of ?? always exists and is not nullable.

Check failure on line 73 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Result of && is always true.

Check failure on line 73 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Call to function is_array() with array will always evaluate to true.

Check failure on line 73 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Call to function is_array() with array will always evaluate to true.

Check failure on line 73 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Offset 'profile' on array{profile: array, tags: array, app_name: string, hostname: string, date: int<1, max>} on left side of ?? always exists and is not nullable.

Check failure on line 73 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Offset 'tags' on array{profile: array, tags: array, app_name: string, hostname: string, date: int<1, max>} on left side of ?? always exists and is not nullable.

Check failure on line 73 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Result of && is always true.
or throw new \InvalidArgumentException('Invalid payload');
$metadata = $payload;
callsProvider: fn(): Profile => $this->profileBuilder->createProfile(
date: $time,
metadata: $metadata,
tags: $payload['tags'] ?? [],

Check failure on line 91 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Offset 'tags' on array{profile: array, tags: array, app_name: string, hostname: string, date: int<1, max>} on left side of ?? always exists and is not nullable.

Check failure on line 91 in src/Handler/Http/Middleware/XHProfTrap.php

GitHub Actions / phpstan (ubuntu-latest, 8.2, locked)

Offset 'tags' on array{profile: array, tags: array, app_name: string, hostname: string, date: int<1, max>} on left side of ?? always exists and is not nullable.
calls: $payload['profile'] ?? [],
),
),