1

我正在 Symfony 2.0 上开发网站,并被教义翻译卡住了。我一直在谷歌搜索,Stackoverflow,但没有合适的答案。所以首先,我不会遇到我所有的项目只需要的东西。首先,我安装了理论扩展,然后是 Stof。在 WAMMP 上,sluggable 毫无问题地开始工作(但在 Linux 上我不得不复制并且 config_dev.yml 被破坏了)。但我找不到如何制作可翻译作品的决定。于是我在谷歌上找到了http://gediminasm.org/article/translatable-behavior-extension-for-doctrine-2 创建了实体和翻译实体。

代码如下:

<?php

namespace AV\TradeBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\Translatable\Translatable;
use Doctrine\Common\Collections\ArrayCollection;


/**
 * AV\TradeBundle\Entity\Countries
 *
 * @ORM\Table(name="countries")
 * @ORM\Entity
 * @Gedmo\TranslationEntity(class="AV\TradeBundle\Entity\CountryTranslation")
 */
class Countries implements Translatable
{
/**
 * @var integer $id
 *
 * @ORM\Column(name="id", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $id;

/**
 * @var string $country
 * @Gedmo\Translatable
 * @ORM\Column(name="country", type="string", length=255, nullable=false)
 */
private $country;

/**
 * @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;

/**
* @ORM\OneToMany(
* targetEntity="CountryTranslation",
* mappedBy="object",
* cascade={"persist", "remove"}
* )
*/
private $translations;


public function __construct()
{
    $this->translations = new ArrayCollection();
}
/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}

/**
 * Set country
 *
 * @param string $country
 */
public function setCountry($country)
{
    $this->country = $country;
}

/**
 * Get country
 *
 * @return string 
 */
public function getCountry()
{
    return $this->country;
}

public function setTranslatableLocale($locale)
{
    $this->locale = $locale;
}

public function getTranslations()
{
    return $this->translations;
}

public function addTranslation(CountryTranslation $t)
{
    if (!$this->translations->contains($t)) {
        $this->translations[] = $t;
        $t->setObject($this);
    }
}

public function __toString() {
    return $this->getCountry();
}

}

在这里继续到那个博客上提到的这样的翻译实体

<?php
namespace AV\TradeBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Translatable\Entity\MappedSuperclass\AbstractPersonalTranslation;

/**
* @ORM\Entity
* @ORM\Table(name="country_translations",
* uniqueConstraints={@ORM\UniqueConstraint(name="lookup_unique_idx", columns={
* "locale", "object_id", "field"
* })}
* )
*/
class CountryTranslation extends AbstractPersonalTranslation
{
/**
* Convinient constructor
*
* @param string $locale
* @param string $field
* @param string $value
*/
public function __construct($locale, $field, $value)
{
    $this->setLocale($locale);
    $this->setField($field);
    $this->setContent($value);
}

/**
* @ORM\ManyToOne(targetEntity="Countries", inversedBy="translations")
* @ORM\JoinColumn(name="object_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $object;
}

?>

最后但不是最后一个 $em = $this->getDoctrine()->getEntityManager();

    $query = $em->createQuery(
            " SELECT c FROM AVTradeBundle:Companies c " .
            " ORDER BY c.title ASC "
            )->setHint(
\Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE,'en');

我只看到项目的默认语言没有翻译(在国家/地区左加入公司)。也许我应该将 Symfony 的版本升级到 2.1,但是我的 2.0 冻结了很多包。

请看我的问题。在 symfony 的论坛上根本没有答案。

顺便说一句,我没有注册任何内核侦听器,因为我使用了 Stof。谢谢,事先,亚历克斯

4

1 回答 1

2

您误解了在学说扩展包中使用 Translatable。您应用于查询的提示是当您希望所有字段的翻译自动加入时(因此您不必进行左连接),因此您可以使用排序过滤或任何您想要的翻译字段而不是原始记录字段。请参阅可翻译文档的“使用 ORM 查询提示”部分。因此,通过将提示应用于查询,在您的情况下,它所做的只是您的国家/地区将在您的结果中自动翻译。此外,您提供\Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE,'en'作为提示,这意味着您的结果将始终翻译成英文。我真的怀疑这是你正在寻找的行为。利用

$query->setHint(
    \Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER,
    'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker'
);

如果您希望在用户的语言环境中翻译结果。您只需要在\Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE使用 apc 或 memcache 时使用,因为查询将使用第一次使用的语言环境进行缓存。然后,您需要将此提示与当前用户区域设置一起使用,而不是始终使用“en”。同样,这一切都在文档中。

所以如果你想要你的翻译,你需要自己去获取它们。如果您不关心您所在国家/地区的名称被自动翻译,则不要应用提示并对您所在国家/地区的翻译执行 LEFT JOIN(在这里我看到您正在查询公司表,因此您必须 LEFT JOIN the country第一的)。这些将通过$country->getTranslations(). 如果应用提示,则 LEFT JOIN 是隐式的,但名称将被翻译。

于 2012-09-26T11:03:08.703 回答