elementTypeNameGenerator = $elementTypeNameGenerator; $this->translator = $translator; } public function configure(DataTable $dataTable, array $options) { $dataTable->add('id', TextColumn::class, [ 'label' => $this->translator->trans('log.id'), 'visible' => false, ]); $dataTable->add('timestamp', LocaleDateTimeColumn::class, [ 'label' => $this->translator->trans('log.timestamp'), 'timeFormat' => 'medium' ]); $dataTable->add('type', TextColumn::class, [ 'label' => $this->translator->trans('log.type'), 'propertyPath' => 'type', 'render' => function (string $value, AbstractLogEntry $context) { return $this->translator->trans('log.type.' . $value); } ]); $dataTable->add('level', TextColumn::class, [ 'label' => $this->translator->trans('log.level'), 'propertyPath' => 'levelString', 'render' => function (string $value, AbstractLogEntry $context) { return $value; } ]); $dataTable->add('user', TextColumn::class, [ 'label' => $this->translator->trans('log.user'), 'propertyPath' => 'user.name', ]); $dataTable->add('target_type', TextColumn::class, [ 'label' => $this->translator->trans('log.target_type'), 'visible' => false, 'render' => function ($value, AbstractLogEntry $context) { $class = $context->getTargetClass(); if ($class !== null) { return $this->elementTypeNameGenerator->getLocalizedTypeLabel($class); } return ''; } ]); $dataTable->add('target', LogEntryTargetColumn::class, [ 'label' => $this->translator->trans('log.target') ]); $dataTable->addOrderBy('timestamp', DataTable::SORT_DESCENDING); $dataTable->createAdapter(ORMAdapter::class, [ 'entity' => AbstractLogEntry::class, 'query' => function (QueryBuilder $builder): void { $this->getQuery($builder); }, ]); } protected function getQuery(QueryBuilder $builder): void { $builder->distinct()->select('log') ->addSelect('user') ->from(AbstractLogEntry::class, 'log') ->leftJoin('log.user', 'user'); } }