Skip to content

Commit

Permalink
Removed more functional-php usages
Browse files Browse the repository at this point in the history
  • Loading branch information
acelaya committed Nov 30, 2023
1 parent 549c660 commit bff4bd1
Show file tree
Hide file tree
Showing 20 changed files with 155 additions and 90 deletions.
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@
"symfony/var-dumper": "^6.3",
"veewee/composer-run-parallel": "^1.3"
},
"conflict": {
"symfony/var-exporter": ">=6.3.9,<=6.4.0"
},
"autoload": {
"psr-4": {
"Shlinkio\\Shlink\\CLI\\": "module/CLI/src",
Expand Down
9 changes: 5 additions & 4 deletions data/migrations/Version20200105165647.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use Doctrine\DBAL\Types\Types;
use Doctrine\Migrations\AbstractMigration;

use function Functional\some;
use function Shlinkio\Shlink\Core\some;

final class Version20200105165647 extends AbstractMigration
{
Expand All @@ -23,11 +23,12 @@ final class Version20200105165647 extends AbstractMigration
public function preUp(Schema $schema): void
{
$visitLocations = $schema->getTable('visit_locations');
$this->skipIf(some(
self::COLUMNS,
fn (string $v, string $newColName) => $visitLocations->hasColumn($newColName),
$this->skipIf(some(
self::COLUMNS,
fn (string $v, string $newColName) => $visitLocations->hasColumn($newColName),
), 'New columns already exist');


foreach (self::COLUMNS as $columnName) {
$qb = $this->connection->createQueryBuilder();
$qb->update('visit_locations')
Expand Down
19 changes: 13 additions & 6 deletions data/migrations/Version20200106215144.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Types\Types;
use Doctrine\Migrations\AbstractMigration;

use function Functional\none;

final class Version20200106215144 extends AbstractMigration
{
private const COLUMNS = ['latitude', 'longitude'];
Expand All @@ -22,16 +21,24 @@ final class Version20200106215144 extends AbstractMigration
public function up(Schema $schema): void
{
$visitLocations = $schema->getTable('visit_locations');
$this->skipIf(none(
self::COLUMNS,
fn (string $oldColName) => $visitLocations->hasColumn($oldColName),
), 'Old columns do not exist');
$this->skipIf($this->oldColumnsDoNotExist($visitLocations), 'Old columns do not exist');

foreach (self::COLUMNS as $colName) {
$visitLocations->dropColumn($colName);
}
}

public function oldColumnsDoNotExist(Table $visitLocations): bool
{
foreach (self::COLUMNS as $oldColName) {
if ($visitLocations->hasColumn($oldColName)) {
return false;
}
}

return true;
}

/**
* @throws Exception
*/
Expand Down
13 changes: 5 additions & 8 deletions data/migrations/Version20200110182849.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

use function Functional\each;
use function Functional\partial_left;

final class Version20200110182849 extends AbstractMigration
{
private const DEFAULT_EMPTY_VALUE = '';
Expand All @@ -31,11 +28,11 @@ final class Version20200110182849 extends AbstractMigration

public function up(Schema $schema): void
{
each(
self::COLUMN_DEFAULTS_MAP,
fn (array $columns, string $tableName) =>
each($columns, partial_left([$this, 'setDefaultValueForColumnInTable'], $tableName)),
);
foreach (self::COLUMN_DEFAULTS_MAP as $tableName => $columns) {
foreach ($columns as $columnName) {
$this->setDefaultValueForColumnInTable($tableName, $columnName);
}
}
}

/**
Expand Down
12 changes: 6 additions & 6 deletions module/CLI/src/Command/Domain/DomainRedirectsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

use function Functional\filter;
use function Functional\invoke;
use function array_filter;
use function array_map;
use function sprintf;
use function str_contains;

class DomainRedirectsCommand extends Command
{
public const NAME = 'domain:redirects';

public function __construct(private DomainServiceInterface $domainService)
public function __construct(private readonly DomainServiceInterface $domainService)
{
parent::__construct();
}
Expand Down Expand Up @@ -52,9 +52,9 @@ protected function interact(InputInterface $input, OutputInterface $output): voi
$askNewDomain = static fn () => $io->ask('Domain authority for which you want to set specific redirects');

/** @var string[] $availableDomains */
$availableDomains = invoke(
filter($this->domainService->listDomains(), static fn (DomainItem $item) => ! $item->isDefault),
'toString',
$availableDomains = array_map(
static fn (DomainItem $item) => $item->toString(),
array_filter($this->domainService->listDomains(), static fn (DomainItem $item) => ! $item->isDefault),
);
if (empty($availableDomains)) {
$input->setArgument('domain', $askNewDomain());
Expand Down
28 changes: 22 additions & 6 deletions module/CLI/src/Util/ShlinkTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,38 @@
use Symfony\Component\Console\Helper\TableSeparator;
use Symfony\Component\Console\Output\OutputInterface;

use function Functional\intersperse;
use function array_pop;

final class ShlinkTable
{
private const DEFAULT_STYLE_NAME = 'default';
private const TABLE_TITLE_STYLE = '<options=bold> %s </>';

private function __construct(private readonly Table $baseTable, private readonly bool $withRowSeparators)
private function __construct(private readonly Table $baseTable, private readonly bool $withRowSeparators = false)
{
}

public static function default(OutputInterface $output): self
{
return new self(new Table($output), false);
return new self(new Table($output));
}

public static function withRowSeparators(OutputInterface $output): self
{
return new self(new Table($output), true);
return new self(new Table($output), withRowSeparators: true);
}

public static function fromBaseTable(Table $baseTable): self
{
return new self($baseTable, false);
return new self($baseTable);
}

public function render(array $headers, array $rows, ?string $footerTitle = null, ?string $headerTitle = null): void
{
$style = Table::getStyleDefinition(self::DEFAULT_STYLE_NAME);
$style->setFooterTitleFormat(self::TABLE_TITLE_STYLE)
->setHeaderTitleFormat(self::TABLE_TITLE_STYLE);
$tableRows = $this->withRowSeparators ? intersperse($rows, new TableSeparator()) : $rows;
$tableRows = $this->withRowSeparators ? $this->addRowSeparators($rows) : $rows;

$table = clone $this->baseTable;
$table->setStyle($style)
Expand All @@ -49,4 +49,20 @@ public function render(array $headers, array $rows, ?string $footerTitle = null,
->setHeaderTitle($headerTitle)
->render();
}

private function addRowSeparators(array $rows): array
{
$aggregation = [];
$separator = new TableSeparator();

foreach ($rows as $row) {
$aggregation[] = $row;
$aggregation[] = $separator;
}

// Remove last separator
array_pop($aggregation);

return $aggregation;
}
}
36 changes: 34 additions & 2 deletions module/Core/functions/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlMode;

use function array_keys;
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;
Expand Down Expand Up @@ -95,10 +95,12 @@ function getNonEmptyOptionalValueFromInputFilter(InputFilter $inputFilter, strin
function arrayToString(array $array, int $indentSize = 4): string
{
$indent = str_repeat(' ', $indentSize);
$names = array_keys($array);
$index = 0;

return reduce_left($array, static function ($messages, string $name, $_, string $acc) use (&$index, $indent) {
return array_reduce($names, static function (string $acc, string $name) use (&$index, $indent, $array) {
$index++;
$messages = $array[$name];

return $acc . sprintf(
"%s%s'%s' => %s",
Expand Down Expand Up @@ -199,3 +201,33 @@ function flatten(array $multiArray): array
initial: [],
);
}

/**
* Checks if a callback returns true for at least one item in a collection.
* @param callable(mixed $value, string|number $key): bool $callback
*/
function some(iterable $collection, callable $callback): bool
{
foreach ($collection as $key => $value) {
if ($callback($value, $key)) {
return true;
}
}

return false;
}

/**
* Checks if a callback returns true for all item in a collection.
* @param callable(mixed $value, string|number $key): bool $callback
*/
function every(iterable $collection, callable $callback): bool
{
foreach ($collection as $key => $value) {
if (! $callback($value, $key)) {
return false;
}
}

return true;
}
7 changes: 3 additions & 4 deletions module/Core/src/Config/NotFoundRedirectResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
use Shlinkio\Shlink\Core\Util\RedirectResponseHelperInterface;

use function Functional\compose;
use function Functional\id;
use function str_replace;
use function urlencode;

Expand All @@ -23,8 +22,8 @@ class NotFoundRedirectResolver implements NotFoundRedirectResolverInterface
private const ORIGINAL_PATH_PLACEHOLDER = '{ORIGINAL_PATH}';

public function __construct(
private RedirectResponseHelperInterface $redirectResponseHelper,
private LoggerInterface $logger,
private readonly RedirectResponseHelperInterface $redirectResponseHelper,
private readonly LoggerInterface $logger,
) {
}

Expand Down Expand Up @@ -73,7 +72,7 @@ private function resolvePlaceholders(UriInterface $currentUri, string $redirectU
$replacePlaceholderForPattern(self::ORIGINAL_PATH_PLACEHOLDER, $path, $modifier),
);
$replacePlaceholdersInPath = compose(
$replacePlaceholders(id(...)),
$replacePlaceholders(static fn (mixed $v) => $v),
static fn (?string $path) => $path === null ? null : str_replace('//', '/', $path),
);
$replacePlaceholdersInQuery = $replacePlaceholders(urlencode(...));
Expand Down
29 changes: 19 additions & 10 deletions module/Core/src/Config/PostProcessor/ShortUrlMethodsProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,34 @@
use Shlinkio\Shlink\Core\Action\RedirectAction;
use Shlinkio\Shlink\Core\Util\RedirectStatus;

use function array_values;
use function count;
use function Functional\partition;

use const Shlinkio\Shlink\DEFAULT_REDIRECT_STATUS_CODE;

/**
* Sets the appropriate allowed methods on the redirect route, based on the redirect status code that was configured.
* * For "legacy" status codes (301 and 302) the redirect URL will work only on GET method.
* * For other status codes (307 and 308) the redirect URL will work on any method.
*/
class ShortUrlMethodsProcessor
{
public function __invoke(array $config): array
{
[$redirectRoutes, $rest] = partition(
$config['routes'] ?? [],
static fn (array $route) => $route['name'] === RedirectAction::class,
);
if (count($redirectRoutes) === 0) {
$allRoutes = $config['routes'] ?? [];
$redirectRoute = null;
$rest = [];

// Get default route from routes array
foreach ($allRoutes as $route) {
if ($route['name'] === RedirectAction::class) {
$redirectRoute ??= $route;
} else {
$rest[] = $route;
}
}

if ($redirectRoute === null) {
return $config;
}

[$redirectRoute] = array_values($redirectRoutes);
$redirectStatus = RedirectStatus::tryFrom(
$config['redirects']['redirect_status_code'] ?? 0,
) ?? DEFAULT_REDIRECT_STATUS_CODE;
Expand Down
19 changes: 12 additions & 7 deletions module/Core/src/Domain/DomainService.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
use Shlinkio\Shlink\Rest\Entity\ApiKey;

use function array_map;
use function Functional\first;
use function Functional\group;

class DomainService implements DomainServiceInterface
{
Expand Down Expand Up @@ -49,12 +47,19 @@ private function defaultDomainAndRest(?ApiKey $apiKey): array
{
/** @var DomainRepositoryInterface $repo */
$repo = $this->em->getRepository(Domain::class);
$groups = group(
$repo->findDomains($apiKey),
fn (Domain $domain) => $domain->authority === $this->defaultDomain ? 'default' : 'domains',
);
$allDomains = $repo->findDomains($apiKey);
$defaultDomain = null;
$restOfDomains = [];

foreach ($allDomains as $domain) {
if ($domain->authority === $this->defaultDomain) {
$defaultDomain = $domain;
} else {
$restOfDomains[] = $domain;
}
}

return [first($groups['default'] ?? []), $groups['domains'] ?? []];
return [$defaultDomain, $restOfDomains];
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Throwable;

use function Functional\each;
use function array_walk;

abstract class AbstractNotifyVisitListener extends AbstractAsyncListener
{
Expand Down Expand Up @@ -46,7 +46,7 @@ public function __invoke(VisitLocated $visitLocated): void
$updates = $this->determineUpdatesForVisit($visit);

try {
each($updates, fn (Update $update) => $this->publishingHelper->publishUpdate($update));
array_walk($updates, fn (Update $update) => $this->publishingHelper->publishUpdate($update));
} catch (Throwable $e) {
$this->logger->debug(
'Error while trying to notify {name} with new visit. {e}',
Expand Down
Loading

0 comments on commit bff4bd1

Please sign in to comment.