<?php
/**
 * Sitemap single template.
 *
 * @package SEOPress
 * @subpackage Templates
 */

defined( 'ABSPATH' ) || exit( 'Cheatin&#8217; uh?' );

if ( '' !== get_query_var( 'seopress_cpt' ) ) {
	$path = get_query_var( 'seopress_cpt' );
}

$request_uri = '';
if ( isset( $_SERVER['REQUEST_URI'] ) ) {
	$request_uri = esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) );
}
$offset = basename( (string) wp_parse_url( $request_uri, PHP_URL_PATH ), '.xml' );
$offset = preg_match_all( '/\d+/', $offset, $matches );
$offset = end( $matches[0] );

// Max posts per paginated sitemap.
$max = 1000;
$max = apply_filters( 'seopress_sitemaps_max_posts_per_sitemap', $max );

if ( isset( $offset ) && absint( $offset ) && '' !== $offset && 0 !== $offset ) {
	$offset = ( ( --$offset ) * $max );
} else {
	$offset = 0;
}

$home_url = home_url() . '/';

$home_url = apply_filters( 'seopress_sitemaps_home_url', $home_url );
echo '<?xml version="1.0" encoding="UTF-8"?>';
printf( '<?xml-stylesheet type="text/xsl" href="%s"?>', esc_url( $home_url . 'sitemaps_xsl.xsl' ) );

$urlset = '<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">';

echo apply_filters( 'seopress_sitemaps_urlset', $urlset );

// Archive link.
if ( get_post_type_archive_link( $path ) && 0 === $offset ) {
	if ( ! function_exists( 'seopress_get_service' ) ) {
		return;
	}
	if ( '1' !== seopress_get_service( 'TitleOption' )->getTitlesCptNoIndexByPath( $path ) ) {
		$sitemap_url   = '';
		$archive_links = array();

		// WPML Workaround.
		if ( class_exists( 'SitePress' ) ) {
			if ( 2 != apply_filters( 'wpml_setting', false, 'language_negotiation_type' ) ) {
				$original_language = apply_filters( 'wpml_current_language', null );
				$language_list     = apply_filters( 'wpml_active_languages', null, 'orderby=id&order=desc' );

				if ( ! empty( $language_list ) ) {
					foreach ( $language_list as $key => $language_infos ) {
						if ( $original_language !== $language_infos['language_code'] ) {

							// Switch Language.
							do_action( 'wpml_switch_language', $language_infos['language_code'] );

							if ( is_plugin_active( 'woocommerce/woocommerce.php' ) && 'product' === $path ) {
								if ( function_exists( 'wc_get_page_id' ) ) {
									$archive_links[] = htmlspecialchars( urldecode( user_trailingslashit( get_permalink( wc_get_page_id( 'shop' ) ) ) ) );
								}
							} else {
								$archive_links[] = htmlspecialchars( urldecode( user_trailingslashit( get_post_type_archive_link( $path ) ) ) );
							}

							// Restore language to the original.
							do_action( 'wpml_switch_language', $original_language );
						}
					}
				}
			}
		}

		// Polylang support.
		$polylang_handled = false;
		if ( function_exists( 'PLL' )
			&& function_exists( 'pll_current_language' )
			&& function_exists( 'pll_is_translated_post_type' )
			&& pll_is_translated_post_type( $path )
			&& ( is_plugin_active( 'polylang/polylang.php' ) || is_plugin_active( 'polylang-pro/polylang.php' ) )
		) {
			$pll_options     = PLL()->options;
			$is_multi_domain = isset( $pll_options['force_lang'] ) && $pll_options['force_lang'] >= 2;

			if ( $is_multi_domain ) {
				// Multi-domain / subdomain: each host has its own sitemap,
				// only include the current language archive link.
				$pll_current_lang = pll_current_language();

				if ( ! empty( $pll_current_lang ) ) {
					$polylang_handled  = true;
					$localized_archive = '';

					if ( is_plugin_active( 'woocommerce/woocommerce.php' ) && 'product' === $path && function_exists( 'wc_get_page_id' ) ) {
						$shop_id = wc_get_page_id( 'shop' );

						if ( $shop_id && function_exists( 'pll_get_post' ) ) {
							$translated_shop_id = pll_get_post( $shop_id, $pll_current_lang );

							if ( $translated_shop_id ) {
								$localized_archive = get_permalink( $translated_shop_id );
							}
						}
					} else {
						$localized_archive = get_post_type_archive_link( $path );
					}

					// Replace default home URL with the current language home URL
					// so the domain is correct in multi-domain setups.
					if ( ! empty( $localized_archive ) && function_exists( 'pll_home_url' ) ) {
						$default_home = untrailingslashit( get_option( 'home' ) );
						$lang_home    = untrailingslashit( pll_home_url( $pll_current_lang ) );

						if ( $default_home !== $lang_home ) {
							$localized_archive = str_replace( $default_home, $lang_home, $localized_archive );
						}
					}

					if ( ! empty( $localized_archive ) && ! is_wp_error( $localized_archive ) ) {
						$archive_links[] = htmlspecialchars( urldecode( user_trailingslashit( $localized_archive ) ) );
					}
				}
			} else {
				// Single-domain (directory mode): one sitemap contains all
				// languages, include archive links for every active language.
				$languages = PLL()->model->get_languages_list();

				if ( ! empty( $languages ) ) {
					$polylang_handled       = true;
					$previous_language_slug = pll_current_language();

					foreach ( $languages as $language ) {
						if ( ! $language->active ) {
							continue;
						}

						if ( function_exists( 'pll_switch_language' ) ) {
							pll_switch_language( $language->slug );
						} elseif ( isset( PLL()->curlang ) ) {
							PLL()->curlang = $language;
						}

						$localized_archive = '';

						if ( is_plugin_active( 'woocommerce/woocommerce.php' ) && 'product' === $path && function_exists( 'wc_get_page_id' ) ) {
							$shop_id = wc_get_page_id( 'shop' );

							if ( $shop_id && function_exists( 'pll_get_post' ) ) {
								$translated_shop_id = pll_get_post( $shop_id, $language->slug );

								if ( $translated_shop_id ) {
									$localized_archive = get_permalink( $translated_shop_id );
								}
							}
						} else {
							$localized_archive = get_post_type_archive_link( $path );
						}

						if ( ! empty( $localized_archive ) && ! is_wp_error( $localized_archive ) ) {
							$archive_links[] = htmlspecialchars( urldecode( user_trailingslashit( $localized_archive ) ) );
						}
					}

					// Restore original language.
					if ( function_exists( 'pll_switch_language' ) && ! empty( $previous_language_slug ) ) {
						pll_switch_language( $previous_language_slug );
					}
				}
			}
		}

		// Fallback when Polylang is not handling this post type.
		if ( ! $polylang_handled ) {
			$archive_links[] = htmlspecialchars( urldecode( user_trailingslashit( get_post_type_archive_link( $path ) ) ) );
		}

		$archive_links = array_unique( $archive_links );

		foreach ( $archive_links as $loc ) {
			$seopress_url = array(
				'loc'    => $loc,
				'mod'    => '',
				'images' => array(),
			);
			$sitemap_url  = sprintf( "<url>\n<loc>%s</loc>\n</url>", $loc );

			$sitemap_url = apply_filters( 'seopress_sitemaps_no_archive_link', $sitemap_url, $path );

			echo apply_filters( 'seopress_sitemaps_url', $sitemap_url, $seopress_url );
		}
	}
}

remove_all_filters( 'pre_get_posts' );

$args = array(
	'posts_per_page' => $max,
	'offset'         => $offset,
	'order'          => 'DESC',
	'orderby'        => 'modified',
	'post_type'      => $path,
	'post_status'    => 'publish',
	'lang'           => '',
	'has_password'   => false,
);

if ( 'attachment' === $path ) {
	unset( $args['post_status'] );
}

if ( is_plugin_active( 'woocommerce/woocommerce.php' ) && 'product' === $path ) {
	$args['tax_query'][] = array(
		'taxonomy' => 'product_visibility',
		'field'    => 'slug',
		'terms'    => array( 'exclude-from-catalog' ),
		'operator' => 'NOT IN',
	);
}

// Polylang: remove hidden languages.
if ( defined( 'POLYLANG_VERSION' ) && function_exists( 'PLL' ) && isset( PLL()->model ) ) {
	$languages = PLL()->model->get_languages_list();
	if ( wp_list_filter( $languages, array( 'active' => false ) ) ) {
		$args['lang'] = wp_list_pluck( wp_list_filter( $languages, array( 'active' => false ), 'NOT' ), 'slug' );
	}
}

$args = apply_filters( 'seopress_sitemaps_single_query', $args, $path );

$postslist = get_posts( $args );

/**
 * Primary category.
 *
 * @param object $cats_0 The primary category.
 * @param object $cats The categories.
 * @param object $post The post.
 *
 * @return object The primary category.
 */
function seopress_sitemaps_primary_cat_hook( $cats_0, $cats, $post ) {
	$primary_cat = null;

	if ( $post ) {
		$_seopress_robots_primary_cat = get_post_meta( $post->ID, '_seopress_robots_primary_cat', true );
		if ( isset( $_seopress_robots_primary_cat ) && '' !== $_seopress_robots_primary_cat && 'none' !== $_seopress_robots_primary_cat ) {
			if ( null !== $post->post_type && 'product' === $post->post_type ) {
				$primary_cat = get_term( $_seopress_robots_primary_cat, 'product_cat' );
			} elseif ( null !== $post->post_type && 'post' === $post->post_type ) {
				$primary_cat = get_category( $_seopress_robots_primary_cat );
			}

			if ( ! is_wp_error( $primary_cat ) && null !== $primary_cat ) {
				return $primary_cat;
			} else {
				return $cats_0;
			}
		} else {
			// no primary cat.
			return $cats_0;
		}
	} else {
		return $cats_0;
	}
}

foreach ( $postslist as $post ) {
	setup_postdata( $post );

	$dom         = '';
	$images      = '';
	$product_img = array();

	$modified_date = '';
	if ( get_the_modified_date( 'c', $post ) ) {
		$modified_date = get_the_modified_date( 'c', $post );
	} else {
		$modified_date = get_post_modified_time( 'c', false, $post );
	}

	$post_date    = get_the_date( 'c', $post );
	$seopress_mod = $modified_date;

	if ( ! empty( $modified_date ) ) {
		if ( strtotime( $post_date ) > strtotime( $modified_date ) ) {
			$seopress_mod = $post_date;
		}

		if ( false === $seopress_mod ) {
			$seopress_mod = $modified_date;
		}
	}

	// primary category.
	if ( 'post' === $path ) {
		add_filter( 'post_link_category', 'seopress_sitemaps_primary_cat_hook', 10, 3 );
	}
	if ( 'product' === $path ) {
		add_filter( 'wc_product_post_type_link_product_cat', 'seopress_sitemaps_primary_cat_hook', 10, 3 );
	}

	// initialize the sitemap url output.
	$sitemap_data = '';

	// array with all the information needed for a sitemap url.
	$seopress_url = array(
		'loc'    => htmlspecialchars( urldecode( get_permalink( $post ) ) ),
		'mod'    => $seopress_mod,
		'images' => array(),
	);

	$seopress_url = apply_filters( 'seopress_sitemaps_single_url', $seopress_url, $post );

	if ( ! empty( $seopress_url['loc'] ) ) {
		$sitemap_data .= sprintf( "\n<url>\n<loc>%s</loc>\n<lastmod>%s</lastmod>", $seopress_url['loc'], $seopress_url['mod'] );

		// XML Image Sitemaps.
		if ( '1' === seopress_get_service( 'SitemapOption' )->imageIsEnable() ) {
			// noimageindex?
			if ( 'yes' !== get_post_meta( $post, '_seopress_robots_imageindex', true ) ) {
				// Standard images.
				$post_content    = '';
				$dom             = new domDocument();
				$internal_errors = libxml_use_internal_errors( true );

				$run_shortcodes = apply_filters( 'seopress_sitemaps_single_shortcodes', false );

				if ( true === $run_shortcodes ) {
					// WP.
					if ( '' !== get_post_field( 'post_content', $post ) ) {
						$post_content .= do_shortcode( get_post_field( 'post_content', $post ) );
					}

					// Oxygen Builder.
					if ( is_plugin_active( 'oxygen/functions.php' ) ) {
						$post_content .= do_shortcode( get_post_meta( $post, 'ct_builder_shortcodes', true ) );
					}
				} else {
					$post_content = get_post_field( 'post_content', $post );
				}

				if ( '' !== $post_content ) {
					$dom->loadHTML( '<?xml encoding="utf-8" ?>' . $post_content );

					// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
					$dom->preserveWhiteSpace = false;

					if ( $dom->getElementsByTagName( 'img' )->length > 0 ) {
						$images = $dom->getElementsByTagName( 'img' );
					}
				}
				libxml_use_internal_errors( $internal_errors );

				// WooCommerce.
				global $product;
				if ( ! empty( $product ) && is_object( $product ) && method_exists( $product, 'get_gallery_image_ids' ) ) {
					$product_img = $product->get_gallery_image_ids();
				}

				// Post Thumbnail.
				$post_thumbnail    = get_the_post_thumbnail_url( $post, 'full' );
				$post_thumbnail_id = get_post_thumbnail_id( $post );

				if ( ( isset( $images ) && ! empty( $images ) && $images->length >= 1 ) || ( isset( $product ) && ! empty( $product_img ) ) || ! empty( $post_thumbnail ) ) {
					// Standard img.
					if ( isset( $images ) && ! empty( $images ) ) {
						if ( $images->length >= 1 ) {
							foreach ( $images as $img ) {
								$url = $img->getAttribute( 'src' );
								$url = apply_filters( 'seopress_sitemaps_single_img_url', $url );
								if ( '' !== $url ) {
									// Exclude Base64 img.
									if ( false === strpos( $url, 'data:image/' ) ) {

										// Initiate $seopress_url['images] and needed data for the sitemap image template.
										if ( true === seopress_is_absolute( $url ) ) {
											// do nothing.
										} else {
											$url = $home_url . $url;
										}

										// cleaning url.
										$url = htmlspecialchars( urldecode( esc_attr( wp_filter_nohtml_kses( $url ) ) ) );

										// remove query strings.
										$parse_url = wp_parse_url( $url );

										if ( ! empty( $parse_url['scheme'] ) && ! empty( $parse_url['host'] ) && ! empty( $parse_url['path'] ) ) {
											$seopress_image_loc = sprintf( '<![CDATA[%s://%s]]>', $parse_url['scheme'], $parse_url['host'] . $parse_url['path'] );
										} else {
											$seopress_image_loc = '<![CDATA[' . $url . ']]>';
											$seopress_image_loc = sprintf( '<![CDATA[%s]]>', $url );
										}

										$seopress_url['images'][] = array(
											'src' => $seopress_image_loc,
										);

										// Build up the template.
										$sitemap_data .= sprintf( "\n<image:image>\n<image:loc>%s</image:loc>", $seopress_image_loc );

										$sitemap_data .= "\n</image:image>";
									}
								}
							}
						}
					}

					// WooCommerce img.
					if ( ! empty( $product ) && is_object( $product ) && ! empty( $product_img ) ) {
						foreach ( $product_img as $product_attachment_id ) {
							$seopress_image_loc = '<![CDATA[' . esc_attr( wp_filter_nohtml_kses( wp_get_attachment_url( $product_attachment_id ) ) ) . ']]>';

							$seopress_url['images'][] = array(
								'src' => $seopress_image_loc,
							);

							// Build up the template.

							$sitemap_data .= sprintf( "\n<image:image>\n<image:loc>%s</image:loc>", $seopress_image_loc );

							$sitemap_data .= "\n</image:image>";
						}
					}
					// Post thumbnail.
					if ( ! empty( $post_thumbnail ) ) {
						$seopress_image_loc = '<![CDATA[' . $post_thumbnail . ']]>';

						$seopress_url['images'][] = array(
							'src' => $seopress_image_loc,
						);

						// Build up the template.
						$sitemap_data .= sprintf( "\n<image:image>\n<image:loc>%s</image:loc>", $seopress_image_loc );

						$sitemap_data .= "\n</image:image>";
					}
				}

				$sitemap_data = apply_filters( 'seopress_sitemaps_single_img', $sitemap_data, $post );
			}
		}
		$sitemap_data .= '</url>';
	}

	echo apply_filters( 'seopress_sitemaps_url', $sitemap_data, $seopress_url );
}
wp_reset_postdata();
?>
</urlset>
