<?php

namespace Barn2\Plugin\Password_Protected_Categories;

use Barn2\Plugin\Password_Protected_Categories\Dependencies\Lib\Registerable;
use Barn2\Plugin\Password_Protected_Categories\Dependencies\Lib\Service\Premium_Service;

/**
 * This class provides protection for XML sitemaps.
 *
 * Currently supports: WordPress SEO, All in One SEO Pack.
 *
 * @package   Barn2\password-protected-categories
 * @author    Barn2 Plugins <support@barn2.co.uk>
 * @license   GPL-3.0
 * @copyright Barn2 Media Ltd
 */
class XML_Sitemaps implements Premium_Service, Registerable {

	private $taxonomies = false;

	public function register() {
		// All in One SEO Pack
		if ( \defined( 'AIOSEOP_VERSION' ) && ! \is_admin() ) {
			\add_filter( 'option_aioseop_options', [ $this, 'aioseop_excludes' ] );
		}

		// WordPress SEO
		\add_action( 'admin_init', [ $this, 'wpseo_maybe_clear_cache' ] );
		\add_filter( 'wpseo_sitemap_entry', [ $this, 'wpseo_exclude_protected_terms' ], 10, 3 );

		// @todo: More sitemap plugins

		\do_action( 'ppc_sitemap_hooks_registered', $this );
	}

	public function aioseop_excludes( $value ) {

		if ( isset( $value['modules']['aiosp_sitemap_options'] ) ) {
			$sitemap_options = $value['modules']['aiosp_sitemap_options'];

			// Get all hidden term IDs
			$excluded_term_ids = PPC_Util::get_hidden_terms( $this->get_taxonomies(), 'ids' );

			// Exclude hidden terms
			if ( isset( $sitemap_options['aiosp_sitemap_excl_categories'] ) ) {
				$sitemap_options['aiosp_sitemap_excl_categories'] = \array_unique( \array_merge( $sitemap_options['aiosp_sitemap_excl_categories'], $excluded_term_ids ) );
			}

			// Exclude hidden posts
			if ( isset( $sitemap_options['aiosp_sitemap_excl_pages'] ) ) {

				// Get all hidden post IDs
				$post_excludes = \get_objects_in_term( $excluded_term_ids, $this->get_taxonomies() );

				if ( $post_excludes && \is_array( $post_excludes ) ) {
					if ( ! empty( $sitemap_options['aiosp_sitemap_excl_pages'] ) ) {
						$post_excludes = \array_merge( $post_excludes, \explode( ',', \str_replace( ' ', '', $sitemap_options['aiosp_sitemap_excl_pages'] ) ) );
					}

					$sitemap_options['aiosp_sitemap_excl_pages'] = \array_unique( $post_excludes );
				}
			}

			$value['modules']['aiosp_sitemap_options'] = $sitemap_options;
		}

		return $value;
	}

	public function wpseo_maybe_clear_cache() {
		$cache_cleared = \get_option( 'ppc_wpseo_cache_cleared' );

		// Clear WPSEO cache once when PPC is first run. If WPSEO is later deactivated, update option.
		if ( \defined( 'WPSEO_VERSION' ) && 'wpseo' !== $cache_cleared ) {
			self::clear_wpseo_sitemap_cache();
			\update_option( 'ppc_wpseo_cache_cleared', 'wpseo' );
		} elseif ( 'nowpseo' !== $cache_cleared ) {
			\update_option( 'ppc_wpseo_cache_cleared', 'nowpseo' );
		}
	}

	public static function clear_wpseo_sitemap_cache() {
		if ( \class_exists( '\WPSEO_Sitemaps_Cache_Validator' ) ) {
			\WPSEO_Sitemaps_Cache_Validator::invalidate_storage();
		}
	}

	public function wpseo_exclude_protected_terms( $url, $type, $obj ) {
		if ( 'term' === $type && $obj instanceof \WP_Term && \in_array( $obj->taxonomy, $this->get_taxonomies() ) ) {
			$term_visibility = PPC_Util::get_term_visibility( $obj );

			if ( $term_visibility->is_hidden() ) {
				return false;
			}
		} elseif ( 'post' === $type && $obj instanceof \WP_Post ) {
			if ( PPC_Util::is_hidden_post( $obj ) ) {
				return false;
			}
		}

		return $url;
	}

	private function get_taxonomies() {
		if ( false === $this->taxonomies ) {
			$this->taxonomies = PPC_Util::get_protectable_taxonomies();
		}
		return $this->taxonomies;
	}

}
