Skip to content

Commit

Permalink
* fix not accepting int typed value for numeric params: https://www.p…
Browse files Browse the repository at this point in the history
…hp.net/manual/en/function.ctype-digit.php#108712

* rename `params` in method name and param to `param`
@ `validateParamValue()`

* replace public prop `$params` with getter and fluent setter contain the param `$params` in ctor
@ `ParamsValidator`

* now not being fluent method @ `BaseQuery->query()`
@ `App\PostsQuery`

* replace `new ParamsValidator()` & `new $queryClass()` with services locator
* fix misusing `AbstractController->getParameter()` for getting the value of query string `?cursor=`
@ `App\Controller\PostsController`

* fix unquoted table name will become lowercase ing Postgres @ `PostRepository->__construct()`
* fix typo in table name @ `SubReplyRepository->getTableNameSuffix()`
@ `App\Repository\Post`
@ symfony
  • Loading branch information
n0099 committed Oct 8, 2024
1 parent c79a749 commit 8483414
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 27 deletions.
18 changes: 14 additions & 4 deletions symfony/src/Controller/PostsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Controller;

use App\Helper;
use App\PostsQuery\BaseQuery;
use App\PostsQuery\IndexQuery;
use App\PostsQuery\ParamsValidator;
use App\PostsQuery\SearchQuery;
Expand All @@ -12,7 +13,9 @@
use App\Validator\Validator;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Psr\Container\ContainerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Stopwatch\Stopwatch;
Expand All @@ -26,6 +29,12 @@ public function __construct(
private readonly ForumRepository $forumRepository,
private readonly UserRepository $userRepository,
private readonly LatestReplierRepository $latestReplierRepository,
#[AutowireLocator([
ParamsValidator::class,
IndexQuery::class,
SearchQuery::class,
])]
private readonly ContainerInterface $locator,
) {}

#[Route('/posts')]
Expand All @@ -38,8 +47,8 @@ public function query(Request $request): array
)),
'query' => new Assert\Required(new Assert\Json()),
]));
$validator = new ParamsValidator($this->validator, \Safe\json_decode($request->query->get('query'), true));
$params = $validator->params;
$validator = $this->locator->get(ParamsValidator::class);
$params = $validator->setParams(\Safe\json_decode($request->query->get('query'), true))->getParams();

$postIDParams = $params->pick(...Helper::POST_ID);
$isQueryByPostID =
Expand All @@ -58,9 +67,10 @@ public function query(Request $request): array

$validator->addDefaultParamsThenValidate(shouldSkip40003: $isIndexQuery);

$queryClass = $isIndexQuery ? IndexQuery::class : SearchQuery::class;
$this->stopwatch->start('$queryClass->query()');
$query = (new $queryClass())->query($params, $this->getParameter('cursor'));
/** @var BaseQuery $query */
$query = $this->locator->get($isIndexQuery ? IndexQuery::class : SearchQuery::class);
$query->query($params, $request->query->get('cursor'));
$this->stopwatch->stop('$queryClass->query()');
$this->stopwatch->start('fillWithParentPost');
$result = $query->fillWithParentPost();
Expand Down
2 changes: 1 addition & 1 deletion symfony/src/PostsQuery/BaseQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ abstract class BaseQuery

protected bool $orderByDesc;

abstract public function query(QueryParams $params, ?string $cursor): self;
abstract public function query(QueryParams $params, ?string $cursor): void;

public function __construct(
private readonly SerializerInterface $serializer,
Expand Down
3 changes: 1 addition & 2 deletions symfony/src/PostsQuery/IndexQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function __construct(
}

/** @SuppressWarnings(PHPMD.ElseExpression) */
public function query(QueryParams $params, ?string $cursor): self
public function query(QueryParams $params, ?string $cursor): void
{
/** @var array<string, mixed> $flatParams key by param name */
$flatParams = array_reduce(
Expand Down Expand Up @@ -107,6 +107,5 @@ public function query(QueryParams $params, ?string $cursor): self
}

$this->setResult($fid, $queries, $cursor, $hasPostIDParam ? $postIDParamName : null);
return $this;
}
}
43 changes: 27 additions & 16 deletions symfony/src/PostsQuery/ParamsValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,23 @@ class ParamsValidator
{
public const array UNIQUE_PARAMS_NAME = ['fid', 'postTypes', 'orderBy'];

public QueryParams $params;
private QueryParams $params;

public function __construct(private readonly Validator $validator) {}

public function getParams(): QueryParams
{
return $this->params;
}

/** @param array[] $params */
public function __construct(private readonly Validator $validator, array $params)
public function setParams(array $params): static
{
$this->validateParamsValue($params);
array_map($this->validateParamValue(...), $params);
$this->params = new QueryParams($params);
$this->validate40001();
$this->validate40005();
return $this;
}

public function addDefaultParamsThenValidate(bool $shouldSkip40003): void
Expand All @@ -37,33 +45,36 @@ public function addDefaultParamsThenValidate(bool $shouldSkip40003): void
$this->validate40004($currentPostTypes);
}

private function validateParamsValue(array $params): void
private function validateParamValue(array $param): void
{
$paramsPossibleValue = [
'userGender' => [0, 1, 2],
'userManagerType' => ['NULL', 'manager', 'assist', 'voiceadmin'],
];
$numericParams = collect([
'fid',
'tid',
'pid',
'spid',
'threadViewCount',
'threadShareCount',
'threadReplyCount',
'replySubReplyCount',
'authorUid',
'authorExpGrade',
'latestReplierUid',
])->mapWithKeys(fn(string $paramName) => [$paramName => new Assert\Type(['digit', 'int'])]);
// note here we haven't validated that is every sub param have a corresponding main param yet
$this->validator->validate($params, new Assert\Collection([
'fid' => new Assert\Type('digit'),
$this->validator->validate($param, new Assert\Collection([
...$numericParams,
'postTypes' => new Assert\Collection([new Assert\Choice(Helper::POST_TYPES)]),
'orderBy' => new Assert\Collection([new Assert\Choice([...Helper::POST_ID, 'postedAt'])]),
'direction' => new Assert\Choice(['ASC', 'DESC']),
'tid' => new Assert\Type('digit'),
'pid' => new Assert\Type('digit'),
'spid' => new Assert\Type('digit'),
'postedAt' => new DateTimeRange(),
'latestReplyPostedAt' => new DateTimeRange(),
'threadViewCount' => new Assert\Type('digit'),
'threadShareCount' => new Assert\Type('digit'),
'threadReplyCount' => new Assert\Type('digit'),
'replySubReplyCount' => new Assert\Type('digit'),
'threadProperties' => new Assert\Collection([new Assert\Choice(['good', 'sticky'])]),
'authorUid' => new Assert\Type('digit'),
'authorExpGrade' => new Assert\Type('digit'),
'authorGender' => new Assert\Choice($paramsPossibleValue['userGender']),
'authorManagerType' => new Assert\Choice($paramsPossibleValue['userManagerType']),
'latestReplierUid' => new Assert\Type('digit'),
'latestReplierGender' => new Assert\Choice($paramsPossibleValue['userGender']),

'not' => new Assert\Type('boolean'),
Expand Down
3 changes: 1 addition & 2 deletions symfony/src/PostsQuery/SearchQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function __construct(
parent::__construct($serializer, $stopwatch, $cursorCodec, $postRepositoryFactory);
}

public function query(QueryParams $params, ?string $cursor): self
public function query(QueryParams $params, ?string $cursor): void
{
/** @var int $fid */
$fid = $params->getUniqueParamValue('fid');
Expand Down Expand Up @@ -55,7 +55,6 @@ public function query(QueryParams $params, ?string $cursor): self
}

$this->setResult($fid, $queries, $cursor);
return $this;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion symfony/src/Repository/Post/PostRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function __construct(
) {
parent::__construct($registry, $postClass);
$entityManager->getClassMetadata($postClass)->setPrimaryTable([
'name' => "tbmc_f{$fid}_" . $this->getTableNameSuffix()
'name' => "\"tbmc_f{$fid}_" . $this->getTableNameSuffix() . '"'
]);
}

Expand Down
2 changes: 1 addition & 1 deletion symfony/src/Repository/Post/SubReplyRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ public function __construct(ManagerRegistry $registry, EntityManagerInterface $e

protected function getTableNameSuffix(): string
{
return 'subRreply';
return 'subReply';
}
}

0 comments on commit 8483414

Please sign in to comment.