<?php

namespace AppBundle\Repository;

use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;

/**
 * ContentRepository
 */
class ContentRepository extends EntityRepository
{
    /**
     * Get the Content elements related to a menu.
     * Also retrieve the menu, and optionnaly all the children menus
     *
     * @param int $menuId Menu identifier
     * @param bool $withChildren Retrieve the children too
     * @param array $filters Content filtering
     * @param int $hydrationMode Doctrine hydratation mode
     *
     * @return array
     */
    public function findWithMenu(int $menuId, bool $withChildren = false, array $filters = [], $hydrationMode = Query::HYDRATE_OBJECT): array
    {
        $qbC = $this->getEntityManager()->createQueryBuilder();

        $qbC->select('content, menu')
            ->from('AppBundle:Content', 'content')
            ->leftJoin('content.menu', 'menu')
            ->where('content.is_main = :content_is_main')
            ->andWhere('menu.id = :menu_id')
            ->orderBy('content.position', 'ASC')
            ->addOrderBy('content.id', 'ASC')
            ->addOrderBy('menu.position', 'ASC')
            ->addOrderBy('menu.id', 'ASC')
            ->setParameter('menu_id', $menuId)
        ;

        if ($filters) {
            foreach ($filters as $name => $value) {
                $qbC
                    ->andWhere('content.' . $name . ' = :content_' . $name)
                    ->setParameter('content_' . $name, $value)
                ;
            }
        }

        if ($withChildren) {
            $qbC
                ->addSelect('children')
                ->leftJoin('menu.children', 'children', 'with', 'children.parent = :menu_parent')
                ->setParameter('menu_parent', $menuId)
            ;
        }

        return $qbC->getQuery()->getResult($hydrationMode);
    }
}
