lshamanl /symfony-ui-bundle-query
该包已被弃用且不再维护。作者建议使用intellect-web-development/symfony-presentation-bundle包代替。
Symfony UI Bundle Query (筛选、排序、分页、单个资源)
0.3.1
2022-01-07 15:21 UTC
Requires
- php: >=8.0
- ext-mbstring: *
- composer/package-versions-deprecated: ^1.11
- doctrine/annotations: ^1.13
- doctrine/doctrine-bundle: ^2.4
- doctrine/doctrine-migrations-bundle: ^3.1
- doctrine/orm: ^2.9
- lshamanl/symfony-ui-bundle-foundation: ^0.1
- symfony-bundles/bundle-dependency: ^1.0
- symfony/config: ^5.2
- symfony/dependency-injection: ^5.2
- symfony/serializer: ^5.2
- symfony/translation: ^5.2
- symfony/validator: ^5.2
- zircote/swagger-php: ^3.2
Requires (Dev)
- fakerphp/faker: 1.13.0
- overtrue/phplint: ^3.0
- phpmetrics/phpmetrics: ^2.7
- phpstan/phpstan: ^0.12.81
- phpunit/phpunit: ^9.5
- roave/security-advisories: dev-latest
- squizlabs/php_codesniffer: ^3.5
- vimeo/psalm: ^4.6
README
描述
此包是Symfoni-bundle。
此包解决的问题:减少开发者编写UI入口点(控制器、CommandBus)等重复代码的需要,例如控制器。
外部使用示例
查询字符串示例
GET /clients?filter[emails.email][like]=26d@&sort=-createdAt,updatedAt&page[number]=1&page[size]=20&filter[userId][eq]=ccf92b7a-8e05-4f4b-9f0a-e4360dbacb23&filter[name.translations.last][eq]=Tesla&lang=ru
合同
排序
描述
排序由"sort"参数指定。排序方向由名称前可选的'-'符号指定。如果存在'-',则按该字段排序使用DESC修饰符,否则使用ASC。允许对多个聚合字段进行排序。要这样做,需要写几个字段,并用','分隔。越早指定的字段,在选择时权重越大。
示例
sort='-createdAt,updatedAt'
分页
描述
分页由"page"参数指定。参数有两个字段 - number和size。
- "number"指定客户端请求的页码。默认值:1
- "size"指定页面大小(应显示多少聚合)。默认值:20
描述
page[number]='1'
page[size]='20'
筛选
描述
搜索运算符
名称 | 允许值 | 示例 | 描述 |
---|---|---|---|
NOT_IN | 'not-in' | filter[status][not-in][]='blocked' | 属性不包含指定的任何值 |
IN | 'in' | filter[status][in][]='active' | 属性包含指定的任何值 |
RANGE | 'range' | filter[rating][range]='17,42' | 属性位于指定的选择范围内 |
IS_NULL | 'is-null' | filter[gender][is-null] | 属性等于null |
NOT_NULL | 'not-null' | filter[name][not-null] | 属性不等于null |
LESS_THAN | 'less-than', '<', 'lt' | filter[rating][<]='94' | 属性小于指定值 |
GREATER_THAN | 'greater-than', '>', 'gt' | filter[rating][>]='42' | 属性大于指定值 |
LESS_OR_EQUALS | 'less-or-equals', '<=', 'lte' | filter[rating][<=]='15' | 属性小于或等于指定值 |
GREATER_OR_EQUALS | 'greater-or-equals', '>=', 'gte' | filter[rating][>=]='97' | 属性大于或等于指定值 |
LIKE | 'like' | filter[email][like]='26d@' | 属性包含指定值的一部分 |
NOT_LIKE | 'not-like' | filter[email][not-like]='27d@' | 属性不包含指定值的一部分 |
EQUALS | 'equals', '=', 'eq' | filter[userId][eq]='ccf92b7a-8e05-4f4b-9f0a-e4360dbacb23' | 属性等于指定值 |
NOT_EQUALS | 'not-equals', '!=', '<>', 'neq' | filter[userId][neq]='aaf92b7a-8e05-4f4b-9f0a-e4360dbacb23' | 属性不等于指定值 |
示例
filter[userId][eq]='ccf92b7a-8e05-4f4b-9f0a-e4360dbacb23'
filter[name.translations.last][eq]='Tesla'
filter[emails.email][like]='26d@'
filter[userId][eq]='ccf92b7a-8e05-4f4b-9f0a-e4360dbacb23'
filter[name.translations.last][eq]='Tesla'
filter[emails.email][in][]='0791d11b6a952a3804e7cb8a220d0a9b@mail.ru'
filter[emails.email][in][]='0891d11b6a952a3804e7cb8a220d0a9b@mail.ru'
内部使用
查询
聚合
读取操作的示例
use App\Path\To\Entity; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Nelmio\ApiDocBundle\Annotation\Model; use SymfonyBundle\UIBundle\Foundation\Core\Contract\ApiFormatter; use SymfonyBundle\UIBundle\Foundation\Core\Dto\OutputFormat; use SymfonyBundle\UIBundle\Query\Core\CQRS\Query\Aggregate\Processor as AggregateProcessor; use SymfonyBundle\UIBundle\Query\Core\CQRS\Query\Aggregate\Context as AggregateContext; class Controller { /** * @Route("/{id}.{_format}", methods={"GET"}, name=".read", defaults={"_format"="json"}) * @OA\Response( * response=200, * description="Read Entity", * @OA\JsonContent( * allOf={ * @OA\Schema(ref=@Model(type=ApiFormatter::class)), * @OA\Schema(type="object", * @OA\Property( * property="data", * type="object", * @OA\Property( * property="entity", * ref=@Model(type=UseCase\CommonOutputContract::class) * ) * ), * @OA\Property( * property="status", * example="200" * ) * ) * } * ) * ) */ public function read( string $id, AggregateProcessor $processor, OutputFormat $outputFormat ): Response { $context = new AggregateContext( outputFormat: $outputFormat->getFormat(), entityId: $id, targetEntityClass: User::class, outputDtoClass: UseCase\CommonOutputContract::class, ); $processor->process($context); return $processor->makeResponse(); }
搜索
搜索操作的示例
use App\Path\To\Entity; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Nelmio\ApiDocBundle\Annotation\Model; use SymfonyBundle\UIBundle\Foundation\Core\Contract\ApiFormatter; use SymfonyBundle\UIBundle\Foundation\Core\Dto\OutputFormat; use SymfonyBundle\UIBundle\Query\Core\Contract\Filter\FilterSortPagination; use SymfonyBundle\UIBundle\Query\Core\CQRS\Query\Search\Processor as SearchProcessor; use SymfonyBundle\UIBundle\Query\Core\CQRS\Query\Search\Context as SearchContext; use SymfonyBundle\UIBundle\Query\Core\Service\Filter\SearchQuery; class Controller { /** * @Route(".{_format}", methods={"GET"}, name=".search", defaults={"_format"="json"}) * @OA\Get( * @OA\Parameter( * name="searchParams", * in="query", * required=false, * @OA\Schema( * ref=@Model(type=FilterSortPagination::class) * ), * ) * ) * @OA\Response( * response=200, * description="Search by Users", * @OA\JsonContent( * allOf={ * @OA\Schema(ref=@Model(type=ApiFormatter::class)), * @OA\Schema(type="object", * @OA\Property( * property="data", * type="object", * @OA\Property( * property="entities", * ref=@Model(type=UseCase\CommonOutputContract::class) * ) * ), * @OA\Property( * property="status", * example="200" * ) * ) * } * ) * ) */ public function search( SearchProcessor $processor, SearchQuery $searchQuery, OutputFormat $outputFormat ): Response { $context = new SearchContext( targetEntityClass: User::class, outputFormat: $outputFormat->getFormat(), outputDtoClass: UseCase\CommonOutputContract::class, filterBlackList: ['id'], pagination: $searchQuery->getPagination(), filters: $searchQuery->getFilters(), sorts: $searchQuery->getSorts() ); $processor->process($context); return $processor->makeResponse(); } }