Результат Doctrine QueryBuilder: Группировка по объединенному свойству DateTime (Y, m) в Twig - PullRequest
0 голосов
/ 18 апреля 2019

Я создаю программу «событий», сгруппированных и упорядоченных по «годам» (точнее, временам года) и «месяцам» (с сентября по август).

  • Объекты: 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 %}

Я оборачиваюсь, пытаясь отобразить только События, соответствующие их месяцу / году ... Заранее благодарю за любой совет! ...

...