Using output buffering seems like the way to go in this case, ob_start()
to start buffering, then ob_get_clean()
to get and clean the buffering.
<?php ob_start(); ?>
<div class="column">
<div class="columns resource_downloads">
<?php if ( have_rows('_downloads_group') ) : ?>
<?php while( have_rows('_downloads_group') ) : the_row(); ?>
<div class="column v-align-top">
<figure class="download__img outer-1by1">
<img class="inner-1by1" src="<?php echo wp_get_attachment_image_src( get_sub_field('_file_image'), 'download' )[0]; ?>" alt="<?php the_field('_file_image_alt'); ?>" width="150" height="150">
</figure>
<div class="resource_downloads-info stack__sm">
<h3><?php the_sub_field('_file_title'); ?></h3>
<p><?php the_sub_field('_file_description'); ?></p>
</div>
<div class="btn-wrap">
<a class="button primary" href="<?php the_sub_field('_file_download_button'); ?>" title="<?php the_sub_field('_file_download_button_title'); ?>"><?php the_sub_field('_file_download_button_label'); ?></a>
</div>
</div>
<?php endwhile; ?>
<?php endif; ?>
</div>
</div>
<?php
$output = ob_get_clean();
echo do_shortcode('[signinlocker id="506"]' . $output . '[/signinlocker]');
?>