Create a customized myers diff based system for snip content

This commit is contained in:
Tim
2025-04-14 23:25:11 +02:00
parent a18eda6748
commit 2db9c5f1d9
8 changed files with 317 additions and 88 deletions

View File

@ -8,49 +8,96 @@ use Doctrine\ORM\EntityManagerInterface;
readonly class SnipContentService
{
public function __construct(
private Snip $snip,
private EntityManagerInterface $em,
) {}
public function update(string $snipContents): void
public function update(Snip $snip, string $snipContents): void
{
if ($this->snip->getActiveVersion()?->getText() === $snipContents) {
$parentContent = $snip->getActiveVersion();
if ($this->rebuildText($parentContent) === $snipContents) {
return;
}
// Create new snipContent entity with previous one as parent
$content = new SnipContent();
$content
->setText($snipContents)
->setSnip($this->snip)
->setSnip($snip)
;
if ($this->snip->getActiveVersion() !== null) {
$content->setParent($this->snip->getActiveVersion());
if ($parentContent !== null) {
$content->setParent($parentContent);
$this->contentToRelative($parentContent);
}
$this->em->persist($content);
$this->em->flush();
$this->snip->setActiveVersion($content);
$this->em->persist($this->snip);
$snip->setActiveVersion($content);
$this->em->persist($snip);
$this->em->flush();
}
// Shortcut to get the active text
public function getActiveText(): string
public function getActiveText(Snip $snip): string
{
$contentRepo = $this->em->getRepository(SnipContent::class);
return $contentRepo->find($this->snip->getActiveVersion())->getText();
return $this->rebuildText($contentRepo->find($snip->getActiveVersion()));
}
public function setVersion(SnipContent $version): void
public function rebuildText(SnipContent $snipContent): string
{
$this->snip->setActiveVersion($version);
$this->em->persist($this->snip);
if ($snipContent->getText()) {
return $snipContent->getText();
}
$parentContent = $snipContent->getParent();
if ($parentContent === null && $snipContent->getDiff() === null) {
return '---Something went very wrong, cant rebuild the text---';
}
return MyersDiff::rebuildBFromCompact(
$this->rebuildText($parentContent), $snipContent->getDiff()
);
}
public function setVersion(Snip $snip, SnipContent $version): void
{
$activeVersion = $snip->getActiveVersion();
$this->contentToAbsolute($version);
$this->contentToRelative($activeVersion);
$snip->setActiveVersion($version);
$this->em->persist($snip);
$this->em->flush();
}
public function delete(): void
public function contentToRelative(SnipContent $content): void
{
if ($content->getText() === null || $content->getParent() === null) {
return;
}
$contentText = $content->getText();
$parentText = $this->rebuildText($content->getParent());
$diff = MyersDiff::calculate($parentText, $contentText);
$content->setDiff($diff);
$content->setText(null);
$this->em->persist($content);
$this->em->flush();
}
public function contentToAbsolute(SnipContent $content): void
{
if ($content->getDiff() === null) {
return;
}
$content->setText($this->rebuildText($content));
$content->setDiff(null);
$this->em->persist($content);
$this->em->flush();
}
public function delete(Snip $snip): void
{
// Cleanup the versions
}