Skip to content

Commit 94a20e5

Browse files
committed
Added JsonLoggingFormatter, min version php 8.1
1 parent fd99ebb commit 94a20e5

35 files changed

Lines changed: 451 additions & 448 deletions
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
FROM php:8.0-fpm-alpine
1+
FROM php:8.1-fpm-alpine
22

33
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
44

5-
WORKDIR /http-client
5+
WORKDIR /http-client

composer.json

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,26 @@
1414
}
1515
],
1616
"require": {
17-
"php": ">=7.1",
18-
"composer/ca-bundle": "^1.1",
19-
"psr/log": "^1.0",
20-
"psr/http-message": "^1.0",
17+
"php": ">=8.1",
18+
"composer/ca-bundle": "^1.4",
19+
"psr/log": "^3.0",
20+
"psr/http-message": "^1.0 | ^2.0",
2121
"psr/http-client": "^1.0",
22-
"guzzlehttp/psr7": "^1.4 | ^2.0",
22+
"guzzlehttp/psr7": "^1.4 |^2.6",
2323
"ext-json": "*",
2424
"ext-curl": "*"
2525
},
2626
"require-dev": {
27-
"nette/tester": ">=2.3",
27+
"nette/tester": "^2.5",
2828
"guzzlehttp/guzzle": "^6.0 | ^7.0",
29-
"tracy/tracy": ">=2.7",
30-
"nette/di": "^3.0",
31-
"phpstan/phpstan": "^0.12.85",
32-
"phpstan/phpstan-nette": "^0.12.17",
33-
"react/http": "^1.3",
34-
"react/child-process": "^0.6.2",
35-
"phpstan/phpstan-strict-rules": "^0.12.9",
36-
"orisai/coding-standard": "^1.1"
29+
"tracy/tracy": "^2.10",
30+
"nette/di": "^3.1",
31+
"phpstan/phpstan": "^1.10",
32+
"phpstan/phpstan-nette": "^1.2",
33+
"react/http": "^1.9",
34+
"react/child-process": "^0.6.5",
35+
"phpstan/phpstan-strict-rules": "^1.5",
36+
"orisai/coding-standard": "^3.10"
3737
},
3838
"suggest": {
3939
"ext-curl": "to use class CurlHttpClient",

src/Fapi/HttpClient/BaseLoggingFormatter.php

Lines changed: 1 addition & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -2,118 +2,7 @@
22

33
namespace Fapi\HttpClient;
44

5-
use Fapi\HttpClient\Utils\Json;
6-
use Fapi\HttpClient\Utils\JsonException;
7-
use Psr\Http\Message\RequestInterface;
8-
use Psr\Http\Message\ResponseInterface;
9-
use Throwable;
10-
use function base64_encode;
11-
use function extension_loaded;
12-
use function function_exists;
13-
use function get_class;
14-
use function iconv_substr;
15-
use function mb_substr;
16-
use function serialize;
17-
use function sprintf;
18-
use function strlen;
19-
use function substr;
20-
use const JSON_UNESCAPED_UNICODE;
21-
22-
final class BaseLoggingFormatter implements ILoggingFormatter
5+
final class BaseLoggingFormatter extends \Fapi\HttpClient\LoggingFormatters\BaseLoggingFormatter implements ILoggingFormatter
236
{
247

25-
/** @var int */
26-
private $maxBodyLength;
27-
28-
public function __construct(int $maxBodyLength = 40000)
29-
{
30-
$this->maxBodyLength = $maxBodyLength;
31-
}
32-
33-
public function formatSuccessful(RequestInterface $request, ResponseInterface $response, float $elapsedTime): string
34-
{
35-
return 'Fapi\HttpClient: an HTTP request has been sent.'
36-
. $this->dumpHttpRequest($request)
37-
. $this->dumpHttpResponse($response)
38-
. $this->dumpElapsedTime($elapsedTime);
39-
}
40-
41-
public function formatFailed(RequestInterface $request, Throwable $exception, float $elapsedTime): string
42-
{
43-
return 'Fapi\HttpClient: an HTTP request failed.'
44-
. $this->dumpHttpRequest($request)
45-
. $this->dumpException($exception)
46-
. $this->dumpElapsedTime($elapsedTime);
47-
}
48-
49-
private function dumpHttpRequest(RequestInterface $request): string
50-
{
51-
$body = $this->processBody((string) $request->getBody());
52-
53-
return ' Request URL: ' . $this->dumpValue((string) $request->getUri())
54-
. ' Request method: ' . $this->dumpValue($request->getMethod())
55-
. ' Request headers: ' . $this->dumpValue($request->getHeaders())
56-
. ' Request body: ' . $this->dumpValue($body);
57-
}
58-
59-
private function dumpHttpResponse(ResponseInterface $response): string
60-
{
61-
$body = $this->processBody((string) $response->getBody());
62-
63-
return ' Response status code: ' . $this->dumpValue($response->getStatusCode())
64-
. ' Response headers: ' . $this->dumpValue($response->getHeaders())
65-
. ' Response body: ' . $this->dumpValue($body);
66-
}
67-
68-
private function dumpException(Throwable $exception): string
69-
{
70-
$dump = ' Exception type: ' . $this->dumpValue(get_class($exception))
71-
. ' Exception message: ' . $this->dumpValue($exception->getMessage());
72-
73-
if ($exception->getPrevious() !== null) {
74-
$previousException = $exception->getPrevious();
75-
76-
$dump .= ' Previous exception type: ' . $this->dumpValue(get_class($previousException))
77-
. ' Previous exception message: ' . $this->dumpValue($previousException->getMessage());
78-
}
79-
80-
return $dump;
81-
}
82-
83-
private function dumpElapsedTime(float $elapsedTime): string
84-
{
85-
$elapsedTime *= 1000;
86-
87-
return ' Elapsed time: ' . sprintf('%0.2f', $elapsedTime) . ' ms';
88-
}
89-
90-
/**
91-
* @param mixed $value
92-
*/
93-
private function dumpValue($value): string
94-
{
95-
try {
96-
return Json::encode($value, JSON_UNESCAPED_UNICODE);
97-
} catch (JsonException $e) {
98-
return '(serialized) ' . base64_encode(serialize($value));
99-
}
100-
}
101-
102-
private function processBody(string $body): string
103-
{
104-
if (strlen($body) <= $this->maxBodyLength) {
105-
return $body;
106-
}
107-
108-
if (function_exists('mb_substr')) {
109-
return mb_substr($body, 0, $this->maxBodyLength, 'UTF-8');
110-
}
111-
112-
if (!extension_loaded('iconv')) {
113-
return (string) iconv_substr($body, 0, $this->maxBodyLength, 'UTF-8');
114-
}
115-
116-
return substr($body, 0, $this->maxBodyLength);
117-
}
118-
1198
}

src/Fapi/HttpClient/Bridges/NetteDI/HttpClientExtension.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php declare(strict_types = 1);
22

3-
namespace Fapi\HttpClient\Bidges\NetteDI;
3+
namespace Fapi\HttpClient\Bridges\NetteDI;
44

55
use Fapi\HttpClient\Bridges\Tracy\BarHttpClient;
66
use Fapi\HttpClient\Bridges\Tracy\TracyToPsrLogger;
@@ -15,14 +15,14 @@ class HttpClientExtension extends CompilerExtension
1515
{
1616

1717
/** @var array<mixed> */
18-
public $defaults = [
18+
public array $defaults = [
1919
'type' => 'guzzle',
2020
'logging' => false,
2121
'bar' => false,
2222
];
2323

2424
/** @var array<string> */
25-
private $typeClasses = [
25+
private array $typeClasses = [
2626
'curl' => CurlHttpClient::class,
2727
'guzzle' => GuzzleHttpClient::class,
2828
];

src/Fapi/HttpClient/Bridges/Tracy/BarHttpClient.php

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,17 @@
1616
final class BarHttpClient implements IHttpClient, IBarPanel
1717
{
1818

19-
/** @var int */
20-
private $maxRequests = 100;
21-
22-
/** @var IHttpClient */
23-
private $httpClient;
19+
private int $maxRequests = 100;
2420

2521
/** @var array<mixed> */
26-
private $requests = [];
22+
private array $requests = [];
2723

28-
/** @var int */
29-
private $count = 0;
24+
private int $count = 0;
3025

31-
/** @var float */
32-
private $totalTime = 0.0;
26+
private float $totalTime = 0.0;
3327

34-
public function __construct(IHttpClient $httpClient)
28+
public function __construct(private IHttpClient $httpClient)
3529
{
36-
$this->httpClient = $httpClient;
3730
Debugger::getBar()->addPanel($this);
3831
}
3932

src/Fapi/HttpClient/Bridges/Tracy/TracyToPsrLogger.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Psr\Log\AbstractLogger;
66
use Psr\Log\LogLevel;
7+
use Stringable;
78
use Throwable;
89
use Tracy\ILogger;
910

@@ -21,18 +22,16 @@ final class TracyToPsrLogger extends AbstractLogger
2122
LogLevel::DEBUG => ILogger::DEBUG,
2223
];
2324

24-
/** @var ILogger */
25-
private $tracyLogger;
26-
27-
public function __construct(ILogger $tracyLogger)
25+
public function __construct(private ILogger $tracyLogger)
2826
{
29-
$this->tracyLogger = $tracyLogger;
3027
}
3128

3229
/**
30+
* @param array<mixed> $context
31+
*
3332
* @inheritdoc
3433
*/
35-
public function log($level, $message, array $context = [])
34+
public function log($level, string|Stringable $message, array $context = []): void
3635
{
3736
$priority = self::PRIORITY_MAP[$level] ?? ILogger::ERROR;
3837

src/Fapi/HttpClient/CapturingHttpClient.php

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,40 +15,29 @@
1515
class CapturingHttpClient implements IHttpClient
1616
{
1717

18-
/** @var IHttpClient */
19-
private $httpClient;
20-
2118
/** @var array<RequestInterface> */
22-
private $httpRequests = [];
19+
private array $httpRequests = [];
2320

2421
/** @var array<ResponseInterface> */
25-
private $httpResponses = [];
26-
27-
/** @var string */
28-
private $file;
29-
30-
/** @var string */
31-
private $className;
22+
private array $httpResponses = [];
3223

33-
public function __construct(IHttpClient $httpClient, string $file, string $className)
24+
public function __construct(private IHttpClient $httpClient, private string $file, private string $className)
3425
{
3526
if (!class_exists('Tester\Dumper')) {
3627
throw new InvalidStateException('Capturing HTTP client requires Nette Tester.');
3728
}
3829

39-
$this->httpClient = $httpClient;
40-
4130
if (is_file($file)) {
4231
require_once $file;
4332
spl_autoload($className);
4433

4534
if (class_exists($className)) {
46-
$this->httpClient = new $className();
35+
/** @var IHttpClient $httpClient */
36+
$httpClient = new $className();
37+
38+
$this->httpClient = $httpClient;
4739
}
4840
}
49-
50-
$this->file = $file;
51-
$this->className = $className;
5241
}
5342

5443
public function sendRequest(RequestInterface $request): ResponseInterface
@@ -82,7 +71,7 @@ private function writeToPhpFile(string $fileName, string $className): void
8271
$code = '<?php declare(strict_types = 1);' . "\n";
8372
$code .= "\n";
8473

85-
if ($namespace) {
74+
if ((bool) $namespace) {
8675
$code .= 'namespace ' . $namespace . ';' . "\n";
8776
$code .= "\n";
8877
}
@@ -106,13 +95,13 @@ private function writeToPhpFile(string $fileName, string $className): void
10695
$code .= "\t\t\t\t" . $this->exportValue((string) $httpRequest->getUri(), "\t\t\t\t") . ",\n";
10796
$code .= "\t\t\t\t" . $this->exportValue($httpRequest->getHeaders(), "\t\t\t\t") . ",\n";
10897
$code .= "\t\t\t\t" . $this->exportValue((string) $httpRequest->getBody(), "\t\t\t\t") . ",\n";
109-
$code .= "\t\t\t\t" . $this->exportValue($httpRequest->getProtocolVersion(), "\t\t\t\t") . "\n";
98+
$code .= "\t\t\t\t" . $this->exportValue($httpRequest->getProtocolVersion(), "\t\t\t\t") . ",\n";
11099
$code .= "\t\t\t" . '),' . "\n";
111100
$code .= "\t\t\t" . 'new HttpResponse(' . "\n";
112101
$code .= "\t\t\t\t" . $this->exportValue($httpResponse->getStatusCode(), "\t\t\t\t") . ",\n";
113102
$code .= "\t\t\t\t" . $this->exportValue($httpResponse->getHeaders(), "\t\t\t\t") . ",\n";
114-
$code .= "\t\t\t\t" . $this->exportValue((string) $httpResponse->getBody(), "\t\t\t\t") . "\n";
115-
$code .= "\t\t\t" . ')' . "\n";
103+
$code .= "\t\t\t\t" . $this->exportValue((string) $httpResponse->getBody(), "\t\t\t\t") . ",\n";
104+
$code .= "\t\t\t" . ')' . ",\n";
116105
$code .= "\t\t" . ');' . "\n";
117106
}
118107

@@ -123,10 +112,7 @@ private function writeToPhpFile(string $fileName, string $className): void
123112
file_put_contents($fileName, $code);
124113
}
125114

126-
/**
127-
* @param mixed $value
128-
*/
129-
private function exportValue($value, string $indent = ''): string
115+
private function exportValue(mixed $value, string $indent = ''): string
130116
{
131117
$s = Dumper::toPhp($value);
132118
$s = str_replace("\n", "\n" . $indent, $s);

0 commit comments

Comments
 (0)