在从数据库(by findAll()
)获取实体之后以及将结果序列化为json
.
我想在某些领域添加翻译。我知道我可以通过迭代每个实体并在控制器中应用我的逻辑来手动完成。但我需要一个更好的方法来做到这一点。
有没有建议让这个自动化?
在从数据库(by findAll()
)获取实体之后以及将结果序列化为json
.
我想在某些领域添加翻译。我知道我可以通过迭代每个实体并在控制器中应用我的逻辑来手动完成。但我需要一个更好的方法来做到这一点。
有没有建议让这个自动化?
我遇到了类似的问题,并尝试使用自定义处理程序解决此问题,但没有成功,因此我创建了编译器传递并覆盖 JsonSerializationVisitor,其中字符串值使用 TranslatableJsonSerializationVisitor 类进行序列化:
namespace tkuska\DemoBundle\Serialization;
use JMS\Serializer\JsonSerializationVisitor;
use JMS\Serializer\Context;
class TranslatableJsonSerializationVisitor extends JsonSerializationVisitor
{
/**
* @var \Symfony\Component\Translation\Translator;
*/
private $translator;
public function visitString($data, array $type, Context $context)
{
if (in_array('translatable', $type['params'])) {
return (string) $this->translator->trans($data);
}
return (string) $data;
}
public function setTranslator(\Symfony\Component\Translation\Translator $translator)
{
$this->translator = $translator;
}
}
和编译器:
namespace tkuska\DemoBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
class TranslatableJsonSerializationCompiler implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$jmsJsonSerializationVisitor = $container->getDefinition('jms_serializer.json_serialization_visitor');
$jmsJsonSerializationVisitor->setClass('tkuska\DemoBundle\Serialization\TranslatableJsonSerializationVisitor');
$jmsJsonSerializationVisitor->addMethodCall('setTranslator', array(new Reference('translator')));
}
}
在实体中,我使用参数“可翻译”为“字符串”类型设置注释
/**
* @VirtualProperty
* @Groups({"details"})
* @Type("string<'translatable'>")
* @return order status
*/
public function getOrderStatus(){
return 'status.ordered';
}
当然 'status.ordered' 是我的翻译键。
谢谢@zizoujab。很有用的帖子。我对其进行了小的改进,以调用父方法并取消设置我的参数,这样我就可以使用这种方式来更改更复杂类型(如数组)的数据,这些类型已经具有参数并已使用
/**
* @VirtualProperty
* @Groups({"details"})
* @Type("string<translatable>")
* @return order status
*/
代替
/**
* @VirtualProperty
* @Groups({"details"})
* @Type("string<'translatable'>")
* @return order status
*/
将字符串“可翻译”转换为参数名称而不是参数值,因此您可以像这样传递更复杂的参数,并允许我在调用父方法之前取消设置此参数。
/**
* @VirtualProperty
* @Groups({"details"})
* @Type("string<translatable<set of parameters>>")
* @return order status
*/
代码:
<?php
namespace Mktp\DefaultBundle\Service\JmsSerializer;
use JMS\Serializer\Context;
use JMS\Serializer\JsonSerializationVisitor;
use Symfony\Component\Translation\Translator;
class TranslatableJsonSerializationVisitor extends JsonSerializationVisitor
{
/**
* @var Translator;
*/
private $translator;
/**
* @param string $data
* @param array $type
* @param Context $context
* @return string
*/
public function visitString($data, array $type, Context $context)
{
$translatable = $this->getParameters('translatable', $type['params']);
if (count($translatable)) {
$data = (string)$this->translator->trans($data);
}
return parent::visitString($data, $type, $context);
}
/**
* @param array $data
* @param array $type
* @param Context $context
* @return array|\ArrayObject|mixed
*/
public function visitArray($data, array $type, Context $context)
{
$translatable = $this->getParameters('translatable', $type['params']);
if (count($translatable)) {
foreach ($data as $key => $value) {
if (is_string($value)) {
$data[$key] = (string)$this->translator->trans($value);
}
}
}
return parent::visitArray($data, $type, $context);
}
/**
* @param Translator $translator
*/
public function setTranslator(Translator $translator)
{
$this->translator = $translator;
}
/**
* @param string $type
* @param array $parameters
* @param bool $unsetParameters
* @return array
*/
protected function getParameters($type, &$parameters, $unsetParameters = true)
{
$result = array();
foreach ($parameters as $key => $parameter) {
if ($parameter['name'] == $type) {
$result[] = $parameter;
if ($unsetParameters) {
unset($parameters[$key]);
}
}
}
$parameters = array_values($parameters);
return $result;
}
}