<?php

class WPML_Get_Page_By_Path {

	/** @link https://onthegosystems.myjetbrains.com/youtrack/issue/wpmlcore-4918 */
	const BEFORE_REMOVE_PLACEHOLDER_ESCAPE_PRIORITY = -1;

	/** @var wpdb $wpdb */
	private $wpdb;

	/** @var SitePress $sitepress */
	private $sitepress;

	/** @var WPML_Debug_BackTrace $debug_backtrace */
	private $debug_backtrace;

	/** @var string $language */
	private $language;

	/** @var string $post_type */
	private $post_type;

	public function __construct( wpdb $wpdb, SitePress $sitepress, WPML_Debug_BackTrace $debug_backtrace ) {
		$this->wpdb            = $wpdb;
		$this->sitepress       = $sitepress;
		$this->debug_backtrace = $debug_backtrace;
	}

	public function get( $page_name, $lang, $output = OBJECT, $post_type = 'page' ) {
		$this->post_type = $post_type;
		$this->language  = $lang;

		$this->clear_cache( $page_name, $post_type );

		add_filter( 'query', [ $this, 'get_page_by_path_filter' ], self::BEFORE_REMOVE_PLACEHOLDER_ESCAPE_PRIORITY );
		$temp_lang_switch = new WPML_Temporary_Switch_Language( $this->sitepress, $lang );
		$page             = get_page_by_path( $page_name, $output, $post_type );
		$temp_lang_switch->restore_lang();
		remove_filter( 'query', [ $this, 'get_page_by_path_filter' ], self::BEFORE_REMOVE_PLACEHOLDER_ESCAPE_PRIORITY );

		return $page;
	}

	public function get_page_by_path_filter( $query ) {
		if (
			$this->sitepress->is_translated_post_type( $this->post_type )
			&& $this->debug_backtrace->is_function_in_call_stack( 'get_page_by_path' )
		) {

			$where = $this->wpdb->prepare( "ID IN ( SELECT element_id FROM {$this->wpdb->prefix}icl_translations WHERE language_code = %s AND element_type LIKE 'post_%%' ) AND ", $this->language );

			$query = str_replace( 'WHERE ', 'WHERE ' . $where, $query );
		}

		return $query;
	}

	/**
	 * @param string $page_name
	 * @param string $post_type
	 *
	 * @see get_page_by_path where the cache key is built
	 */
	private function clear_cache( $page_name, $post_type ) {
		$hash = md5( $page_name . serialize( $post_type ) );
		// For WP 6.8.3 or lower, use $last_changed in the cache key.
		$last_changed             = wp_cache_get_last_changed( 'posts' );
		$cache_key_with_timestamp = "get_page_by_path:$hash:$last_changed";
		wp_cache_delete( $cache_key_with_timestamp, 'posts' );
		wp_cache_delete( $cache_key_with_timestamp, 'post-queries' );
		// For WP 6.9, remove $last_changed in the cache key.
		$cache_key = "get_page_by_path:$hash";
		wp_cache_delete( $cache_key, 'posts' );
		wp_cache_delete( $cache_key, 'post-queries' );
	}
}
