如何使用 Doctrine 和 Gedmo Translatable Extension 获取不同翻译的对象
How to get object in different translations with Doctrine and Gedmo Translatable Extension
我遇到了以下问题:我想在不破坏我的 Symfony 应用程序的默认行为的情况下获取特定语言环境的学说实体。
这是我的实体之一的示例:
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @ORM\Entity(repositoryClass="ProductRepository")
* @ORM\Table(name="product")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="discr", type="string")
*/
class Product
{
/**
* @var integer $id
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
* @ORM\Column(name="name", type="string")
* @Gedmo\Translatable
*/
protected $name;
// ...
}
相关学说知识库的一部分:
class ProductRepository extends \Doctrine\ORM\EntityRepository
{
public function findOneProductInLocale($id, $locale)
{
$qb = $this->createQueryBuilder('p')
->select('p')
->where('p.id = :id')
->setMaxResults(1)
->setParameter('id', $id);
;
$query = $qb->getQuery();
$query->setHint(
\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER,
'Gedmo\Translatable\Query\TreeWalker\TranslationWalker'
);
// force Gedmo Translatable to not use current locale
$query->setHint(
\Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE,
$locale
);
$query->setHint(
\Gedmo\Translatable\TranslatableListener::HINT_FALLBACK,
1
);
return $query->getOneOrNullResult();
}
}
以及我的部分脚本:
// default Locale: en
// request Locale: de
$repo = $em->getRepository('Acme\Entity\Product');
$product1 = $repo->findOneById($id);
echo $product1->getName(); // return 'Name (DE)'
$product_de = $repo->findOneProductInLocale($id, 'de');
echo $product_de->getName(); // return 'Name (DE)';
$product_en = $repo->findOneProductInLocale($id, 'en');
echo $product_en->getName(); // return 'Name (EN)'
echo $product1->getName(); // return 'Name (EN)' instead of 'Name (DE)' !! <-- What is wrong?
// even if I refetch a product
$product2 = $repo->findOneById($id);
echo $product2->getName(); // return 'Name (EN)' without taking anymore in account the current locale
现在有人知道为什么这没有按预期工作吗?
我的 ProductRepository::findOneProductInLocale()
实现有问题吗?
欢迎任何帮助或提示。
刷新实体应恢复当前区域设置:
$em->refresh($product1);
问题是,你的$product1
、$product_de
、$product_en
和$product2
都是一样的。如果你var_dump
他们,他们有相同的object #id
。他们指的是同一个Product Entity
。如果你改变其中的任何东西,它就会在所有的人中改变。要使它们与众不同,您必须 clone
它们。
$product_de = clone $repo->findOneProductInLocale($id, 'de');
$product_en = clone $repo->findOneProductInLocale($id, 'en');
我知道我的回答有点晚了,但我遇到了同样的问题并找到了解决方案。我希望它能帮助其他一些开发人员。
你的 findOneProductInLocale
如果完全没问题。
它按照设计工作-当您使用findOneProductInLocale
时,查询将在给定的语言环境中搜索,但是最终实体将始终在当前语言环境中加载,您无法更改它。
一旦通过 findOneProductInLocale
找到 实体 并且 在当前语言环境中加载 ,您可以使用 Gedmo 的 setTranslatableLocale
方法获取您需要的语言环境变体并按照 @umadesign
的解释刷新您的实体
// Reload the entity in different languages.
$entity->setTranslatableLocale($locale);
$em->refresh($entity);
(可选)您可能需要将 setTranslatableLocale
方法和伴随 属性 $local
添加到您的可翻译实体
class Product {
// ...
/**
* @Gedmo\Locale
* Used locale to override Translation listener`s locale
* this is not a mapped field of entity metadata, just a simple property
*/
private $locale;
/**
* Set the locale to use for translation listener
*
* @param string $locale
*
* @return static
*/
public function setTranslatableLocale($locale) {
$this->locale = $locale;
return $this;
}
// ...
}
您可以在 Gedmo documentation under "Basic usage examples" subsection 中找到完整的解释。
我遇到了以下问题:我想在不破坏我的 Symfony 应用程序的默认行为的情况下获取特定语言环境的学说实体。
这是我的实体之一的示例:
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @ORM\Entity(repositoryClass="ProductRepository")
* @ORM\Table(name="product")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="discr", type="string")
*/
class Product
{
/**
* @var integer $id
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
* @ORM\Column(name="name", type="string")
* @Gedmo\Translatable
*/
protected $name;
// ...
}
相关学说知识库的一部分:
class ProductRepository extends \Doctrine\ORM\EntityRepository
{
public function findOneProductInLocale($id, $locale)
{
$qb = $this->createQueryBuilder('p')
->select('p')
->where('p.id = :id')
->setMaxResults(1)
->setParameter('id', $id);
;
$query = $qb->getQuery();
$query->setHint(
\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER,
'Gedmo\Translatable\Query\TreeWalker\TranslationWalker'
);
// force Gedmo Translatable to not use current locale
$query->setHint(
\Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE,
$locale
);
$query->setHint(
\Gedmo\Translatable\TranslatableListener::HINT_FALLBACK,
1
);
return $query->getOneOrNullResult();
}
}
以及我的部分脚本:
// default Locale: en
// request Locale: de
$repo = $em->getRepository('Acme\Entity\Product');
$product1 = $repo->findOneById($id);
echo $product1->getName(); // return 'Name (DE)'
$product_de = $repo->findOneProductInLocale($id, 'de');
echo $product_de->getName(); // return 'Name (DE)';
$product_en = $repo->findOneProductInLocale($id, 'en');
echo $product_en->getName(); // return 'Name (EN)'
echo $product1->getName(); // return 'Name (EN)' instead of 'Name (DE)' !! <-- What is wrong?
// even if I refetch a product
$product2 = $repo->findOneById($id);
echo $product2->getName(); // return 'Name (EN)' without taking anymore in account the current locale
现在有人知道为什么这没有按预期工作吗?
我的 ProductRepository::findOneProductInLocale()
实现有问题吗?
欢迎任何帮助或提示。
刷新实体应恢复当前区域设置:
$em->refresh($product1);
问题是,你的$product1
、$product_de
、$product_en
和$product2
都是一样的。如果你var_dump
他们,他们有相同的object #id
。他们指的是同一个Product Entity
。如果你改变其中的任何东西,它就会在所有的人中改变。要使它们与众不同,您必须 clone
它们。
$product_de = clone $repo->findOneProductInLocale($id, 'de');
$product_en = clone $repo->findOneProductInLocale($id, 'en');
我知道我的回答有点晚了,但我遇到了同样的问题并找到了解决方案。我希望它能帮助其他一些开发人员。
你的
findOneProductInLocale
如果完全没问题。它按照设计工作-当您使用
findOneProductInLocale
时,查询将在给定的语言环境中搜索,但是最终实体将始终在当前语言环境中加载,您无法更改它。一旦通过
的解释刷新您的实体findOneProductInLocale
找到 实体 并且 在当前语言环境中加载 ,您可以使用 Gedmo 的setTranslatableLocale
方法获取您需要的语言环境变体并按照 @umadesign// Reload the entity in different languages. $entity->setTranslatableLocale($locale); $em->refresh($entity);
(可选)您可能需要将
setTranslatableLocale
方法和伴随 属性$local
添加到您的可翻译实体class Product { // ... /** * @Gedmo\Locale * Used locale to override Translation listener`s locale * this is not a mapped field of entity metadata, just a simple property */ private $locale; /** * Set the locale to use for translation listener * * @param string $locale * * @return static */ public function setTranslatableLocale($locale) { $this->locale = $locale; return $this; } // ... }
您可以在 Gedmo documentation under "Basic usage examples" subsection 中找到完整的解释。