<?php
/**
* Created by simpson <simpsonwork@gmail.com>
* Date: 11.10.2019
* Time: 14:59
*/
namespace AngelGamez\TranslatableBundle\Entity;
use Symfony\Component\Intl\Intl;
use Symfony\Component\Intl\Languages;
/**
* @method TranslatableValue en(string $translation)
* @method TranslatableValue ru(string $translation)
*/
final class TranslatableValue implements \JsonSerializable, \ArrayAccess
{
/**
* @var string[]
*/
protected $translations;
/**
* @var string[]
*/
private static $locales;
/**
* TranslatableValue constructor.
*
* @param string[] $translations
*/
public function __construct(array $translations = [])
{
foreach ($translations as $locale => $translation) {
$this->translations[$locale] = (string) $translation;
}
}
/**
* @param string $locale
* @param string $translation
*
* @return TranslatableValue
*/
public function withTranslation(string $locale, string $translation): self
{
$translations = $this->translations;
$translations[$locale] = $translation;
return new static($translations);
}
/**
* @param string $locale
*
* @return bool
*/
public function hasTranslation(string $locale): bool
{
return \array_key_exists($locale, $this->translations);
}
/**
* @param string $locale
*
* @return string|null
*/
public function getTranslation(string $locale): ?string
{
return $this->translations[$locale] ?? null;
}
/**
* @param TranslatableValue $other
*
* @return bool
*/
public function equals(self $other): bool
{
return $this->translations === $other->translations;
}
/**
* @inheritDoc
*/
public function __call($name, $arguments)
{
if (!$this->isValidLocale($name)) {
throw new \DomainException(sprintf('%s is not a valid locale.', $name));
}
return $this->withTranslation($name, $arguments[0]);
}
/**
* @inheritDoc
*/
public function jsonSerialize()
{
return $this->translations;
}
/**
* @inheritDoc
*/
public function __toString()
{
@trigger_error(sprintf('Casting translatable value to string, %s.', \json_encode($this->translations)), E_USER_WARNING);
if (empty($this->translations)) {
return '';
}
$defaultLocale = 'ru';
$default = $this->getTranslation($defaultLocale) ?? reset($this->translations);
return $default;
}
/**
* @inheritDoc
*/
public function offsetExists($offset)
{
return $this->hasTranslation($offset);
}
/**
* @inheritDoc
*/
public function offsetGet($offset)
{
return $this->getTranslation($offset);
}
/**
* @inheritDoc
*/
public function offsetSet($offset, $value)
{
throw new \LogicException(__METHOD__.' is not implemented.');
}
/**
* @inheritDoc
*/
public function offsetUnset($offset)
{
throw new \LogicException(__METHOD__.' is not implemented.');
}
private function isValidLocale(string $locale): bool
{
if (null === self::$locales) {
self::$locales = Languages::getLanguageCodes();
}
return \in_array($locale, self::$locales, true);
}
}