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 :)
Categories
object and persist that to the db. YMMV – Darragh Enright