This is an alternative version of Morten Lindorf’s snippet, “Control Which Parts Of A Location String Is Shown.”
It’s use case specific – I needed to reliably show the “city, state” or “city, province” for USA and Canadian locations without using any type of manual intervention from the user. I also wanted to strip off post codes for a cleaner presentation.
This is an alternative version of Morten Lindorf's snippet, "Control Which Parts Of
A Location String Is Shown."
It's use case specific - I needed to reliably show the "city, state"
or "city, province" for USA and Canadian locations without using any type of
manual intervention from the user.
I also wanted to strip off post codes for a cleaner presentation.
/*
* Customization of Morten Lindorf's code snippet to pull values from the google
* location field using the google location Long Address, this will pull out
* the city, state or city, province.
* It will also strip off the postal codes from both US and Canadian addresses.
* Use the modifier of -2, -1 to get the City, State or City, Province.
*/
add_filter( 'voxel/dynamic-tags/modifiers', function( $modifiers ) {
  class Get_Address_Parts extends \Voxel\Dynamic_Tags\Base_Modifier {
    public function get_label(): string {
      return 'Get address parts';
    }
    public function get_key(): string {
      return 'get_address_parts';
    }
    public function get_arguments(): array {
      return [
        'parts' => [
          'type' => \Voxel\Form_Models\Text_Model::class,
          'label' => _x( 'Enter parts, e.g. 1,3', 'modifiers', 'voxel-backend' ),
          'classes' => 'x-col-12',
        ],
      ];
    }
    public function apply( $value, $args, $group ) {
      $parts = explode( ', ', $value );
      $requested = array_filter( array_map( 'intval', explode( ',', $args[0] ?? '' ) ) );
      // Check if the last item is "United States" or "Canada"
      $last_item = trim(end($parts));
      if ($last_item === 'United States' || $last_item === 'Canada') {
        // Drop the last item
        array_pop($parts);
      }
      // Check if the string contains a Canadian postal code (A1A 1A1)
      if (preg_match('/[A-Z]\d[A-Z]\s\d[A-Z]\d/', $value)) {
        // Remove the Canadian postal code from the string
        $parts = array_map(function($part) {
          return preg_replace('/[A-Z]\d[A-Z]\s\d[A-Z]\d/', '', $part);
        }, $parts);
      } else {
        // Remove numbers from the end of each part
        $parts = array_map(function($part) {
          return preg_replace('/\d+$/', '', $part);
        }, $parts);
      }
      // Filter and map requested parts
      return join( ', ', array_filter( array_map( function( $i ) use ( $parts ) {
        return $i < 0 ? ( $parts[ count( $parts ) + $i ] ?? null ) : ( $parts[ $i - 1 ] ?? null );
      }, $requested ) ) );
    }
  }
  $modifiers['get_address_parts'] = \Get_Address_Parts::class;
  return $modifiers;
});