bentools/doctrine-changeset

Doctrine UnitOfWork 辅助工具,方便访问更改集。

安装: 311

依赖者: 0

建议者: 0

安全: 0

星标: 0

关注者: 2

分支: 0

开放问题: 0

类型:symfony-bundle

1.1 2023-12-09 15:28 UTC

This package is auto-updated.

Last update: 2024-09-09 17:08:41 UTC


README

CI Workflow Coverage

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.