I would try a somewhat different approach.
I would move the array of post types to your new WP_Query (since you are working with a limited defined set), and then below where you’re looping through each post type in your first foreach statement, I would setup a second query to get all posts found within each $type. If you need to access non-standard postdata (i.e. custom metadata), use global $post, otherwise you don’t need it.
That way you can use the_permalink.
Modify your new WP_Query like so:
$search_query = new WP_Query(
array(
'posts_per_page' => -1,
's' => esc_attr($_GET['s']),
'post_status' => 'publish',
'post_type' => array( 'post', 'page', 'glossary' )
)
);
Then, you can get rid of all the stuff directly below your opening div for your search-results-list and just skip to this:
foreach($types as $type) :
echo '<ul class="' . $type . '">';
while( have_posts() ) {
the_post();
if( $type == get_post_type() ){ ?>
<div class="entry-content">
<?php if ( has_post_thumbnail() ) { ?>
<a href="<?php the_permalink(); ?>" title="<?php echo esc_attr( sprintf( esc_html__( 'Permalink to %s', 'quark' ), the_title_attribute( 'echo=0' ) ) ); ?>">
<?php the_post_thumbnail( array(100,100) ); ?>
</a>
<?php } ?>
<?php the_excerpt(); ?>
<?php
}
rewind_posts();
echo '</ul>';
endforeach;
?>
OR Alternatively if you want to keep to WP’s newer way of organizing content/templates, you could have a separate template part for each post type with it’s own style options, etc.
echo '<ul class="' . $type . '">';
while( have_posts() ) {
the_post();
if( $type == get_post_type() ){
get_template_part('content', 'search' . $type);
}
rewind_posts();
echo '</ul>';
endforeach;