Ver código fonte

mb_* functions with BC

vershinin_so 6 anos atrás
pai
commit
c79d81ec28

+ 2 - 1
composer.json

@@ -42,7 +42,8 @@
         "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
         "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
         "rollbar/rollbar": "Allow sending log messages to Rollbar",
-        "php-console/php-console": "Allow sending log messages to Google Chrome"
+        "php-console/php-console": "Allow sending log messages to Google Chrome",
+        "ext-mbstring": "Allow to work properly with unicode symbols"
     },
     "autoload": {
         "psr-4": {"Monolog\\": "src/Monolog"}

+ 4 - 14
src/Monolog/Formatter/FlowdockFormatter.php

@@ -11,6 +11,8 @@
 
 namespace Monolog\Formatter;
 
+use Monolog\Utils;
+
 /**
  * formats the record to be used in the FlowdockHandler
  *
@@ -84,22 +86,10 @@ class FlowdockFormatter implements FormatterInterface
 
     public function getShortMessage(string $message): string
     {
-        static $hasMbString;
-
-        if (null === $hasMbString) {
-            $hasMbString = function_exists('mb_strlen');
-        }
-
         $maxLength = 45;
 
-        if ($hasMbString) {
-            if (mb_strlen($message, 'UTF-8') > $maxLength) {
-                $message = mb_substr($message, 0, $maxLength - 4, 'UTF-8') . ' ...';
-            }
-        } else {
-            if (strlen($message) > $maxLength) {
-                $message = substr($message, 0, $maxLength - 4) . ' ...';
-            }
+        if (Utils::strlen($message) > $maxLength) {
+            $message = Utils::substr($message, 0, $maxLength - 4) . ' ...';
         }
 
         return $message;

+ 9 - 6
src/Monolog/Formatter/GelfMessageFormatter.php

@@ -13,6 +13,7 @@ namespace Monolog\Formatter;
 
 use Monolog\Logger;
 use Gelf\Message;
+use Monolog\Utils;
 
 /**
  * Serializes a log message to GELF
@@ -93,10 +94,10 @@ class GelfMessageFormatter extends NormalizerFormatter
             ->setLevel($this->logLevels[$record['level']]);
 
         // message length + system name length + 200 for padding / metadata
-        $len = 200 + mb_strlen((string) $record['message']) + mb_strlen($this->systemName);
+        $len = 200 + Utils::strlen((string) $record['message']) + Utils::strlen($this->systemName);
 
         if ($len > $this->maxLength) {
-            $message->setShortMessage(mb_substr($record['message'], 0, $this->maxLength));
+            $message->setShortMessage(Utils::substr($record['message'], 0, $this->maxLength));
         }
 
         if (isset($record['channel'])) {
@@ -113,9 +114,10 @@ class GelfMessageFormatter extends NormalizerFormatter
 
         foreach ($record['extra'] as $key => $val) {
             $val = is_scalar($val) || null === $val ? $val : $this->toJson($val);
-            $len = mb_strlen($this->extraPrefix . $key . $val);
+            $len = Utils::strlen($this->extraPrefix . $key . $val);
             if ($len > $this->maxLength) {
-                $message->setAdditional($this->extraPrefix . $key, mb_substr($val, 0, $this->maxLength));
+                $message->setAdditional($this->extraPrefix . $key, Utils::substr($val, 0, $this->maxLength));
+
                 continue;
             }
             $message->setAdditional($this->extraPrefix . $key, $val);
@@ -123,9 +125,10 @@ class GelfMessageFormatter extends NormalizerFormatter
 
         foreach ($record['context'] as $key => $val) {
             $val = is_scalar($val) || null === $val ? $val : $this->toJson($val);
-            $len = mb_strlen($this->contextPrefix . $key . $val);
+            $len = Utils::strlen($this->contextPrefix . $key . $val);
             if ($len > $this->maxLength) {
-                $message->setAdditional($this->contextPrefix . $key, mb_substr($val, 0, $this->maxLength));
+                $message->setAdditional($this->contextPrefix . $key, Utils::substr($val, 0, $this->maxLength));
+
                 continue;
             }
             $message->setAdditional($this->contextPrefix . $key, $val);

+ 2 - 2
src/Monolog/Formatter/NormalizerFormatter.php

@@ -379,12 +379,12 @@ class NormalizerFormatter implements FormatterInterface
 
         return $date->format($this->dateFormat);
     }
-    
+
     protected function addJsonEncodeOption($option)
     {
         $this->jsonEncodeOptions |= $option;
     }
-    
+
     protected function removeJsonEncodeOption($option)
     {
         $this->jsonEncodeOptions ^= $option;

+ 2 - 1
src/Monolog/Formatter/WildfireFormatter.php

@@ -12,6 +12,7 @@
 namespace Monolog\Formatter;
 
 use Monolog\Logger;
+use Monolog\Utils;
 
 /**
  * Serializes a log message according to Wildfire's header requirements
@@ -90,7 +91,7 @@ class WildfireFormatter extends NormalizerFormatter
         // The message itself is a serialization of the above JSON object + it's length
         return sprintf(
             '%d|%s|',
-            strlen($json),
+            Utils::strlen($json),
             $json
         );
     }

+ 2 - 1
src/Monolog/Handler/BrowserConsoleHandler.php

@@ -13,6 +13,7 @@ namespace Monolog\Handler;
 
 use Monolog\Formatter\LineFormatter;
 use Monolog\Formatter\FormatterInterface;
+use Monolog\Utils;
 
 /**
  * Handler sending logs to browser's javascript console with no browser extension required
@@ -175,7 +176,7 @@ class BrowserConsoleHandler extends AbstractProcessingHandler
             $args[] = '"font-weight: normal"';
 
             $pos = $match[0][1];
-            $format = substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . substr($format, $pos + strlen($match[0][0]));
+            $format = Utils::substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . Utils::substr($format, $pos + Utils::strlen($match[0][0]));
         }
 
         array_unshift($args, static::quote($format));

+ 2 - 1
src/Monolog/Handler/ChromePHPHandler.php

@@ -14,6 +14,7 @@ namespace Monolog\Handler;
 use Monolog\Formatter\ChromePHPFormatter;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\Logger;
+use Monolog\Utils;
 
 /**
  * Handler sending logs to the ChromePHP extension (http://www.chromephp.com/)
@@ -146,7 +147,7 @@ class ChromePHPHandler extends AbstractProcessingHandler
 
         $json = @json_encode(self::$json);
         $data = base64_encode(utf8_encode($json));
-        if (strlen($data) > 240 * 1024) {
+        if (Utils::strlen($data) > 240 * 1024) {
             self::$overflowed = true;
 
             $record = [

+ 3 - 2
src/Monolog/Handler/CubeHandler.php

@@ -12,6 +12,7 @@
 namespace Monolog\Handler;
 
 use Monolog\Logger;
+use Monolog\Utils;
 
 /**
  * Logs to Cube.
@@ -134,7 +135,7 @@ class CubeHandler extends AbstractProcessingHandler
             $this->connectUdp();
         }
 
-        socket_send($this->udpConnection, $data, strlen($data), 0);
+        socket_send($this->udpConnection, $data, Utils::strlen($data), 0);
     }
 
     private function writeHttp(string $data): void
@@ -146,7 +147,7 @@ class CubeHandler extends AbstractProcessingHandler
         curl_setopt($this->httpConnection, CURLOPT_POSTFIELDS, '['.$data.']');
         curl_setopt($this->httpConnection, CURLOPT_HTTPHEADER, [
             'Content-Type: application/json',
-            'Content-Length: ' . strlen('['.$data.']'),
+            'Content-Length: ' . Utils::strlen('['.$data.']'),
         ]);
 
         Curl\Util::execute($this->httpConnection, 5, false);

+ 4 - 4
src/Monolog/Handler/Curl/Util.php

@@ -31,9 +31,9 @@ final class Util
     /**
      * Executes a CURL request with optional retries and exception on failure
      *
-     * @param resource $ch curl handler
-     * @param int $retries
-     * @param bool $closeAfterDone
+     * @param  resource    $ch             curl handler
+     * @param  int         $retries
+     * @param  bool        $closeAfterDone
      * @return bool|string @see curl_exec
      */
     public static function execute($ch, int $retries = 5, bool $closeAfterDone = true)
@@ -65,4 +65,4 @@ final class Util
 
         return false;
     }
-}
+}

+ 3 - 2
src/Monolog/Handler/DeduplicationHandler.php

@@ -12,6 +12,7 @@
 namespace Monolog\Handler;
 
 use Monolog\Logger;
+use Monolog\Utils;
 
 /**
  * Simple handler wrapper that deduplicates log records across multiple requests
@@ -66,7 +67,7 @@ class DeduplicationHandler extends BufferHandler
     {
         parent::__construct($handler, 0, Logger::DEBUG, $bubble, false);
 
-        $this->deduplicationStore = $deduplicationStore === null ? sys_get_temp_dir() . '/monolog-dedup-' . substr(md5(__FILE__), 0, 20) .'.log' : $deduplicationStore;
+        $this->deduplicationStore = $deduplicationStore === null ? sys_get_temp_dir() . '/monolog-dedup-' . Utils::substr(md5(__FILE__), 0, 20) .'.log' : $deduplicationStore;
         $this->deduplicationLevel = Logger::toMonologLevel($deduplicationLevel);
         $this->time = $time;
     }
@@ -149,7 +150,7 @@ class DeduplicationHandler extends BufferHandler
 
         while (!feof($handle)) {
             $log = fgets($handle);
-            if ($log && substr($log, 0, 10) >= $timestampValidity) {
+            if ($log && Utils::substr($log, 0, 10) >= $timestampValidity) {
                 $validLogs[] = $log;
             }
         }

+ 2 - 1
src/Monolog/Handler/FleepHookHandler.php

@@ -14,6 +14,7 @@ namespace Monolog\Handler;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\Formatter\LineFormatter;
 use Monolog\Logger;
+use Monolog\Utils;
 
 /**
  * Sends logs to Fleep.io using Webhook integrations
@@ -96,7 +97,7 @@ class FleepHookHandler extends SocketHandler
         $header = "POST " . static::FLEEP_HOOK_URI . $this->token . " HTTP/1.1\r\n";
         $header .= "Host: " . static::FLEEP_HOST . "\r\n";
         $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
-        $header .= "Content-Length: " . strlen($content) . "\r\n";
+        $header .= "Content-Length: " . Utils::strlen($content) . "\r\n";
         $header .= "\r\n";
 
         return $header;

+ 2 - 1
src/Monolog/Handler/FlowdockHandler.php

@@ -14,6 +14,7 @@ namespace Monolog\Handler;
 use Monolog\Logger;
 use Monolog\Formatter\FlowdockFormatter;
 use Monolog\Formatter\FormatterInterface;
+use Monolog\Utils;
 
 /**
  * Sends notifications through the Flowdock push API
@@ -107,7 +108,7 @@ class FlowdockHandler extends SocketHandler
         $header = "POST /v1/messages/team_inbox/" . $this->apiToken . " HTTP/1.1\r\n";
         $header .= "Host: api.flowdock.com\r\n";
         $header .= "Content-Type: application/json\r\n";
-        $header .= "Content-Length: " . strlen($content) . "\r\n";
+        $header .= "Content-Length: " . Utils::strlen($content) . "\r\n";
         $header .= "\r\n";
 
         return $header;

+ 2 - 1
src/Monolog/Handler/MailHandler.php

@@ -13,6 +13,7 @@ namespace Monolog\Handler;
 
 use Monolog\Formatter\FormatterInterface;
 use Monolog\Formatter\HtmlFormatter;
+use Monolog\Utils;
 
 /**
  * Base class for all mail handlers
@@ -70,7 +71,7 @@ abstract class MailHandler extends AbstractProcessingHandler
 
     protected function isHtmlBody(string $body): bool
     {
-        return substr($body, 0, 1) === '<';
+        return Utils::substr($body, 0, 1) === '<';
     }
 
     /**

+ 5 - 5
src/Monolog/Handler/OverflowHandler.php

@@ -13,7 +13,6 @@ namespace Monolog\Handler;
 
 use Monolog\Logger;
 
-
 /**
  * Handler to only pass log messages when a certain threshold of number of messages is reached.
  *
@@ -60,9 +59,9 @@ class OverflowHandler extends AbstractHandler
 
     /**
      * @param HandlerInterface $handler
-     * @param int[] $thresholdMap Dictionary of logger level => threshold
-     * @param int $level
-     * @param bool $bubble
+     * @param int[]            $thresholdMap Dictionary of logger level => threshold
+     * @param int              $level
+     * @param bool             $bubble
      */
     public function __construct(
         HandlerInterface $handler,
@@ -87,7 +86,7 @@ class OverflowHandler extends AbstractHandler
      * Unless the bubbling is interrupted (by returning true), the Logger class will keep on
      * calling further handlers in the stack with a given log record.
      *
-     * @param  array $record The record to handle
+     * @param array $record The record to handle
      *
      * @return Boolean true means that this handler handled the record, and that bubbling is not permitted.
      *                 false means the record was either not processed or that this handler allows bubbling.
@@ -108,6 +107,7 @@ class OverflowHandler extends AbstractHandler
             // The overflow threshold is not yet reached, so we're buffering the record and lowering the threshold by 1
             $this->thresholdMap[$level]--;
             $this->buffer[$level][] = $record;
+
             return false === $this->bubble;
         }
 

+ 4 - 3
src/Monolog/Handler/PushoverHandler.php

@@ -12,6 +12,7 @@
 namespace Monolog\Handler;
 
 use Monolog\Logger;
+use Monolog\Utils;
 
 /**
  * Sends notifications through the pushover api to mobile phones
@@ -115,10 +116,10 @@ class PushoverHandler extends SocketHandler
     private function buildContent(array $record): string
     {
         // Pushover has a limit of 512 characters on title and message combined.
-        $maxMessageLength = 512 - strlen($this->title);
+        $maxMessageLength = 512 - Utils::strlen($this->title);
 
         $message = ($this->useFormattedMessage) ? $record['formatted'] : $record['message'];
-        $message = substr($message, 0, $maxMessageLength);
+        $message = Utils::substr($message, 0, $maxMessageLength);
 
         $timestamp = $record['datetime']->getTimestamp();
 
@@ -158,7 +159,7 @@ class PushoverHandler extends SocketHandler
         $header = "POST /1/messages.json HTTP/1.1\r\n";
         $header .= "Host: api.pushover.net\r\n";
         $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
-        $header .= "Content-Length: " . strlen($content) . "\r\n";
+        $header .= "Content-Length: " . Utils::strlen($content) . "\r\n";
         $header .= "\r\n";
 
         return $header;

+ 2 - 1
src/Monolog/Handler/Slack/SlackRecord.php

@@ -14,6 +14,7 @@ namespace Monolog\Handler\Slack;
 use Monolog\Logger;
 use Monolog\Formatter\NormalizerFormatter;
 use Monolog\Formatter\FormatterInterface;
+use Monolog\Utils;
 
 /**
  * Slack record utility helping to log to Slack webhooks or API.
@@ -307,7 +308,7 @@ class SlackRecord
     private function generateAttachmentField(string $title, $value): array
     {
         $value = is_array($value)
-            ? sprintf('```%s```', substr($this->stringify($value), 0, 1990))
+            ? sprintf('```%s```', Utils::substr($this->stringify($value), 0, 1990))
             : $value;
 
         return array(

+ 2 - 1
src/Monolog/Handler/SlackHandler.php

@@ -14,6 +14,7 @@ namespace Monolog\Handler;
 use Monolog\Formatter\FormatterInterface;
 use Monolog\Logger;
 use Monolog\Handler\Slack\SlackRecord;
+use Monolog\Utils;
 
 /**
  * Sends notifications through Slack API
@@ -129,7 +130,7 @@ class SlackHandler extends SocketHandler
         $header = "POST /api/chat.postMessage HTTP/1.1\r\n";
         $header .= "Host: slack.com\r\n";
         $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
-        $header .= "Content-Length: " . strlen($content) . "\r\n";
+        $header .= "Content-Length: " . Utils::strlen($content) . "\r\n";
         $header .= "\r\n";
 
         return $header;

+ 2 - 1
src/Monolog/Handler/SocketHandler.php

@@ -12,6 +12,7 @@
 namespace Monolog\Handler;
 
 use Monolog\Logger;
+use Monolog\Utils;
 
 /**
  * Stores to any socket - uses fsockopen() or pfsockopen().
@@ -325,7 +326,7 @@ class SocketHandler extends AbstractProcessingHandler
 
     private function writeToSocket(string $data): void
     {
-        $length = strlen($data);
+        $length = Utils::strlen($data);
         $sent = 0;
         $this->lastSentBytes = $sent;
         while ($this->isConnected() && $sent < $length) {

+ 3 - 2
src/Monolog/Handler/SqsHandler.php

@@ -13,6 +13,7 @@ namespace Monolog\Handler;
 
 use Aws\Sqs\SqsClient;
 use Monolog\Logger;
+use Monolog\Utils;
 
 /**
  * Writes to any sqs queue.
@@ -51,8 +52,8 @@ class SqsHandler extends AbstractProcessingHandler
         }
 
         $messageBody = $record['formatted'];
-        if (strlen($messageBody) >= static::MAX_MESSAGE_SIZE) {
-            $messageBody = substr($messageBody, 0, static::HEAD_MESSAGE_SIZE);
+        if (Utils::strlen($messageBody) >= static::MAX_MESSAGE_SIZE) {
+            $messageBody = Utils::substr($messageBody, 0, static::HEAD_MESSAGE_SIZE);
         }
 
         $this->client->sendMessage([

+ 3 - 2
src/Monolog/Handler/StreamHandler.php

@@ -12,6 +12,7 @@
 namespace Monolog\Handler;
 
 use Monolog\Logger;
+use Monolog\Utils;
 
 /**
  * Stores to any stream resource
@@ -146,8 +147,8 @@ class StreamHandler extends AbstractProcessingHandler
             return dirname($stream);
         }
 
-        if ('file://' === substr($stream, 0, 7)) {
-            return dirname(substr($stream, 7));
+        if ('file://' === Utils::substr($stream, 0, 7)) {
+            return dirname(Utils::substr($stream, 7));
         }
 
         return null;

+ 5 - 3
src/Monolog/Handler/SyslogUdp/UdpSocket.php

@@ -11,6 +11,8 @@
 
 namespace Monolog\Handler\SyslogUdp;
 
+use Monolog\Utils;
+
 class UdpSocket
 {
     protected const DATAGRAM_MAX_LENGTH = 65023;
@@ -47,13 +49,13 @@ class UdpSocket
         if (!is_resource($this->socket)) {
             throw new \RuntimeException('The UdpSocket to '.$this->ip.':'.$this->port.' has been closed and can not be written to anymore');
         }
-        socket_sendto($this->socket, $chunk, strlen($chunk), $flags = 0, $this->ip, $this->port);
+        socket_sendto($this->socket, $chunk, Utils::strlen($chunk), $flags = 0, $this->ip, $this->port);
     }
 
     protected function assembleMessage(string $line, string $header): string
     {
-        $chunkSize = static::DATAGRAM_MAX_LENGTH - strlen($header);
+        $chunkSize = static::DATAGRAM_MAX_LENGTH - Utils::strlen($header);
 
-        return $header . substr($line, 0, $chunkSize);
+        return $header . Utils::substr($line, 0, $chunkSize);
     }
 }

+ 12 - 3
src/Monolog/Handler/TelegramBotHandler.php

@@ -1,4 +1,13 @@
-<?php
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
 
 namespace Monolog\Handler;
 
@@ -38,7 +47,7 @@ class TelegramBotHandler extends AbstractProcessingHandler
     private $channel;
 
     /**
-     * @param string $apiKey Telegram bot access token provided by BotFather
+     * @param string $apiKey  Telegram bot access token provided by BotFather
      * @param string $channel Telegram channel name
      * @inheritDoc
      */
@@ -87,4 +96,4 @@ class TelegramBotHandler extends AbstractProcessingHandler
             throw new RuntimeException('Telegram API error. Description: ' . $result['description']);
         }
     }
-}
+}

+ 3 - 2
src/Monolog/Processor/UidProcessor.php

@@ -12,6 +12,7 @@
 namespace Monolog\Processor;
 
 use Monolog\ResettableInterface;
+use Monolog\Utils;
 
 /**
  * Adds a unique identifier into records
@@ -45,11 +46,11 @@ class UidProcessor implements ProcessorInterface, ResettableInterface
 
     public function reset()
     {
-        $this->uid = $this->generateUid(strlen($this->uid));
+        $this->uid = $this->generateUid(Utils::strlen($this->uid));
     }
 
     private function generateUid(int $length): string
     {
-        return substr(bin2hex(random_bytes((int) ceil($length / 2))), 0, $length);
+        return Utils::substr(bin2hex(random_bytes((int) ceil($length / 2))), 0, $length);
     }
 }

+ 29 - 0
src/Monolog/Utils.php

@@ -22,4 +22,33 @@ final class Utils
 
         return 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class;
     }
+
+    private static function hasMbString(): bool
+    {
+        static $hasMbString;
+
+        if (null === $hasMbString) {
+            $hasMbString = extension_loaded('mbstring');
+        }
+
+        return $hasMbString;
+    }
+
+    public static function strlen(string $string, ?string $encoding = null): int
+    {
+        if (self::hasMbString()) {
+            return mb_strlen($string, $encoding);
+        }
+
+        return strlen($string);
+    }
+
+    public static function substr(string $string, int $start, ?int $length = null)
+    {
+        if (self::hasMbString()) {
+            return mb_substr($string, $start, $length);
+        }
+
+        return substr($string, $start, $length);
+    }
 }

+ 0 - 1
tests/Monolog/Handler/AmqpHandlerTest.php

@@ -14,7 +14,6 @@ namespace Monolog\Handler;
 use Monolog\Test\TestCase;
 use Monolog\Logger;
 use PhpAmqpLib\Message\AMQPMessage;
-use PhpAmqpLib\Connection\AMQPConnection;
 
 /**
  * @covers Monolog\Handler\RotatingFileHandler

+ 0 - 1
tests/Monolog/Handler/SyslogUdpHandlerTest.php

@@ -75,7 +75,6 @@ class SyslogUdpHandlerTest extends TestCase
         $handler->handle($this->getRecordWithMessage(null));
     }
 
-
     public function testRfc()
     {
         $time = 'Mar 22 21:16:47';

+ 11 - 2
tests/Monolog/Handler/TelegramBotHandlerTest.php

@@ -1,4 +1,13 @@
-<?php
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
 
 namespace Monolog\Handler;
 
@@ -39,4 +48,4 @@ class TelegramBotHandlerTest extends TestCase
             ->method('send')
             ->willReturn(null);
     }
-}
+}