vrok / symfony-addons
Symfony 辅助类
Requires
- php: ^8.2
- symfony/framework-bundle: ^6.3.0|^7.0.0
- symfony/yaml: ^6.3.0|^7.0.0
Requires (Dev)
- api-platform/core: ^3.2.10
- doctrine/data-fixtures: ^1.5.2
- doctrine/doctrine-bundle: ^2.6.0
- doctrine/doctrine-fixtures-bundle: ^3.4.4
- doctrine/orm: ^2.14.0
- friendsofphp/php-cs-fixer: ^3.59.3
- monolog/monolog: ^3.0.0
- phpunit/phpunit: ^10.5.27
- roave/security-advisories: dev-latest
- symfony/browser-kit: ^6.3.0|^7.0.0
- symfony/doctrine-messenger: ^6.3.0|^7.0.0
- symfony/http-client: ^6.3.0|^7.0.0
- symfony/mailer: ^6.3.0|^7.0.0
- symfony/monolog-bundle: ^3.8.0
- symfony/phpunit-bridge: ^6.3.0|^7.0.0
- symfony/twig-bundle: ^6.3.0|^7.0.0
- symfony/validator: ^6.3.0|^7.0.0
- symfony/workflow: ^6.3.0|^7.0.0
- vrok/doctrine-addons: ^2.6.2
- dev-main
- 2.12.0
- 2.11.0
- 2.10.0
- 2.9.0
- 2.8.1
- 2.8.0
- 2.7.0
- 2.6.0
- 2.5.0
- 2.4.0
- 2.3.0
- 2.2.0
- 2.1.0
- 2.0.1
- 2.0.0
- v1.11.0
- v1.9.10
- v1.9.1
- v1.9.0
- v1.8.0
- v1.6.1
- v1.6.0
- v1.5.2
- v1.5.1
- v1.5.0
- v1.4.3
- v1.4.2
- v1.4.1
- v1.4.0
- v1.3.1
- v1.3.0
- v1.2.0
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.0
- dev-renovate/all
- dev-develop
- dev-release-1.x
This package is auto-updated.
Last update: 2024-09-27 04:24:14 UTC
README
这是一个库,包含用于与 Symfony 框架结合使用的附加类。
邮件辅助器
自动设置发送地址
我们想要替换通过 mailer.yaml 设置发送地址的方法(参见https://symfonycasts.com/screencast/mailer/event-global-recipients),因为这仍然需要为每封邮件设置 FROM 地址,并且也不允许我们设置发送者姓名。
config/services.yaml
Vrok\SymfonyAddons\EventSubscriber\AutoSenderSubscriber: arguments: $sender: "%env(MAILER_SENDER)%"
.env[.local]
MAILER_SENDER="Change Me <your@email>"
消息传递辅助器
在消息前后重置记录器
我们希望将属于单个消息的所有日志条目分组,并带有唯一的 UID,在处理完消息后(成功或失败)刷新缓冲记录器,以便立即在日志中看到条目。
config/services.yaml
# add a UID to the context, same UID for each HTTP request or console command # and with the event subscriber also for each message Monolog\Processor\UidProcessor: tags: - { name: monolog.processor, handler: logstash } # resets the UID when a message is received, flushed a buffer after a # message was handled. Add this multiple times if you want to flush more # channels, e.g. messenger app.event.reset_app_logger: class: Vrok\SymfonyAddons\EventSubscriber\ResetLoggerSubscriber tags: - { name: monolog.logger, channel: app }
验证器
AtLeastOneOf
类似于 Symfony 自带的 AtLeastOneOf 约束,但返回的是最后一次失败的验证消息,而不是像 This value should satisfy at least ...
这样的消息。当使用 AtLeastOne
与 Blank
作为第一个约束时,可以用于明显可选的表单字段,此时应只显示简单的消息。
参见 AtLeastOneOfValidatorTest
中的示例。
NoHtml
此验证器尝试检测字符串是否包含 HTML,以允许纯文本。
参见 NoHtmlValidatorTest
中的允许值/禁止值示例。
NoLineBreak
此验证器在验证的字符串中检测到一个或多个换行符时引发违规。
检测 unicode 换行符,参见 NoLineBreaksValidatorTest
获取详细信息。
NoSurroundingWhitespace
此验证器在验证的字符串中检测到尾随或前导空白或换行符时引发违规。
使用正则表达式查找 \s
和 \R
,参见 NoSurroundingWhitespaceValidatorTest
获取检测到的字符的详细信息。
PasswordStrength
此验证器通过确定密码字符串的熵来评估给定密码字符串的强度,而不是要求像“必须包含至少一个大写字母、一个数字和一个特殊字符”这样的东西。
可以设置 minStrength
来调整要求。有关计算详情,请参阅 Vrok\SymfonyAddons\Helper\PasswordStrength
。
PHPUnit 辅助器
使用 ApiPlatformTestCase
此类用于通过指定输入数据和验证响应数据来测试 ApiPlatform 端点。它结合了以下记录的特性,在每次测试前刷新数据库,可选地创建已认证的请求并检查创建的日志/发送的电子邮件/分发的消息。它允许轻松检查预期的响应内容、数据中的允许或禁止键或验证给定的模式。
需要安装 "symfony/browser-kit" 和 "symfony/http-client"(当然还有 ApiPlatform)。
<?php use Vrok\SymfonyAddons\PHPUnit\ApiPlatformTestCase; class AuthApiTest extends ApiPlatformTestCase { public function testAuthRequiresPassword(): void { $this->testOperation([ 'uri' => '/authentication_token', 'method' => 'POST', 'requestOptions' => ['json' => ['username' => 'fakeuser']], 'responseCode' => 400, 'contentType' => 'application/json', 'json' => [ 'type' => 'https://tools.ietf.org/html/rfc2616#section-10', 'title' => 'An error occurred', 'detail' => 'The key "password" must be provided.', ], ]); } }
使用 RefreshDatabaseTrait
为每个测试(重新)创建 DB 架构,删除现有数据并用预定义的固定值填充表。安装 doctrine/doctrine-fixtures-bundle
并创建固定值,特性默认使用 test 组。
只需在测试用例中包含特性并在 setUp
方法中调用 bootKernel()
或 createClient()
即可,例如。
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Vrok\SymfonyAddons\PHPUnit\RefreshDatabaseTrait; class DatabaseTest extends KernelTestCase { use RefreshDatabaseTrait; /** * @var \Doctrine\ORM\EntityManager */ private $entityManager; protected function setUp(): void { $kernel = self::bootKernel(); $this->entityManager = $kernel->getContainer() ->get('doctrine') ->getManager(); } }
可选地定义为此测试类使用哪些固定值
protected static $fixtureGroups = ['test', 'other'];
支持通过 DB_CLEANUP_METHOD
设置测试后的清理方法。允许的值是 purge 和 dropSchema,更多详细信息请参阅 RefreshDatabaseTrait::$cleanupMethod
。
使用 AuthenticatedClientTrait
适用于与APIPlatform项目配合使用 lexik/jwt-authentication-bundle
。根据用户的唯一邮箱、用户名等创建JWT,并将其添加到测试客户端的头部。
在测试用例中包含特性并调用 createAuthenticatedClient
use ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestCase; use Vrok\SymfonyAddons\PHPUnit\AuthenticatedClientTrait; class ApiTest extends ApiTestCase { use AuthenticatedClientTrait; public function testAccess(): void { $client = static::createAuthenticatedClient([ 'email' => TestFixtures::ADMIN['email'] ]); $iri = $this->findIriBy(User::class, ['id' => 1]); $client->request('GET', $iri); self::assertResponseIsSuccessful(); } }
使用MonologAssertsTrait
适用于使用monolog-bundle的Symfony项目。
需要v3.0或更高版本的 monolog/monolog
。
在触发应创建日志的操作之前,包含特性并调用 prepareLogger
,然后使用 assertLoggerHasMessage
检查是否创建了带有指定消息和严重性的日志记录。
use Monolog\Level; use Psr\Log\LoggerInterface; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Vrok\SymfonyAddons\PHPUnit\MonologAssertsTrait; class LoggerTest extends KernelTestCase { use MonologAssertsTrait; public function testLog(): void { self::prepareLogger(); $logger = static::getContainer()->get(LoggerInterface::class); $logger->error('Failed to do something'); self::assertLoggerHasMessage('Failed to do something', Level::Error); } }
工作流助手
需要 symfony/workflow
。
PropertyMarkingStore
可以用于替代默认的 MethodMarkingStore
,用于没有Setter/Getter的实体和属性。
workflow.yaml
framework: workflows: application_state: type: state_machine marking_store: # We need to use a service as there is no option to register a new "type" service: workflow.application.marking_store
services.yaml
# When using the "service" option, all other settings like "property: state" # are ignored in the workflow.yaml -> That's why we need a service definition # with the correct arguments. workflow.application.marking_store: class: Vrok\SymfonyAddons\Workflow\PropertyMarkingStore arguments: [true, 'state']
WorkflowHelper
允许获取可用转换及其阻塞器的数组,可用于显示用户从当前状态可以执行哪些转换,以及为什么当前转换被阻塞。
public function __invoke( Entity $data WorkflowInterface $entityStateMachine, ): array { $result = $data->toArray(); $result['transitions'] = WorkflowHelper::getTransitionList($data, $entityStateMachine); return $result; }
'publish' => [
'blockers' => [
TransitionBlocker::UNKNOWN => 'Title is empty!',
],
],
Cron事件
将此捆绑包添加到 bundles.php
注册了三个新的CLI命令
Vrok\SymfonyAddons\VrokSymfonyAddonsBundle::class => ['all' => true],
bin/console cron:hourly bin/console cron:daily bin/console cron:monthly
当调用这些命令时,它们会触发一个事件(CronHourlyEvent
、CronDailyEvent
、CronMonthlyEvent
),该事件可以被一个或多个事件监听器/订阅者用来进行维护、推送消息到messenger等。执行这些命令的正确性由您负责通过crontab来执行!
use Vrok\SymfonyAddons\Event\CronDailyEvent; class MyEventSubscriber implements EventSubscriberInterface public static function getSubscribedEvents(): array { return [ CronDailyEvent::class => [ ['onCronDaily', 100], ], ]; } }
ApiPlatform过滤器
SimpleSearchFilter
选择包含至少一个指定属性中搜索词的实体(不区分大小写)。所有指定属性类型必须是字符串。
#[ApiFilter( filterClass: SimpleSearchFilter::class, properties: [ 'description', 'name', 'slug', ], arguments: ['searchParameterName' => 'pattern'] )]
需要CAST,如Doctrine函数所定义,例如通过 vrok/doctrine-addons
doctrine: orm: dql: string_functions: CAST: Vrok\DoctrineAddons\ORM\Query\AST\CastFunction
ContainsFilter
仅适用于Postgres:通过使用 @>
运算符,根据它们的jsonb字段过滤实体,如果它们包含搜索参数。例如,用于过滤数组中的数字。
#[ApiFilter(filterClass: ContainsFilter::class, properties: ['numbers'])]
需要CONTAINS,如Doctrine函数所定义,由 vrok/doctrine-addons
提供
doctrine: orm: dql: string_functions: CONTAINS: Vrok\DoctrineAddons\ORM\Query\AST\ContainsFunction
JsonExistsFilter
仅适用于Postgres:通过使用 ?
运算符,根据它们的jsonb字段过滤实体,如果它们包含搜索参数。例如,用于过滤用户的角色,以防止在以文本方式搜索时与重叠的角色名称(例如,ROLE_ADMIN和ROLE_ADMIN_BLOG)意外匹配。
#[ApiFilter(filterClass: JsonExistsFilter::class, properties: ['roles'])]
需要JSON_CONTAINS_TEXT,如Doctrine函数所定义,由 vrok/doctrine-addons
提供
doctrine: orm: dql: string_functions: JSON_CONTAINS_TEXT: Vrok\DoctrineAddons\ORM\Query\AST\JsonContainsTextFunction
MultipartDecoder
将此捆绑包添加到 bundles.php
注册了 MultipartDecoder
,允许处理带有附加数据的文件上传(例如在ApiPlatform中)
Vrok\SymfonyAddons\VrokSymfonyAddonsBundle::class => ['all' => true],
解码器会自动用于 multipart
请求,并简单返回所有POST参数和上传的文件。要启用此功能,请将 multipart
格式添加到您的 config\api_platform.yaml
api_platform: formats: multipart: ['multipart/form-data']
FormDecoder
将此捆绑包添加到 bundles.php
注册了 FormDecoder
,允许在ApiPlatform中处理HTML表单数据
Vrok\SymfonyAddons\VrokSymfonyAddonsBundle::class => ['all' => true],
解码器会自动用于 form
请求,并简单返回所有POST参数。要启用此功能,请将 form
格式添加到您的 config\api_platform.yaml
api_platform: formats: form: ['application/x-www-form-urlencoded']
Twig扩展
将此捆绑包添加到 bundles.php
与 symfony/twig-bundle
一起注册新扩展
Vrok\SymfonyAddons\VrokSymfonyAddonsBundle::class => ['all' => true],
FormatBytes
将字节转换为可读格式(支持高达TiB)。
此扩展自动注册。
在您的Twig模板中
{{ attachment.filesize|formatBytes }}
输出:9.34 MiB
开发者文档
composer.json require
- symfony/yaml 是加载捆绑包和测试配置所必需的
composer.json dev
- doctrine/data-fixtures 由 doctrine-fixtures 扩展自动安装,但我们需要将其版本锁定为最小版本,因为 1.5.2 之前的版本与 DBAL < 3 不兼容(@see doctrine/data-fixtures#370)
- doctrine/doctrine-fixtures-bundle 对于 ApiPlatformTestCase 的测试是必需的
- symfony/browser-kit 对于 MultipartDecoder 的测试是必需的
- symfony/mailer 对于 AutoSenderSubscriber 的测试是必需的
- symfony/doctrine-messenger 对于 ResetLoggerSubscriber 的测试是必需的
- symfony/monolog-bundle 对于 MonologAssertsTrait 和 ResetLoggerSubscriber 的测试是必需的
- symfony/phpunit-bridge 必须至少是 v6.2.3,以防止 "调用未定义的方法 Doctrine\Common\Annotations\AnnotationRegistry::registerLoader()"
- symfony/string 对于 API Platform 的屈折变化器是必需的
- symfony/twig-bundle 对于 FormatBytesExtension 的测试是必需的
- symfony/workflow 对于 WorkflowHelper 和 PropertyMarkingStore 的测试是必需的
- monolog/monolog 至少必须是 v3,以支持
Monolog\Level
- api-platform/core 和 vrok/doctrine-addons 对于测试 ApiPlatform 过滤器是必需的
待办事项
- 对
AuthenticatedClientTrait
和RefreshDatabaseTrait
的测试 ApiPlatformTestCase
应该不再使用AuthenticatedClientTrait
,而应该使用自己的 getJWT() 并使 User 类可配置,就像 fixtures 一样。- QueryBuilderHelper 的测试
- 将代码与 ApiPlatform\Doctrine\Orm\Util\QueryBuilderHelper 进行比较