diff --git a/.php_cs b/.php_cs index e1343300..b16a35e5 100644 --- a/.php_cs +++ b/.php_cs @@ -32,7 +32,7 @@ return PhpCsFixer\Config::create() 'no_blank_lines_after_class_opening' => true, 'no_blank_lines_after_phpdoc' => true, 'no_blank_lines_between_uses' => true, - 'no_duplicate_semicolons' => true, + 'no_empty_statement' => true, 'no_extra_consecutive_blank_lines' => true, 'no_leading_import_slash' => true, 'no_leading_namespace_whitespace' => true, diff --git a/composer.json b/composer.json index 4d9aa733..1a6c609c 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ }, "require-dev": { "phpunit/phpunit": "^5.3", - "graylog2/gelf-php": "^1.0.1", + "graylog2/gelf-php": "1.3.x-dev", "sentry/sentry": "^0.13", "ruflin/elastica": ">=0.90 <3.0", "doctrine/couchdb": "~1.0@dev", diff --git a/src/Monolog/DateTimeImmutable.php b/src/Monolog/DateTimeImmutable.php index f1536f43..6ca786c1 100644 --- a/src/Monolog/DateTimeImmutable.php +++ b/src/Monolog/DateTimeImmutable.php @@ -1,4 +1,4 @@ -'; $output .= $this->addRow('Message', (string) $record['message']); - $output .= $this->addRow('Time', $record['datetime']->format($this->dateFormat)); + $output .= $this->addRow('Time', $this->formatDate($record['datetime'])); $output .= $this->addRow('Channel', $record['channel']); if ($record['context']) { $embeddedTable = ''; diff --git a/src/Monolog/Formatter/JsonFormatter.php b/src/Monolog/Formatter/JsonFormatter.php index 17ede7da..2c7db92f 100644 --- a/src/Monolog/Formatter/JsonFormatter.php +++ b/src/Monolog/Formatter/JsonFormatter.php @@ -1,4 +1,4 @@ -dateFormat = $dateFormat; + $this->dateFormat = null === $dateFormat ? static::SIMPLE_DATE : $dateFormat; if (!function_exists('json_encode')) { throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s NormalizerFormatter'); } @@ -87,11 +87,7 @@ class NormalizerFormatter implements FormatterInterface } if ($data instanceof \DateTimeInterface) { - if ($data instanceof DateTimeImmutable) { - return (string) $data; - } - - return $data->format($this->dateFormat ?: static::SIMPLE_DATE); + return $this->formatDate($data); } if (is_object($data)) { @@ -271,7 +267,9 @@ class NormalizerFormatter implements FormatterInterface if (is_string($data) && !preg_match('//u', $data)) { $data = preg_replace_callback( '/[\x80-\xFF]+/', - function ($m) { return utf8_encode($m[0]); }, + function ($m) { + return utf8_encode($m[0]); + }, $data ); $data = str_replace( @@ -281,4 +279,13 @@ class NormalizerFormatter implements FormatterInterface ); } } + + protected function formatDate(\DateTimeInterface $date) + { + if ($date instanceof DateTimeImmutable) { + return (string) $date; + } + + return $date->format($this->dateFormat); + } } diff --git a/src/Monolog/Formatter/ScalarFormatter.php b/src/Monolog/Formatter/ScalarFormatter.php index 5d345d53..fcff1294 100644 --- a/src/Monolog/Formatter/ScalarFormatter.php +++ b/src/Monolog/Formatter/ScalarFormatter.php @@ -1,4 +1,4 @@ -facilities)) { + if (is_string($facility) && array_key_exists(strtolower($facility), $this->facilities)) { $facility = $this->facilities[strtolower($facility)]; } elseif (!in_array($facility, array_values($this->facilities), true)) { throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given'); diff --git a/src/Monolog/Handler/AmqpHandler.php b/src/Monolog/Handler/AmqpHandler.php index 223d6bf5..5b77e4f7 100644 --- a/src/Monolog/Handler/AmqpHandler.php +++ b/src/Monolog/Handler/AmqpHandler.php @@ -1,4 +1,4 @@ -= $timestampValidity) { + if ($log && substr($log, 0, 10) >= $timestampValidity) { $validLogs[] = $log; } } diff --git a/src/Monolog/Handler/DoctrineCouchDBHandler.php b/src/Monolog/Handler/DoctrineCouchDBHandler.php index 2752dd2f..13a08eec 100644 --- a/src/Monolog/Handler/DoctrineCouchDBHandler.php +++ b/src/Monolog/Handler/DoctrineCouchDBHandler.php @@ -1,4 +1,4 @@ -getContentType() ?: ($this->isHtmlBody($content) ? 'text/html' : 'text/plain'); diff --git a/src/Monolog/Handler/NewRelicHandler.php b/src/Monolog/Handler/NewRelicHandler.php index 03952e77..fb037782 100644 --- a/src/Monolog/Handler/NewRelicHandler.php +++ b/src/Monolog/Handler/NewRelicHandler.php @@ -1,4 +1,4 @@ -token = $token; $this->channel = $channel; $this->username = $username; - $this->iconEmoji = trim($iconEmoji, ':'); + $this->iconEmoji = is_string($iconEmoji) ? trim($iconEmoji, ':') : null; $this->useAttachment = $useAttachment; $this->useShortAttachment = $useShortAttachment; $this->includeContextAndExtra = $includeContextAndExtra; diff --git a/src/Monolog/Handler/SocketHandler.php b/src/Monolog/Handler/SocketHandler.php index 7a61bf4e..520bedd5 100644 --- a/src/Monolog/Handler/SocketHandler.php +++ b/src/Monolog/Handler/SocketHandler.php @@ -1,4 +1,4 @@ -mailer->send($this->buildMessage($content, $records)); } @@ -51,19 +52,19 @@ class SwiftMailerHandler extends MailHandler * * @param string $content formatted email body to be sent * @param array $records Log records that formed the content - * @return \Swift_Message + * @return Swift_Message */ - protected function buildMessage($content, array $records) + protected function buildMessage(string $content, array $records): Swift_Message { $message = null; - if ($this->messageTemplate instanceof \Swift_Message) { + if ($this->messageTemplate instanceof Swift_Message) { $message = clone $this->messageTemplate; $message->generateId(); } elseif (is_callable($this->messageTemplate)) { $message = call_user_func($this->messageTemplate, $content, $records); } - if (!$message instanceof \Swift_Message) { + if (!$message instanceof Swift_Message) { throw new \InvalidArgumentException('Could not resolve message as instance of Swift_Message or a callable returning it'); } diff --git a/src/Monolog/Handler/SyslogHandler.php b/src/Monolog/Handler/SyslogHandler.php index 376bc3b2..863fc56d 100644 --- a/src/Monolog/Handler/SyslogHandler.php +++ b/src/Monolog/Handler/SyslogHandler.php @@ -1,4 +1,4 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -declare(strict_types=1); +name = $name; @@ -315,7 +304,8 @@ class Logger implements LoggerInterface return false; } - $ts = $this->createDateTime(); + $dateTime = new DateTimeImmutable($this->microsecondTimestamps, $this->timezone); + $dateTime->setTimezone($this->timezone); $record = [ 'message' => $message, @@ -323,7 +313,7 @@ class Logger implements LoggerInterface 'level' => $level, 'level_name' => $levelName, 'channel' => $this->name, - 'datetime' => $ts, + 'datetime' => $dateTime, 'extra' => [], ]; @@ -555,17 +545,4 @@ class Logger implements LoggerInterface { return $this->timezone; } - - /** - * Circumvent DateTimeImmutable::createFromFormat() which always returns the native DateTime instead of the specialized one - * - * @link https://bugs.php.net/bug.php?id=60302 - */ - private function createDateTime(): DateTimeImmutable - { - $dateTime = new DateTimeImmutable($this->microsecondTimestamps, $this->timezone); - $dateTime->setTimezone($this->timezone); - - return $dateTime; - } } diff --git a/src/Monolog/Processor/GitProcessor.php b/src/Monolog/Processor/GitProcessor.php index c4d95a91..cf16be8e 100644 --- a/src/Monolog/Processor/GitProcessor.php +++ b/src/Monolog/Processor/GitProcessor.php @@ -1,4 +1,4 @@ -getMock('Monolog\\Formatter\\FormatterInterface'); $formatter->expects($this->any()) ->method('format') - ->will($this->returnCallback(function ($record) { return $record['message']; })); + ->will($this->returnCallback(function ($record) { + return $record['message']; + })); return $formatter; } diff --git a/tests/Monolog/ErrorHandlerTest.php b/tests/Monolog/ErrorHandlerTest.php index 26ac7ead..7b3ba82a 100644 --- a/tests/Monolog/ErrorHandlerTest.php +++ b/tests/Monolog/ErrorHandlerTest.php @@ -1,4 +1,4 @@ - $value) { - if (!in_array($key, ['level', 'timestamp'])) { + if (!in_array($key, ['level', 'timestamp']) && is_string($value)) { $length += strlen($value); } } diff --git a/tests/Monolog/Formatter/JsonFormatterTest.php b/tests/Monolog/Formatter/JsonFormatterTest.php index 2a0b8d17..392647fd 100644 --- a/tests/Monolog/Formatter/JsonFormatterTest.php +++ b/tests/Monolog/Formatter/JsonFormatterTest.php @@ -1,4 +1,4 @@ -markTestSkipped('Not supported in HHVM since it detects errors differently'); } - // This happens i.e. in React promises or Guzzle streams where stream wrappers are registered - // and no file or line are included in the trace because it's treated as internal function - set_error_handler(function ($errno, $errstr, $errfile, $errline) { - throw new \ErrorException($errstr, 0, $errno, $errfile, $errline); - }); - try { // This will contain $resource and $wrappedResource as arguments in the trace item $resource = fopen('php://memory', 'rw+'); @@ -292,9 +288,12 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase $wrappedResource = new TestFooNorm; $wrappedResource->foo = $resource; // Just do something stupid with a resource/wrapped resource as argument - array_keys($wrappedResource); + $arr = [$wrappedResource, null]; + // modifying the array inside throws a "usort(): Array was modified by the user comparison function" + usort($arr, function ($a, $b) use (&$arr) { + $arr[] = 'new'; + }); } catch (\Throwable $e) { - restore_error_handler(); } $formatter = new NormalizerFormatter(); diff --git a/tests/Monolog/Formatter/ScalarFormatterTest.php b/tests/Monolog/Formatter/ScalarFormatterTest.php index 73707d9b..ea488e5d 100644 --- a/tests/Monolog/Formatter/ScalarFormatterTest.php +++ b/tests/Monolog/Formatter/ScalarFormatterTest.php @@ -1,4 +1,4 @@ -handle($this->getRecord(Logger::DEBUG)); $handler->handle($this->getRecord(Logger::INFO)); $this->assertFalse($test->hasDebugRecords()); @@ -133,8 +133,8 @@ class FingersCrossedHandlerTest extends TestCase public function testHandleWithBadCallbackThrowsException() { $handler = new FingersCrossedHandler(function ($record, $handler) { - return 'foo'; - }); + return 'foo'; + }); $handler->handle($this->getRecord(Logger::WARNING)); } diff --git a/tests/Monolog/Handler/FirePHPHandlerTest.php b/tests/Monolog/Handler/FirePHPHandlerTest.php index bb30fdb4..b62e7fd0 100644 --- a/tests/Monolog/Handler/FirePHPHandlerTest.php +++ b/tests/Monolog/Handler/FirePHPHandlerTest.php @@ -1,4 +1,4 @@ -expects($this->once()) ->method('formatBatch'); // Each record is formatted - $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler'); + $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler', [], '', true, true, true, ['send', 'write']); $handler->expects($this->once()) ->method('send'); $handler->expects($this->never()) diff --git a/tests/Monolog/Handler/MockRavenClient.php b/tests/Monolog/Handler/MockRavenClient.php index a0833225..d344d342 100644 --- a/tests/Monolog/Handler/MockRavenClient.php +++ b/tests/Monolog/Handler/MockRavenClient.php @@ -1,4 +1,4 @@ -getRecord(Logger::INFO, 'information'), ]; - $handler = $this->getMock('Monolog\Handler\RavenHandler', null, [$this->getRavenClient()]); + $handler = $this->getMock('Monolog\Handler\RavenHandler', ['handle'], [$this->getRavenClient()]); $handler->expects($this->never())->method('handle'); $handler->setLevel(Logger::ERROR); $handler->handleBatch($records); diff --git a/tests/Monolog/Handler/RedisHandlerTest.php b/tests/Monolog/Handler/RedisHandlerTest.php index 57bfb34c..8363c9a2 100644 --- a/tests/Monolog/Handler/RedisHandlerTest.php +++ b/tests/Monolog/Handler/RedisHandlerTest.php @@ -1,4 +1,4 @@ -