12 Commits
1.1.0 ... 2.0.0

9 changed files with 21 additions and 312 deletions

View File

@ -4,7 +4,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased](https://git.d3data.de/D3Public/guzzleFactory/compare/1.1.0...rel_1.x)
## [Unreleased](https://git.d3data.de/D3Public/guzzleFactory/compare/2.0.0...rel_2.x)
## [2.0.0](https://git.d3data.de/D3Public/guzzleFactory/compare/1.2.0...2.0.0) - 2025-02-10
### removed
- creating logger via LoggerFactory - add configured logger using the `addConfiguredLogger` method
- OXID dependend code - can use from third party LoggerFactory library instead
## [1.2.0](https://git.d3data.de/D3Public/guzzleFactory/compare/1.1.0...1.2.0) - 2025-02-10
### Added
- special log handlers
### Changed
- use [LoggerFactory](https://packagist.org/packages/d3/logger-factory) instead of internal methods
## [1.1.0](https://git.d3data.de/D3Public/guzzleFactory/compare/1.0.0...1.1.0) - 2025-01-27
### Added
@ -15,7 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [1.0.0](https://git.d3data.de/D3Public/guzzleFactory/releases/tag/1.0.0) - 2025-01-01
### Added
- initial implementation
- can create am cutom Guzzle instance
- can create a custom Guzzle instance
- "accept" option
- "contentType" option
- "userAgent" option

View File

@ -17,7 +17,7 @@ composer require d3/guzzle-factory
```
$guzzleFactory = GuzzleFactory::create();
$guzzleFactory->setUserAgent('myApi-php-client/1.0.0'));
$guzzleFactory->addFileLogger('myPluginLogger', 'plugin_requests.log', Logger::DEBUG, 5);
$guzzleFactory->addConfiguredLogger($logger);
$guzzleFactory->setMessageFormatter(
'{method} {uri} HTTP/{version} {req_body}'.PHP_EOL.'RESPONSE: {code} - {res_body}',
['myUsername', 'myPassword']

View File

@ -19,13 +19,13 @@
],
"require": {
"guzzlehttp/guzzle": "^7.0",
"monolog/monolog": "^1.20",
"d3/sensitive-message-formatter": "^1.0"
},
"require-dev": {
"phpunit/phpunit": "^10.5",
"friendsofphp/php-cs-fixer": "^3.65",
"phpstan/phpstan": "^2.0"
"phpstan/phpstan": "^2.0",
"monolog/monolog": "^3.9"
},
"autoload": {
"psr-4": {
@ -38,10 +38,12 @@
}
},
"scripts": {
"test": "./vendor/bin/phpunit --no-coverage",
"test": "XDEBUG_MODE=off ./vendor/bin/phpunit --no-coverage",
"test-coverage": "XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-html=coverage",
"check-style": "./vendor/bin/php-cs-fixer fix --verbose --dry-run",
"fix-style": "./vendor/bin/php-cs-fixer fix --verbose",
"check-code": "./vendor/bin/phpstan analyse -c phpstan.neon --no-progress --ansi"
}
}

View File

@ -1,76 +0,0 @@
<?php
/**
* Copyright (c) D3 Data Development (Inh. Thomas Dartsch)
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\GuzzleFactory\Apps;
use Exception;
use InvalidArgumentException;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use OxidEsales\Eshop\Core\Registry;
use RuntimeException;
trait OxidLoggerTrait
{
public function addOxidLogger(): void
{
if (!class_exists(Registry::class)) {
throw new RuntimeException(__METHOD__.' can executed in OXID eShop installations only');
}
$this->loggers['oxid'] = Registry::getLogger();
}
/**
* @throws Exception
* @throws InvalidArgumentException
*/
public function addCombinedOxidAndFileLogger(
string $loggerName,
string $filePath,
int $logLevel = Logger::INFO,
?int $maxFiles = null
): void
{
if (!class_exists(Registry::class)) {
throw new RuntimeException(__METHOD__.' can executed in OXID eShop installations only');
}
$logger = new Logger($loggerName);
$stream_handler = $this->getFileLoggerStreamHandler($filePath, $logLevel, $maxFiles);
$logger->pushHandler($stream_handler);
$oxidLogFilePath = $this->getOxidLogPath('oxideshop.log');
$oxidStreamHandler = new StreamHandler($oxidLogFilePath, Logger::ERROR);
$logger->pushHandler($oxidStreamHandler);
if (isset($this->loggers['oxid'])) {
unset($this->loggers['oxid']);
}
$this->loggers[$loggerName] = $logger;
}
public function getOxidLogPath(string $fileName): string
{
if (!class_exists(Registry::class)) {
throw new RuntimeException(__METHOD__.' can executed in OXID eShop installations only');
}
return OX_BASE_PATH . '/log' . DIRECTORY_SEPARATOR . $fileName;
}
}

View File

@ -52,6 +52,7 @@ class GuzzleFactory
foreach ($this->getLoggers() as $logger) {
/** @var 'alert'|'critical'|'debug'|'emergency'|'error'|'info'|'notice'|'warning' $logLevelName */
/** @phpstan-ignore argument.type */
$logLevelName = Logger::getLevelName($this->getMessageLevel());
$stack->push(
Middleware::log(

View File

@ -17,59 +17,15 @@ declare(strict_types=1);
namespace D3\GuzzleFactory;
use D3\GuzzleFactory\Apps\OxidLoggerTrait;
use Exception;
use InvalidArgumentException;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Psr\Log\LoggerInterface;
trait LoggerTrait
{
use OxidLoggerTrait;
/** @var LoggerInterface[] */
protected array $loggers = [];
protected ?int $messageLevel = null;
/**
* @throws Exception
* @throws InvalidArgumentException
*/
public function addFileLogger(
string $loggerName,
string $filePath,
int $logLevel = Logger::INFO,
?int $maxFiles = null
): void
{
$logger = new Logger($loggerName);
$stream_handler = $this->getFileLoggerStreamHandler($filePath, $logLevel, $maxFiles);
$logger->pushHandler($stream_handler);
$this->loggers[$loggerName] = $logger;
}
/**
* @param string $filePath
* @param int $logLevel
* @param int|null $maxFiles
* @return AbstractProcessingHandler
* @throws Exception
*/
public function getFileLoggerStreamHandler(
string $filePath,
int $logLevel = Logger::INFO,
?int $maxFiles = null
): AbstractProcessingHandler
{
return is_null($maxFiles) ?
new StreamHandler($filePath, $logLevel) :
new RotatingFileHandler($filePath, $maxFiles, $logLevel);
}
public function addConfiguredLogger(LoggerInterface $logger): void
{
$this->loggers[md5(serialize($logger))] = $logger;

View File

@ -1,153 +0,0 @@
<?php
/**
* Copyright (c) D3 Data Development (Inh. Thomas Dartsch)
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
namespace D3\GuzzleFactory\tests\Apps;
use D3\GuzzleFactory\GuzzleFactory;
use Monolog\Logger;
use ReflectionException;
use RuntimeException;
trait OxidLoggerTestTrait
{
/**
* @test
* @return void
* @throws ReflectionException
* @covers \D3\GuzzleFactory\GuzzleFactory::addOxidLogger
*/
public function testAddOxidLoggerWithoutOxid(): void
{
$sut = GuzzleFactory::create();
$this->expectException(RuntimeException::class);
$this->callMethod(
$sut,
'addOxidLogger',
);
}
/**
* @test
* @return void
* @throws ReflectionException
* @covers \D3\GuzzleFactory\GuzzleFactory::addCombinedOxidAndFileLogger
*/
public function testAddCombinedOxidAndFileLoggerWithoutOxid(): void
{
$sut = GuzzleFactory::create();
$this->expectException(RuntimeException::class);
$this->callMethod(
$sut,
'addCombinedOxidAndFileLogger',
['nameFixture', 'file/path.log', 1, 5]
);
}
/**
* @test
* @return void
* @throws ReflectionException
* @covers \D3\GuzzleFactory\GuzzleFactory::getOxidLogPath
*/
public function testGetOxidLogPathWithoutOxid(): void
{
$sut = GuzzleFactory::create();
$this->expectException(RuntimeException::class);
$this->assertSame(
'foo',
$this->callMethod(
$sut,
'getOxidLogPath',
['fixture.log']
)
);
}
/**
* @test
* @return void
* @throws ReflectionException
* @covers \D3\GuzzleFactory\GuzzleFactory::addOxidLogger
*/
public function testAddOxidLoggerInOxid(): void
{
require_once __DIR__.'/../Helpers/classAliases.php';
$sut = GuzzleFactory::create();
$this->callMethod(
$sut,
'addOxidLogger',
);
$loggers = $this->getValue($sut, 'loggers');
$this->assertArrayHasKey('oxid', $loggers);
$this->assertInstanceOf(Logger::class, $loggers['oxid']);
}
/**
* @test
* @return void
* @throws ReflectionException
* @covers \D3\GuzzleFactory\GuzzleFactory::addCombinedOxidAndFileLogger
*/
public function testAddCombinedOxidAndFileLoggerInOxid(): void
{
require_once __DIR__.'/../Helpers/classAliases.php';
$sut = GuzzleFactory::create();
$this->setValue($sut, 'loggers', ['oxid' => 1]);
$this->callMethod(
$sut,
'addCombinedOxidAndFileLogger',
['nameFixture', 'file/path.log', 1, 5]
);
$loggers = $this->getValue($sut, 'loggers');
$this->assertArrayHasKey('nameFixture', $loggers);
$this->assertArrayNotHasKey('oxid', $loggers);
$this->assertInstanceOf(Logger::class, $loggers['nameFixture']);
}
/**
* @test
* @return void
* @throws ReflectionException
* @covers \D3\GuzzleFactory\GuzzleFactory::getOxidLogPath
*/
public function testGetOxidLogPathInOxid(): void
{
require_once __DIR__.'/../Helpers/classAliases.php';
$sut = GuzzleFactory::create();
$this->assertStringEndsWith(
'tests/Helpers/log/fixture.log',
$this->callMethod(
$sut,
'getOxidLogPath',
['fixture.log']
)
);
}
}

View File

@ -32,7 +32,6 @@ class GuzzleFactoryTest extends ApiTestCase
use HeaderTestTrait;
use LoggerTestTrait;
use MessageFormatterTestTrait;
use OxidLoggerTestTrait;
/**
* @test

View File

@ -16,45 +16,14 @@
namespace D3\GuzzleFactory\tests;
use D3\GuzzleFactory\GuzzleFactory;
use D3\LoggerFactory\LoggerFactory;
use Generator;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use ReflectionException;
trait LoggerTestTrait
{
/**
* @test
* @throws ReflectionException
* @covers \D3\GuzzleFactory\GuzzleFactory::addFileLogger
* @covers \D3\GuzzleFactory\GuzzleFactory::getFileLoggerStreamHandler
* @dataProvider addFileLoggerDataProvider
*/
public function testAddFileLogger(int $logLevel, ?int $maxFiles, string $expectedHandlerClass): void
{
$sut = GuzzleFactory::create();
$this->callMethod(
$sut,
'addFileLogger',
['nameFixture', 'file/path.log', $logLevel, $maxFiles]
);
$loggers = $this->getValue($sut, 'loggers');
$this->assertArrayHasKey('nameFixture', $loggers);
$this->assertInstanceOf(Logger::class, $loggers['nameFixture']);
$this->assertInstanceOf($expectedHandlerClass, $loggers['nameFixture']->getHandlers()[0]);
$this->assertSame($logLevel, $loggers['nameFixture']->popHandler('nameFixture')->getLevel());
}
public static function addFileLoggerDataProvider(): Generator
{
yield 'no rotation' => [Logger::INFO, null, StreamHandler::class];
yield 'rotation 1' => [Logger::ERROR, 1, RotatingFileHandler::class];
yield 'rotation 20' => [Logger::DEBUG, 20, RotatingFileHandler::class];
}
/**
* @test
* @return void