KillDash9
KillDash9

Reputation: 909

How can I access to a Count of relation elements of an Entity Object in Twig (Symfony 4)

I have a specific object that I pass to twig for a loop.

categories -> post -> comments

I pass the "categories" object from the controller to the loop.

I can see using dump() that the entire relation tree is in there, and I need to get the amount of comments for each category in twig.

Is it possible to have something like

categories->getTotalCommentCount()

Is it possible to have that getter inside the Categories entity?

Thanks a lot in advance.

Upvotes: 1

Views: 812

Answers (2)

Darragh Enright
Darragh Enright

Reputation: 14136

As you suggested in your question you could indeed add a getTotalComments() method to your top-level Category object.

I am making some assumptions about your code here but one example implementation might iterate/map/reduce over the collection of child Post objects and count their child Comment objects to sum a total; e.g:

<?php

class Categories
{
    public function getTotalCommentCount()
    {        
        return array_reduce($this->posts->toArray(), function ($total, Post $post) {
            return $total + $post->comments->count();
        }, 0);
    }
}

Or you may prefer a loop:

public function getTotalCommentCount()
{        
    $commentCount = 0;

    foreach ($this->posts as $post) {
        $commentCount += $post->count();
    }

    return $commentCount;
}

I am assuming you are using Doctrine - which means that the association will be an ArrayCollection or PersistentCollection. Either way, both implement PHP's Countable interface, which allow them to be used with PHP built-in function count() (and its alias sizeof(). This also means that there is a count() method defined on this object.

This may be computationally expensive so you might decide to do one of several things, including storing the value after computing it:

<?php

class Categories
{
    private $commentCount = null;

    public function getTotalCommentCount()
    {        
        if (!$this->commentCount) {
            $this->commentCount = 0;
            foreach ($this->posts as $post) {
                $this->commentCount += $post->count();
            }
        }

        return $this->commentCount;
    }
}

Or you could use Doctrine to create a persistent $commentCount property and use Doctrine's PrePersist and PreUpdate lifecycle hooks to compute the value when the record is being persisted to the database.

Something like this:

<?php

/**
 * @ORM\HasLifecycleEvents()
 */
class Categories
{
    /**
     * @ORM\Column(name="comment_count", type="integer")
     */
    private $commentCount;

    public function getTotalCommentCount()
    {        
        return $this->commentCount;
    }

    /**
     * @ORM\PrePersist()
     * @ORM\PreUpdate()
     */
    public function calculateCommentCount()
    {
        // this method runs every time 
        // this object is persisted/flushed 
        // to the database

        $this->commentCount = 0;
        foreach ($this->posts as $post) {
            $this->commentCount += $post->count();
        }
    }
}

More information on that here:

https://symfony.com/doc/current/doctrine/lifecycle_callbacks.html

Hope this helps :)

Upvotes: 4

amin saffar
amin saffar

Reputation: 2041

If you create relation between categories and comment class, use something like this

sizeof($category1->post->comments)

Upvotes: 1

Related Questions