Display meta-fields in datatables (#1116)
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
|
||||
namespace App\Repository\Loader;
|
||||
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\Timesheet;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
@@ -19,10 +21,15 @@ final class TimesheetIdLoader implements LoaderInterface
|
||||
* @var EntityManagerInterface
|
||||
*/
|
||||
private $entityManager;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $fullyHydrated = false;
|
||||
|
||||
public function __construct(EntityManagerInterface $entityManager)
|
||||
public function __construct(EntityManagerInterface $entityManager, bool $hydrateFullTree = false)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
$this->fullyHydrated = $hydrateFullTree;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,23 +44,45 @@ final class TimesheetIdLoader implements LoaderInterface
|
||||
$em = $this->entityManager;
|
||||
|
||||
$qb = $em->createQueryBuilder();
|
||||
$projects = $qb->select('PARTIAL t.{id}', 'project')
|
||||
$timesheets = $qb->select('PARTIAL t.{id}', 'project')
|
||||
->from(Timesheet::class, 't')
|
||||
->leftJoin('t.project', 'project')
|
||||
->andWhere($qb->expr()->in('t.id', $ids))
|
||||
->getQuery()
|
||||
->execute();
|
||||
|
||||
if (!empty($projects)) {
|
||||
$projectIds = array_map(function (Timesheet $timesheet) {
|
||||
return $timesheet->getProject()->getId();
|
||||
$projectIds = array_map(function (Timesheet $timesheet) {
|
||||
return $timesheet->getProject()->getId();
|
||||
}, $timesheets);
|
||||
|
||||
if ($this->fullyHydrated) {
|
||||
$qb = $em->createQueryBuilder();
|
||||
$qb->select('PARTIAL p.{id}', 'meta')
|
||||
->from(Project::class, 'p')
|
||||
->leftJoin('p.meta', 'meta')
|
||||
->andWhere($qb->expr()->in('p.id', $projectIds))
|
||||
->getQuery()
|
||||
->execute();
|
||||
}
|
||||
|
||||
$qb = $em->createQueryBuilder();
|
||||
$projects = $qb->select('PARTIAL p.{id}', 'customer')
|
||||
->from(Project::class, 'p')
|
||||
->leftJoin('p.customer', 'customer')
|
||||
->andWhere($qb->expr()->in('p.id', $projectIds))
|
||||
->getQuery()
|
||||
->execute();
|
||||
|
||||
if ($this->fullyHydrated) {
|
||||
$customerIds = array_map(function (Project $project) {
|
||||
return $project->getCustomer()->getId();
|
||||
}, $projects);
|
||||
|
||||
$qb = $em->createQueryBuilder();
|
||||
$qb->select('PARTIAL p.{id}', 'customer')
|
||||
->from(Project::class, 'p')
|
||||
->leftJoin('p.customer', 'customer')
|
||||
->andWhere($qb->expr()->in('p.id', $projectIds))
|
||||
$qb->select('PARTIAL c.{id}', 'meta')
|
||||
->from(Customer::class, 'c')
|
||||
->leftJoin('c.meta', 'meta')
|
||||
->andWhere($qb->expr()->in('c.id', $customerIds))
|
||||
->getQuery()
|
||||
->execute();
|
||||
}
|
||||
@@ -66,6 +95,20 @@ final class TimesheetIdLoader implements LoaderInterface
|
||||
->getQuery()
|
||||
->execute();
|
||||
|
||||
if ($this->fullyHydrated) {
|
||||
$activityIds = array_map(function (Timesheet $timesheet) {
|
||||
return $timesheet->getActivity()->getId();
|
||||
}, $timesheets);
|
||||
|
||||
$qb = $em->createQueryBuilder();
|
||||
$qb->select('PARTIAL a.{id}', 'meta')
|
||||
->from(Activity::class, 'a')
|
||||
->leftJoin('a.meta', 'meta')
|
||||
->andWhere($qb->expr()->in('a.id', $activityIds))
|
||||
->getQuery()
|
||||
->execute();
|
||||
}
|
||||
|
||||
$qb = $em->createQueryBuilder();
|
||||
$qb->select('PARTIAL t.{id}', 'user')
|
||||
->from(Timesheet::class, 't')
|
||||
|
||||
@@ -19,9 +19,9 @@ final class TimesheetLoader implements LoaderInterface
|
||||
*/
|
||||
private $loader;
|
||||
|
||||
public function __construct(EntityManagerInterface $entityManager)
|
||||
public function __construct(EntityManagerInterface $entityManager, bool $hydrateFullTree = false)
|
||||
{
|
||||
$this->loader = new TimesheetIdLoader($entityManager);
|
||||
$this->loader = new TimesheetIdLoader($entityManager, $hydrateFullTree);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,6 +42,11 @@ class TagRepository extends EntityRepository
|
||||
$entityManager->flush();
|
||||
}
|
||||
|
||||
public function findTagByName(string $tagName): ?Tag
|
||||
{
|
||||
return $this->findOneBy(['name' => $tagName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find ids of the given tagNames separated by comma
|
||||
* @param string $tagNames
|
||||
|
||||
@@ -432,12 +432,7 @@ class TimesheetRepository extends EntityRepository
|
||||
$qb->setParameter('user', $user);
|
||||
}
|
||||
|
||||
$results = $qb->getQuery()->getResult();
|
||||
|
||||
$loader = new TimesheetLoader($qb->getEntityManager());
|
||||
$loader->loadResults($results);
|
||||
|
||||
return $results;
|
||||
return $this->getHydratedResultsByQuery($qb, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -530,16 +525,33 @@ class TimesheetRepository extends EntityRepository
|
||||
}
|
||||
|
||||
/**
|
||||
* When switching $fullyHydrated to true, the call gets even more expensive.
|
||||
* You normally don't need this, unless you want to access deeply nested attributes for many entries!
|
||||
*
|
||||
* @param TimesheetQuery $query
|
||||
* @param bool $fullyHydrated
|
||||
* @return Timesheet[]
|
||||
*/
|
||||
public function getTimesheetsForQuery(TimesheetQuery $query): iterable
|
||||
public function getTimesheetsForQuery(TimesheetQuery $query, bool $fullyHydrated = false): iterable
|
||||
{
|
||||
// this is using the paginator internally, as it will load all joined entities into the working unit
|
||||
// do not "optimize" to use the query directly, as it would results in hundreds of additional lazy queries
|
||||
$paginator = $this->getPaginatorForQuery($query);
|
||||
$qb = $this->getQueryBuilderForQuery($query);
|
||||
|
||||
return $paginator->getAll();
|
||||
return $this->getHydratedResultsByQuery($qb, $fullyHydrated);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param QueryBuilder $qb
|
||||
* @param bool $fullyHydrated
|
||||
* @return Timesheet[]
|
||||
*/
|
||||
protected function getHydratedResultsByQuery(QueryBuilder $qb, bool $fullyHydrated = false): iterable
|
||||
{
|
||||
$results = $qb->getQuery()->getResult();
|
||||
|
||||
$loader = new TimesheetLoader($qb->getEntityManager(), $fullyHydrated);
|
||||
$loader->loadResults($results);
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
private function getQueryBuilderForQuery(TimesheetQuery $query): QueryBuilder
|
||||
@@ -738,12 +750,7 @@ class TimesheetRepository extends EntityRepository
|
||||
->orderBy('t.end', 'DESC')
|
||||
;
|
||||
|
||||
$results = $qb->getQuery()->getResult();
|
||||
|
||||
$loader = new TimesheetLoader($qb->getEntityManager());
|
||||
$loader->loadResults($results);
|
||||
|
||||
return $results;
|
||||
return $this->getHydratedResultsByQuery($qb, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user