我正在尝试设置一个加权标签云,当标签是博客实体中的字符串属性时,它可以工作。
现在我已将标签设置为它自己的实体,并作为双向 ManyToMany/ManyToMany 关系与博客相关。
不用说它不起作用,我猜这是因为标签现在是它自己的对象。
我的问题:现在标签是它自己的实体而不是来自博客实体的字符串属性,我在这里做错了什么?
当我从下面的控制器转储 $tagWeights 时,当我应该看到类似这样的内容时,我收到错误:
array (size=78)
'Tag1' => float 1
'Tag2' => float 5
'Tag3' => float 2
错误:(这一行:
foreach ($tags as $tag) {
$tagWeights[$tag] = (isset($tagWeights[$tag])) ? $tagWeights[$tag] + 1 : 1;
}
ContextErrorException:警告:isset 中存在非法偏移类型或 /var/www/html/Satori/src/Symfony/AcmeBundle/Entity/TagRepository.php 第 34 行中为空
我在twig中按以下方式调用标签:
树枝
{% for tag, weight in tags %}
<span class="weight-{{ weight }}"><a href="">{{ tag }}</a></span>
{% else %}
<p>There are no tags</p>
{% endfor %}
控制器(转储 $tags 效果很好,可以显示所有标签)
public function footerAction()
{
$em = $this->getDoctrine()->getManager();
$tags = $em->getRepository('AcmeBundle:Tag')
->getTags();
$tagWeights = $em->getRepository('AcmeBundle:Tag')
->getTagWeights($tags);
var_dump($tagWeights); die();
return array(
'tags' => $tagWeights,
);
}
这是 getTags 和 getTagWeights:
public function getTags()
{
$tags = $this->createQueryBuilder('t')
->select('t.tag')
->getQuery()
->getResult();
return $tags;
}
public function getTagWeights($tags)
{
$tagWeights = array();
if (empty($tags))
return $tagWeights;
foreach ($tags as $tag)
{
$tagWeights[$tag] = (isset($tagWeights[$tag['tag']])) ? $tagWeights[$tag] + 1 : 1;
}
// Shuffle the tags
uksort($tagWeights, function() {
return rand() > rand();
});
$max = max($tagWeights);
// Max of 5 weights
$multiplier = ($max > 5) ? 5 / $max : 1;
foreach ($tagWeights as &$tag)
{
$tag = ceil($tag * $multiplier);
}
return $tagWeights;
}
标签实体
class Tag
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="tag", type="string", length=255)
*/
private $tag;
/**
* @ORM\ManyToMany(targetEntity="Blog", mappedBy="tags")
*/
protected $blogs;
public function __construct()
{
$this->blogs = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set tag
*
* @param string $tag
* @return Tag
*/
public function setTag($tag)
{
$this->tag = $tag;
return $this;
}
/**
* Get tag
*
* @return string
*/
public function getTag()
{
return $this->tag;
}
/**
* Add blogs
*
* @param \AcmeBundle\Entity\Blog $blogs
* @return Tag
*/
public function addBlog(\AcmeBundle\Entity\Blog $blogs)
{
$this->blogs[] = $blogs;
return $this;
}
/**
* Remove blogs
*
* @param \AcmeBundle\Entity\Blog $blogs
*/
public function removeBlog(\AcmeBundle\Entity\Blog $blogs)
{
$this->blogs->removeElement($blogs);
}
/**
* Get blogs
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getBlogs()
{
return $this->blogs;
}
}
建议的解决方案和结果
使用
(isset($tagWeights[$tag['tag']]))
错误:
ContextErrorException:警告:/var/www/html/Satori/src/Symfony/AcmeBundle/Entity/TagRepository.php 第 34 行中存在非法偏移类型
使用
(isset($tagWeights[$tag[$tag->getTag()]))
错误:
ContextErrorException:注意:尝试获取 /var/www/html/Satori/src/Symfony/AcmeBundle/Entity/TagRepository.php 第 34 行中非对象的属性
我想我知道这里发生了什么......
当您在
footerAction
中拨打此电话时:
$tags = $em->getRepository('AcmeBundle:Tag')
->getTags();
您的存储库返回给您一个数组数组。所以当你说:
isset($tagWeights[$tag])
...那个
$tag
实际上是结果集的关联数组。我想你在这里想说的是:
isset($tagWeights[$tag['tag']])
也就是说,我建议不要为您的
Tag
实体提供名为 tag
的属性。标签没有标签,它有名称或描述。在这里说更有意义
isset($tagWeights[$tag['name']])
...或者让存储库返回
Tag
实体本身(为什么您甚至需要重写内置 getXyz()
方法?),然后执行:
isset($tagWeights[$tag->getName()])