anker/src/Entity/UnicodeNote.php

100 lines
2.6 KiB
PHP

<?php
namespace App\Entity;
use App\Utils\Number;
class UnicodeNote extends Note
{
const string MODEL_NAME = 'Unicode';
const string DECK = 'unicode';
private ?int $codepoint = null;
public static function fromCharacter(string $character): self
{
$note = new UnicodeNote()->setCharacter($character);
$note->model = self::MODEL_NAME;
return $note;
}
// ------------------------------------------------------- Anki-related ---
public static function fromAnki(array $noteInfo): static
{
$note = parent::fromAnki($noteInfo);
$note->setCharacter($note->fields['Character']);
return $note;
}
/** @return array<mixed> */
public function toAnki(): array
{
return array_merge(parent::toAnki(), [
'fields' => [
'Character' => $this->getCharacter(),
'Codepoint' => $this->getHex(),
],
]);
}
// ---------------------------------------------------- Derived methods ---
/** @throws \RuntimeException */
public function setCharacter(string $character): static
{
if (mb_strlen($character) !== 1) throw new \InvalidArgumentException(sprintf(
<<<FMT
Character should be only one multi-byte character long.
Passed '%s' which has a length of %d.
FMT,
$character,
mb_strlen($character),
));
$codepoint = mb_ord($character, 'UTF-8')
?: throw new \RuntimeException(sprintf(
'Tried to assign invalid unicode character "%s".',
$character,
));
return $this->setCodepoint($codepoint);
}
public function getCharacter(): string
{
return mb_chr($this->codepoint, 'UTF-8')
?: throw new \RuntimeException(sprintf(
'Codepoint "%s" is not valid',
$this->getHex(),
));
}
public function getHex(): string
{
return dechex($this->codepoint);
}
public function setHex(string $hex): static
{
return $this->setCodepoint(Number::hexint($hex));
}
public function setCodepoint(int $codepoint): static
{
if (!mb_chr($codepoint, 'UTF-8')) throw new \InvalidArgumentException(sprintf(
'Codepoint "%s" is not valid',
$this->getHex(),
));
$this->codepoint = $codepoint;
$this->fields['Character'] = $this->getCharacter();
$this->fields['Codepoint'] = $this->getHex();
return $this;
}
}