Merge pull request #2398 from shlinkio/develop

Release 4.4.6
This commit is contained in:
Alejandro Celaya
2025-03-20 09:24:27 +01:00
committed by GitHub
8 changed files with 56 additions and 15 deletions

View File

@@ -96,7 +96,7 @@ jobs:
- upload-coverage
runs-on: ubuntu-24.04
steps:
- uses: geekyeggo/delete-artifact@v2
- uses: geekyeggo/delete-artifact@v5
with:
name: |
coverage-*

View File

@@ -45,6 +45,6 @@ jobs:
needs: ['publish']
runs-on: ubuntu-24.04
steps:
- uses: geekyeggo/delete-artifact@v2
- uses: geekyeggo/delete-artifact@v5
with:
name: dist-files-*

View File

@@ -4,6 +4,24 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com), and this project adheres to [Semantic Versioning](https://semver.org).
## [4.4.6] - 2025-03-20
### Added
* *Nothing*
### Changed
* *Nothing*
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#2391](https://github.com/shlinkio/shlink/issues/2391) When sending visits to Matomo, send the country code, not the country name.
* Fix error with new option introduced by `endroid/qr-code` 6.0.4.
## [4.4.5] - 2025-03-01
### Added
* *Nothing*

View File

@@ -24,7 +24,7 @@
"doctrine/migrations": "^3.8",
"doctrine/orm": "^3.3",
"donatj/phpuseragentparser": "^1.10",
"endroid/qr-code": "^6.0",
"endroid/qr-code": "^6.0.5",
"friendsofphp/proxy-manager-lts": "^1.0",
"geoip2/geoip2": "^3.1",
"guzzlehttp/guzzle": "^7.9",
@@ -77,7 +77,8 @@
"veewee/composer-run-parallel": "^1.4"
},
"conflict": {
"symfony/var-exporter": ">=6.3.9,<=6.4.0"
"symfony/var-exporter": ">=6.3.9,<=6.4.0",
"phpunit/phpunit": "12.0.9"
},
"autoload": {
"psr-4": {

View File

@@ -38,6 +38,7 @@ final readonly class QrCodeParams
public int $size,
public int $margin,
public WriterInterface $writer,
public array $writerOptions,
public ErrorCorrectionLevel $errorCorrectionLevel,
public RoundBlockSizeMode $roundBlockSizeMode,
public ColorInterface $color,
@@ -49,11 +50,13 @@ final readonly class QrCodeParams
public static function fromRequest(ServerRequestInterface $request, QrCodeOptions $defaults): self
{
$query = $request->getQueryParams();
[$writer, $writerOptions] = self::resolveWriterAndWriterOptions($query, $defaults);
return new self(
size: self::resolveSize($query, $defaults),
margin: self::resolveMargin($query, $defaults),
writer: self::resolveWriter($query, $defaults),
writer: $writer,
writerOptions: $writerOptions,
errorCorrectionLevel: self::resolveErrorCorrection($query, $defaults),
roundBlockSizeMode: self::resolveRoundBlockSize($query, $defaults),
color: self::resolveColor($query, $defaults),
@@ -83,14 +86,17 @@ final readonly class QrCodeParams
return max($intMargin, 0);
}
private static function resolveWriter(array $query, QrCodeOptions $defaults): WriterInterface
/**
* @return array{WriterInterface, array}
*/
private static function resolveWriterAndWriterOptions(array $query, QrCodeOptions $defaults): array
{
$qFormat = self::normalizeParam($query['format'] ?? '');
$format = contains($qFormat, self::SUPPORTED_FORMATS) ? $qFormat : self::normalizeParam($defaults->format);
return match ($format) {
'svg' => new SvgWriter(),
default => new PngWriter(),
'svg' => [new SvgWriter(), []],
default => [new PngWriter(), [PngWriter::WRITER_OPTION_NUMBER_OF_COLORS => null]],
};
}

View File

@@ -45,6 +45,7 @@ readonly class QrCodeAction implements MiddlewareInterface
$params = QrCodeParams::fromRequest($request, $this->options);
$qrCodeBuilder = new Builder(
writer: $params->writer,
writerOptions: $params->writerOptions,
data: $this->stringifier->stringify($shortUrl),
errorCorrectionLevel: $params->errorCorrectionLevel,
size: $params->size,

View File

@@ -11,6 +11,8 @@ use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Visit\Repository\VisitIterationRepositoryInterface;
use Throwable;
use function strtolower;
readonly class MatomoVisitSender implements MatomoVisitSenderInterface
{
public function __construct(
@@ -60,7 +62,7 @@ readonly class MatomoVisitSender implements MatomoVisitSenderInterface
if ($location !== null) {
$tracker
->setCity($location->cityName)
->setCountry($location->countryName)
->setCountry(strtolower($location->countryCode))
->setLatitude($location->latitude)
->setLongitude($location->longitude);
}

View File

@@ -43,6 +43,9 @@ class MatomoVisitSenderTest extends TestCase
}
#[Test, DataProvider('provideTrackerMethods')]
/**
* @param array<string, string[]> $invokedMethods
*/
public function visitIsSentToMatomo(Visit $visit, string|null $originalIpAddress, array $invokedMethods): void
{
$tracker = $this->createMock(MatomoTracker::class);
@@ -66,8 +69,8 @@ class MatomoVisitSenderTest extends TestCase
)->willReturn($tracker);
}
foreach ($invokedMethods as $invokedMethod) {
$tracker->expects($this->once())->method($invokedMethod)->willReturn($tracker);
foreach ($invokedMethods as $invokedMethod => $args) {
$tracker->expects($this->once())->method($invokedMethod)->with(...$args)->willReturn($tracker);
}
$this->trackerBuilder->expects($this->once())->method('buildMatomoTracker')->willReturn($tracker);
@@ -81,18 +84,28 @@ class MatomoVisitSenderTest extends TestCase
yield 'located regular visit' => [
Visit::forValidShortUrl(ShortUrl::withLongUrl('https://shlink.io'), Visitor::empty())
->locate(VisitLocation::fromGeolocation(new Location(
countryCode: 'countryCode',
countryCode: 'US',
countryName: 'countryName',
regionName: 'regionName',
city: 'city',
latitude: 123,
longitude: 123,
longitude: 456,
timeZone: 'timeZone',
))),
'1.2.3.4',
['setCity', 'setCountry', 'setLatitude', 'setLongitude', 'setIp'],
[
'setCity' => ['city'],
'setCountry' => ['us'],
'setLatitude' => [123],
'setLongitude' => [456],
'setIp' => ['1.2.3.4'],
],
];
yield 'fallback IP' => [
Visit::forBasePath(Visitor::fromParams(remoteAddress: '5.6.7.8')),
null,
['setIp' => ['5.6.7.0']],
];
yield 'fallback IP' => [Visit::forBasePath(Visitor::fromParams(remoteAddress: '1.2.3.4')), null, ['setIp']];
}
#[Test, DataProvider('provideUrlsToTrack')]