/**
  * 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;
 }