Я создаю программу «событий», сгруппированных и упорядоченных по «годам» (точнее, временам года) и «месяцам» (с сентября по август).
- Объекты: Event + EventDate (для лет и месяцев)
- Отношение: многие-к-одному (двунаправленное)
- Запрос через QueryBuilder вEventRepository ('Присоединиться' к EventDates: addSelect 'year' и 'month' с помощью SUBSTRING (). Затем orderBy -> year and month)
С groupBy (year, month),Я получаю только несколько событий ... Без groupBy я получаю все события с их EventDate.Но все события повторяются в каждом месяце каждого года!
Мой код ниже ...
EventRepository:
public function getEventsWithSeasons()
{
$qb = $this->createQueryBuilder('e')
->addSelect('e.name')
->addSelect('e.city')
->innerJoin('e.eventDate', 'ed') // "Join" = "innerJoin"
->addSelect('SUBSTRING(ed.seasonMonth, 1, 4) AS year')
->addSelect('SUBSTRING(ed.seasonMonth, 6, 2) AS month')
// ->groupBy('year')
// ->addGroupBy('month')
->orderBy('year', 'DESC')
->addOrderBy('month', 'ASC')
;
return $qb->getQuery()->getResult();
}
Отношение вСущность события:
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\EventDate", inversedBy="e")
* @ORM\JoinColumn(nullable=false)
* @var
*/
private $eventDate;
Субъект EvenDate:
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var \DateTime
*
* @ORM\Column(name="season_month", type="date")
*/
private $seasonMonth;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Event", mappedBy="eventDate")
*
* @var
*/
private $events;
// (getters and setters...)
// Added "->format()" for returning a string,
// not an Object \DateTime
/**
* Get seasonMonth.
*
* @return string
*/
public function getSeasonMonth()
{
return $this->seasonMonth->format('m Y');
}
// Added 2 methods for easily get Year and Month
/**
* Get season.
*
* @return string
*/
public function getSeason()
{
return $this->seasonMonth->format('Y');
}
/**
* Get month.
*
* @return string
*/
public function getMonth()
{
return $this->seasonMonth->format('m');
}
Контроллер:
public function agendaAction()
{
$em = $this->getDoctrine()->getManager();
$season = $em->getRepository('AppBundle:Event')
->getEventsWithSeasons();
return $this->render('agenda.html.twig', array(
'season' => $season,
));
Вид ветки (часть):
{# Loop for grouping items by year ('set array' for not repeating same years) #}
{% set newArray = [] %}
{% for itemY in season %}
<h2 class="accordion-toggle">
{% if itemY.year not in newArray %}
<strong>Season {{ (itemY.year - 1) ~ " - " ~ itemY.year }}</strong></h2>
{% set newArray = newArray|merge([itemY.year]) %}
{% endif %}
{# Todo: Ordering months in this way: y-1(months n° 09 to 12) + y(months n° 01 to 08).
(Ex.: if the event is taking place in Sept 2019, it should be attributed the year 2020,
because it will be displayed in the season 2019-2020 #}
<div class="accordion-content default">
<div class="row fondAgenda">
{# (In each year) loop for grouping item by month ('set array' for not repeating them).
'groupBy' via the QueryBuilder is not working well with Join/addSelect.
The month numbers will be replaced by their real name (other than English) #}
{% set newArrayM = [] %}
{% for itemM in season %}
<div class="col-xs-12">
{% if itemM.month not in newArrayM %}
<h1 class="agendaMois">{{ itemM.month|upper }}</h1>
{% set newArrayM = newArrayM|merge([itemM.month]) %}
{% endif %}
</div>
<div class="col-xs-12 col-sm-6">
{# Loop for displaying Events of each month of the season (ideally m09(y-1) to m08(y) #}
{% for itemE in season %}
<p><strong>{{ itemE.name|upper ~ " > " ~ itemE.city|upper }}</strong><br>
{# Place name, etc. <br> #}
{# Event dates (string ?)</p> #}
{% endfor %}
</div>
{% endfor %}
</div>
</div>
{% endfor %}
Я оборачиваюсь, пытаясь отобразить только События, соответствующие их месяцу / году ... Заранее благодарю за любой совет! ...