bentools / doctrine-changeset
Doctrine UnitOfWork 辅助工具,方便访问更改集。
1.1
2023-12-09 15:28 UTC
Requires
- php: >=8.2
- doctrine/orm: ~2.5
Requires (Dev)
- ext-ctype: *
- ext-iconv: *
- ext-sqlite3: *
- doctrine/doctrine-bundle: ^2.10
- doctrine/doctrine-migrations-bundle: ^3.2
- dunglas/doctrine-json-odm: ^1.3
- friendsofphp/php-cs-fixer: ^3.35
- pestphp/pest: ^2.23
- pestphp/pest-plugin-drift: ^2.5
- phpstan/phpstan: ^1.10
- symfony/browser-kit: 6.3.*
- symfony/console: 6.3.*
- symfony/css-selector: 6.3.*
- symfony/dotenv: 6.3.*
- symfony/flex: ^2
- symfony/framework-bundle: 6.3.*
- symfony/phpunit-bridge: ^6.3
- symfony/runtime: 6.3.*
- symfony/yaml: 6.3.*
README
Doctrine 变更跟踪器
此包为您的 Doctrine 实体提供了一个 EntityTracker
服务。此服务允许您轻松跟踪实体的更改,例如。
$entity->name = 'foo'; $tracker->hasChanged($entity); // true $tracker->hasChanged($entity, 'name'); // true $changeSet=$tracker->getChangeSet($entity, 'name'); $changeSet->from; // Previous value $changeSet->to; // New value $changeSet->hadPreviousValue('foo'); // false $changeSet->hasNewValue('bar'); // false $changeSet->hasChangedFor(null, 'foo'); // true $changeSet->hadPreviousValue(whatever()->except(null)); // false $changeSet->hasNewValue(oneOf('foo', 'bar')); // true
此包还提供了对属性类型为 object
的 #[TrackChanges]
属性的支持 - 这使得 Doctrine 能够感知嵌套对象的更改(默认情况下不是这样,除非您分配了不同的对象)。
用法
只需在您的服务中注入 EntityTracker
并使用辅助方法即可。
示例
<?php namespace App\Services; use App\Entity\Book; use BenTools\DoctrineChangeSet\Tracker\EntityTracker; use Doctrine\ORM\EntityManagerInterface; use function assert; use function BenTools\DoctrineChangeSet\Tracker\oneOf; use function BenTools\DoctrineChangeSet\Tracker\whatever; final readonly class MyService { public function __construct( private EntityTracker $tracker, private EntityManagerInterface $em, ) {} public function createBook(): void { $book = new Book(); $book->title = 'PHP For Dummiez'; $book->isbn = '00000000001'; assert(true === $this->tracker->hasChanged($book)); $this->em->persist($book); $this->em->flush(); } public function updateBook(): void { $repository = $this->em->getRepository(Book::class) $book = $repository->findOneBy(['isbn' => '00000000001']); $book->title = 'PHP For Dummies'; assert(true === $this->tracker->hasChanged($book)); assert(true === $this->tracker->hasChanged($book, 'title')); assert(false === $this->tracker->hasChanged($book, 'isbn')); assert(true === $this->tracker->getChangeSet($book, 'title')->hadPreviousValue('PHP For Dummiez')); assert(true === $this->tracker->getChangeSet($book, 'title')->hasNewValue('PHP For Dummies')); // Shorthand for both methods above assert(true === $this->tracker->getChangeSet($book, 'title')->hasChangedFor('PHP For Dummiez', 'PHP For Dummies')); // You can also check for multiple values assert(true === $this->tracker->getChangeSet($book, 'title')->hadPreviousValue(oneOf('PHP For Dummies', 'PHP For Dummiez'))); assert(true === $this->tracker->getChangeSet($book, 'title')->hasNewValue(whatever()->except(null, 'PHP For Dummiez'))); $this->em->flush(); } }
跟踪对象更改
默认情况下,Doctrine 不跟踪嵌入式对象的更改。例如
namespace App\Entity; use DateTimeImmutable; use Doctrine\ORM\Mapping as ORM; use Doctrine\DBAL\Types\Types; #[ORM\Entity] class Book { #[ORM\Id, ORM\Column, ORM\GeneratedValue] public int $id; #[ORM\Column] public string $title; #[ORM\Column(type: Types::OBJECT)] public object $data; }
这样做
$book = $repository->findOneBy([]) $book->data->foo = 'bar' $em->flush(); // Will have no effect as soon as no other scalar or array property has been changed
为了强制 Doctrine 跟踪嵌入式对象的更改,只需添加 TrackChanges
属性即可。
namespace App\Entity; use BenTools\DoctrineChangeSet\Tracker\TrackChanges; // ... #[ORM\Entity] class Book { // ... #[ORM\Column(type: Types::OBJECT)] #[TrackChanges] public object $data; }
安装
composer require bentools/doctrine-changeset
然后,将以下行添加到您的 bundles.php
# config/bundles.php return [ // ... BenTools\DoctrineChangeSet\Bundle\DoctrineChangeSetBundle::class => ['all' => true], ];
测试
composer ci:check
许可协议
MIT.