mirror of
https://github.com/shlinkio/shlink.git
synced 2025-02-25 18:45:27 -06:00
Remove usage of Functional\map function
This commit is contained in:
@@ -199,7 +199,7 @@ services:
|
|||||||
|
|
||||||
shlink_swagger_ui:
|
shlink_swagger_ui:
|
||||||
container_name: shlink_swagger_ui
|
container_name: shlink_swagger_ui
|
||||||
image: swaggerapi/swagger-ui:v5.9.1
|
image: swaggerapi/swagger-ui:v5.10.3
|
||||||
ports:
|
ports:
|
||||||
- "8005:8080"
|
- "8005:8080"
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use Symfony\Component\Console\Input\InputOption;
|
|||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
use function array_filter;
|
use function array_filter;
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
use function implode;
|
use function implode;
|
||||||
use function sprintf;
|
use function sprintf;
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ class ListKeysCommand extends Command
|
|||||||
{
|
{
|
||||||
$enabledOnly = $input->getOption('enabled-only');
|
$enabledOnly = $input->getOption('enabled-only');
|
||||||
|
|
||||||
$rows = map($this->apiKeyService->listKeys($enabledOnly), function (ApiKey $apiKey) use ($enabledOnly) {
|
$rows = array_map(function (ApiKey $apiKey) use ($enabledOnly) {
|
||||||
$expiration = $apiKey->getExpirationDate();
|
$expiration = $apiKey->getExpirationDate();
|
||||||
$messagePattern = $this->determineMessagePattern($apiKey);
|
$messagePattern = $this->determineMessagePattern($apiKey);
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ class ListKeysCommand extends Command
|
|||||||
));
|
));
|
||||||
|
|
||||||
return $rowData;
|
return $rowData;
|
||||||
});
|
}, $this->apiKeyService->listKeys($enabledOnly));
|
||||||
|
|
||||||
ShlinkTable::withRowSeparators($output)->render(array_filter([
|
ShlinkTable::withRowSeparators($output)->render(array_filter([
|
||||||
'Key',
|
'Key',
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ use Symfony\Component\Lock\LockFactory;
|
|||||||
use Symfony\Component\Process\PhpExecutableFinder;
|
use Symfony\Component\Process\PhpExecutableFinder;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
|
use function array_map;
|
||||||
use function Functional\contains;
|
use function Functional\contains;
|
||||||
use function Functional\map;
|
|
||||||
use function Functional\some;
|
use function Functional\some;
|
||||||
|
|
||||||
class CreateDatabaseCommand extends AbstractDatabaseCommand
|
class CreateDatabaseCommand extends AbstractDatabaseCommand
|
||||||
@@ -70,7 +70,7 @@ class CreateDatabaseCommand extends AbstractDatabaseCommand
|
|||||||
{
|
{
|
||||||
$existingTables = $this->ensureDatabaseExistsAndGetTables();
|
$existingTables = $this->ensureDatabaseExistsAndGetTables();
|
||||||
$allMetadata = $this->em->getMetadataFactory()->getAllMetadata();
|
$allMetadata = $this->em->getMetadataFactory()->getAllMetadata();
|
||||||
$shlinkTables = map($allMetadata, static fn (ClassMetadata $metadata) => $metadata->getTableName());
|
$shlinkTables = array_map(static fn (ClassMetadata $metadata) => $metadata->getTableName(), $allMetadata);
|
||||||
|
|
||||||
// If at least one of the shlink tables exist, we will consider the database exists somehow.
|
// If at least one of the shlink tables exist, we will consider the database exists somehow.
|
||||||
// Any other inconsistency will be taken care of by the migrations.
|
// Any other inconsistency will be taken care of by the migrations.
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ use Symfony\Component\Console\Input\InputInterface;
|
|||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
|
|
||||||
class ListDomainsCommand extends Command
|
class ListDomainsCommand extends Command
|
||||||
{
|
{
|
||||||
public const NAME = 'domain:list';
|
public const NAME = 'domain:list';
|
||||||
|
|
||||||
public function __construct(private DomainServiceInterface $domainService)
|
public function __construct(private readonly DomainServiceInterface $domainService)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
@@ -47,7 +47,7 @@ class ListDomainsCommand extends Command
|
|||||||
|
|
||||||
$table->render(
|
$table->render(
|
||||||
$showRedirects ? [...$commonFields, '"Not found" redirects'] : $commonFields,
|
$showRedirects ? [...$commonFields, '"Not found" redirects'] : $commonFields,
|
||||||
map($domains, function (DomainItem $domain) use ($showRedirects) {
|
array_map(function (DomainItem $domain) use ($showRedirects) {
|
||||||
$commonValues = [$domain->toString(), $domain->isDefault ? 'Yes' : 'No'];
|
$commonValues = [$domain->toString(), $domain->isDefault ? 'Yes' : 'No'];
|
||||||
|
|
||||||
return $showRedirects
|
return $showRedirects
|
||||||
@@ -56,7 +56,7 @@ class ListDomainsCommand extends Command
|
|||||||
$this->notFoundRedirectsToString($domain->notFoundRedirectConfig),
|
$this->notFoundRedirectsToString($domain->notFoundRedirectConfig),
|
||||||
]
|
]
|
||||||
: $commonValues;
|
: $commonValues;
|
||||||
}),
|
}, $domains),
|
||||||
);
|
);
|
||||||
|
|
||||||
return ExitCode::EXIT_SUCCESS;
|
return ExitCode::EXIT_SUCCESS;
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
|
||||||
use function array_keys;
|
use function array_keys;
|
||||||
|
use function array_map;
|
||||||
use function array_pad;
|
use function array_pad;
|
||||||
use function explode;
|
use function explode;
|
||||||
use function Functional\map;
|
|
||||||
use function implode;
|
use function implode;
|
||||||
use function sprintf;
|
use function sprintf;
|
||||||
|
|
||||||
@@ -184,10 +184,10 @@ class ListShortUrlsCommand extends Command
|
|||||||
): Paginator {
|
): Paginator {
|
||||||
$shortUrls = $this->shortUrlService->listShortUrls($params);
|
$shortUrls = $this->shortUrlService->listShortUrls($params);
|
||||||
|
|
||||||
$rows = map($shortUrls, function (ShortUrl $shortUrl) use ($columnsMap) {
|
$rows = array_map(function (ShortUrl $shortUrl) use ($columnsMap) {
|
||||||
$rawShortUrl = $this->transformer->transform($shortUrl);
|
$rawShortUrl = $this->transformer->transform($shortUrl);
|
||||||
return map($columnsMap, fn (callable $call) => $call($rawShortUrl, $shortUrl));
|
return array_map(fn (callable $call) => $call($rawShortUrl, $shortUrl), $columnsMap);
|
||||||
});
|
}, [...$shortUrls]);
|
||||||
|
|
||||||
ShlinkTable::default($output)->render(
|
ShlinkTable::default($output)->render(
|
||||||
array_keys($columnsMap),
|
array_keys($columnsMap),
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ use Symfony\Component\Console\Command\Command;
|
|||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
|
|
||||||
class ListTagsCommand extends Command
|
class ListTagsCommand extends Command
|
||||||
{
|
{
|
||||||
public const NAME = 'tag:list';
|
public const NAME = 'tag:list';
|
||||||
|
|
||||||
public function __construct(private TagServiceInterface $tagService)
|
public function __construct(private readonly TagServiceInterface $tagService)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
@@ -44,9 +44,9 @@ class ListTagsCommand extends Command
|
|||||||
return [['No tags found', '-', '-']];
|
return [['No tags found', '-', '-']];
|
||||||
}
|
}
|
||||||
|
|
||||||
return map(
|
return array_map(
|
||||||
$tags,
|
|
||||||
static fn (TagInfo $tagInfo) => [$tagInfo->tag, $tagInfo->shortUrlsCount, $tagInfo->visitsSummary->total],
|
static fn (TagInfo $tagInfo) => [$tagInfo->tag, $tagInfo->shortUrlsCount, $tagInfo->visitsSummary->total],
|
||||||
|
[...$tags],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,15 @@ use Symfony\Component\Console\Command\Command;
|
|||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
use function array_filter;
|
||||||
use function array_keys;
|
use function array_keys;
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
use function Functional\select_keys;
|
use function in_array;
|
||||||
use function Shlinkio\Shlink\Common\buildDateRange;
|
use function Shlinkio\Shlink\Common\buildDateRange;
|
||||||
use function Shlinkio\Shlink\Core\camelCaseToHumanFriendly;
|
use function Shlinkio\Shlink\Core\camelCaseToHumanFriendly;
|
||||||
|
|
||||||
|
use const ARRAY_FILTER_USE_KEY;
|
||||||
|
|
||||||
abstract class AbstractVisitsListCommand extends Command
|
abstract class AbstractVisitsListCommand extends Command
|
||||||
{
|
{
|
||||||
private readonly StartDateOption $startDateOption;
|
private readonly StartDateOption $startDateOption;
|
||||||
@@ -49,7 +52,7 @@ abstract class AbstractVisitsListCommand extends Command
|
|||||||
private function resolveRowsAndHeaders(Paginator $paginator): array
|
private function resolveRowsAndHeaders(Paginator $paginator): array
|
||||||
{
|
{
|
||||||
$extraKeys = [];
|
$extraKeys = [];
|
||||||
$rows = map($paginator->getCurrentPageResults(), function (Visit $visit) use (&$extraKeys) {
|
$rows = array_map(function (Visit $visit) use (&$extraKeys) {
|
||||||
$extraFields = $this->mapExtraFields($visit);
|
$extraFields = $this->mapExtraFields($visit);
|
||||||
$extraKeys = array_keys($extraFields);
|
$extraKeys = array_keys($extraFields);
|
||||||
|
|
||||||
@@ -60,9 +63,18 @@ abstract class AbstractVisitsListCommand extends Command
|
|||||||
...$extraFields,
|
...$extraFields,
|
||||||
];
|
];
|
||||||
|
|
||||||
return select_keys($rowData, ['referer', 'date', 'userAgent', 'country', 'city', ...$extraKeys]);
|
// Filter out unknown keys
|
||||||
});
|
return array_filter(
|
||||||
$extra = map($extraKeys, camelCaseToHumanFriendly(...));
|
$rowData,
|
||||||
|
static fn (string $key) => in_array(
|
||||||
|
$key,
|
||||||
|
['referer', 'date', 'userAgent', 'country', 'city', ...$extraKeys],
|
||||||
|
strict: true,
|
||||||
|
),
|
||||||
|
ARRAY_FILTER_USE_KEY,
|
||||||
|
);
|
||||||
|
}, [...$paginator->getCurrentPageResults()]);
|
||||||
|
$extra = array_map(camelCaseToHumanFriendly(...), $extraKeys);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
$rows,
|
$rows,
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ use Shlinkio\Shlink\Rest\ApiKey\Model\RoleDefinition;
|
|||||||
use Shlinkio\Shlink\Rest\ApiKey\Role;
|
use Shlinkio\Shlink\Rest\ApiKey\Role;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
|
||||||
use function Functional\map;
|
|
||||||
|
|
||||||
class RoleResolverTest extends TestCase
|
class RoleResolverTest extends TestCase
|
||||||
{
|
{
|
||||||
private RoleResolver $resolver;
|
private RoleResolver $resolver;
|
||||||
@@ -49,10 +47,13 @@ class RoleResolverTest extends TestCase
|
|||||||
{
|
{
|
||||||
$domain = self::domainWithId(Domain::withAuthority('example.com'));
|
$domain = self::domainWithId(Domain::withAuthority('example.com'));
|
||||||
$buildInput = static fn (array $definition) => function (TestCase $test) use ($definition): InputInterface {
|
$buildInput = static fn (array $definition) => function (TestCase $test) use ($definition): InputInterface {
|
||||||
|
$returnMap = [];
|
||||||
|
foreach ($definition as $param => $returnValue) {
|
||||||
|
$returnMap[] = [$param, $returnValue];
|
||||||
|
}
|
||||||
|
|
||||||
$input = $test->createStub(InputInterface::class);
|
$input = $test->createStub(InputInterface::class);
|
||||||
$input->method('getOption')->willReturnMap(
|
$input->method('getOption')->willReturnMap($returnMap);
|
||||||
map($definition, static fn (mixed $returnValue, string $param) => [$param, $returnValue]),
|
|
||||||
);
|
|
||||||
|
|
||||||
return $input;
|
return $input;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ use Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdaterInterface;
|
|||||||
use Symfony\Component\Lock;
|
use Symfony\Component\Lock;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
use function range;
|
use function range;
|
||||||
|
|
||||||
class GeolocationDbUpdaterTest extends TestCase
|
class GeolocationDbUpdaterTest extends TestCase
|
||||||
@@ -128,7 +128,7 @@ class GeolocationDbUpdaterTest extends TestCase
|
|||||||
return [$days % 2 === 0 ? $timestamp : (string) $timestamp];
|
return [$days % 2 === 0 ? $timestamp : (string) $timestamp];
|
||||||
};
|
};
|
||||||
|
|
||||||
return map(range(0, 34), $generateParamsWithTimestamp);
|
return array_map($generateParamsWithTimestamp, range(0, 34));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Test]
|
#[Test]
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ use PUGX\Shortid\Factory as ShortIdFactory;
|
|||||||
use Shlinkio\Shlink\Common\Util\DateRange;
|
use Shlinkio\Shlink\Common\Util\DateRange;
|
||||||
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlMode;
|
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlMode;
|
||||||
|
|
||||||
|
use function array_map;
|
||||||
use function date_default_timezone_get;
|
use function date_default_timezone_get;
|
||||||
use function Functional\map;
|
|
||||||
use function Functional\reduce_left;
|
use function Functional\reduce_left;
|
||||||
use function is_array;
|
use function is_array;
|
||||||
use function print_r;
|
use function print_r;
|
||||||
@@ -177,6 +177,6 @@ function enumValues(string $enum): array
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $cache[$enum] ?? (
|
return $cache[$enum] ?? (
|
||||||
$cache[$enum] = map($enum::cases(), static fn (BackedEnum $type) => (string) $type->value)
|
$cache[$enum] = array_map(static fn (BackedEnum $type) => (string) $type->value, $enum::cases())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Shlinkio\Shlink\Core\Config\PostProcessor;
|
namespace Shlinkio\Shlink\Core\Config\PostProcessor;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
|
|
||||||
class BasePathPrefixer
|
class BasePathPrefixer
|
||||||
{
|
{
|
||||||
@@ -23,13 +23,13 @@ class BasePathPrefixer
|
|||||||
|
|
||||||
private function prefixPathsWithBasePath(string $configKey, array $config, string $basePath): array
|
private function prefixPathsWithBasePath(string $configKey, array $config, string $basePath): array
|
||||||
{
|
{
|
||||||
return map($config[$configKey] ?? [], function (array $element) use ($basePath) {
|
return array_map(function (array $element) use ($basePath) {
|
||||||
if (! isset($element['path'])) {
|
if (! isset($element['path'])) {
|
||||||
return $element;
|
return $element;
|
||||||
}
|
}
|
||||||
|
|
||||||
$element['path'] = $basePath . $element['path'];
|
$element['path'] = $basePath . $element['path'];
|
||||||
return $element;
|
return $element;
|
||||||
});
|
}, $config[$configKey] ?? []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Shlinkio\Shlink\Core\Config\PostProcessor;
|
namespace Shlinkio\Shlink\Core\Config\PostProcessor;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
use function str_replace;
|
use function str_replace;
|
||||||
|
|
||||||
class MultiSegmentSlugProcessor
|
class MultiSegmentSlugProcessor
|
||||||
@@ -19,11 +19,11 @@ class MultiSegmentSlugProcessor
|
|||||||
return $config;
|
return $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
$config['routes'] = map($config['routes'] ?? [], static function (array $route): array {
|
$config['routes'] = array_map(static function (array $route): array {
|
||||||
['path' => $path] = $route;
|
['path' => $path] = $route;
|
||||||
$route['path'] = str_replace(self::SINGLE_SEGMENT_PATTERN, self::MULTI_SEGMENT_PATTERN, $path);
|
$route['path'] = str_replace(self::SINGLE_SEGMENT_PATTERN, self::MULTI_SEGMENT_PATTERN, $path);
|
||||||
return $route;
|
return $route;
|
||||||
});
|
}, $config['routes'] ?? []);
|
||||||
|
|
||||||
return $config;
|
return $config;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ use Shlinkio\Shlink\Core\Exception\DomainNotFoundException;
|
|||||||
use Shlinkio\Shlink\Rest\ApiKey\Role;
|
use Shlinkio\Shlink\Rest\ApiKey\Role;
|
||||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||||
|
|
||||||
|
use function array_map;
|
||||||
use function Functional\first;
|
use function Functional\first;
|
||||||
use function Functional\group;
|
use function Functional\group;
|
||||||
use function Functional\map;
|
|
||||||
|
|
||||||
class DomainService implements DomainServiceInterface
|
class DomainService implements DomainServiceInterface
|
||||||
{
|
{
|
||||||
@@ -30,7 +30,7 @@ class DomainService implements DomainServiceInterface
|
|||||||
public function listDomains(?ApiKey $apiKey = null): array
|
public function listDomains(?ApiKey $apiKey = null): array
|
||||||
{
|
{
|
||||||
[$default, $domains] = $this->defaultDomainAndRest($apiKey);
|
[$default, $domains] = $this->defaultDomainAndRest($apiKey);
|
||||||
$mappedDomains = map($domains, fn (Domain $domain) => DomainItem::forNonDefaultDomain($domain));
|
$mappedDomains = array_map(fn (Domain $domain) => DomainItem::forNonDefaultDomain($domain), $domains);
|
||||||
|
|
||||||
if ($apiKey?->hasRole(Role::DOMAIN_SPECIFIC)) {
|
if ($apiKey?->hasRole(Role::DOMAIN_SPECIFIC)) {
|
||||||
return $mappedDomains;
|
return $mappedDomains;
|
||||||
|
|||||||
@@ -19,18 +19,18 @@ use Shlinkio\Shlink\Core\Options\WebhookOptions;
|
|||||||
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
|
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
|
|
||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
class NotifyVisitToWebHooks
|
class NotifyVisitToWebHooks
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private ClientInterface $httpClient,
|
private readonly ClientInterface $httpClient,
|
||||||
private EntityManagerInterface $em,
|
private readonly EntityManagerInterface $em,
|
||||||
private LoggerInterface $logger,
|
private readonly LoggerInterface $logger,
|
||||||
private WebhookOptions $webhookOptions,
|
private readonly WebhookOptions $webhookOptions,
|
||||||
private DataTransformerInterface $transformer,
|
private readonly DataTransformerInterface $transformer,
|
||||||
private AppOptions $appOptions,
|
private readonly AppOptions $appOptions,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,11 +82,11 @@ class NotifyVisitToWebHooks
|
|||||||
*/
|
*/
|
||||||
private function performRequests(array $requestOptions, string $visitId): array
|
private function performRequests(array $requestOptions, string $visitId): array
|
||||||
{
|
{
|
||||||
return map(
|
return array_map(
|
||||||
$this->webhookOptions->webhooks(),
|
|
||||||
fn (string $webhook): PromiseInterface => $this->httpClient
|
fn (string $webhook): PromiseInterface => $this->httpClient
|
||||||
->requestAsync(RequestMethodInterface::METHOD_POST, $webhook, $requestOptions)
|
->requestAsync(RequestMethodInterface::METHOD_POST, $webhook, $requestOptions)
|
||||||
->otherwise(fn (Throwable $e) => $this->logWebhookFailure($webhook, $visitId, $e)),
|
->otherwise(fn (Throwable $e) => $this->logWebhookFailure($webhook, $visitId, $e)),
|
||||||
|
$this->webhookOptions->webhooks(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl;
|
|||||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||||
|
|
||||||
use function array_fill_keys;
|
use function array_fill_keys;
|
||||||
|
use function array_map;
|
||||||
use function count;
|
use function count;
|
||||||
use function Functional\map;
|
|
||||||
use function Shlinkio\Shlink\Core\enumValues;
|
use function Shlinkio\Shlink\Core\enumValues;
|
||||||
use function Shlinkio\Shlink\Core\generateRandomShortCode;
|
use function Shlinkio\Shlink\Core\generateRandomShortCode;
|
||||||
use function Shlinkio\Shlink\Core\normalizeDate;
|
use function Shlinkio\Shlink\Core\normalizeDate;
|
||||||
@@ -90,9 +90,9 @@ class ShortUrl extends AbstractEntity
|
|||||||
$instance->longUrl = $creation->getLongUrl();
|
$instance->longUrl = $creation->getLongUrl();
|
||||||
$instance->dateCreated = Chronos::now();
|
$instance->dateCreated = Chronos::now();
|
||||||
$instance->visits = new ArrayCollection();
|
$instance->visits = new ArrayCollection();
|
||||||
$instance->deviceLongUrls = new ArrayCollection(map(
|
$instance->deviceLongUrls = new ArrayCollection(array_map(
|
||||||
$creation->deviceLongUrls,
|
|
||||||
fn (DeviceLongUrlPair $pair) => DeviceLongUrl::fromShortUrlAndPair($instance, $pair),
|
fn (DeviceLongUrlPair $pair) => DeviceLongUrl::fromShortUrlAndPair($instance, $pair),
|
||||||
|
$creation->deviceLongUrls,
|
||||||
));
|
));
|
||||||
$instance->tags = $relationResolver->resolveTags($creation->tags);
|
$instance->tags = $relationResolver->resolveTags($creation->tags);
|
||||||
$instance->validSince = $creation->validSince;
|
$instance->validSince = $creation->validSince;
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ namespace Shlinkio\Shlink\Core\ShortUrl\Model;
|
|||||||
|
|
||||||
use Shlinkio\Shlink\Core\Model\DeviceType;
|
use Shlinkio\Shlink\Core\Model\DeviceType;
|
||||||
|
|
||||||
use function array_values;
|
|
||||||
use function Functional\group;
|
use function Functional\group;
|
||||||
use function Functional\map;
|
|
||||||
use function trim;
|
use function trim;
|
||||||
|
|
||||||
final class DeviceLongUrlPair
|
final class DeviceLongUrlPair
|
||||||
@@ -32,15 +30,23 @@ final class DeviceLongUrlPair
|
|||||||
*/
|
*/
|
||||||
public static function fromMapToChangeSet(array $map): array
|
public static function fromMapToChangeSet(array $map): array
|
||||||
{
|
{
|
||||||
|
$toRemove = []; // TODO Use when group is removed
|
||||||
|
$toKeep = []; // TODO Use when group is removed
|
||||||
$typesWithNullUrl = group($map, static fn (?string $longUrl) => $longUrl === null ? 'remove' : 'keep');
|
$typesWithNullUrl = group($map, static fn (?string $longUrl) => $longUrl === null ? 'remove' : 'keep');
|
||||||
$deviceTypesToRemove = array_values(map(
|
|
||||||
$typesWithNullUrl['remove'] ?? [],
|
$deviceTypesToRemove = [];
|
||||||
static fn ($_, string $deviceType) => DeviceType::from($deviceType),
|
foreach ($typesWithNullUrl['remove'] ?? [] as $deviceType => $_) {
|
||||||
));
|
$deviceTypesToRemove[] = DeviceType::from($deviceType);
|
||||||
$pairsToKeep = map(
|
}
|
||||||
$typesWithNullUrl['keep'] ?? [],
|
|
||||||
fn (string $longUrl, string $deviceType) => self::fromRawTypeAndLongUrl($deviceType, $longUrl),
|
$pairsToKeep = [];
|
||||||
);
|
/**
|
||||||
|
* @var string $deviceType
|
||||||
|
* @var string $longUrl
|
||||||
|
*/
|
||||||
|
foreach ($typesWithNullUrl['keep'] ?? [] as $deviceType => $longUrl) {
|
||||||
|
$pairsToKeep[$deviceType] = self::fromRawTypeAndLongUrl($deviceType, $longUrl);
|
||||||
|
}
|
||||||
|
|
||||||
return [$pairsToKeep, $deviceTypesToRemove];
|
return [$pairsToKeep, $deviceTypesToRemove];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,9 +15,8 @@ use Symfony\Component\Lock\Lock;
|
|||||||
use Symfony\Component\Lock\LockFactory;
|
use Symfony\Component\Lock\LockFactory;
|
||||||
use Symfony\Component\Lock\Store\InMemoryStore;
|
use Symfony\Component\Lock\Store\InMemoryStore;
|
||||||
|
|
||||||
use function Functional\invoke;
|
use function array_map;
|
||||||
use function Functional\map;
|
use function array_unique;
|
||||||
use function Functional\unique;
|
|
||||||
|
|
||||||
class PersistenceShortUrlRelationResolver implements ShortUrlRelationResolverInterface
|
class PersistenceShortUrlRelationResolver implements ShortUrlRelationResolverInterface
|
||||||
{
|
{
|
||||||
@@ -74,10 +73,10 @@ class PersistenceShortUrlRelationResolver implements ShortUrlRelationResolverInt
|
|||||||
return new Collections\ArrayCollection();
|
return new Collections\ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
$tags = unique($tags);
|
$tags = array_unique($tags);
|
||||||
$repo = $this->em->getRepository(Tag::class);
|
$repo = $this->em->getRepository(Tag::class);
|
||||||
|
|
||||||
return new Collections\ArrayCollection(map($tags, function (string $tagName) use ($repo): Tag {
|
return new Collections\ArrayCollection(array_map(function (string $tagName) use ($repo): Tag {
|
||||||
$this->lock($this->tagLocks, 'tag_' . $tagName);
|
$this->lock($this->tagLocks, 'tag_' . $tagName);
|
||||||
|
|
||||||
$existingTag = $repo->findOneBy(['name' => $tagName]);
|
$existingTag = $repo->findOneBy(['name' => $tagName]);
|
||||||
@@ -91,7 +90,7 @@ class PersistenceShortUrlRelationResolver implements ShortUrlRelationResolverInt
|
|||||||
$this->em->persist($tag);
|
$this->em->persist($tag);
|
||||||
|
|
||||||
return $tag;
|
return $tag;
|
||||||
}));
|
}, $tags));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function memoizeNewTag(string $tagName): Tag
|
private function memoizeNewTag(string $tagName): Tag
|
||||||
@@ -110,6 +109,7 @@ class PersistenceShortUrlRelationResolver implements ShortUrlRelationResolverInt
|
|||||||
$lock->acquire(true);
|
$lock->acquire(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
/**
|
||||||
* @param array<string, Lock> $locks
|
* @param array<string, Lock> $locks
|
||||||
*/
|
*/
|
||||||
@@ -126,9 +126,15 @@ class PersistenceShortUrlRelationResolver implements ShortUrlRelationResolverInt
|
|||||||
$this->memoizedNewTags = [];
|
$this->memoizedNewTags = [];
|
||||||
|
|
||||||
// Release all locks
|
// Release all locks
|
||||||
invoke($this->tagLocks, 'release');
|
$this->releaseLocks($this->tagLocks);
|
||||||
invoke($this->domainLocks, 'release');
|
$this->releaseLocks($this->domainLocks);
|
||||||
$this->tagLocks = [];
|
}
|
||||||
$this->domainLocks = [];
|
|
||||||
|
private function releaseLocks(array &$locks): void
|
||||||
|
{
|
||||||
|
foreach ($locks as $tagLock) {
|
||||||
|
$tagLock->release();
|
||||||
|
}
|
||||||
|
$locks = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use Doctrine\Common\Collections;
|
|||||||
use Shlinkio\Shlink\Core\Domain\Entity\Domain;
|
use Shlinkio\Shlink\Core\Domain\Entity\Domain;
|
||||||
use Shlinkio\Shlink\Core\Tag\Entity\Tag;
|
use Shlinkio\Shlink\Core\Tag\Entity\Tag;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
|
|
||||||
class SimpleShortUrlRelationResolver implements ShortUrlRelationResolverInterface
|
class SimpleShortUrlRelationResolver implements ShortUrlRelationResolverInterface
|
||||||
{
|
{
|
||||||
@@ -23,6 +23,6 @@ class SimpleShortUrlRelationResolver implements ShortUrlRelationResolverInterfac
|
|||||||
*/
|
*/
|
||||||
public function resolveTags(array $tags): Collections\Collection
|
public function resolveTags(array $tags): Collections\Collection
|
||||||
{
|
{
|
||||||
return new Collections\ArrayCollection(map($tags, fn (string $tag) => new Tag($tag)));
|
return new Collections\ArrayCollection(array_map(fn (string $tag) => new Tag($tag), $tags));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ namespace Shlinkio\Shlink\Core\ShortUrl\Transformer;
|
|||||||
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
|
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
|
||||||
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
||||||
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface;
|
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface;
|
||||||
|
use Shlinkio\Shlink\Core\Tag\Entity\Tag;
|
||||||
use Shlinkio\Shlink\Core\Visit\Model\VisitsSummary;
|
use Shlinkio\Shlink\Core\Visit\Model\VisitsSummary;
|
||||||
|
|
||||||
use function Functional\invoke;
|
use function array_map;
|
||||||
use function Functional\invoke_if;
|
|
||||||
|
|
||||||
class ShortUrlDataTransformer implements DataTransformerInterface
|
class ShortUrlDataTransformer implements DataTransformerInterface
|
||||||
{
|
{
|
||||||
@@ -29,7 +29,7 @@ class ShortUrlDataTransformer implements DataTransformerInterface
|
|||||||
'longUrl' => $shortUrl->getLongUrl(),
|
'longUrl' => $shortUrl->getLongUrl(),
|
||||||
'deviceLongUrls' => $shortUrl->deviceLongUrls(),
|
'deviceLongUrls' => $shortUrl->deviceLongUrls(),
|
||||||
'dateCreated' => $shortUrl->getDateCreated()->toAtomString(),
|
'dateCreated' => $shortUrl->getDateCreated()->toAtomString(),
|
||||||
'tags' => invoke($shortUrl->getTags(), '__toString'),
|
'tags' => array_map(static fn (Tag $tag) => $tag->__toString(), $shortUrl->getTags()->toArray()),
|
||||||
'meta' => $this->buildMeta($shortUrl),
|
'meta' => $this->buildMeta($shortUrl),
|
||||||
'domain' => $shortUrl->getDomain(),
|
'domain' => $shortUrl->getDomain(),
|
||||||
'title' => $shortUrl->title(),
|
'title' => $shortUrl->title(),
|
||||||
@@ -52,8 +52,8 @@ class ShortUrlDataTransformer implements DataTransformerInterface
|
|||||||
$maxVisits = $shortUrl->getMaxVisits();
|
$maxVisits = $shortUrl->getMaxVisits();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'validSince' => invoke_if($validSince, 'toAtomString'),
|
'validSince' => $validSince?->toAtomString(),
|
||||||
'validUntil' => invoke_if($validUntil, 'toAtomString'),
|
'validUntil' => $validUntil?->toAtomString(),
|
||||||
'maxVisits' => $maxVisits,
|
'maxVisits' => $maxVisits,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ use Shlinkio\Shlink\Rest\ApiKey\Role;
|
|||||||
use Shlinkio\Shlink\Rest\ApiKey\Spec\WithApiKeySpecsEnsuringJoin;
|
use Shlinkio\Shlink\Rest\ApiKey\Spec\WithApiKeySpecsEnsuringJoin;
|
||||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||||
|
|
||||||
|
use function array_map;
|
||||||
use function Functional\each;
|
use function Functional\each;
|
||||||
use function Functional\map;
|
|
||||||
use function Shlinkio\Shlink\Core\camelCaseToSnakeCase;
|
use function Shlinkio\Shlink\Core\camelCaseToSnakeCase;
|
||||||
|
|
||||||
use const PHP_INT_MAX;
|
use const PHP_INT_MAX;
|
||||||
@@ -126,9 +126,9 @@ class TagRepository extends EntitySpecificationRepository implements TagReposito
|
|||||||
$rsm->addScalarResult('non_bot_visits', 'nonBotVisits');
|
$rsm->addScalarResult('non_bot_visits', 'nonBotVisits');
|
||||||
$rsm->addScalarResult('short_urls_count', 'shortUrlsCount');
|
$rsm->addScalarResult('short_urls_count', 'shortUrlsCount');
|
||||||
|
|
||||||
return map(
|
return array_map(
|
||||||
$this->getEntityManager()->createNativeQuery($mainQb->getSQL(), $rsm)->getResult(),
|
|
||||||
TagInfo::fromRawData(...),
|
TagInfo::fromRawData(...),
|
||||||
|
$this->getEntityManager()->createNativeQuery($mainQb->getSQL(), $rsm)->getResult(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ use Shlinkio\Shlink\Core\Options\TrackingOptions;
|
|||||||
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
||||||
use Shlinkio\Shlink\Core\Visit\Model\Visitor;
|
use Shlinkio\Shlink\Core\Visit\Model\Visitor;
|
||||||
|
|
||||||
|
use function array_keys;
|
||||||
|
use function array_map;
|
||||||
use function explode;
|
use function explode;
|
||||||
use function Functional\map;
|
|
||||||
use function Functional\some;
|
|
||||||
use function implode;
|
use function implode;
|
||||||
use function str_contains;
|
use function str_contains;
|
||||||
|
|
||||||
@@ -85,22 +85,30 @@ class RequestTracker implements RequestTrackerInterface, RequestMethodInterface
|
|||||||
$remoteAddrParts = explode('.', $remoteAddr);
|
$remoteAddrParts = explode('.', $remoteAddr);
|
||||||
$disableTrackingFrom = $this->trackingOptions->disableTrackingFrom;
|
$disableTrackingFrom = $this->trackingOptions->disableTrackingFrom;
|
||||||
|
|
||||||
return some($disableTrackingFrom, function (string $value) use ($ip, $remoteAddrParts): bool {
|
foreach ($disableTrackingFrom as $value) {
|
||||||
$range = str_contains($value, '*')
|
$range = str_contains($value, '*')
|
||||||
? $this->parseValueWithWildcards($value, $remoteAddrParts)
|
? $this->parseValueWithWildcards($value, $remoteAddrParts)
|
||||||
: Factory::parseRangeString($value);
|
: Factory::parseRangeString($value);
|
||||||
|
|
||||||
return $range !== null && $ip->matches($range);
|
if ($range !== null && $ip->matches($range)) {
|
||||||
});
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function parseValueWithWildcards(string $value, array $remoteAddrParts): ?RangeInterface
|
private function parseValueWithWildcards(string $value, array $remoteAddrParts): ?RangeInterface
|
||||||
{
|
{
|
||||||
|
$octets = explode('.', $value);
|
||||||
|
$keys = array_keys($octets);
|
||||||
|
|
||||||
// Replace wildcard parts with the corresponding ones from the remote address
|
// Replace wildcard parts with the corresponding ones from the remote address
|
||||||
return Factory::parseRangeString(
|
return Factory::parseRangeString(
|
||||||
implode('.', map(
|
implode('.', array_map(
|
||||||
explode('.', $value),
|
|
||||||
fn (string $part, int $index) => $part === '*' ? $remoteAddrParts[$index] : $part,
|
fn (string $part, int $index) => $part === '*' ? $remoteAddrParts[$index] : $part,
|
||||||
|
$octets,
|
||||||
|
$keys,
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ use Shlinkio\Shlink\Core\Visit\Entity\Visit;
|
|||||||
use Shlinkio\Shlink\Core\Visit\Model\Visitor;
|
use Shlinkio\Shlink\Core\Visit\Model\Visitor;
|
||||||
use Shlinkio\Shlink\TestUtils\DbTest\DatabaseTestCase;
|
use Shlinkio\Shlink\TestUtils\DbTest\DatabaseTestCase;
|
||||||
|
|
||||||
|
use function array_map;
|
||||||
use function count;
|
use function count;
|
||||||
use function Functional\map;
|
|
||||||
use function range;
|
use function range;
|
||||||
|
|
||||||
class ShortUrlListRepositoryTest extends DatabaseTestCase
|
class ShortUrlListRepositoryTest extends DatabaseTestCase
|
||||||
@@ -60,22 +60,22 @@ class ShortUrlListRepositoryTest extends DatabaseTestCase
|
|||||||
$this->getEntityManager()->persist($foo);
|
$this->getEntityManager()->persist($foo);
|
||||||
|
|
||||||
$bar = ShortUrl::withLongUrl('https://bar');
|
$bar = ShortUrl::withLongUrl('https://bar');
|
||||||
$visits = map(range(0, 5), function () use ($bar) {
|
$visits = array_map(function () use ($bar) {
|
||||||
$visit = Visit::forValidShortUrl($bar, Visitor::botInstance());
|
$visit = Visit::forValidShortUrl($bar, Visitor::botInstance());
|
||||||
$this->getEntityManager()->persist($visit);
|
$this->getEntityManager()->persist($visit);
|
||||||
|
|
||||||
return $visit;
|
return $visit;
|
||||||
});
|
}, range(0, 5));
|
||||||
$bar->setVisits(new ArrayCollection($visits));
|
$bar->setVisits(new ArrayCollection($visits));
|
||||||
$this->getEntityManager()->persist($bar);
|
$this->getEntityManager()->persist($bar);
|
||||||
|
|
||||||
$foo2 = ShortUrl::withLongUrl('https://foo_2');
|
$foo2 = ShortUrl::withLongUrl('https://foo_2');
|
||||||
$visits2 = map(range(0, 3), function () use ($foo2) {
|
$visits2 = array_map(function () use ($foo2) {
|
||||||
$visit = Visit::forValidShortUrl($foo2, Visitor::emptyInstance());
|
$visit = Visit::forValidShortUrl($foo2, Visitor::emptyInstance());
|
||||||
$this->getEntityManager()->persist($visit);
|
$this->getEntityManager()->persist($visit);
|
||||||
|
|
||||||
return $visit;
|
return $visit;
|
||||||
});
|
}, range(0, 3));
|
||||||
$foo2->setVisits(new ArrayCollection($visits2));
|
$foo2->setVisits(new ArrayCollection($visits2));
|
||||||
$ref = new ReflectionObject($foo2);
|
$ref = new ReflectionObject($foo2);
|
||||||
$dateProp = $ref->getProperty('dateCreated');
|
$dateProp = $ref->getProperty('dateCreated');
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use Shlinkio\Shlink\Core\Tag\Paginator\Adapter\TagsPaginatorAdapter;
|
|||||||
use Shlinkio\Shlink\Core\Tag\Repository\TagRepository;
|
use Shlinkio\Shlink\Core\Tag\Repository\TagRepository;
|
||||||
use Shlinkio\Shlink\TestUtils\DbTest\DatabaseTestCase;
|
use Shlinkio\Shlink\TestUtils\DbTest\DatabaseTestCase;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
|
|
||||||
class TagsPaginatorAdapterTest extends DatabaseTestCase
|
class TagsPaginatorAdapterTest extends DatabaseTestCase
|
||||||
{
|
{
|
||||||
@@ -47,7 +47,7 @@ class TagsPaginatorAdapterTest extends DatabaseTestCase
|
|||||||
'orderBy' => $orderBy,
|
'orderBy' => $orderBy,
|
||||||
]), null);
|
]), null);
|
||||||
|
|
||||||
$tagNames = map($adapter->getSlice($offset, $length), static fn (Tag $tag) => $tag->__toString());
|
$tagNames = array_map(static fn (Tag $tag) => $tag->__toString(), [...$adapter->getSlice($offset, $length)]);
|
||||||
|
|
||||||
self::assertEquals($expectedTags, $tagNames);
|
self::assertEquals($expectedTags, $tagNames);
|
||||||
self::assertEquals($expectedTotalCount, $adapter->getNbResults());
|
self::assertEquals($expectedTotalCount, $adapter->getNbResults());
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use Shlinkio\Shlink\Core\Visit\Repository\VisitLocationRepository;
|
|||||||
use Shlinkio\Shlink\IpGeolocation\Model\Location;
|
use Shlinkio\Shlink\IpGeolocation\Model\Location;
|
||||||
use Shlinkio\Shlink\TestUtils\DbTest\DatabaseTestCase;
|
use Shlinkio\Shlink\TestUtils\DbTest\DatabaseTestCase;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
use function range;
|
use function range;
|
||||||
|
|
||||||
class VisitLocationRepositoryTest extends DatabaseTestCase
|
class VisitLocationRepositoryTest extends DatabaseTestCase
|
||||||
@@ -57,6 +57,6 @@ class VisitLocationRepositoryTest extends DatabaseTestCase
|
|||||||
|
|
||||||
public static function provideBlockSize(): iterable
|
public static function provideBlockSize(): iterable
|
||||||
{
|
{
|
||||||
return map(range(1, 10), fn (int $value) => [$value]);
|
return array_map(static fn (int $value) => [$value], range(1, 10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use Shlinkio\Shlink\CLI\GeoLite\GeolocationResult;
|
|||||||
use Shlinkio\Shlink\Core\EventDispatcher\Event\GeoLiteDbCreated;
|
use Shlinkio\Shlink\Core\EventDispatcher\Event\GeoLiteDbCreated;
|
||||||
use Shlinkio\Shlink\Core\EventDispatcher\UpdateGeoLiteDb;
|
use Shlinkio\Shlink\Core\EventDispatcher\UpdateGeoLiteDb;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
|
|
||||||
class UpdateGeoLiteDbTest extends TestCase
|
class UpdateGeoLiteDbTest extends TestCase
|
||||||
{
|
{
|
||||||
@@ -124,9 +124,9 @@ class UpdateGeoLiteDbTest extends TestCase
|
|||||||
|
|
||||||
public static function provideGeolocationResults(): iterable
|
public static function provideGeolocationResults(): iterable
|
||||||
{
|
{
|
||||||
return map(GeolocationResult::cases(), static fn (GeolocationResult $value) => [
|
return array_map(static fn (GeolocationResult $value) => [
|
||||||
$value,
|
$value,
|
||||||
$value === GeolocationResult::DB_CREATED ? 1 : 0,
|
$value === GeolocationResult::DB_CREATED ? 1 : 0,
|
||||||
]);
|
], GeolocationResult::cases());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
use Shlinkio\Shlink\Core\Exception\DeleteShortUrlException;
|
use Shlinkio\Shlink\Core\Exception\DeleteShortUrlException;
|
||||||
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
|
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
use function range;
|
use function range;
|
||||||
use function Shlinkio\Shlink\Core\generateRandomShortCode;
|
use function Shlinkio\Shlink\Core\generateRandomShortCode;
|
||||||
use function sprintf;
|
use function sprintf;
|
||||||
@@ -42,13 +42,13 @@ class DeleteShortUrlExceptionTest extends TestCase
|
|||||||
|
|
||||||
public static function provideThresholds(): array
|
public static function provideThresholds(): array
|
||||||
{
|
{
|
||||||
return map(range(5, 50, 5), function (int $number) {
|
return array_map(function (int $number) {
|
||||||
return [$number, $shortCode = generateRandomShortCode(6), sprintf(
|
return [$number, $shortCode = generateRandomShortCode(6), sprintf(
|
||||||
'Impossible to delete short URL with short code "%s", since it has more than "%s" visits.',
|
'Impossible to delete short URL with short code "%s", since it has more than "%s" visits.',
|
||||||
$shortCode,
|
$shortCode,
|
||||||
$number,
|
$number,
|
||||||
)];
|
)];
|
||||||
});
|
}, range(5, 50, 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Test]
|
#[Test]
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use Shlinkio\Shlink\Core\Model\DeviceType;
|
|||||||
use Shlinkio\Shlink\Core\ShortUrl\Model\OrderableField;
|
use Shlinkio\Shlink\Core\ShortUrl\Model\OrderableField;
|
||||||
use Shlinkio\Shlink\Core\Visit\Model\VisitType;
|
use Shlinkio\Shlink\Core\Visit\Model\VisitType;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
use function Shlinkio\Shlink\Core\enumValues;
|
use function Shlinkio\Shlink\Core\enumValues;
|
||||||
|
|
||||||
class FunctionsTest extends TestCase
|
class FunctionsTest extends TestCase
|
||||||
@@ -29,18 +29,21 @@ class FunctionsTest extends TestCase
|
|||||||
|
|
||||||
public static function provideEnums(): iterable
|
public static function provideEnums(): iterable
|
||||||
{
|
{
|
||||||
yield EnvVars::class => [EnvVars::class, map(EnvVars::cases(), static fn (EnvVars $envVar) => $envVar->value)];
|
yield EnvVars::class => [
|
||||||
|
EnvVars::class,
|
||||||
|
array_map(static fn (EnvVars $envVar) => $envVar->value, EnvVars::cases()),
|
||||||
|
];
|
||||||
yield VisitType::class => [
|
yield VisitType::class => [
|
||||||
VisitType::class,
|
VisitType::class,
|
||||||
map(VisitType::cases(), static fn (VisitType $envVar) => $envVar->value),
|
array_map(static fn (VisitType $envVar) => $envVar->value, VisitType::cases()),
|
||||||
];
|
];
|
||||||
yield DeviceType::class => [
|
yield DeviceType::class => [
|
||||||
DeviceType::class,
|
DeviceType::class,
|
||||||
map(DeviceType::cases(), static fn (DeviceType $envVar) => $envVar->value),
|
array_map(static fn (DeviceType $envVar) => $envVar->value, DeviceType::cases()),
|
||||||
];
|
];
|
||||||
yield OrderableField::class => [
|
yield OrderableField::class => [
|
||||||
OrderableField::class,
|
OrderableField::class,
|
||||||
map(OrderableField::cases(), static fn (OrderableField $envVar) => $envVar->value),
|
array_map(static fn (OrderableField $envVar) => $envVar->value, OrderableField::cases()),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use Shlinkio\Shlink\Core\ShortUrl\ShortUrlResolverInterface;
|
|||||||
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
|
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
|
||||||
use Shlinkio\Shlink\Core\Visit\Model\Visitor;
|
use Shlinkio\Shlink\Core\Visit\Model\Visitor;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
use function range;
|
use function range;
|
||||||
use function sprintf;
|
use function sprintf;
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ class DeleteShortUrlServiceTest extends TestCase
|
|||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
$shortUrl = ShortUrl::createFake()->setVisits(new ArrayCollection(
|
$shortUrl = ShortUrl::createFake()->setVisits(new ArrayCollection(
|
||||||
map(range(0, 10), fn () => Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::emptyInstance())),
|
array_map(fn () => Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::emptyInstance()), range(0, 10)),
|
||||||
));
|
));
|
||||||
$this->shortCode = $shortUrl->getShortCode();
|
$this->shortCode = $shortUrl->getShortCode();
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlInputFilter;
|
|||||||
use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl;
|
use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl;
|
||||||
use Shlinkio\Shlink\Importer\Sources\ImportSource;
|
use Shlinkio\Shlink\Importer\Sources\ImportSource;
|
||||||
|
|
||||||
|
use function array_map;
|
||||||
use function Functional\every;
|
use function Functional\every;
|
||||||
use function Functional\map;
|
|
||||||
use function range;
|
use function range;
|
||||||
use function strlen;
|
use function strlen;
|
||||||
use function strtolower;
|
use function strtolower;
|
||||||
@@ -88,7 +88,7 @@ class ShortUrlTest extends TestCase
|
|||||||
public static function provideLengths(): iterable
|
public static function provideLengths(): iterable
|
||||||
{
|
{
|
||||||
yield [null, DEFAULT_SHORT_CODES_LENGTH];
|
yield [null, DEFAULT_SHORT_CODES_LENGTH];
|
||||||
yield from map(range(4, 10), fn (int $value) => [$value, $value]);
|
yield from array_map(fn (int $value) => [$value, $value], range(4, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Test]
|
#[Test]
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ use Shlinkio\Shlink\Core\Visit\Model\Visitor;
|
|||||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||||
use ShlinkioTest\Shlink\Core\Util\ApiKeyDataProviders;
|
use ShlinkioTest\Shlink\Core\Util\ApiKeyDataProviders;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
use function range;
|
use function range;
|
||||||
|
|
||||||
class ShortUrlResolverTest extends TestCase
|
class ShortUrlResolverTest extends TestCase
|
||||||
@@ -113,9 +113,9 @@ class ShortUrlResolverTest extends TestCase
|
|||||||
$shortUrl = ShortUrl::create(
|
$shortUrl = ShortUrl::create(
|
||||||
ShortUrlCreation::fromRawData(['maxVisits' => 3, 'longUrl' => 'https://longUrl']),
|
ShortUrlCreation::fromRawData(['maxVisits' => 3, 'longUrl' => 'https://longUrl']),
|
||||||
);
|
);
|
||||||
$shortUrl->setVisits(new ArrayCollection(map(
|
$shortUrl->setVisits(new ArrayCollection(array_map(
|
||||||
range(0, 4),
|
|
||||||
fn () => Visit::forValidShortUrl($shortUrl, Visitor::emptyInstance()),
|
fn () => Visit::forValidShortUrl($shortUrl, Visitor::emptyInstance()),
|
||||||
|
range(0, 4),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
return $shortUrl;
|
return $shortUrl;
|
||||||
@@ -132,9 +132,9 @@ class ShortUrlResolverTest extends TestCase
|
|||||||
'validUntil' => $now->subMonths(1)->toAtomString(),
|
'validUntil' => $now->subMonths(1)->toAtomString(),
|
||||||
'longUrl' => 'https://longUrl',
|
'longUrl' => 'https://longUrl',
|
||||||
]));
|
]));
|
||||||
$shortUrl->setVisits(new ArrayCollection(map(
|
$shortUrl->setVisits(new ArrayCollection(array_map(
|
||||||
range(0, 4),
|
|
||||||
fn () => Visit::forValidShortUrl($shortUrl, Visitor::emptyInstance()),
|
fn () => Visit::forValidShortUrl($shortUrl, Visitor::emptyInstance()),
|
||||||
|
range(0, 4),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
return $shortUrl;
|
return $shortUrl;
|
||||||
|
|||||||
@@ -84,4 +84,14 @@ class ShortUrlDataTransformerTest extends TestCase
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Test]
|
||||||
|
public function properTagsAreReturned(): void
|
||||||
|
{
|
||||||
|
['tags' => $tags] = $this->transformer->transform(ShortUrl::create(ShortUrlCreation::fromRawData([
|
||||||
|
'longUrl' => 'https://longUrl',
|
||||||
|
'tags' => ['foo', 'bar', 'baz'],
|
||||||
|
])));
|
||||||
|
self::assertEquals(['foo', 'bar', 'baz'], $tags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ use Shlinkio\Shlink\Core\Visit\Model\Visitor;
|
|||||||
use Shlinkio\Shlink\Core\Visit\Repository\VisitLocationRepositoryInterface;
|
use Shlinkio\Shlink\Core\Visit\Repository\VisitLocationRepositoryInterface;
|
||||||
use Shlinkio\Shlink\IpGeolocation\Model\Location;
|
use Shlinkio\Shlink\IpGeolocation\Model\Location;
|
||||||
|
|
||||||
|
use function array_map;
|
||||||
use function count;
|
use function count;
|
||||||
use function floor;
|
use function floor;
|
||||||
use function Functional\map;
|
|
||||||
use function range;
|
use function range;
|
||||||
use function sprintf;
|
use function sprintf;
|
||||||
|
|
||||||
@@ -45,12 +45,12 @@ class VisitLocatorTest extends TestCase
|
|||||||
string $serviceMethodName,
|
string $serviceMethodName,
|
||||||
string $expectedRepoMethodName,
|
string $expectedRepoMethodName,
|
||||||
): void {
|
): void {
|
||||||
$unlocatedVisits = map(
|
$unlocatedVisits = array_map(
|
||||||
range(1, 200),
|
|
||||||
fn (int $i) => Visit::forValidShortUrl(
|
fn (int $i) => Visit::forValidShortUrl(
|
||||||
ShortUrl::withLongUrl(sprintf('https://short_code_%s', $i)),
|
ShortUrl::withLongUrl(sprintf('https://short_code_%s', $i)),
|
||||||
Visitor::emptyInstance(),
|
Visitor::emptyInstance(),
|
||||||
),
|
),
|
||||||
|
range(1, 200),
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->repo->expects($this->once())->method($expectedRepoMethodName)->willReturn($unlocatedVisits);
|
$this->repo->expects($this->once())->method($expectedRepoMethodName)->willReturn($unlocatedVisits);
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ use Shlinkio\Shlink\Core\Visit\VisitsStatsHelper;
|
|||||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||||
use ShlinkioTest\Shlink\Core\Util\ApiKeyDataProviders;
|
use ShlinkioTest\Shlink\Core\Util\ApiKeyDataProviders;
|
||||||
|
|
||||||
|
use function array_map;
|
||||||
use function count;
|
use function count;
|
||||||
use function Functional\map;
|
|
||||||
use function range;
|
use function range;
|
||||||
|
|
||||||
class VisitsStatsHelperTest extends TestCase
|
class VisitsStatsHelperTest extends TestCase
|
||||||
@@ -75,8 +75,8 @@ class VisitsStatsHelperTest extends TestCase
|
|||||||
public static function provideCounts(): iterable
|
public static function provideCounts(): iterable
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
...map(range(0, 50, 5), fn (int $value) => [$value, null]),
|
...array_map(fn (int $value) => [$value, null], range(0, 50, 5)),
|
||||||
...map(range(0, 18, 3), fn (int $value) => [$value, ApiKey::create()]),
|
...array_map(fn (int $value) => [$value, ApiKey::create()], range(0, 18, 3)),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +90,10 @@ class VisitsStatsHelperTest extends TestCase
|
|||||||
$repo = $this->createMock(ShortUrlRepositoryInterface::class);
|
$repo = $this->createMock(ShortUrlRepositoryInterface::class);
|
||||||
$repo->expects($this->once())->method('shortCodeIsInUse')->with($identifier, $spec)->willReturn(true);
|
$repo->expects($this->once())->method('shortCodeIsInUse')->with($identifier, $spec)->willReturn(true);
|
||||||
|
|
||||||
$list = map(range(0, 1), fn () => Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::emptyInstance()));
|
$list = array_map(
|
||||||
|
static fn () => Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::emptyInstance()),
|
||||||
|
range(0, 1),
|
||||||
|
);
|
||||||
$repo2 = $this->createMock(VisitRepository::class);
|
$repo2 = $this->createMock(VisitRepository::class);
|
||||||
$repo2->method('findVisitsByShortCode')->with(
|
$repo2->method('findVisitsByShortCode')->with(
|
||||||
$identifier,
|
$identifier,
|
||||||
@@ -147,7 +150,10 @@ class VisitsStatsHelperTest extends TestCase
|
|||||||
$repo = $this->createMock(TagRepository::class);
|
$repo = $this->createMock(TagRepository::class);
|
||||||
$repo->expects($this->once())->method('tagExists')->with($tag, $apiKey)->willReturn(true);
|
$repo->expects($this->once())->method('tagExists')->with($tag, $apiKey)->willReturn(true);
|
||||||
|
|
||||||
$list = map(range(0, 1), fn () => Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::emptyInstance()));
|
$list = array_map(
|
||||||
|
static fn () => Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::emptyInstance()),
|
||||||
|
range(0, 1),
|
||||||
|
);
|
||||||
$repo2 = $this->createMock(VisitRepository::class);
|
$repo2 = $this->createMock(VisitRepository::class);
|
||||||
$repo2->method('findVisitsByTag')->with($tag, $this->isInstanceOf(VisitsListFiltering::class))->willReturn(
|
$repo2->method('findVisitsByTag')->with($tag, $this->isInstanceOf(VisitsListFiltering::class))->willReturn(
|
||||||
$list,
|
$list,
|
||||||
@@ -185,7 +191,10 @@ class VisitsStatsHelperTest extends TestCase
|
|||||||
$repo = $this->createMock(DomainRepository::class);
|
$repo = $this->createMock(DomainRepository::class);
|
||||||
$repo->expects($this->once())->method('domainExists')->with($domain, $apiKey)->willReturn(true);
|
$repo->expects($this->once())->method('domainExists')->with($domain, $apiKey)->willReturn(true);
|
||||||
|
|
||||||
$list = map(range(0, 1), fn () => Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::emptyInstance()));
|
$list = array_map(
|
||||||
|
static fn () => Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::emptyInstance()),
|
||||||
|
range(0, 1),
|
||||||
|
);
|
||||||
$repo2 = $this->createMock(VisitRepository::class);
|
$repo2 = $this->createMock(VisitRepository::class);
|
||||||
$repo2->method('findVisitsByDomain')->with(
|
$repo2->method('findVisitsByDomain')->with(
|
||||||
$domain,
|
$domain,
|
||||||
@@ -212,7 +221,10 @@ class VisitsStatsHelperTest extends TestCase
|
|||||||
$repo = $this->createMock(DomainRepository::class);
|
$repo = $this->createMock(DomainRepository::class);
|
||||||
$repo->expects($this->never())->method('domainExists');
|
$repo->expects($this->never())->method('domainExists');
|
||||||
|
|
||||||
$list = map(range(0, 1), fn () => Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::emptyInstance()));
|
$list = array_map(
|
||||||
|
static fn () => Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::emptyInstance()),
|
||||||
|
range(0, 1),
|
||||||
|
);
|
||||||
$repo2 = $this->createMock(VisitRepository::class);
|
$repo2 = $this->createMock(VisitRepository::class);
|
||||||
$repo2->method('findVisitsByDomain')->with(
|
$repo2->method('findVisitsByDomain')->with(
|
||||||
'DEFAULT',
|
'DEFAULT',
|
||||||
@@ -236,7 +248,7 @@ class VisitsStatsHelperTest extends TestCase
|
|||||||
#[Test]
|
#[Test]
|
||||||
public function orphanVisitsAreReturnedAsExpected(): void
|
public function orphanVisitsAreReturnedAsExpected(): void
|
||||||
{
|
{
|
||||||
$list = map(range(0, 3), fn () => Visit::forBasePath(Visitor::emptyInstance()));
|
$list = array_map(static fn () => Visit::forBasePath(Visitor::emptyInstance()), range(0, 3));
|
||||||
$repo = $this->createMock(VisitRepository::class);
|
$repo = $this->createMock(VisitRepository::class);
|
||||||
$repo->expects($this->once())->method('countOrphanVisits')->with(
|
$repo->expects($this->once())->method('countOrphanVisits')->with(
|
||||||
$this->isInstanceOf(VisitsCountFiltering::class),
|
$this->isInstanceOf(VisitsCountFiltering::class),
|
||||||
@@ -254,7 +266,10 @@ class VisitsStatsHelperTest extends TestCase
|
|||||||
#[Test]
|
#[Test]
|
||||||
public function nonOrphanVisitsAreReturnedAsExpected(): void
|
public function nonOrphanVisitsAreReturnedAsExpected(): void
|
||||||
{
|
{
|
||||||
$list = map(range(0, 3), fn () => Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::emptyInstance()));
|
$list = array_map(
|
||||||
|
static fn () => Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::emptyInstance()),
|
||||||
|
range(0, 3),
|
||||||
|
);
|
||||||
$repo = $this->createMock(VisitRepository::class);
|
$repo = $this->createMock(VisitRepository::class);
|
||||||
$repo->expects($this->once())->method('countNonOrphanVisits')->with(
|
$repo->expects($this->once())->method('countNonOrphanVisits')->with(
|
||||||
$this->isInstanceOf(VisitsCountFiltering::class),
|
$this->isInstanceOf(VisitsCountFiltering::class),
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use Shlinkio\Shlink\Common\Middleware\AccessLogMiddleware;
|
|||||||
return [
|
return [
|
||||||
|
|
||||||
'access_logs' => [
|
'access_logs' => [
|
||||||
'ignored_paths' => [
|
'ignored_path_prefixes' => [
|
||||||
Action\HealthAction::ROUTE_PATH,
|
Action\HealthAction::ROUTE_PATH,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@@ -20,7 +20,7 @@ return [
|
|||||||
ConfigAbstractFactory::class => [
|
ConfigAbstractFactory::class => [
|
||||||
// Use MergeReplaceKey to overwrite what was defined in shlink-common, instead of merging it
|
// Use MergeReplaceKey to overwrite what was defined in shlink-common, instead of merging it
|
||||||
AccessLogMiddleware::class => new MergeReplaceKey(
|
AccessLogMiddleware::class => new MergeReplaceKey(
|
||||||
[AccessLogMiddleware::LOGGER_SERVICE_NAME, 'config.access_logs.ignored_paths'],
|
[AccessLogMiddleware::LOGGER_SERVICE_NAME, 'config.access_logs.ignored_path_prefixes'],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use Shlinkio\Shlink\Core\Tag\TagServiceInterface;
|
|||||||
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
|
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
|
||||||
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
|
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
|
|
||||||
class ListTagsAction extends AbstractRestAction
|
class ListTagsAction extends AbstractRestAction
|
||||||
{
|
{
|
||||||
@@ -41,7 +41,7 @@ class ListTagsAction extends AbstractRestAction
|
|||||||
// This part is deprecated. To get tags with stats, the /tags/stats endpoint should be used instead
|
// This part is deprecated. To get tags with stats, the /tags/stats endpoint should be used instead
|
||||||
$tagsInfo = $this->tagService->tagsInfo($params, $apiKey);
|
$tagsInfo = $this->tagService->tagsInfo($params, $apiKey);
|
||||||
$rawTags = $this->serializePaginator($tagsInfo, dataProp: 'stats');
|
$rawTags = $this->serializePaginator($tagsInfo, dataProp: 'stats');
|
||||||
$rawTags['data'] = map($tagsInfo, static fn (TagInfo $info) => $info->tag);
|
$rawTags['data'] = array_map(static fn (TagInfo $info) => $info->tag, [...$tagsInfo]);
|
||||||
|
|
||||||
return new JsonResponse(['tags' => $rawTags]);
|
return new JsonResponse(['tags' => $rawTags]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Shlinkio\Shlink\Rest;
|
namespace Shlinkio\Shlink\Rest;
|
||||||
|
|
||||||
|
use function array_map;
|
||||||
use function Functional\first;
|
use function Functional\first;
|
||||||
use function Functional\map;
|
|
||||||
use function Shlinkio\Shlink\Config\loadConfigFromGlob;
|
use function Shlinkio\Shlink\Config\loadConfigFromGlob;
|
||||||
use function sprintf;
|
use function sprintf;
|
||||||
|
|
||||||
@@ -23,11 +23,11 @@ class ConfigProvider
|
|||||||
public static function applyRoutesPrefix(array $routes): array
|
public static function applyRoutesPrefix(array $routes): array
|
||||||
{
|
{
|
||||||
$healthRoute = self::buildUnversionedHealthRouteFromExistingRoutes($routes);
|
$healthRoute = self::buildUnversionedHealthRouteFromExistingRoutes($routes);
|
||||||
$prefixedRoutes = map($routes, static function (array $route) {
|
$prefixedRoutes = array_map(static function (array $route) {
|
||||||
['path' => $path] = $route;
|
['path' => $path] = $route;
|
||||||
$route['path'] = sprintf('%s%s', self::ROUTES_PREFIX, $path);
|
$route['path'] = sprintf('%s%s', self::ROUTES_PREFIX, $path);
|
||||||
return $route;
|
return $route;
|
||||||
});
|
}, $routes);
|
||||||
|
|
||||||
return $healthRoute !== null ? [...$prefixedRoutes, $healthRoute] : $prefixedRoutes;
|
return $healthRoute !== null ? [...$prefixedRoutes, $healthRoute] : $prefixedRoutes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use PHPUnit\Framework\Attributes\DataProvider;
|
|||||||
use PHPUnit\Framework\Attributes\Test;
|
use PHPUnit\Framework\Attributes\Test;
|
||||||
use Shlinkio\Shlink\TestUtils\ApiTest\ApiTestCase;
|
use Shlinkio\Shlink\TestUtils\ApiTest\ApiTestCase;
|
||||||
|
|
||||||
use function Functional\map;
|
use function array_map;
|
||||||
use function range;
|
use function range;
|
||||||
use function sprintf;
|
use function sprintf;
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ class CreateShortUrlTest extends ApiTestCase
|
|||||||
|
|
||||||
public static function provideMaxVisits(): array
|
public static function provideMaxVisits(): array
|
||||||
{
|
{
|
||||||
return map(range(10, 15), fn(int $i) => [$i]);
|
return array_map(static fn (int $i) => [$i], range(10, 15));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Test]
|
#[Test]
|
||||||
|
|||||||
Reference in New Issue
Block a user