我试图在我的API平台项目中的某个实体上添加KnpLabs Doctrine Behaviors - 正是Translatable Behavior - 。
这是我到目前为止所做的事情:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use ApiPlatform\Core\Annotation\ApiResource;
/**
* @ORM\Entity(repositoryClass="App\Repository\ArticleRepository")
* @ApiResource
*/
class Article
{
use ORMBehaviors\Translatable\Translation,
ORMBehaviors\Timestampable\Timestampable
;
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
protected $id;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
}
这是实体翻译:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Traits as CustomTraits;
/**
* @ORM\Entity(repositoryClass="App\Repository\ArticleTranslationRepository")
* @ApiResource
*/
class ArticleTranslation
{
use ORMBehaviors\Translatable\Translatable;
/**
* @var string
*
* @ORM\Column(name="someFieldToTranslate", type="string", length=255, nullable=true)
*/
private $someFieldToTranslate;
public function getSomeFieldToTranslate(){...}
public function setSomeFieldToTranslate($someFieldToTranslate){...}
}
这是基本的"配置"根据文档获得可翻译行为。
当我尝试更新数据库架构时会出现问题:我收到此错误:
没有为实体" App \ Entity \ ArticleTranslation"指定标识符/主键。每个实体必须有一个标识符/主键。 (正在从" /Sites/bookshop-api/config/routes/api_platform.yaml"中导入)。确保有一个 装载机支持" api_platform"类型。
然而,在Translatable Traits中,已经有一个ID和文档准确,翻译实体应该只有我们想要翻译的字段......
无论如何,我已经为这个ArtcleTranslation实体提供了一个ID来摆脱错误:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Traits as CustomTraits;
/**
* @ORM\Entity(repositoryClass="App\Repository\ArticleTranslationRepository")
* @ApiResource
*/
class ArticleTranslation
{
use ORMBehaviors\Translatable\Translatable;
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="content", type="string", length=255, nullable=true)
*/
private $content;
public function getContent(){...}
public function setContent($someContent){...}
}
从此处更新数据库架构时没有错误。完美! 现在我可以看一下Swagger文档:
一切都很好看!但是当我看看数据库时:
在文章表中:
在ArticleTranslation表中:
我想它必须链接,但在招摇的POST标签中,模型也是不同的。
我只在两个实体上尝试了/ GET和/ POST方法,它们正在工作(我可以在数据库中看到它),但两者之间没有关系。
我希望我的帖子不会太长,但我试着更具体!
提前致谢
答案 0 :(得分:1)
我做了另一个回答,因为第一个问题是解决一个错误,而不是解释我如何将Knp Labs教义翻译与Api平台集成。
摘要:
我们有一个实体Article
,该实体在ArticleTranslation
内翻译了一些字段。我们想通过Api platform
检索其翻译的实体,并希望通过api添加或更新翻译。
我做了什么:
1- Article
实体有一个use ORMBehaviors\Translatable\Translatable
。如果我们查看此trait
的内部,则它具有2个属性:$translations
和$newTranslations
。我们需要在Article
实体中公开这些属性:
class Article {
use ORMBehaviors\Translatable\Translatable;
protected $translations;
protected $newTranslations;
}
现在,我们有了一个新属性translations
,当我们从ArticleTranslation
获取Article
时,这些属性会自动从api
填充
2-现在,我们想添加/编辑一些翻译:在发送到api时,我们需要在newTranslations
内填充Article
属性:>
"newTranslations": {
"en": {
"description": "Firstname"
},
"fr": {
"description": "Prénom"
}
}
现在,我们正在接收到api的新翻译,但由于需要调用函数mergeNewTranslations()
,因此尚未持久化。此函数仅将属性$newTranslations
内的所有翻译内容并与$translations
属性合并,以使其持久。
3-我创建了一个名为trait
的新TranslatableOverride
。我直接将其导入到ORMBehaviors\Translatable\Translation
旁边的我的实体上:
trait TranslatableOverride
{
/**
* Set collection of new translations.
*
* @return ArrayCollection
*/
public function setNewTranslations($newTranslations)
{
if ($newTranslations) {
foreach ($newTranslations as $locale => $translations) {
foreach ($translations as $key => $value) {
$tr = $this->translate($locale);
$setter = 'set' . ucfirst($key);
if (method_exists($tr, $setter)) {
$tr->{$setter}($value);
}
}
}
$this->mergeNewTranslations();
}
}
}
我不确定它是否漂亮,但是它与api-platform
一样具有魅力。
我不打算一次只翻译一份。目前,我使用全部翻译检索我的实体,这肯定不是很有效。我会在我的覆盖getTranslations
中为trait
添加覆盖。
答案 1 :(得分:0)
我认为您做错了。您有一个实体Article
,该实体应该是translatable
,并且您想要转换某些字段,这些字段将是translations
?
因此您应该相反,将use ORMBehaviors\Translatable\Translatable
放在Article
上,将use ORMBehaviors\Translatable\Translation
放在ArticleTranslation
上
您的Article
实体的修复方法:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use ApiPlatform\Core\Annotation\ApiResource;
/**
* @ORM\Entity(repositoryClass="App\Repository\ArticleRepository")
* @ApiResource
*/
class Article
{
use ORMBehaviors\Translatable\Translatable,
ORMBehaviors\Timestampable\Timestampable
;
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
protected $id;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
}
以及您的ArticleTranslation
实体的修补程序:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Traits as CustomTraits;
/**
* @ORM\Entity(repositoryClass="App\Repository\ArticleTranslationRepository")
* @ApiResource
*/
class ArticleTranslation
{
use ORMBehaviors\Translatable\Translation;
/**
* @var string
*
* @ORM\Column(name="someFieldToTranslate", type="string", length=255, nullable=true)
*/
private $someFieldToTranslate;
public function getSomeFieldToTranslate(){...}
public function setSomeFieldToTranslate($someFieldToTranslate){...}
}
让我知道现在一切都还好吗。