Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 083a32d

Browse filesBrowse files
Merge branch '5.0'
* 5.0: Add missing symfony/mime to require-dev [Validator] Added the missing Mongolian translations [ErrorHandler] Never throw on warnings triggered by assert() and set assert.exception=1 in Debug::enable() refactor(Process): fromShellCommandLine [Mailer] Do not ping the SMTP server before sending every message
2 parents ebdcd63 + 255a748 commit 083a32d
Copy full SHA for 083a32d

File tree

Expand file treeCollapse file tree

9 files changed

+412
-1
lines changed
Filter options
Expand file treeCollapse file tree

9 files changed

+412
-1
lines changed

‎src/Symfony/Component/ErrorHandler/Debug.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/ErrorHandler/Debug.php
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ public static function enable(): ErrorHandler
2929
ini_set('display_errors', 1);
3030
}
3131

32+
ini_set('zend.assertions', 1);
33+
ini_set('assert.active', 1);
34+
ini_set('assert.warning', 0);
35+
ini_set('assert.exception', 1);
36+
3237
DebugClassLoader::enable();
3338

3439
return ErrorHandler::register(new ErrorHandler(new BufferingLogger(), true));

‎src/Symfony/Component/ErrorHandler/ErrorHandler.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/ErrorHandler/ErrorHandler.php
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,11 @@ public function handleError(int $type, string $message, string $file, int $line)
413413
$throw = $this->thrownErrors & $type & $level;
414414
$type &= $level | $this->screamedErrors;
415415

416+
// Never throw on warnings triggered by assert()
417+
if (E_WARNING === $type && 'a' === $message[0] && 0 === strncmp($message, 'assert(): ', 10)) {
418+
$throw = 0;
419+
}
420+
416421
if (!$type || (!$log && !$throw)) {
417422
return !$silenced && $type && $log;
418423
}

‎src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php
+35Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,4 +615,39 @@ public function errorHandlerWhenLoggingProvider(): iterable
615615
}
616616
}
617617
}
618+
619+
public function testAssertQuietEval()
620+
{
621+
$ini = [
622+
ini_set('zend.assertions', 1),
623+
ini_set('assert.active', 1),
624+
ini_set('assert.bail', 0),
625+
ini_set('assert.warning', 1),
626+
ini_set('assert.callback', null),
627+
ini_set('assert.exception', 0),
628+
];
629+
630+
$logger = new BufferingLogger();
631+
$handler = new ErrorHandler($logger);
632+
$handler = ErrorHandler::register($handler);
633+
634+
try {
635+
\assert(false);
636+
} finally {
637+
restore_error_handler();
638+
restore_exception_handler();
639+
640+
ini_set('zend.assertions', $ini[0]);
641+
ini_set('assert.active', $ini[1]);
642+
ini_set('assert.bail', $ini[2]);
643+
ini_set('assert.warning', $ini[3]);
644+
ini_set('assert.callback', $ini[4]);
645+
ini_set('assert.exception', $ini[5]);
646+
}
647+
648+
$logs = $logger->cleanLogs();
649+
650+
$this->assertSame('warning', $logs[0][0]);
651+
$this->assertSame('Warning: assert(): assert(false) failed', $logs[0][1]);
652+
}
618653
}

‎src/Symfony/Component/Mailer/Tests/Transport/Smtp/SmtpTransportTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Mailer/Tests/Transport/Smtp/SmtpTransportTest.php
+95Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@
1212
namespace Symfony\Component\Mailer\Tests\Transport\Smtp;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Mailer\Envelope;
1516
use Symfony\Component\Mailer\Transport\Smtp\SmtpTransport;
17+
use Symfony\Component\Mailer\Transport\Smtp\Stream\AbstractStream;
1618
use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream;
19+
use Symfony\Component\Mime\Address;
20+
use Symfony\Component\Mime\RawMessage;
1721

1822
class SmtpTransportTest extends TestCase
1923
{
@@ -25,4 +29,95 @@ public function testToString()
2529
$t = new SmtpTransport((new SocketStream())->setHost('127.0.0.1')->setPort(2525)->disableTls());
2630
$this->assertEquals('smtp://127.0.0.1:2525', (string) $t);
2731
}
32+
33+
public function testSendDoesNotPingBelowThreshold(): void
34+
{
35+
$stream = new DummyStream();
36+
$envelope = new Envelope(new Address('sender@example.org'), [new Address('recipient@example.org')]);
37+
38+
$transport = new SmtpTransport($stream);
39+
$transport->send(new RawMessage('Message 1'), $envelope);
40+
$transport->send(new RawMessage('Message 2'), $envelope);
41+
$transport->send(new RawMessage('Message 3'), $envelope);
42+
43+
$this->assertNotContains("NOOP\r\n", $stream->getCommands());
44+
}
45+
46+
public function testSendDoesPingAboveThreshold(): void
47+
{
48+
$stream = new DummyStream();
49+
$envelope = new Envelope(new Address('sender@example.org'), [new Address('recipient@example.org')]);
50+
51+
$transport = new SmtpTransport($stream);
52+
$transport->setPingThreshold(1);
53+
54+
$transport->send(new RawMessage('Message 1'), $envelope);
55+
$transport->send(new RawMessage('Message 2'), $envelope);
56+
57+
$this->assertNotContains("NOOP\r\n", $stream->getCommands());
58+
59+
$stream->clearCommands();
60+
sleep(1);
61+
62+
$transport->send(new RawMessage('Message 3'), $envelope);
63+
$this->assertContains("NOOP\r\n", $stream->getCommands());
64+
}
65+
}
66+
67+
class DummyStream extends AbstractStream
68+
{
69+
/**
70+
* @var string
71+
*/
72+
private $nextResponse;
73+
74+
/**
75+
* @var string[]
76+
*/
77+
private $commands;
78+
79+
public function initialize(): void
80+
{
81+
$this->nextResponse = '220 localhost';
82+
}
83+
84+
public function write(string $bytes, $debug = true): void
85+
{
86+
$this->commands[] = $bytes;
87+
88+
if (0 === strpos($bytes, 'DATA')) {
89+
$this->nextResponse = '354 Enter message, ending with "." on a line by itself';
90+
} elseif (0 === strpos($bytes, 'QUIT')) {
91+
$this->nextResponse = '221 Goodbye';
92+
} else {
93+
$this->nextResponse = '250 OK';
94+
}
95+
}
96+
97+
public function readLine(): string
98+
{
99+
return $this->nextResponse;
100+
}
101+
102+
public function flush(): void
103+
{
104+
}
105+
106+
/**
107+
* @return string[]
108+
*/
109+
public function getCommands(): array
110+
{
111+
return $this->commands;
112+
}
113+
114+
public function clearCommands(): void
115+
{
116+
$this->commands = [];
117+
}
118+
119+
protected function getReadConnectionDescription(): string
120+
{
121+
return 'null';
122+
}
28123
}

‎src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php
+31-1Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class SmtpTransport extends AbstractTransport
3535
private $restartThreshold = 100;
3636
private $restartThresholdSleep = 0;
3737
private $restartCounter;
38+
private $pingThreshold = 100;
39+
private $lastMessageTime = 0;
3840
private $stream;
3941
private $domain = '[127.0.0.1]';
4042

@@ -66,6 +68,28 @@ public function setRestartThreshold(int $threshold, int $sleep = 0): self
6668
return $this;
6769
}
6870

71+
/**
72+
* Sets the minimum number of seconds required between two messages, before the server is pinged.
73+
* If the transport wants to send a message and the time since the last message exceeds the specified threshold,
74+
* the transport will ping the server first (NOOP command) to check if the connection is still alive.
75+
* Otherwise the message will be sent without pinging the server first.
76+
*
77+
* Do not set the threshold too low, as the SMTP server may drop the connection if there are too many
78+
* non-mail commands (like pinging the server with NOOP).
79+
*
80+
* By default, the threshold is set to 100 seconds.
81+
*
82+
* @param int $seconds The minimum number of seconds between two messages required to ping the server
83+
*
84+
* @return $this
85+
*/
86+
public function setPingThreshold(int $seconds): self
87+
{
88+
$this->pingThreshold = $seconds;
89+
90+
return $this;
91+
}
92+
6993
/**
7094
* Sets the name of the local domain that will be used in HELO.
7195
*
@@ -160,7 +184,10 @@ public function executeCommand(string $command, array $codes): string
160184

161185
protected function doSend(SentMessage $message): void
162186
{
163-
$this->ping();
187+
if (microtime(true) - $this->lastMessageTime > $this->pingThreshold) {
188+
$this->ping();
189+
}
190+
164191
if (!$this->started) {
165192
$this->start();
166193
}
@@ -183,6 +210,8 @@ protected function doSend(SentMessage $message): void
183210
$e->appendDebug($this->stream->getDebug());
184211

185212
throw $e;
213+
} finally {
214+
$this->lastMessageTime = microtime(true);
186215
}
187216
}
188217

@@ -213,6 +242,7 @@ private function start(): void
213242
$this->assertResponseCode($this->getFullResponse(), [220]);
214243
$this->doHeloCommand();
215244
$this->started = true;
245+
$this->lastMessageTime = 0;
216246

217247
$this->getLogger()->debug(sprintf('Email transport "%s" started', __CLASS__));
218248
}

‎src/Symfony/Component/Process/PhpProcess.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Process/PhpProcess.php
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Process;
1313

14+
use Symfony\Component\Process\Exception\LogicException;
1415
use Symfony\Component\Process\Exception\RuntimeException;
1516

1617
/**
@@ -49,6 +50,14 @@ public function __construct(string $script, string $cwd = null, array $env = nul
4950
parent::__construct($php, $cwd, $env, $script, $timeout);
5051
}
5152

53+
/**
54+
* {@inheritdoc}
55+
*/
56+
public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60)
57+
{
58+
throw new LogicException(sprintf('The "%s()" method cannot be called when using "%s".', __METHOD__, self::class));
59+
}
60+
5261
/**
5362
* {@inheritdoc}
5463
*/

‎src/Symfony/Component/Process/Tests/PhpProcessTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Process/Tests/PhpProcessTest.php
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Process\Tests;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Process\Exception\LogicException;
1516
use Symfony\Component\Process\PhpExecutableFinder;
1617
use Symfony\Component\Process\PhpProcess;
1718

@@ -60,4 +61,14 @@ public function testPassingPhpExplicitly()
6061
$process->run();
6162
$this->assertEquals($expected, $process->getOutput());
6263
}
64+
65+
public function testProcessCannotBeCreatedUsingFromShellCommandLine()
66+
{
67+
static::expectException(LogicException::class);
68+
static::expectExceptionMessage('The "Symfony\Component\Process\PhpProcess::fromShellCommandline()" method cannot be called when using "Symfony\Component\Process\PhpProcess".');
69+
PhpProcess::fromShellCommandline(<<<PHP
70+
<?php echo 'Hello World!';
71+
PHP
72+
);
73+
}
6374
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.