<?php
/**
 * Breadcrumbs
 *
 * @package marie
 */

// To keep track of number of breadcrumbs. used in meta content="".
$marie_crumb_count = 0;
/**
 * Util for marie_breadcrumbs(). Renders crumb markup.
 *
 * Note: When validating rich text (https://search.google.com/test/rich-results?) localhost://anything as the href will fail with the extremely unhelpful error "Missing field "item"". The href needs to be a proper remote url.
 *
 * @param string $active Active page or not. Render <a> tag and aria-current if !== ''.
 * @param string $link Url of page.
 * @param string $txt Text to render in span tag (ie the name of the crumb).
 */
function marie_wrap_in_li_span( $active = '', $link = '', $txt ) {
	global $marie_crumb_count;
	$marie_crumb_count++;
	$aria = '';
	// If $active is set, add 'class="active" as well as 'aria-current="page"' to the <li> attributes.
	if ( '' !== $active ) {
		$active = ' class="' . esc_attr( $active ) . '"';
		$aria   = ' aria-current="' . esc_attr( 'page' ) . '"';
	}

	$open_li_span  = '<li aria-current="page" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"' . $active . ' ' . $aria . '><span itemprop="name">';
	$close_li_span = '</span><meta itemprop="position" content="' . esc_attr( $marie_crumb_count ) . '" /></li>';

	if ( '' !== $link ) {

		$new_ans = '<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"' . $active . ' ' . $aria . '><a itemprop="item" href="' . esc_url( $link ) . '"><span itemprop="name">' . esc_html( $txt ) . '</span></a><meta itemprop="position" content="' . esc_attr( $marie_crumb_count ) . '" /></li>';

	} else {

		// If $link is NOT set, only the $txt will be wrapped in the <li><span>.
		$new_ans = $open_li_span . esc_html( $txt ) . $close_li_span;
	}
	// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped above.
	echo $new_ans;
}

/**
 * Echo Breadcrumbs.
 *
 * @package marie
 */
if ( ! function_exists( 'marie_breadcrumbs' ) ) {

	/**
	 * Echo Breadcrumbs
	 *
	 * A lot of the logic is based on Breadcrumbs in https://github.com/rachelbaker/bootstrapwp-Twitter-Bootstrap-for-WordPress/blob/master/functions.php
	 */
	function marie_breadcrumbs() {
			global $post, $paged;
			$aria_nav_label = __( 'Breadcrumb', 'marie' );
			ob_start();
			echo '<nav class="breadcrumbs" aria-label="' . esc_attr( $aria_nav_label ) . '">';
			echo '<ol itemscope itemtype="https://schema.org/BreadcrumbList" aria-label="breadcrumbs">';

		if ( ! is_home() || ! is_front_page() || ! is_paged() ) {

			marie_wrap_in_li_span( '', get_home_url(), __( 'Home', 'marie' ) );

			// Custom Taxonomies eg '/staff/marie', '/location/prospect-hill'.
			$term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) );

			// Check Custom Taxonomy First.
			if ( $term ) {

				// So these are never undefined.
				$taxonomy_slug                       = false;
				$taxonomy_label                      = false;
				$link_to_parent_taxonomy_page_exists = false;

				$this_term_name = $term->name; // eg 'Galway City'.

				// use this term's taxonomy name (eg club_contact, staff, location) to get all details for parent custom taxonomy.
				$taxonomy_dets = get_taxonomy( $term->taxonomy ); // returns tax or false.

				if ( false !== $taxonomy_dets ) {

					// To use in the href="...$taxonomy_slug".
					$taxonomy_slug = $taxonomy_dets->rewrite['slug'];

					// To use in the <a>$taxonomy_label</a>.
					$taxonomy_label = $taxonomy_dets->label;

				}

				/**
				* Taxonomies don't have an archive page. ie <site-url>/categories doesn't exist.
				* This theme (with associated plugins) DOES have pseudo custom taxonomy archive pages (created with wp pages & appropiate page template selected). Eg <site-url>/locations will show a list of custom taxonomy locations whereas <site-url>/location/some-location will show default one specific location.
				* We want to include these pseudo taxonomy archives in the breadcrumbs...
				* Therefore get the (potential) link to $this_term_names parent taxonomy. eg <site-url>/locations.
				* For this to work the permalink structure in settings->permalinks may need to be 'Post name'?
				*/

				if ( false !== $taxonomy_label && false !== $taxonomy_slug ) {

					$link_to_parent_tax_page = site_url( $taxonomy_slug, null ); // returns <site-url>/tax-slug.

					/*
					Note: This is expensive but it has to be done.
					*/

					// check that parent link exists. eg for url <site-url>/locations/galway, check <site-url>/locations exists.
					$link_to_parent_taxonomy_page_exists = marie_url_exists( $link_to_parent_tax_page );
				}

				// If $link_to_parent_tax_page is <site-url> with no slug appended, don't continue.
				if ( $link_to_parent_taxonomy_page_exists && site_url( null, null ) !== $link_to_parent_tax_page ) {

					// render link if it exists. eg /location.
					marie_wrap_in_li_span( '', $link_to_parent_tax_page, $taxonomy_label );
					?>

					<?php
				} else {

					// else just render the parent taxonomy name.
					if ( $taxonomy_label ) {
						marie_wrap_in_li_span( 'active', '', $taxonomy_label );
					}
				}

				marie_wrap_in_li_span( 'active', '', $this_term_name );
				$term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) );

			} elseif ( is_category() ) {

				// ie we are on something like /news/category/category.

				// 1. Definitely show link to /<a>News</a>.
				$blog_page_link  = get_permalink( get_option( 'page_for_posts' ) );
				$blog_page_title = get_the_title( get_option( 'page_for_posts', true ) );
				if ( $blog_page_link ) {
					marie_wrap_in_li_span( '', $blog_page_link, $blog_page_title );
				}

				// 2. Check parent cat

				// Use the name of whatever category we are on to get it's id.
				$this_cat_id = get_cat_ID( single_cat_title( '', false ) );

				// Use id of whatever category we are on to get category ancestors. Note this just returns an array of category ids.
				$gran = get_ancestors( $this_cat_id, 'category' );

				// Reverse the array because we display them from the top down.
				$gran_reversed = array_reverse( $gran );

				// Loop through the ancestor category ids.
				$num_ancestor_cats = count( $gran );
				for ( $i = 0;  $i < $num_ancestor_cats; $i++ ) {

					if ( isset( $gran_reversed[ $i ] ) ) {

						// Get ancestor category name and link.
						$related_cat  = get_category( $gran_reversed[ $i ] );
						$related_name = $related_cat->name;
						$related_link = get_category_link( $related_cat->term_id );

						// Display each ancestor <a>category</a>.
						marie_wrap_in_li_span( '', $related_link, $related_name );
					}
				}

				// 3. Finally display the name of the current category.
				marie_wrap_in_li_span( 'active', '', single_cat_title( '', false ) );

			} elseif ( is_day() ) {

				// For posts from 23rd November 2020... 'home/2020/11/23'.
					$year_link  = get_year_link( get_the_time( 'Y' ) );
					$month_link = get_month_link( get_the_time( 'Y' ), get_the_time( 'm' ) );

					// Eg '/<a>2020<a>'.
					marie_wrap_in_li_span( '', $year_link, get_the_time( 'Y' ) );

					// Eg '/<a>November<a>'.
					marie_wrap_in_li_span( '', $month_link, get_the_time( 'F' ) );

					// Eg '/23'.
					marie_wrap_in_li_span( 'active', '', get_the_time( 'd' ) );
			} elseif ( is_month() ) {

					// For posts from November 2020... 'home/2020/11'.

					// Eg  '/2020.
					marie_wrap_in_li_span( '', get_year_link( get_the_time( 'Y' ) ), get_the_time( 'Y' ) );

					// Eg'/november'.
					marie_wrap_in_li_span( 'active', '', get_the_time( 'F' ) );

			} elseif ( is_year() ) {
					marie_wrap_in_li_span( 'active', '', get_the_time( 'Y' ) );
			} elseif ( is_single() && ! is_attachment() ) {

				if ( get_post_type() !== 'post' ) {

					// Eg. 'home/project(cpt)/shout. Because no categories for cpts.
					$post_type      = get_post_type_object( get_post_type() );
					$slug           = $post_type->rewrite;
					$link_to_parent = home_url() . '/' . $slug['slug'];

					// Eg. '/<a>project</a>'.
					marie_wrap_in_li_span( '', $link_to_parent, $post_type->name );

					// Eg. '/shout'.
					marie_wrap_in_li_span( 'active', '', get_the_title() );

				} else {
						// Single post page. eg 'home / news / category / post name'.
						$category       = get_the_category();
						$blog_page_link = get_permalink( get_option( 'page_for_posts' ) );

						$blog_page_title = get_the_title( get_option( 'page_for_posts', true ) );
						marie_wrap_in_li_span( '', $blog_page_link, $blog_page_title );

					if ( is_array( $category ) ) {

						if ( count( $category ) > 0 ) {
							// Just use the first category even though some posts will be in more than one.
							// If post is in sub-categories breadcrumb will still only show 'home / news / category / post name'.
							marie_wrap_in_li_span( '', get_category_link( $category[0]->term_id ), $category[0]->name );
						}
					}

						// Finally show post title.
						marie_wrap_in_li_span( 'active', '', get_the_title() );

				}
			} elseif ( is_home() ) {

				$blog_page_title = get_the_title( get_option( 'page_for_posts', true ) );
				if ( is_paged() ) {
					$blog_page_link = get_permalink( get_option( 'page_for_posts' ) );

					// ie. We need an <a> tag on Home on paged results...  'Home / <a>News</a> / Page 2'.
					if ( '' !== $blog_page_link && is_string( $blog_page_link ) ) {
						marie_wrap_in_li_span( '', $blog_page_link, $blog_page_title );

					}
				} else {

					// ie. No <a> tag on News page... 'Home / News'.
					marie_wrap_in_li_span( 'active', '', $blog_page_title );
				}
			} elseif ( ! is_single() && ! is_page() && get_post_type() !== 'post' && ! is_404() && ! is_search() ) {

					// This one is a post type archive. Eg. '/project(cpt)', '/youthclub(cpt)'.
					$post_type = get_post_type_object( get_post_type() );
				if ( $post_type && is_object( $post_type ) ) {
					marie_wrap_in_li_span( 'active', '', $post_type->labels->singular_name );
				}
			} elseif ( is_attachment() ) {

				// marie does not use this.
				$parent   = get_post( $post->post_parent );
				$category = get_the_category( $parent->ID );
				if ( $category ) {
					foreach ( $category as $category ) {
						marie_wrap_in_li_span( '', get_category_link( $category->term_id ), $category->name );
					}
				}

					echo '<li class="active" aria-current="page"><span>' . esc_html( get_the_title() ) . '</span></li>';
			} elseif ( is_page() && ! $post->post_parent ) {
				// Regular page with no parent. Eg. '/resources'.

				if ( get_the_title() ) {
					marie_wrap_in_li_span( 'active', '', get_the_title() );

					// For the case of untitled pages.
				} else {
					// Use the current slug (if it exists).
					$untitled_page_slug = get_queried_object()->post_name;
					if ( $untitled_page_slug ) {
						marie_wrap_in_li_span( 'active', '', $untitled_page_slug );
					}
				}
			} elseif ( is_page() && $post->post_parent ) {
				$parent_id = $post->post_parent;
				$pg        = get_post( $parent_id );

				// For pages with a parent page.

				// Eg. '/resources/vacancies', this renders <a>resources</a>.
				marie_wrap_in_li_span( '', get_permalink( $pg->ID ), get_the_title( $pg->ID ) );

				// Eg. '/resources/vacancies', this renders <span>vacancies<span>.
				marie_wrap_in_li_span( 'active', '', get_the_title() );
			} elseif ( is_search() ) {

				/* translators: %s: search term. */
				$txt = __( 'Search results', 'marie' );

				// Eg. 'home/search results for whatever' (Page 1 of results).
				marie_wrap_in_li_span( 'active', '', $txt );

			} elseif ( is_tag() ) {

				// Eg. /tag/test-tag.

				/* translators: %s: name of current tag. */
				$txt = sprintf( __( 'Posts tagged <q>"%s"</q>', 'marie' ), single_tag_title( '', false ) );
				marie_wrap_in_li_span( 'active', '', $txt );
			} elseif ( is_author() ) {
				global $author;

				/* translators: %s: author name. */
				$txt = sprintf( __( 'All posts by %s', 'marie' ), get_the_author_meta( 'display_name', $author ) );

				// Eg. 'home/all posts by whoever' (Page 1 of results).
				marie_wrap_in_li_span( 'active', '', $txt );
			} elseif ( is_404() ) {
				marie_wrap_in_li_span( 'active', '', __( 'Page not found', 'marie' ) );
			}
		}

		// Paged results.
		if ( is_paged() ) {

			if ( is_category() || is_day() || is_month() || is_year() || is_search() || is_tag() || is_author() ) {

				/* translators: %s: current page of results. */
					$txt = sprintf( __( 'Page %s', 'marie' ), esc_attr( $paged ) );
					marie_wrap_in_li_span( 'active', '', $txt );
			} else {

				/* translators: %s: current page of results. */
				$txt = sprintf( __( 'Page %s', 'marie' ), esc_attr( $paged ) );
				marie_wrap_in_li_span( 'active', '', $txt );
			}
		}

			echo '</ol>';
			echo '</nav>';
			$ans = ob_get_clean();
		if ( $ans ) {

			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped above & in marie_wrap_in_li_span.
			echo $ans;
		}

	}
}
