self::F_COUNTRY, 'postal_code' => self::F_POSTAL_CODE, 'street' => self::F_STREET, 'building' => self::F_BUILDING, 'string' => self::F_AS_STRING, 'geom' => self::F_GEOM, 'attributes' => self::F_ATTRIBUTES, ]; private const COLUMN_MAPPING = [ 'country' => ['country'], 'postal_code' => ['postcode_code', 'postcode_name'], 'street' => ['street', 'streetNumber'], 'building' => ['buildingName', 'corridor', 'distribution', 'extra', 'flat', 'floor'], 'string' => ['_as_string'], 'attributes' => ['isNoAddress', 'confidential', 'id'], 'geom' => ['_lat', '_lon'], ]; private AddressRender $addressRender; private AddressRepository $addressRepository; private PropertyAccessor $propertyAccess; private TranslatableStringHelperInterface $translatableStringHelper; public function __construct( AddressRepository $addressRepository, TranslatableStringHelperInterface $translatableStringHelper, AddressRender $addressRender ) { $this->addressRepository = $addressRepository; $this->propertyAccess = PropertyAccess::createPropertyAccessor(); $this->translatableStringHelper = $translatableStringHelper; $this->addressRender = $addressRender; } public function addSelectClauses(int $params, QueryBuilder $queryBuilder, $entityName = 'address', $prefix = 'add') { foreach (self::ALL as $key => $bitmask) { if (($params & $bitmask) === $bitmask) { foreach (self::COLUMN_MAPPING[$key] as $field) { switch ($field) { case 'id': case '_as_string': $queryBuilder->addSelect(sprintf('%s.id AS %s%s', $entityName, $prefix, $field)); break; case 'street': case 'streetNumber': case 'building': case 'floor': case 'corridor': case 'steps': case 'buildingName': case 'flat': case 'distribution': case 'extra': $queryBuilder->addSelect(sprintf('%s.%s AS %s%s', $entityName, $field, $prefix, $field)); break; case 'country': case 'postcode_name': case 'postcode_code': $postCodeAlias = sprintf('%spostcode_t', $prefix); if (!in_array($postCodeAlias, $queryBuilder->getAllAliases(), true)) { $queryBuilder->leftJoin($entityName . '.postcode', $postCodeAlias); } if ('postcode_name' === $field) { $queryBuilder->addSelect(sprintf('%s.%s AS %s%s', $postCodeAlias, 'name', $prefix, $field)); break; } if ('postcode_code' === $field) { $queryBuilder->addSelect(sprintf('%s.%s AS %s%s', $postCodeAlias, 'code', $prefix, $field)); break; } $countryAlias = sprintf('%scountry_t', $prefix); if (!in_array($countryAlias, $queryBuilder->getAllAliases(), true)) { $queryBuilder->leftJoin(sprintf('%s.country', $postCodeAlias), $countryAlias); } $queryBuilder->addSelect(sprintf('%s.%s AS %s%s', $countryAlias, 'name', $prefix, $field)); break; case 'isNoAddress': case 'confidential': $queryBuilder->addSelect(sprintf('CASE WHEN %s.%s = \'TRUE\' THEN 1 ELSE 0 END AS %s%s', $entityName, $field, $prefix, $field)); break; case '_lat': $queryBuilder->addSelect(sprintf('ST_Y(%s.point) AS %s%s', $entityName, $prefix, $field)); break; case '_lon': $queryBuilder->addSelect(sprintf('ST_X(%s.point) AS %s%s', $entityName, $prefix, $field)); break; default: throw new LogicException('This key is not supported: ' . $key); } } } } } /** * @param self::F_* $params * * @return array|string[] */ public function getKeys(int $params, string $prefix = ''): array { $prefixes = []; foreach (self::ALL as $key => $bitmask) { if (($params & $bitmask) === $bitmask) { $prefixes = array_merge( $prefixes, array_map( static function ($item) use ($prefix) { return $prefix . $item; }, self::COLUMN_MAPPING[$key] ) ); } } return $prefixes; } public function getLabel($key, array $values, $data, string $prefix = '', string $translationPrefix = 'export.address_helper.'): callable { $sanitizedKey = substr($key, strlen($prefix)); switch ($sanitizedKey) { case 'id': case 'street': case 'streetNumber': case 'buildingName': case 'corridor': case 'distribution': case 'extra': case 'flat': case 'floor': case '_lat': case '_lon': case 'postcode_code': case 'postcode_name': return static function ($value) use ($sanitizedKey, $translationPrefix) { if ('_header' === $value) { return $translationPrefix . $sanitizedKey; } if (null === $value) { return ''; } return $value; }; case 'country': return function ($value) use ($key) { if ('_header' === $value) { return 'export.list.acp' . $key; } if (null === $value) { return ''; } return $this->translatableStringHelper->localize(json_decode($value, true)); }; case 'isNoAddress': case 'confidential': return static function ($value) use ($sanitizedKey, $translationPrefix) { if ('_header' === $value) { return $translationPrefix . $sanitizedKey; } if (null === $value) { return ''; } switch ($value) { case null: return ''; case true: return 1; case false: return 0; default: throw new LogicException('this value is not supported for ' . $sanitizedKey . ': ' . $val); } }; case '_as_string': return function ($value) use ($sanitizedKey, $translationPrefix) { if ('_header' === $value) { return $translationPrefix . $sanitizedKey; } if (null === $value) { return ''; } $address = $this->addressRepository->find($value); return $this->addressRender->renderString($address, []); }; default: throw new LogicException('this key is not supported: ' . $sanitizedKey); } } }