Php 动态反边法
我有两个带标签的实体。我创建了一个基于以下内容的动态关系: 我可以使用Php 动态反边法,php,symfony,doctrine-orm,doctrine,Php,Symfony,Doctrine Orm,Doctrine,我有两个带标签的实体。我创建了一个基于以下内容的动态关系: 我可以使用$category->getTags()或$product->getTags()获取所有标签。这很有效。这是一篇旧的博文,但显然没有过时 但是,由于没有Tag::getProducts()方法,因此没有简单的方法可以获取与标记相关的所有产品 理想情况下,我需要一个标记::getRelatedEntities(),它返回TaggableEntityInterface[],因此集合既包含产品也包含类别实体 在我的模板中,我想到了如
$category->getTags()
或$product->getTags()
获取所有标签。这很有效。这是一篇旧的博文,但显然没有过时
但是,由于没有Tag::getProducts()
方法,因此没有简单的方法可以获取与标记相关的所有产品
理想情况下,我需要一个标记::getRelatedEntities()
,它返回TaggableEntityInterface[]
,因此集合既包含产品
也包含类别
实体
在我的模板中,我想到了如下内容:
<h1>Related entities:</h1>
<ul>
{% for relatedEntity in tag.getRelatedEntities %}
<li>{{ relatedEntity }}</li> //..implementing `__toString()`
{% endfor %}
</ul>
相关实体:
{tag.getRelatedEntities%中的relatedEntity为%1}
- {{relatedEntity}
/…实现`\u toString()`
{%endfor%}
获取标记::getRelatedEntities()和/或标记::getProducts()方法的最佳方法是什么
当然,我可以在标记实体上手动创建一个getProducts
方法,但这打破了动态关系的概念。在本例中,我只得到一个产品和类别实体,但实际上我有许多可标记的实体。在条令中,您无法创建指向多个不同实体的单一关系。换句话说,如果标记
将具有关联实体
,则它必须是同一类的对象数组或至少是映射的超类
您可以做的是编写一个服务,它将迭代所有条令管理的类,检查它是否实现了给定的接口,通过标记搜索这些实体,并将它们全部合并到一个数组中
示例代码:
$entities = [];
foreach ($entityManager->getMetadataFactory()->getAllMetadata() as $classMetadata) {
if (in_array(TaggableEntityInterface::class, class_implements($classMetadata->getName()))) {
$repository = $entityManager->getRepository($classMetadata->getName());
$entities = array_merge($entities, $repository->findBy(['tag' => $tag]));
}
}
如果您想从模板轻松访问此功能,还可以将其包装到细枝函数中
代码没有经过真正的测试,因此可能需要根据您的用例进行一些更正或改进。我在“where子句”中有一个未知列“Product\u Tags.tag\u id”
错误消息。有什么想法吗?您是否运行了迁移(或模式:更新)?因为看起来Doctrine知道使用哪个列,所以它不在数据库中。
$entities = [];
foreach ($entityManager->getMetadataFactory()->getAllMetadata() as $classMetadata) {
if (in_array(TaggableEntityInterface::class, class_implements($classMetadata->getName()))) {
$repository = $entityManager->getRepository($classMetadata->getName());
$entities = array_merge($entities, $repository->findBy(['tag' => $tag]));
}
}