From 549c6605f0c2ebab0573f632df6d553a184ac342 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya <alejandrocelaya@gmail.com> Date: Thu, 30 Nov 2023 09:13:29 +0100 Subject: [PATCH] Replaced usage of Functional\contians --- composer.json | 8 +++--- config/autoload/entity-manager.global.php | 4 +-- config/test/test_config.global.php | 4 +-- .../src/Command/Db/CreateDatabaseCommand.php | 15 +++++++---- .../ShortUrl/CreateShortUrlCommand.php | 9 +++---- .../Visit/AbstractVisitsListCommand.php | 5 ++-- module/Core/functions/functions.php | 25 ++++++++++++++++--- module/Core/src/Action/Model/QrCodeParams.php | 4 +-- .../src/ShortUrl/Model/OrderableField.php | 4 +-- .../Validation/DeviceLongUrlsValidator.php | 4 +-- module/Core/src/Util/RedirectStatus.php | 6 ++--- .../NotifyVisitToWebHooksTest.php | 4 +-- .../Importer/ImportedLinksProcessorTest.php | 4 +-- .../Middleware/AuthenticationMiddleware.php | 12 ++++----- .../src/Middleware/BodyParserMiddleware.php | 6 ++--- 15 files changed, 68 insertions(+), 46 deletions(-) diff --git a/composer.json b/composer.json index 0e1b996e..8071556e 100644 --- a/composer.json +++ b/composer.json @@ -46,12 +46,12 @@ "php-middleware/request-id": "^4.1", "pugx/shortid-php": "^1.1", "ramsey/uuid": "^4.7", - "shlinkio/shlink-common": "^5.7", + "shlinkio/shlink-common": "dev-main#1f1b3b8 as 5.8", "shlinkio/shlink-config": "^2.5", "shlinkio/shlink-event-dispatcher": "^3.1", - "shlinkio/shlink-importer": "^5.2", - "shlinkio/shlink-installer": "^8.6", - "shlinkio/shlink-ip-geolocation": "^3.3", + "shlinkio/shlink-importer": "dev-main#4616c54 as 5.3", + "shlinkio/shlink-installer": "dev-develop#cb0eaea as 8.7", + "shlinkio/shlink-ip-geolocation": "dev-main#ea88ae8 as 3.4", "shlinkio/shlink-json": "^1.1", "spiral/roadrunner": "^2023.2", "spiral/roadrunner-cli": "^2.5", diff --git a/config/autoload/entity-manager.global.php b/config/autoload/entity-manager.global.php index 58899217..44095656 100644 --- a/config/autoload/entity-manager.global.php +++ b/config/autoload/entity-manager.global.php @@ -5,11 +5,11 @@ declare(strict_types=1); use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository; use Shlinkio\Shlink\Core\Config\EnvVars; -use function Functional\contains; +use function Shlinkio\Shlink\Core\contains; return (static function (): array { $driver = EnvVars::DB_DRIVER->loadFromEnv(); - $isMysqlCompatible = contains(['maria', 'mysql'], $driver); + $isMysqlCompatible = contains($driver, ['maria', 'mysql']); $resolveDriver = static fn () => match ($driver) { 'postgres' => 'pdo_pgsql', diff --git a/config/test/test_config.global.php b/config/test/test_config.global.php index 1beed0e3..75937bec 100644 --- a/config/test/test_config.global.php +++ b/config/test/test_config.global.php @@ -28,9 +28,9 @@ use Symfony\Component\Console\Event\ConsoleTerminateEvent; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use function file_exists; -use function Functional\contains; use function Laminas\Stratigility\middleware; use function Shlinkio\Shlink\Config\env; +use function Shlinkio\Shlink\Core\contains; use function sprintf; use function sys_get_temp_dir; @@ -41,7 +41,7 @@ $isApiTest = env('TEST_ENV') === 'api'; $isCliTest = env('TEST_ENV') === 'cli'; $isE2eTest = $isApiTest || $isCliTest; $coverageType = env('GENERATE_COVERAGE'); -$generateCoverage = contains(['yes', 'pretty'], $coverageType); +$generateCoverage = contains($coverageType, ['yes', 'pretty']); $coverage = null; if ($isE2eTest && $generateCoverage) { diff --git a/module/CLI/src/Command/Db/CreateDatabaseCommand.php b/module/CLI/src/Command/Db/CreateDatabaseCommand.php index c70e2f76..b9bb8f10 100644 --- a/module/CLI/src/Command/Db/CreateDatabaseCommand.php +++ b/module/CLI/src/Command/Db/CreateDatabaseCommand.php @@ -17,8 +17,7 @@ use Symfony\Component\Process\PhpExecutableFinder; use Throwable; use function array_map; -use function Functional\contains; -use function Functional\some; +use function Shlinkio\Shlink\Core\contains; class CreateDatabaseCommand extends AbstractDatabaseCommand { @@ -72,9 +71,15 @@ class CreateDatabaseCommand extends AbstractDatabaseCommand $allMetadata = $this->em->getMetadataFactory()->getAllMetadata(); $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. - // Any other inconsistency will be taken care of by the migrations. - return some($shlinkTables, static fn (string $shlinkTable) => contains($existingTables, $shlinkTable)); + foreach ($shlinkTables as $shlinkTable) { + // 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. + if (contains($shlinkTable, $existingTables)) { + return true; + } + } + + return false; } private function ensureDatabaseExistsAndGetTables(): array diff --git a/module/CLI/src/Command/ShortUrl/CreateShortUrlCommand.php b/module/CLI/src/Command/ShortUrl/CreateShortUrlCommand.php index f55f247d..3277f763 100644 --- a/module/CLI/src/Command/ShortUrl/CreateShortUrlCommand.php +++ b/module/CLI/src/Command/ShortUrl/CreateShortUrlCommand.php @@ -20,10 +20,9 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use function array_map; +use function array_unique; use function explode; -use function Functional\curry; -use function Functional\flatten; -use function Functional\unique; +use function Shlinkio\SHlink\Core\flatten; use function sprintf; class CreateShortUrlCommand extends Command @@ -144,8 +143,8 @@ class CreateShortUrlCommand extends Command return ExitCode::EXIT_FAILURE; } - $explodeWithComma = curry(explode(...))(','); - $tags = unique(flatten(array_map($explodeWithComma, $input->getOption('tags')))); + $explodeWithComma = static fn (string $tag) => explode(',', $tag); + $tags = array_unique(flatten(array_map($explodeWithComma, $input->getOption('tags')))); $customSlug = $input->getOption('custom-slug'); $maxVisits = $input->getOption('max-visits'); $shortCodeLength = $input->getOption('short-code-length') ?? $this->options->defaultShortCodesLength; diff --git a/module/CLI/src/Command/Visit/AbstractVisitsListCommand.php b/module/CLI/src/Command/Visit/AbstractVisitsListCommand.php index a247380e..8766ecc5 100644 --- a/module/CLI/src/Command/Visit/AbstractVisitsListCommand.php +++ b/module/CLI/src/Command/Visit/AbstractVisitsListCommand.php @@ -19,9 +19,9 @@ use Symfony\Component\Console\Output\OutputInterface; use function array_filter; use function array_keys; use function array_map; -use function in_array; use function Shlinkio\Shlink\Common\buildDateRange; use function Shlinkio\Shlink\Core\camelCaseToHumanFriendly; +use function Shlinkio\Shlink\Core\contains; use const ARRAY_FILTER_USE_KEY; @@ -66,10 +66,9 @@ abstract class AbstractVisitsListCommand extends Command // Filter out unknown keys return array_filter( $rowData, - static fn (string $key) => in_array( + static fn (string $key) => contains( $key, ['referer', 'date', 'userAgent', 'country', 'city', ...$extraKeys], - strict: true, ), ARRAY_FILTER_USE_KEY, ); diff --git a/module/Core/functions/functions.php b/module/Core/functions/functions.php index 32d357e3..bcda4bb4 100644 --- a/module/Core/functions/functions.php +++ b/module/Core/functions/functions.php @@ -6,7 +6,6 @@ namespace Shlinkio\Shlink\Core; use BackedEnum; use Cake\Chronos\Chronos; -use Cake\Chronos\ChronosInterface; use DateTimeInterface; use Doctrine\ORM\Mapping\Builder\FieldBuilder; use Jaybizzle\CrawlerDetect\CrawlerDetect; @@ -18,8 +17,10 @@ use Shlinkio\Shlink\Common\Util\DateRange; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlMode; use function array_map; +use function array_reduce; use function date_default_timezone_get; use function Functional\reduce_left; +use function in_array; use function is_array; use function print_r; use function Shlinkio\Shlink\Common\buildDateRange; @@ -57,7 +58,7 @@ function parseDateRangeFromQuery(array $query, string $startDateName, string $en /** * @return ($date is null ? null : Chronos) */ -function normalizeOptionalDate(string|DateTimeInterface|ChronosInterface|null $date): ?Chronos +function normalizeOptionalDate(string|DateTimeInterface|Chronos|null $date): ?Chronos { $parsedDate = match (true) { $date === null || $date instanceof Chronos => $date, @@ -68,7 +69,7 @@ function normalizeOptionalDate(string|DateTimeInterface|ChronosInterface|null $d return $parsedDate?->setTimezone(date_default_timezone_get()); } -function normalizeDate(string|DateTimeInterface|ChronosInterface $date): Chronos +function normalizeDate(string|DateTimeInterface|Chronos $date): Chronos { return normalizeOptionalDate($date); } @@ -180,3 +181,21 @@ function enumValues(string $enum): array $cache[$enum] = array_map(static fn (BackedEnum $type) => (string) $type->value, $enum::cases()) ); } + +function contains(mixed $value, array $array): bool +{ + return in_array($value, $array, strict: true); +} + +/** + * @param array[] $multiArray + * @return array + */ +function flatten(array $multiArray): array +{ + return array_reduce( + $multiArray, + static fn (array $carry, array $value) => [...$carry, ...$value], + initial: [], + ); +} diff --git a/module/Core/src/Action/Model/QrCodeParams.php b/module/Core/src/Action/Model/QrCodeParams.php index 306c2b44..51162d5f 100644 --- a/module/Core/src/Action/Model/QrCodeParams.php +++ b/module/Core/src/Action/Model/QrCodeParams.php @@ -18,7 +18,7 @@ use Endroid\QrCode\Writer\WriterInterface; use Psr\Http\Message\ServerRequestInterface; use Shlinkio\Shlink\Core\Options\QrCodeOptions; -use function Functional\contains; +use function Shlinkio\Shlink\Core\contains; use function strtolower; use function trim; @@ -74,7 +74,7 @@ final class QrCodeParams private static function resolveWriter(array $query, QrCodeOptions $defaults): WriterInterface { $qFormat = self::normalizeParam($query['format'] ?? ''); - $format = contains(self::SUPPORTED_FORMATS, $qFormat) ? $qFormat : self::normalizeParam($defaults->format); + $format = contains($qFormat, self::SUPPORTED_FORMATS) ? $qFormat : self::normalizeParam($defaults->format); return match ($format) { 'svg' => new SvgWriter(), diff --git a/module/Core/src/ShortUrl/Model/OrderableField.php b/module/Core/src/ShortUrl/Model/OrderableField.php index ac1bc632..1b61a155 100644 --- a/module/Core/src/ShortUrl/Model/OrderableField.php +++ b/module/Core/src/ShortUrl/Model/OrderableField.php @@ -2,7 +2,7 @@ namespace Shlinkio\Shlink\Core\ShortUrl\Model; -use function Functional\contains; +use function Shlinkio\Shlink\Core\contains; enum OrderableField: string { @@ -16,8 +16,8 @@ enum OrderableField: string public static function isBasicField(string $value): bool { return contains( - [self::LONG_URL->value, self::SHORT_CODE->value, self::DATE_CREATED->value, self::TITLE->value], $value, + [self::LONG_URL->value, self::SHORT_CODE->value, self::DATE_CREATED->value, self::TITLE->value], ); } diff --git a/module/Core/src/ShortUrl/Model/Validation/DeviceLongUrlsValidator.php b/module/Core/src/ShortUrl/Model/Validation/DeviceLongUrlsValidator.php index 9fda1809..5694f6e1 100644 --- a/module/Core/src/ShortUrl/Model/Validation/DeviceLongUrlsValidator.php +++ b/module/Core/src/ShortUrl/Model/Validation/DeviceLongUrlsValidator.php @@ -10,9 +10,9 @@ use Shlinkio\Shlink\Core\Model\DeviceType; use function array_keys; use function array_values; -use function Functional\contains; use function Functional\every; use function is_array; +use function Shlinkio\Shlink\Core\contains; use function Shlinkio\Shlink\Core\enumValues; class DeviceLongUrlsValidator extends AbstractValidator @@ -41,7 +41,7 @@ class DeviceLongUrlsValidator extends AbstractValidator $validValues = enumValues(DeviceType::class); $keys = array_keys($value); - if (! every($keys, static fn ($key) => contains($validValues, $key))) { + if (! every($keys, static fn ($key) => contains($key, $validValues))) { $this->error(self::INVALID_DEVICE); return false; } diff --git a/module/Core/src/Util/RedirectStatus.php b/module/Core/src/Util/RedirectStatus.php index 76c047f4..313dc432 100644 --- a/module/Core/src/Util/RedirectStatus.php +++ b/module/Core/src/Util/RedirectStatus.php @@ -2,7 +2,7 @@ namespace Shlinkio\Shlink\Core\Util; -use function Functional\contains; +use function Shlinkio\Shlink\Core\contains; enum RedirectStatus: int { @@ -13,11 +13,11 @@ enum RedirectStatus: int public function allowsCache(): bool { - return contains([self::STATUS_301, self::STATUS_308], $this); + return contains($this, [self::STATUS_301, self::STATUS_308]); } public function isLegacyStatus(): bool { - return contains([self::STATUS_301, self::STATUS_302], $this); + return contains($this, [self::STATUS_301, self::STATUS_302]); } } diff --git a/module/Core/test/EventDispatcher/NotifyVisitToWebHooksTest.php b/module/Core/test/EventDispatcher/NotifyVisitToWebHooksTest.php index f85a9d44..c4ca402a 100644 --- a/module/Core/test/EventDispatcher/NotifyVisitToWebHooksTest.php +++ b/module/Core/test/EventDispatcher/NotifyVisitToWebHooksTest.php @@ -28,7 +28,7 @@ use Shlinkio\Shlink\Core\Visit\Entity\Visit; use Shlinkio\Shlink\Core\Visit\Model\Visitor; use function count; -use function Functional\contains; +use function Shlinkio\Shlink\Core\contains; class NotifyVisitToWebHooksTest extends TestCase { @@ -102,7 +102,7 @@ class NotifyVisitToWebHooksTest extends TestCase return true; }), )->willReturnCallback(function ($_, $webhook) use ($invalidWebhooks) { - $shouldReject = contains($invalidWebhooks, $webhook); + $shouldReject = contains($webhook, $invalidWebhooks); return $shouldReject ? new RejectedPromise(new Exception('')) : new FulfilledPromise(''); }); $this->logger->expects($this->exactly(count($invalidWebhooks)))->method('warning')->with( diff --git a/module/Core/test/Importer/ImportedLinksProcessorTest.php b/module/Core/test/Importer/ImportedLinksProcessorTest.php index bf2896e2..5b174053 100644 --- a/module/Core/test/Importer/ImportedLinksProcessorTest.php +++ b/module/Core/test/Importer/ImportedLinksProcessorTest.php @@ -32,8 +32,8 @@ use stdClass; use Symfony\Component\Console\Style\StyleInterface; use function count; -use function Functional\contains; use function Functional\some; +use function Shlinkio\Shlink\Core\contains; use function sprintf; use function str_contains; @@ -128,8 +128,8 @@ class ImportedLinksProcessorTest extends TestCase $this->em->method('getRepository')->with(ShortUrl::class)->willReturn($this->repo); $this->repo->expects($this->exactly(count($urls)))->method('findOneByImportedUrl')->willReturnCallback( fn (ImportedShlinkUrl $url): ?ShortUrl => contains( - ['https://foo', 'https://baz2', 'https://baz3'], $url->longUrl, + ['https://foo', 'https://baz2', 'https://baz3'], ) ? ShortUrl::fromImport($url, true) : null, ); $this->shortCodeHelper->expects($this->exactly(2))->method('ensureShortCodeUniqueness')->willReturn(true); diff --git a/module/Rest/src/Middleware/AuthenticationMiddleware.php b/module/Rest/src/Middleware/AuthenticationMiddleware.php index 7b911817..85ec61b7 100644 --- a/module/Rest/src/Middleware/AuthenticationMiddleware.php +++ b/module/Rest/src/Middleware/AuthenticationMiddleware.php @@ -17,16 +17,16 @@ use Shlinkio\Shlink\Rest\Exception\MissingAuthenticationException; use Shlinkio\Shlink\Rest\Exception\VerifyAuthenticationException; use Shlinkio\Shlink\Rest\Service\ApiKeyServiceInterface; -use function Functional\contains; +use function Shlinkio\Shlink\Core\contains; class AuthenticationMiddleware implements MiddlewareInterface, StatusCodeInterface, RequestMethodInterface { public const API_KEY_HEADER = 'X-Api-Key'; public function __construct( - private ApiKeyServiceInterface $apiKeyService, - private array $routesWithoutApiKey, - private array $routesWithQueryApiKey, + private readonly ApiKeyServiceInterface $apiKeyService, + private readonly array $routesWithoutApiKey, + private readonly array $routesWithQueryApiKey, ) { } @@ -38,7 +38,7 @@ class AuthenticationMiddleware implements MiddlewareInterface, StatusCodeInterfa $routeResult === null || $routeResult->isFailure() || $request->getMethod() === self::METHOD_OPTIONS - || contains($this->routesWithoutApiKey, $routeResult->getMatchedRouteName()) + || contains($routeResult->getMatchedRouteName(), $this->routesWithoutApiKey) ) { return $handler->handle($request); } @@ -61,7 +61,7 @@ class AuthenticationMiddleware implements MiddlewareInterface, StatusCodeInterfa { $routeName = $routeResult->getMatchedRouteName(); $query = $request->getQueryParams(); - $isRouteWithApiKeyInQuery = contains($this->routesWithQueryApiKey, $routeName); + $isRouteWithApiKeyInQuery = contains($routeName, $this->routesWithQueryApiKey); $apiKey = $isRouteWithApiKeyInQuery ? ($query['apiKey'] ?? '') : $request->getHeaderLine(self::API_KEY_HEADER); if (empty($apiKey)) { diff --git a/module/Rest/src/Middleware/BodyParserMiddleware.php b/module/Rest/src/Middleware/BodyParserMiddleware.php index c31bc268..b0548f97 100644 --- a/module/Rest/src/Middleware/BodyParserMiddleware.php +++ b/module/Rest/src/Middleware/BodyParserMiddleware.php @@ -12,7 +12,7 @@ use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; use Shlinkio\Shlink\Core\Exception\MalformedBodyException; -use function Functional\contains; +use function Shlinkio\Shlink\Core\contains; use function Shlinkio\Shlink\Json\json_decode; class BodyParserMiddleware implements MiddlewareInterface, RequestMethodInterface @@ -25,11 +25,11 @@ class BodyParserMiddleware implements MiddlewareInterface, RequestMethodInterfac // In requests that do not allow body or if the body has already been parsed, continue to next middleware if ( ! empty($currentParams) - || contains([ + || contains($method, [ self::METHOD_GET, self::METHOD_HEAD, self::METHOD_OPTIONS, - ], $method) + ]) ) { return $handler->handle($request); }