/** * Validates the provided postal code. * * @param string $postalCode The postal code. * @param array $subdivisions An array of found valid subdivisions. * @param AddressFormatInterface $addressFormat The address format. * @param Constraint $constraint The constraint. */ protected function validatePostalCode($postalCode, array $subdivisions, AddressFormatInterface $addressFormat, $constraint) { if (empty($postalCode) || !in_array(AddressField::POSTAL_CODE, $constraint->fields)) { // Nothing to validate. return; } // Resolve the available patterns. $fullPattern = $addressFormat->getPostalCodePattern(); $startPattern = null; foreach ($subdivisions as $subdivision) { $pattern = $subdivision->getPostalCodePattern(); if (empty($pattern)) { continue; } if ($subdivision->getPostalCodePatternType() == PatternType::FULL) { $fullPattern = $pattern; } else { $startPattern = $pattern; } } if ($fullPattern) { // The pattern must match the provided value completely. preg_match('/' . $fullPattern . '/i', $postalCode, $matches); if (empty($matches[0]) || $matches[0] != $postalCode) { $this->addViolation(AddressField::POSTAL_CODE, $constraint->invalidMessage, $postalCode, $addressFormat); return; } } if ($startPattern) { // The pattern must match the start of the provided value. preg_match('/' . $startPattern . '/i', $postalCode, $matches); if (empty($matches[0]) || strpos($postalCode, $matches[0]) !== 0) { $this->addViolation(AddressField::POSTAL_CODE, $constraint->invalidMessage, $postalCode, $addressFormat); return; } } }
/** * Builds the view for the given address. * * @param AddressInterface $address The address. * @param AddressFormatInterface $addressFormat The address format. * * @return array The view. */ protected function buildView(AddressInterface $address, AddressFormatInterface $addressFormat) { $countries = $this->countryRepository->getList($this->locale); $values = $this->getValues($address); $view = []; $view['country'] = ['html_tag' => 'span', 'html_attributes' => ['class' => 'country'], 'value' => $countries[$address->getCountryCode()]]; foreach ($addressFormat->getUsedFields() as $field) { // The constant is more suitable as a class than the value since // it's snake_case and not camelCase. $class = str_replace('_', '-', strtolower(AddressField::getKey($field))); $view[$field] = ['html_tag' => 'span', 'html_attributes' => ['class' => $class], 'value' => $values[$field]]; } return $view; }
/** * Gets the address values used to build the view. * * @param AddressInterface $address The address. * @param AddressFormatInterface $addressFormat The address format. * * @return array The values, keyed by address field. */ protected function getValues(AddressInterface $address, AddressFormatInterface $addressFormat) { $values = []; foreach (AddressField::getAll() as $field) { $getter = 'get' . ucfirst($field); $values[$field] = $address->{$getter}(); } // Replace the subdivision values with the names of any predefined ones. foreach ($addressFormat->getUsedSubdivisionFields() as $field) { if (empty($values[$field])) { // This level is empty, so there can be no sublevels. break; } $subdivision = $this->subdivisionRepository->get($values[$field], $address->getLocale()); if (!$subdivision) { // This level has no predefined subdivisions, stop. break; } $values[$field] = $subdivision->getCode(); if (!$subdivision->hasChildren()) { // The current subdivision has no children, stop. break; } } return $values; }
/** * Gets the labels for the provided address format's fields. * * @param AddressFormatInterface $addressFormat * * @return array An array of labels keyed by field constants. */ protected function getFieldLabels($addressFormat) { // All possible subdivision labels. $subdivisionLabels = [AdministrativeAreaType::AREA => 'Area', AdministrativeAreaType::COUNTY => 'County', AdministrativeAreaType::DEPARTMENT => 'Department', AdministrativeAreaType::DISTRICT => 'District', AdministrativeAreaType::DO_SI => 'Do', AdministrativeAreaType::EMIRATE => 'Emirate', AdministrativeAreaType::ISLAND => 'Island', AdministrativeAreaType::OBLAST => 'Oblast', AdministrativeAreaType::PARISH => 'Parish', AdministrativeAreaType::PREFECTURE => 'Prefecture', AdministrativeAreaType::PROVINCE => 'Province', AdministrativeAreaType::STATE => 'State', LocalityType::CITY => 'City', LocalityType::DISTRICT => 'District', LocalityType::POST_TOWN => 'Post Town', DependentLocalityType::DISTRICT => 'District', DependentLocalityType::NEIGHBORHOOD => 'Neighborhood', DependentLocalityType::VILLAGE_TOWNSHIP => 'Village / Township', DependentLocalityType::SUBURB => 'Suburb', PostalCodeType::POSTAL => 'Postal Code', PostalCodeType::ZIP => 'ZIP code', PostalCodeType::PIN => 'PIN code']; // Determine the correct administrative area label. $administrativeAreaType = $addressFormat->getAdministrativeAreaType(); $administrativeAreaLabel = ''; if (isset($subdivisionLabels[$administrativeAreaType])) { $administrativeAreaLabel = $subdivisionLabels[$administrativeAreaType]; } // Determine the correct locality label. $localityType = $addressFormat->getLocalityType(); $localityLabel = ''; if (isset($subdivisionLabels[$localityType])) { $localityLabel = $subdivisionLabels[$localityType]; } // Determine the correct dependent locality label. $dependentLocalityType = $addressFormat->getDependentLocalityType(); $dependentLocalityLabel = ''; if (isset($subdivisionLabels[$dependentLocalityType])) { $dependentLocalityLabel = $subdivisionLabels[$dependentLocalityType]; } // Determine the correct postal code label. $postalCodeType = $addressFormat->getPostalCodeType(); $postalCodeLabel = $subdivisionLabels[PostalCodeType::POSTAL]; if (isset($subdivisionLabels[$postalCodeType])) { $postalCodeLabel = $subdivisionLabels[$postalCodeType]; } // Assemble the final set of labels. $labels = [AddressField::ADMINISTRATIVE_AREA => $administrativeAreaLabel, AddressField::LOCALITY => $localityLabel, AddressField::DEPENDENT_LOCALITY => $dependentLocalityLabel, AddressField::ADDRESS_LINE1 => 'Street Address', AddressField::ADDRESS_LINE2 => false, AddressField::ORGANIZATION => 'Company', AddressField::RECIPIENT => 'Contact Name', AddressField::SORTING_CODE => 'Cedex', AddressField::POSTAL_CODE => $postalCodeLabel]; return $labels; }