Adding groups support to the ACF field shortcode

I loved the addition of groups to Advanced Custom Fields – instead of endless repetitions like header_heading, header_image, header_video and so on we can now treat them as an associative array: $header['heading'], $header['image'], $header['video']. Unfortunately, there are some problems with displaying fields – e.g. can’t choose to display raw content in get_field(). The bundled shortcode is also pretty basic and can’t access the inner fields, so I’ve added the ability to access the child variables via dot notation:

<?php

/**
 * Overwrite ACF shortcode
 */
function custom_acf_shortcode($atts)
{
  extract(shortcode_atts(array(
    'field'      => '',
    'post_id'    => false,
    'format_value'  => true
  ), $atts));

  // Basic field
  if (false === strpos($field, '.')) {
    $value = get_field($field, $post_id, $format_value);

    if (is_array($value)) {
      $value = @implode(', ', $value);
    }

    return $value;
  }

  // Group field
  $field_parent = strtok($field, '.');
  $field_rest = strtok('');

  $value = get_field($field_parent, $post_id, $format_value);

  if (!is_array($value)) {
    return $value;
  }

  return array_get($value, $field_rest);
}

function overwrite_shortcode()
{
  remove_shortcode('acf');
  add_shortcode('acf', 'custom_acf_shortcode');
}
add_action('wp_loaded', 'overwrite_shortcode');

Usage:

[acf field="header.video" post_id="123"]