100 lines
2.6 KiB
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;
|
|
}
|
|
}
|