-
Notifications
You must be signed in to change notification settings - Fork 0
Iterating over a repeatable group prior to version 1.2
Note: This page refers to all legacy versions of Simple Meta Boxes prior to version 1.2 If you are using version 1.2 please view the using repeatable groups page instead.
Repeater groups allow you to visually bundle meta fields together inside the Wordpress GUI, but under the hood each meta field in the group is still individually saved under its own id. This means that you can use these fields without the need to handle the entire group. On the other hand it also means they are not bundles together in a code-friendly manner. However, you can handle them as a group by creating a for
loop. When a group is saved Simple Meta Boxes will create an iterator meta key for it. This meta key inherits the meta box's key name and stores the number of items in said group as a string. Using this key we can iterate over the individual group meta field arrays, essentially treating them as a group. The following example uses the contact_us_fields
group that we created earlier and outputs the name, phone and email for each item in the group.
//Retrieve all the meta field arrays as well as the group iterator
$post_id = get_the_ID();
$name = get_post_meta( $post_id, 'name', TRUE );
$phone = get_post_meta( $post_id, 'phone', TRUE );
$email = get_post_meta( $post_id, 'email', TRUE );
$groupIterator = (int)get_post_meta( $post_id, 'contact_us_fields', TRUE );
//Iterate over the group items
for ($i = 0 ; $i < $groupIterator; $i++)
{
echo isset($name[$i])? $name[$i]: '';
echo isset($phone[$i])? $phone[$i]: '';
echo isset($email[$i])? $email[$i]: '';
}
This is a very simple example without any HTML formatting but it nonetheless shows how to iterate on a group. There are three important things to note regarding this example:
- Since meta keys are always saved as strings this example uses type casting to ensure that the group iterator (in this case
$groupIterator
) will be a valid integer. -
isset
is being used while accessing meta field keys to prevent cases in which some fields in the group might not exist. To prevent server errors it is recommended not to skip this vital step. - Although not shown in this example it is always a good idea to escape the meta key values before echoing them.
The example above is serviceable, but this method could add many lines of code to projects that make use of multiple repeatable groups. To simplify things add this neat helper function to functions.php
:
/**
* Retrieves a repeater group as a multidimentional array.
* Meta fields that exist but are missing specific items will have boolean FALSE as the value for those items.
* @param String $groupName The key (id) used for this group.
* @param Array $groupFields The meta keys (ids) of all the individual meta fields in this group.
* @return Mixed A multidimentional array with all the group fields or boolean FALSE if the function failed.
**/
function smb_get_group($groupName = FALSE, $groupFields = FALSE)
{
if ( !$groupName || !$groupFields ) return FALSE;
if ( !isset($post) ) global $post;
$groupIterator = $post->$groupName;
if ( !$groupIterator || ($groupIterator == '') || !is_numeric($groupIterator) ) return FALSE;
foreach ($groupFields as $field)
{
//The retrieval attemp of a falsy meta key will return the entire post's meta keys array and we DO NOT want that.
if ($field == FALSE)
{
if( ($key = array_search($field, $groupFields)) !== FALSE ) unset($groupFields[$key]);
continue;
}
${$field} = $post->$field;
//If the field does not exist remove it from the group.
if ( !${$field} || !is_array(${$field}) )
{
if(($key = array_search($field, $groupFields)) !== false) unset($groupFields[$key]);
}
}
//Create the group array.
$group = array();
for ($i=0; $i < $groupIterator ; $i++)
{
foreach ($groupFields as $field) {
$group[$i][$field] = (isset(${$field}[$i]))? ${$field}[$i]:FALSE;
}
}
return $group;
}
Call this function whenever you need to retrieve a group and you'll get the entire array-formatted group in one line:
$contactList = smb_get_group('contact_us_fields', array('name', 'phone', 'email'));