/**
  * Validates the provided subdivision values.
  *
  * @param array         $values        The field values, keyed by field constants.
  * @param AddressFormat $addressFormat The address format.
  * @param Constraint    $constraint    The constraint.
  *
  * @return array An array of found valid subdivisions.
  */
 protected function validateSubdivisions($values, AddressFormat $addressFormat, $constraint)
 {
     $countryCode = $addressFormat->getCountryCode();
     if ($addressFormat->getSubdivisionDepth() < 1) {
         // No predefined subdivisions exist, nothing to validate against.
         return [];
     }
     $subdivisionFields = $addressFormat->getUsedSubdivisionFields();
     $parents = [];
     $subdivisions = [];
     foreach ($subdivisionFields as $index => $field) {
         if (empty($values[$field]) || !in_array($field, $constraint->fields)) {
             // The field is empty or validation is disabled.
             break;
         }
         $parents[] = $index ? $values[$subdivisionFields[$index - 1]] : $countryCode;
         $subdivision = $this->subdivisionRepository->get($values[$field], $parents);
         if (!$subdivision) {
             $this->addViolation($field, $constraint->invalidMessage, $values[$field], $addressFormat);
             break;
         }
         $subdivisions[] = $subdivision;
         if (!$subdivision->hasChildren()) {
             // No predefined subdivisions below this level, stop here.
             break;
         }
     }
     return $subdivisions;
 }
 /**
  * Gets the address values used to build the view.
  *
  * @param AddressInterface $address       The address.
  * @param AddressFormat    $addressFormat The address format.
  *
  * @return array The values, keyed by address field.
  */
 protected function getValues(AddressInterface $address, AddressFormat $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.
     $originalValues = [];
     $subdivisionFields = $addressFormat->getUsedSubdivisionFields();
     $parents = [];
     foreach ($subdivisionFields as $index => $field) {
         if (empty($values[$field])) {
             // This level is empty, so there can be no sublevels.
             break;
         }
         $parents[] = $index ? $originalValues[$subdivisionFields[$index - 1]] : $address->getCountryCode();
         $subdivision = $this->subdivisionRepository->get($values[$field], $parents);
         if (!$subdivision) {
             break;
         }
         // Remember the original value so that it can be used for $parents.
         $originalValues[$field] = $values[$field];
         // Replace the value with the expected code.
         $useLocalName = LocaleHelper::match($address->getLocale(), $subdivision->getLocale());
         $values[$field] = $useLocalName ? $subdivision->getLocalCode() : $subdivision->getCode();
         if (!$subdivision->hasChildren()) {
             // The current subdivision has no children, stop.
             break;
         }
     }
     return $values;
 }