phparrayssymfonytagstag-cloud

Symfony2 - Accessing tag array which has values is giving an error


I am trying to use a getTags() array which is an array of arrays into another method GetTagWeights($tags) but am getting an error when using it with this line:

$tagWeights[$tag] = (isset($tagWeights[$tag['tag']])) ? $tagWeights[$tag['tag']] + 1 : 1;

I get the following error:

ContextErrorException: Warning: Illegal offset type in /var/www/html/Satori/src/Symfony/AcmeBundle/Entity/TagRepository.php line 34

Question: What am I doing wrong here, I've dumped getTags() and there is data?

My process is getting tags then weighting the tags for popularity. Tag is setup as a ManyToMany/ManyToMany entity with a Blog entity.

getTags and getTagWeight methods (dumping $tags from getTags() returns an array of arrays)

array (size=6)
  0 => 
array (size=1)
  'tag' => string 'Tag 1' (length=5)
  1 => 
array (size=1)
  'tag' => string 'Tag 2' (length=5)
  2 => 
array (size=1)
  'tag' => string 'Tag 3' (length=5)


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['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;
}

Controller

$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,
);

Tag entity

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;
}
}

This is how I am accessing tags in twig:

{% for tag, weight in tags %}
    <span class="weight-{{ weight }}"><a href="{{ path('AcmeBundle_tag', { 'tag': tag.tag }) }}">{{ tag.tag }}</a></span>
{% else %}
    <p>There are no tags</p>
{% endfor %}

Solution

  • From the documentation:

    Arrays and objects can not be used as keys. Doing so will result in a warning: Illegal offset type.

    You are trying to use $tag as key here:

    $tagWeights[$tag] = (isset($tagWeights[$tag['tag']])) ? $tagWeights[$tag['tag']] + 1 : 1;
    

    but because $tag is an array, you get an error.

    I guess you wanted to do this:

    $tagWeights[$tag['tag']] = (isset($tagWeights[$tag['tag']])) ? $tagWeights[$tag['tag']] + 1 : 1;