addressHelper = $addressHelper; $this->centerRepository = $centerRepository; $this->civilityRepository = $civilityRepository; $this->countryRepository = $countryRepository; $this->languageRepository = $languageRepository; $this->maritalStatusRepository = $maritalStatusRepository; $this->translatableStringHelper = $translatableStringHelper; $this->translator = $translator; $this->userRepository = $userRepository; } /** * @param array|value-of[] $fields */ public function addSelect(QueryBuilder $qb, array $fields, DateTimeImmutable $computedDate): void { foreach (ListPersonHelper::FIELDS as $f) { if (!in_array($f, $fields, true)) { continue; } switch ($f) { case 'countryOfBirth': case 'nationality': $qb->addSelect(sprintf('IDENTITY(person.%s) as %s', $f, $f)); break; case 'address_fields': $this->addCurrentAddressAt($qb, $computedDate); $qb->leftJoin('personHouseholdAddress.address', 'personAddress'); $this->addressHelper->addSelectClauses(ExportAddressHelper::F_ALL, $qb, 'personAddress', 'address_fields'); break; case 'spokenLanguages': $qb ->leftJoin('person.spokenLanguages', 'spokenLanguage') ->addSelect('AGGREGATE(spokenLanguage.id) AS spokenLanguages') ->addGroupBy('person'); if (in_array('center', $fields, true)) { $qb->addGroupBy('center'); } if (in_array('address_fields', $fields, true)) { $qb ->addGroupBy('address_fieldsid') ->addGroupBy('address_fieldscountry_t.id') ->addGroupBy('address_fieldspostcode_t.id'); } if (in_array('household_id', $fields, true)) { $qb->addGroupBy('household_id'); } break; case 'household_id': $qb ->addSelect('IDENTITY(personHouseholdAddress.household) AS household_id'); $this->addCurrentAddressAt($qb, $computedDate); break; case 'center': $qb ->addSelect('IDENTITY(centerHistory.center) AS center') ->leftJoin('person.centerHistory', 'centerHistory') ->andWhere( $qb->expr()->orX( $qb->expr()->isNull('centerHistory'), $qb->expr()->andX( $qb->expr()->lte('centerHistory.startDate', ':address_date'), $qb->expr()->orX( $qb->expr()->isNull('centerHistory.endDate'), $qb->expr()->gte('centerHistory.endDate', ':address_date') ) ) ) ) ->setParameter('address_date', $computedDate); break; case 'lifecycleUpdate': $qb ->addSelect('person.createdAt AS createdAt') ->addSelect('IDENTITY(person.createdBy) AS createdBy') ->addSelect('person.updatedAt AS updatedAt') ->addSelect('IDENTITY(person.updatedBy) AS updatedBy'); break; case 'genderComment': $qb->addSelect('person.genderComment.comment AS genderComment'); break; case 'maritalStatus': $qb->addSelect('IDENTITY(person.maritalStatus) AS maritalStatus'); break; case 'maritalStatusComment': $qb->addSelect('person.maritalStatusComment.comment AS maritalStatusComment'); break; case 'civility': $qb->addSelect('IDENTITY(person.civility) AS civility'); break; default: $qb->addSelect(sprintf('person.%s as %s', $f, $f)); } } } /** * @return array|string[] */ public function getAllPossibleFields(): array { return array_merge( self::FIELDS, ['createdAt', 'createdBy', 'updatedAt', 'updatedBy'], $this->addressHelper->getKeys(ExportAddressHelper::F_ALL, 'address_fields') ); } public function getLabels($key, array $values, $data): callable { if (substr($key, 0, strlen('address_fields')) === 'address_fields') { return $this->addressHelper->getLabel($key, $values, $data, 'address_fields'); } switch ($key) { case 'center': return function ($value) use ($key) { if ('_header' === $value) { return $this->translator->trans($key); } if (null === $value || null === $center = $this->centerRepository->find($value)) { return ''; } return $center->getName(); }; case 'birthdate': case 'deathdate': case 'maritalStatusDate': case 'createdAt': case 'updatedAt': // for birthdate, we have to transform the string into a date // to format the date correctly. return function ($value) use ($key) { if ('_header' === $value) { return $this->translator->trans($key); } if (null === $value) { return ''; } // warning: won't work with DateTimeImmutable as we reset time a few lines later $date = DateTime::createFromFormat('Y-m-d', $value); $hasTime = false; if (false === $date) { $date = DateTime::createFromFormat('Y-m-d H:i:s', $value); $hasTime = true; } // check that the creation could occurs. if (false === $date) { throw new Exception(sprintf('The value %s could ' . 'not be converted to %s', $value, DateTime::class)); } if (!$hasTime) { $date->setTime(0, 0, 0); } return $date; }; case 'createdBy': case 'updatedBy': return function ($value) use ($key) { if ('_header' === $value) { return $this->translator->trans($key); } if (null === $value) { return ''; } return $this->userRepository->find($value)->getLabel(); }; case 'civility': return function ($value) use ($key) { if ('_header' === $value) { return $this->translator->trans($key); } if (null === $value) { return ''; } $civility = $this->civilityRepository->find($value); if (null === $civility) { return ''; } return $this->translatableStringHelper->localize($civility->getName()); }; case 'gender': // for gender, we have to translate men/women statement return function ($value) use ($key) { if ('_header' === $value) { return $this->translator->trans($key); } return $this->translator->trans($value); }; case 'maritalStatus': return function ($value) use ($key) { if ('_header' === $value) { return $this->translator->trans($key); } if (null === $value) { return ''; } $maritalStatus = $this->maritalStatusRepository->find($value); return $this->translatableStringHelper->localize($maritalStatus->getName()); }; case 'spokenLanguages': return function ($value) use ($key) { if ('_header' === $value) { return $this->translator->trans($key); } if (null === $value) { return ''; } $ids = json_decode($value); return implode( '|', array_map(function ($id) { if (null === $id) { return ''; } $lang = $this->languageRepository->find($id); if (null === $lang) { return null; } return $this->translatableStringHelper->localize($lang->getName()); }, $ids) ); }; case 'countryOfBirth': case 'nationality': return function ($value) use ($key) { if ('_header' === $value) { return $this->translator->trans($key); } if (null === $value) { return ''; } $country = $this->countryRepository->find($value); return $this->translatableStringHelper->localize( $country->getName() ); }; default: if (!in_array($key, self::getAllPossibleFields(), true)) { throw new RuntimeException("this key is not supported by this helper: {$key}"); } // for fields which are associated with person return function ($value) use ($key) { if ('_header' === $value) { return $this->translator->trans($key); } return $value; }; } } private function addCurrentAddressAt(QueryBuilder $qb, DateTimeImmutable $date): void { if (!(in_array('personHouseholdAddress', $qb->getAllAliases(), true))) { $qb ->leftJoin('person.householdAddresses', 'personHouseholdAddress') ->andWhere( $qb->expr()->orX( // no address at this time $qb->expr()->isNull('personHouseholdAddress'), // there is one address... $qb->expr()->andX( $qb->expr()->lte('personHouseholdAddress.validFrom', ':address_date'), $qb->expr()->orX( $qb->expr()->isNull('personHouseholdAddress.validTo'), $qb->expr()->gt('personHouseholdAddress.validTo', ':address_date') ) ) ) ) ->setParameter('address_date', $date); } } }