Update based on the comment:
I think your best shot is to use the PHP output buffers. So you don’t have to repeat the mark up and you can implement what you want with a single while loop.
Example:
if (have_rows('repeater')):
$current_user = wp_get_current_user();
$adminOnlyContent="";
$nonAdminContent="";
while( have_rows('repeater') ): the_row();
$show_only = get_sub_field('show_only_to_logged_in_admins');
ob_start();
echo '';
echo '';
the_sub_field('title');
echo '
';
if ((user_can( $current_user, 'administrator' )) & ($show_only == 1)) {
$adminOnlyContent .= ob_get_clean();
} else {
$nonAdminContent .= ob_get_clean();
}
endwhile;
echo '';
echo $adminOnlyContent;
echo $nonAdminContent;
echo '
';
endif;
Another option is implement a separate function which will return the markup.
Original Answer:
You cannot use the_row()
twice within a loop. So you cannot use the nested loops here. But there are several ways to achieve what you want.
Here is one option: Store the content for both groups of fields in variables and echo them after the while loop.
$other_rows = [];
if (have_rows('repeater')):
$adminFields="";
$nonAdminFields="";
$current_user = wp_get_current_user();
while( have_rows('repeater') ): $row = the_row();
$show_only = get_sub_field('show_only_to_logged_in_admins');
if ((user_can( $current_user, 'administrator' )) & ($show_only == 1)) {
$adminFields .= '';
$adminFields .= the_sub_field('title');
$adminFields .= '
';
} else {
$nonAdminFields .= '';
$nonAdminFields .= the_sub_field('title');
$nonAdminFields .= '
';
}
endwhile;
echo '';
echo $adminFields;
echo $nonAdminFields;
echo '
';
endif;
Alternate solution:
The other options may require at least two loops. You need to use the loops one after the other instead of nested loops.
...
$current_user = wp_get_current_user();
while( have_rows('repeater') ): $row = the_row();
$show_only = get_sub_field('show_only_to_logged_in_admins');
if ((user_can( $current_user, 'administrator' )) && ($show_only == 1)) {
// Display content
}
endwhile;
while( have_rows('repeater') ): $row = the_row();
$show_only = get_sub_field('show_only_to_logged_in_admins');
if (! (user_can( $current_user, 'administrator' )) || ($show_only != 1)) {
// Display content
}
endwhile;
...
Alternate Solution 2
Here is another technique: Get all the repeater rows and segregate them to admin and non-admin rows. Then you can loop over them. Here also you need to use two loops.
// This is just a pseudo-code but you get the idea
$rows = get_field('repeater');
$current_user = wp_get_current_user();
$adminOnlyRows = array_filter($rows, function ($row) {
$show_only = $row['show_only_to_logged_in_admins'];
return (user_can( $current_user, 'administrator' )) && ($show_only == 1);
});
$nonAdminOnlyRows = array_filter($rows, function ($row) {
$show_only = $row['show_only_to_logged_in_admins'];
return ! (user_can( $current_user, 'administrator' )) || ($show_only != 1);
});
echo '';
foreach ($adminOnlyRows as $row) {
// Display content
}
foreach ($nonAdminOnlyRows as $row) {
// Display content
}
echo '
';