Home › Forums › Add-ons › Repeater Field › Combine dates between repeater field › Reply To: Combine dates between repeater field
It is not possible to order the posts by a repeater sub field, so what you want to do is not possible. Even if it were possible, the nature of WP_Query would give you additional problems.
Let’s say for example that “Show 1” is on “date 1” and “date 2” while “Show 2” is on “date 1” and “date 3”. Using WP_Query you will only see each “Show” listed once.
Date 1
=> Show 1
=> Show 2
Date 2
Nothing listed, show 1 already shown
Date 3
Nothing listed, show 2 already shown
I am actually currently working on a project that has a similar problem. The client wants “Events”. Each event can happen on multiple dates. Basically the same thing that you are doing. I have no choice but to use a repeater for this. How am I solving this.
1) I’ve made my post type hierarchical.
2) On top level posts I have a field group with the repeater. On child posts I have a field group that contains just a start date/time and an end date/time field. This requires a custom location rule.
3) When an event is saved I have an acf/save_post action that creates creates and deletes child posts for the event based on the dates saved in the repeater field.
4) In the admin list of posts I am hiding the child posts so that the client cannot see them. I am also hiding the fact that they can create child posts. I have a filter on pre_get_posts for this post type in the admin and I’m using ACF “hide on screen” to hide the page attribute blocks. So, basically, the client will never see the fact that all these posts are being added and deleted.
I will post the relevant code for the above at the end of this.
The remaining is not done. When showing posts on the front end I will do a pre_get_posts filter that will remove parent posts from the query and order all of the child posts by their start date/end date fields. When showing links I will link to the parent post instead of the child post. I’m probably also going to need to limit the number of dates that the client is allowed to add so that updating a post does not time out.
The following code has not been made to work for your needs, it is just provided as as example of what I’ve done so far. The only thing that I’ve done is remove the client’s name from the code. It also has not been completely tested since I’m in the process of building it.
<?php
class client_name_events {
private $post_type = 'events';
public function __construct() {
add_action('pre_get_posts', array($this, 'hide_children_in_admin'));
add_filter('acf/location/rule_types', array($this, 'acf_location_rule_types'));
add_filter('acf/location/rule_values/post_level', array($this, 'acf_location_post_level_values'));
add_filter('acf/location/rule_match/post_level', array($this, 'acf_location_post_level_match'), 20, 3);
add_action('acf/save_post', array($this, 'save_event'), 20);
} // end public function __construct
public function hide_children_in_admin($query) {
if (!is_admin() || !$query->is_main_query()) {
return;
}
if (!isset($query->query_vars) ||
!isset($query->query_vars['post_type']) ||
$query->query_vars['post_type'] != $this->post_type) {
return;
}
$query->set('post_parent', 0);
} // end public function hide_children_in_admin
public function save_event($post_id) {
if (get_post_type($post_id) != $this->post_type) {
// not our post type
return;
}
$parent = wp_get_post_parent_id($post_id);
if ($parent) {
// this is a child post
// this should never happen
// it's only here to cover all bases
return;
}
// get all dates from repeater
$dates = array();
if (have_rows('dates', $post_id)) {
while (have_rows('dates', $post_id)) {
the_row();
$dates[] = array(
'start' => get_sub_field('start'),
'end' => get_sub_field('end')
);
}
}
// get list of existing date posts
$existing_dates = array();
// get all child posts
$args = array(
'post_type' => 'events',
'post_parent' => $post_id,
'numberposts' => -1,
);
$children = get_children($args);
$new = array();
$delete = array();
if (!empty($children)) {
foreach ($children as $id => $event) {
$existing_dates[$id] = array(
'id' => $id,
'title' => $event->post_title,
'start' => get_field('start_date', $id),
'end' => get_field('end_date', $id)
);
} // end foreach children
} // end if !empty children
// create list of dates to add
// loop over all $dates, and all $existing_dates
// if a date does not exist add it to the list to be added
$add = array();
if (count($existing_dates)) {
foreach ($dates as $date) {
$found = false;
foreach ($existing_dates as $existing_date) {
if ($date['start'] == $existing_date['start'] && $date['end'] == $existing_date['end']) {
$found = true;
break;
}
} // end foreach existing date
if (!$found) {
$add[] = $date;
}
} // end foreach dates
} else {
// no existing dates
// add them all
$add = $dates;
}
// create list of dates to remove
// loop over all existing dates and all dates
// if a date does not exist then add it to list of dates to remove
$remove = array();
if (count($exisiting_dates)) {
foreach ($existing_dates as $id => $existing_date) {
$found = false;
foreach ($dates as $date) {
if ($date['start'] == $existing_date['start'] && $date['end'] == $existing_date['end']) {
$found = true;
break;
}
}
if (!$found) {
$remove[] = $id;
}
} // end foreach existing date
} // end if existing dates
// delete posts
if (count($remove)) {
foreach ($remove as $id) {
wp_delete_post($id, true);
}
} // end if posts to remove
// add posts
if (count($add)) {
foreach ($add as $date) {
$post = array(
'post_title' => $date['start'].' to '.$date['end'],
'post_type' => 'events',
'post_parent' => $post_id,
'post_status' => 'publish'
);
$new_id = wp_insert_post($post);
if ($new_id) {
update_field('field_5c6eb7f6dc628', $date['start'], $new_id);
update_field('field_5c6eb81ddc629', $date['end'], $new_id);
}
} // end foreach date to add
} // end if posts to add
} // end public function save_event
public function acf_location_rule_types($choices) {
if (!isset($choices['Other'])) {
$choices['Other'] = array();
}
if (!isset($choices['Other']['post_level'])) {
$choices['Other']['post_level'] = 'Post Level';
}
return $choices;
} // end public function acf_location_rule_types
public function acf_location_post_level_values($choices) {
$choices['top'] = 'Top Level Post';
$choices['child'] = 'Child Post';
return $choices;
} // end public function acf_location_post_level_values
public function acf_location_post_level_match($match, $rule, $options) {
if ($rule['param'] == 'post_level') {
$post_id = $options['post_id'];
$parent = wp_get_post_parent_id($post_id);
if ($parent) {
$level = 'child';
} else {
$level = 'top';
}
}
switch ($rule['operator']) {
case '==':
$match = ($level == $rule['value']);
break;
case '!=':
$match = ($level != $rule['value']);
break;
default:
// do nothing
break;
}
return $match;
} // end public function acf_location_post_level_match
} // end class client_name_events
?>
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.