<?php
/**
 * Rewrite Model
 * Called to handle the rewrites and to change the paths
 *
 * @file  The Rewrite Model file
 * @package HMWP/RewriteModel
 * @since 4.0.0
 */

defined( 'ABSPATH' ) || die( 'Cheating uh?' );

class HMWP_Models_Rewrite {
	/**
	 * All the paths that need to be changed
	 *
	 * @var array
	 */
	public $_replace = array();
	public $paths;
	//
	protected $_rewrites = array();
	protected $_umrewrites = array();

	/**
	 * Triggered after the paths are changed
	 *
	 * @var bool
	 */
	protected $_replaced;

	/**
	 * The current website domain
	 *
	 * @var string
	 */
	protected $_siteurl = '';

	/**
	 * Text Mapping
	 *
	 * @var array
	 */
	protected $_findtextmapping = array();
	protected $_replacetextmapping = array();

	/**
	 * HMWP_Models_Rewrite constructor.
	 */
	public function __construct() {
		//Get the current site URL
		$siteurl = site_url();

		$parsed = wp_parse_url( $siteurl );

		$parsed['path'] = ( $parsed['path'] ?? '' );
		$parsed['host'] = ( $parsed['host'] ?? '' );

		//Set the blog URL
		$this->_siteurl = $parsed['host'] . $parsed['path'];

		//Add the PORT if different from 80
		if ( isset( $parsed['port'] ) && $parsed['port'] <> 80 ) {
			$this->_siteurl = $parsed['host'] . ':' . $parsed['port'] . $parsed['path'];
		}

		//if multisite with subdomains, remove www. to change the paths in all dubdomains
		if( strpos( $this->_siteurl, 'www.' ) !== false && HMWP_Classes_Tools::isMultisites() && defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL ){
			$this->_siteurl = str_replace( 'www.', '', $this->_siteurl );
		}elseif ( strpos( $this->_siteurl, '//' ) === false ) {
			//if not www prefix, add // to the domain
			//don't add // when the www. is removed because it may not change the paths
			$this->_siteurl =  '//' . trim( $this->_siteurl, '/' );
		}
	}

	/**
	 * Get the blog URL with path & port
	 *
	 * @return string The host name + path (e.g. //domain.com/path)
	 */
	public function getSiteUrl() {
		return apply_filters( 'hmwp_root_site_url', $this->_siteurl );
	}

	/**
	 * Start the buffer listener
	 *
	 * @throws Exception
	 */
	public function startBuffer() {

		if ( apply_filters( 'hmwp_start_buffer', true ) ) {

			//start the buffer only for non files or 404 pages
			ob_start( array( $this, 'getBuffer' ) );

		}

	}

	/**
	 * Modify the output buffer
	 * Only text/html header types
	 *
	 * @param $buffer
	 *
	 * @return mixed
	 * @throws Exception
	 */
	public function getBuffer( $buffer ) {

		//If ajax call
		if ( HMWP_Classes_Tools::isAjax() ) {
			//if change the ajax paths
			if ( apply_filters( 'hmwp_process_buffer', true ) && HMWP_Classes_Tools::getOption( 'hmwp_hideajax_paths' ) ) {

				if ( ! HMWP_Classes_ObjController::getClass( 'HMWP_Models_Cookies' )->isLoggedInCookie() ) {
					//replace the buffer in Ajax
					$buffer = $this->find_replace( $buffer );
				}

			}

		} else {
			//////////////////////////////////////
			//Should the buffer be loaded
			if ( apply_filters( 'hmwp_process_buffer', true ) ) {

				//Don't run HMWP in these cases
				if ( HMWP_Classes_Tools::getOption( 'hmwp_mode' ) <> 'default' ) { //If it's not the disabled

					//If there is no buffer
					if ( strlen( $buffer ) < 255 ) {
						return $buffer;
					}

					//Check if other plugins already did the cache
					try {

						//If the content is HTML
						if ( HMWP_Classes_Tools::isContentHeader( array( 'text/html' ) ) ) {
							//If the user set to change the paths for logged users
							$buffer = $this->find_replace( $buffer );
						}

					} catch ( Exception $e ) {
						return $buffer;
					}
				}

			}
		}

		//Return the buffer to HTML
		return apply_filters( 'hmwp_buffer', $buffer );
	}

	/************************************
	 *
	 * BUID & FLUSH REWRITES
	 ****************************************/
	/**
	 * Prepare redirect build
	 *
	 * @return HMWP_Models_Rewrite
	 */
	public function clearRedirect() {
		HMWP_Classes_Tools::$options = HMWP_Classes_Tools::getOptions();
		$this->_replace              = array();

		return $this;
	}

	/**
	 * Build the array with find and replace
	 * Decide what goes to htaccess and not
	 *
	 * @return HMWP_Models_Rewrite
	 */
	public function buildRedirect() {
		if ( ! empty( $this->_replace ) ) {
			return $this;
		}

		add_action( 'home_url', array( $this, 'home_url' ), PHP_INT_MAX, 1 );

		if ( HMWP_Classes_Tools::getOption( 'hmwp_mode' ) <> 'default' ) {
			if ( HMWP_Classes_Tools::isMultisiteWithPath() ) {
				//get all blogs
				$this->paths = array();

				$blogs = get_sites( array(
					'number'  => 10000,
					'public'  => 1,
					'deleted' => 0,
				) );
				foreach ( $blogs as $blog ) {
					$this->paths[] = HMWP_Classes_Tools::getRelativePath( $blog->path );
				}
			}

			//Redirect the AJAX
			if ( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_admin-ajax_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_admin-ajax_url' ) && HMWP_Classes_Tools::getDefault( 'hmwp_admin-ajax_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_admin-ajax_url' ) ) {
				$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_admin-ajax_url' );
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_admin-ajax_url' );
				$this->_replace['rewrite'][] = true;

				$this->_replace['from'][]    = HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_admin-ajax_url' );
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_admin-ajax_url' );
				$this->_replace['rewrite'][] = false;
			}

			//Redirect the ADMIN
			if ( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) ) {
				$safeoptions = HMWP_Classes_Tools::getOptions( true );
				if ( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) <> $safeoptions['hmwp_admin_url'] ) {
					$this->_replace['from'][]    = "wp-admin" . '/';
					$this->_replace['to'][]      = $safeoptions['hmwp_admin_url'] . '/';
					$this->_replace['rewrite'][] = true;
				}
				if ( HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) <> $safeoptions['hmwp_admin_url'] ) {
					$this->_replace['from'][]    = "wp-admin" . '/';
					$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) . '/';
					$this->_replace['rewrite'][] = true;
				}
			}

			//Redirect the LOGIN
			if ( HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) ) {
				$this->_replace['from'][]    = "wp-login.php";
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_login_url' );
				$this->_replace['rewrite'][] = true;

				$this->_replace['from'][]    = "wp-login.php";
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) . '/';
				$this->_replace['rewrite'][] = true;
			}

			if ( HMWP_Classes_Tools::getOption( 'hmwp_lostpassword_url' ) <> '' ) {
				$this->_replace['from'][]    = HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) . "?action=lostpassword";
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_lostpassword_url' );
				$this->_replace['rewrite'][] = false;

				$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ) . "?action=lostpassword";
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_lostpassword_url' );
				$this->_replace['rewrite'][] = true;
			}

			if ( HMWP_Classes_Tools::getDefault( 'hmwp_activate_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_activate_url' ) ) {
				if ( HMWP_Classes_Tools::getOption( 'hmwp_activate_url' ) <> '' ) {
					$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_activate_url' );
					$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_activate_url' );
					$this->_replace['rewrite'][] = true;
				}
			}

			if ( HMWP_Classes_Tools::getOption( 'hmwp_register_url' ) <> '' ) {
				$this->_replace['from'][]    = HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) . "?action=register";
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_register_url' );
				$this->_replace['rewrite'][] = false;

				$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ) . "?action=register";
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_register_url' );
				$this->_replace['rewrite'][] = true;
			}

			if ( HMWP_Classes_Tools::getOption( 'hmwp_logout_url' ) <> '' ) {
				$this->_replace['from'][]    = HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) . "?action=logout";
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_logout_url' );
				$this->_replace['rewrite'][] = false;

				$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ) . "?action=logout";
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_logout_url' );
				$this->_replace['rewrite'][] = true;
			}

			//Modify plugins urls
			if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_plugins' ) ) {
				$all_plugins = HMWP_Classes_Tools::getOption( 'hmwp_plugins' );

				if ( ! empty( $all_plugins['to'] ) ) {
					foreach ( $all_plugins['to'] as $index => $plugin_path ) {
						if ( HMWP_Classes_Tools::isMultisiteWithPath() ) {
							foreach ( $this->paths as $path ) {
								$this->_replace['from'][]    = $path . HMWP_Classes_Tools::getDefault( 'hmwp_plugin_url' ) . '/' . $all_plugins['from'][ $index ];
								$this->_replace['to'][]      = $path . HMWP_Classes_Tools::getOption( 'hmwp_plugin_url' ) . '/' . $plugin_path . '/';
								$this->_replace['rewrite'][] = false;
							}
						}

						$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_plugin_url' ) . '/' . $all_plugins['from'][ $index ];
						$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_plugin_url' ) . '/' . $plugin_path . '/';
						$this->_replace['rewrite'][] = true;
					}
				}
			}
			//Modify plugins
			if ( HMWP_Classes_Tools::getDefault( 'hmwp_plugin_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_plugin_url' ) ) {
				if ( HMWP_Classes_Tools::isMultisiteWithPath() ) {
					foreach ( $this->paths as $path ) {
						$this->_replace['from'][]    = $path . HMWP_Classes_Tools::getDefault( 'hmwp_plugin_url' ) . '/';
						$this->_replace['to'][]      = $path . HMWP_Classes_Tools::getOption( 'hmwp_plugin_url' ) . '/';
						$this->_replace['rewrite'][] = false;
					}
				}
				$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_plugin_url' ) . '/';
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_plugin_url' ) . '/';
				$this->_replace['rewrite'][] = true;

			}

			//Modify themes urls
			if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_themes' ) ) {
				$all_themes = HMWP_Classes_Tools::getOption( 'hmwp_themes' );

				if ( ! empty( $all_themes['to'] ) ) {
					foreach ( $all_themes['to'] as $index => $theme_path ) {
						if ( HMWP_Classes_Tools::isMultisiteWithPath() ) {
							foreach ( $this->paths as $path ) {
								$this->_replace['from'][]    = $path . HMWP_Classes_Tools::getDefault( 'hmwp_wp-content_url' ) . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_themes_url' ) . '/' . $all_themes['from'][ $index ];
								$this->_replace['to'][]      = $path . HMWP_Classes_Tools::getOption( 'hmwp_themes_url' ) . '/' . $theme_path . '/';
								$this->_replace['rewrite'][] = false;

								$this->_replace['from'][]    = $path . HMWP_Classes_Tools::getDefault( 'hmwp_wp-content_url' ) . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_themes_url' ) . '/' . $all_themes['from'][ $index ] . HMWP_Classes_Tools::getDefault( 'hmwp_themes_style' );
								$this->_replace['to'][]      = $path . HMWP_Classes_Tools::getOption( 'hmwp_themes_url' ) . '/' . $theme_path . '/' . HMWP_Classes_Tools::getOption( 'hmwp_themes_style' );
								$this->_replace['rewrite'][] = false;
							}
						}


						if ( HMWP_Classes_Tools::getDefault( 'hmwp_themes_style' ) <> HMWP_Classes_Tools::getOption( 'hmwp_themes_style' ) ) {
							$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_wp-content_url' ) . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_themes_url' ) . '/' . $all_themes['from'][ $index ] . HMWP_Classes_Tools::getDefault( 'hmwp_themes_style' );
							$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_themes_url' ) . '/' . $theme_path . '/' . HMWP_Classes_Tools::getOption( 'hmwp_themes_style' );
							$this->_replace['rewrite'][] = true;

							$this->_replace['from'][]    = HMWP_Classes_Tools::getOption( 'hmwp_themes_url' ) . '/' . $theme_path . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_themes_style' );
							$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_themes_url' ) . '/' . $theme_path . '/' . HMWP_Classes_Tools::getOption( 'hmwp_themes_style' );
							$this->_replace['rewrite'][] = false;
						}

						$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_wp-content_url' ) . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_themes_url' ) . '/' . $all_themes['from'][ $index ];
						$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_themes_url' ) . '/' . $theme_path . '/';
						$this->_replace['rewrite'][] = true;
					}

				}
			}

			//Modify theme URL
			if ( HMWP_Classes_Tools::getDefault( 'hmwp_themes_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_themes_url' ) ) {
				if ( HMWP_Classes_Tools::isMultisiteWithPath() ) {
					foreach ( $this->paths as $path ) {
						$this->_replace['from'][]    = $path . HMWP_Classes_Tools::getDefault( 'hmwp_wp-content_url' ) . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_themes_url' ) . '/';
						$this->_replace['to'][]      = $path . HMWP_Classes_Tools::getOption( 'hmwp_themes_url' ) . '/';
						$this->_replace['rewrite'][] = false;
					}
				}

				$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_wp-content_url' ) . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_themes_url' ) . '/';
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_themes_url' ) . '/';
				$this->_replace['rewrite'][] = true;

			}

			//Modify uploads
			if ( ! HMWP_Classes_Tools::isDifferentUploadPath() ) {
				if ( HMWP_Classes_Tools::getDefault( 'hmwp_upload_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_upload_url' ) ) {
					if ( HMWP_Classes_Tools::isMultisiteWithPath() ) {
						foreach ( $this->paths as $path ) {
							$this->_replace['from'][]    = $path . HMWP_Classes_Tools::getDefault( 'hmwp_wp-content_url' ) . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_upload_url' ) . '/';
							$this->_replace['to'][]      = $path . HMWP_Classes_Tools::getOption( 'hmwp_upload_url' ) . '/';
							$this->_replace['rewrite'][] = false;
						}
					}

					$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_wp-content_url' ) . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_upload_url' ) . '/';
					$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_upload_url' ) . '/';
					$this->_replace['rewrite'][] = true;

				}
			}

			//Modify hmwp_wp-content_url
			if ( HMWP_Classes_Tools::getDefault( 'hmwp_wp-content_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_wp-content_url' ) ) {
				if ( HMWP_Classes_Tools::isMultisiteWithPath() ) {
					foreach ( $this->paths as $path ) {
						$this->_replace['from'][]    = $path . HMWP_Classes_Tools::getDefault( 'hmwp_wp-content_url' ) . '/';
						$this->_replace['to'][]      = $path . HMWP_Classes_Tools::getOption( 'hmwp_wp-content_url' ) . '/';
						$this->_replace['rewrite'][] = false;
					}
				}

				$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_wp-content_url' ) . '/';
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_wp-content_url' ) . '/';
				$this->_replace['rewrite'][] = true;
			}

			//Modify hmwp_wp-includes_url
			if ( HMWP_Classes_Tools::getDefault( 'hmwp_wp-includes_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_wp-includes_url' ) ) {
				if ( HMWP_Classes_Tools::isMultisiteWithPath() ) {
					foreach ( $this->paths as $path ) {
						$this->_replace['from'][]    = $path . HMWP_Classes_Tools::getDefault( 'hmwp_wp-includes_url' ) . '/';
						$this->_replace['to'][]      = $path . HMWP_Classes_Tools::getOption( 'hmwp_wp-includes_url' ) . '/';
						$this->_replace['rewrite'][] = false;
					}
				}

				$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_wp-includes_url' ) . '/';
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_wp-includes_url' ) . '/';
				$this->_replace['rewrite'][] = true;

			}

			//Modify wp-comments-post
			if ( HMWP_Classes_Tools::getDefault( 'hmwp_wp-comments-post' ) <> HMWP_Classes_Tools::getOption( 'hmwp_wp-comments-post' ) ) {
				$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_wp-comments-post' );
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_wp-comments-post' ) . '/';
				$this->_replace['rewrite'][] = true;
			}

			//Modify the author link
			if ( HMWP_Classes_Tools::getDefault( 'hmwp_author_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_author_url' ) ) {
				$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_author_url' ) . '/';
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_author_url' ) . '/';
				$this->_replace['rewrite'][] = true;
			}


			if ( HMWP_Classes_Tools::getDefault( 'hmwp_wp-json' ) <> HMWP_Classes_Tools::getOption( 'hmwp_wp-json' ) ) {
				$this->_replace['from'][]    = HMWP_Classes_Tools::getDefault( 'hmwp_wp-json' ) . '/';
				$this->_replace['to'][]      = HMWP_Classes_Tools::getOption( 'hmwp_wp-json' ) . '/';
				$this->_replace['rewrite'][] = true;
			}

		}

		return $this;

	}

	/**
	 * Rename all the plugin names with a hash
	 */
	public function hidePluginNames() {
		$dbplugins = array();

		try {
			// Get the list of plugins
			$all_plugins = HMWP_Classes_Tools::getAllPlugins();

			foreach ( $all_plugins as $plugin ) {
				$dbplugins['to'][]   = substr( md5( $plugin ), 0, 10 );
				$dbplugins['from'][] = str_replace( ' ', '+', plugin_dir_path( $plugin ) );
			}
		} catch ( Exception $e ) {
		}

		HMWP_Classes_Tools::saveOptions( 'hmwp_plugins', $dbplugins );
	}

	/**
	 * Rename all the themes name with a hash
	 */
	public function hideThemeNames() {
		$dbthemes = array();

		// Initialize WordPress Filesystem
		$wp_filesystem = HMWP_Classes_ObjController::initFilesystem();

		// Get the list of themes
		$all_themes = HMWP_Classes_Tools::getAllThemes();

		foreach ( $all_themes as $theme => $value ) {

			if ( $wp_filesystem->is_dir( $value['theme_root'] ) ) {
				$dbthemes['to'][]   = substr( md5( $theme ), 0, 10 );
				$dbthemes['from'][] = str_replace( ' ', '+', $theme ) . '/';
			}
		}

		HMWP_Classes_Tools::saveOptions( 'hmwp_themes', $dbthemes );
	}

	/**
	 * ADMIN_PATH is the new path and set in /config.php
	 *
	 * @return $this
	 * @throws Exception
	 */
	public function setRewriteRules() {
		$this->_rewrites   = array();
		$this->_umrewrites = array();
		include_once ABSPATH . 'wp-admin/includes/misc.php';
		include_once ABSPATH . 'wp-admin/includes/file.php';

		$home_root = HMWP_Classes_Tools::getHomeRootPath();

		//Build the redirects
		$this->buildRedirect();

		if ( ! empty( $this->_replace ) ) {
			//form the IIS rewrite call getIISRules
			if ( HMWP_Classes_Tools::isIIS() ) {

				add_filter( 'hmwp_iis_hide_files_rules', array(
					HMWP_Classes_ObjController::getClass( 'HMWP_Models_Rules' ),
					'getInjectionRewrite'
				) );

				//HIDE OLD PATHS RULES
				//If hmwp_hide_oldpaths do also the htaccess rewrite
				if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_oldpaths' ) || HMWP_Classes_Tools::getOption( 'hmwp_hide_commonfiles' ) ) {
					add_filter( 'hmwp_iis_hide_paths_rules', array(
						HMWP_Classes_ObjController::getClass( 'HMWP_Models_Rules' ),
						'getHideOldPathRewrite'
					), 9 );
				}

				add_filter( 'iis7_url_rewrite_rules', array(
					$this,
					'getIISRules'
				) );

			} else {
				//URL Mapping
				$hmwp_url_mapping = json_decode( HMWP_Classes_Tools::getOption( 'hmwp_url_mapping' ), true );
				if ( isset( $hmwp_url_mapping['from'] ) && ! empty( $hmwp_url_mapping['from'] ) ) {
					foreach ( $hmwp_url_mapping['from'] as $index => $row ) {
						if ( substr( $hmwp_url_mapping['from'][ $index ], - 1 ) == '/' ) {
							$this->_umrewrites[] = array(
								'from' => '([_0-9a-zA-Z-]+/)?' . str_replace( home_url() . '/', '', ltrim( $hmwp_url_mapping['to'][ $index ], '/' ) ) . '(.*)',
								'to'   => $home_root . str_replace( home_url() . '/', '', ltrim( $hmwp_url_mapping['from'][ $index ], '/' ) ) . "$" . ( substr_count( $hmwp_url_mapping['from'][ $index ], '(' ) + 2 ),
							);
						} else {
							$this->_umrewrites[] = array(
								'from' => '([_0-9a-zA-Z-]+/)?' . str_replace( home_url() . '/', '', ltrim( $hmwp_url_mapping['to'][ $index ], '/' ) ) . '$',
								'to'   => $home_root . str_replace( home_url() . '/', '', ltrim( $hmwp_url_mapping['from'][ $index ], '/' ) ),
							);
						}
					}
				}

				if ( HMW_RULES_IN_CONFIG ) { //if set to add the HMW rules into config file

					foreach ( $this->_replace['to'] as $key => $row ) {
						if ( $this->_replace['rewrite'][ $key ] ) {
							if ( HMWP_Classes_Tools::isDifferentWPContentPath() && strpos( $this->_replace['from'][ $key ], HMWP_Classes_Tools::getDefault( 'hmwp_wp-content_url' ) ) !== false ) {
								$this->_rewrites[] = array(
									'from' => '([_0-9a-zA-Z-]+/)?' . $this->_replace['to'][ $key ] . ( substr( $this->_replace['to'][ $key ], - 1 ) == '/' ? "(.*)" : "$" ),
									'to'   => '/' . $this->_replace['from'][ $key ] . ( substr( $this->_replace['to'][ $key ], - 1 ) == '/' ? "$" . ( substr_count( $this->_replace['to'][ $key ], '(' ) + 2 ) : "" ),
								);
							} else {
								$this->_rewrites[] = array(
									'from' => '([_0-9a-zA-Z-]+/)?' . $this->_replace['to'][ $key ] . ( substr( $this->_replace['to'][ $key ], - 1 ) == '/' ? "(.*)" : "$" ),
									'to'   => $home_root . $this->_replace['from'][ $key ] . ( substr( $this->_replace['to'][ $key ], - 1 ) == '/' ? "$" . ( substr_count( $this->_replace['to'][ $key ], '(' ) + 2 ) : "" ),
								);
							}
						}
					}
				}

				if ( HMWP_Classes_Tools::getOption( 'hmwp_rewrites_in_wp_rules' ) ) {//if set to add the HMW rules into WP rules area
					foreach ( $this->_rewrites as $rewrite ) {

						if ( substr( $rewrite['to'], 0, strlen( $home_root ) ) === $home_root ) {
							$rewrite['to'] = substr( $rewrite['to'], strlen( $home_root ) );
						}

						add_rewrite_rule( $rewrite['from'], $rewrite['to'], 'top' );
					}
				}
			}
		}

		//Hook the rewrites rules
		$this->_umrewrites = apply_filters( 'hmwp_umrewrites', $this->_umrewrites );
		$this->_rewrites   = apply_filters( 'hmwp_rewrites', $this->_rewrites );

		return $this;
	}

	/********
	 *
	 * IIS
	 **********/
	/**
	 * @param string $wrules
	 *
	 * @return string
	 */
	public function getIISRules( $wrules ) {
		$rules    = '';
		$rewrites = array();

		$rules .= apply_filters( 'hmwp_iis_hide_paths_rules', false );
		$rules .= apply_filters( 'hmwp_iis_hide_files_rules', false );

		//////////////IIS URL MAPPING
		$hmwp_url_mapping = json_decode( HMWP_Classes_Tools::getOption( 'hmwp_url_mapping' ), true );
		if ( isset( $hmwp_url_mapping['from'] ) && ! empty( $hmwp_url_mapping['from'] ) ) {
			foreach ( $hmwp_url_mapping['from'] as $index => $row ) {
				if ( substr( $hmwp_url_mapping['from'][ $index ], - 1 ) == '/' ) {
					$rewrites[] = array(
						'from' => '([_0-9a-zA-Z-]+/)?' . str_replace( array( home_url() . '/' ), '', $hmwp_url_mapping['to'][ $index ] ) . '(.*)',
						'to'   => str_replace( array( home_url() . '/' ), '', $hmwp_url_mapping['from'][ $index ] ) . "{R:" . ( substr_count( $hmwp_url_mapping['from'][ $index ], '(' ) + 2 ) . '}',
					);
				} else {
					$rewrites[] = array(
						'from' => '([_0-9a-zA-Z-]+/)?' . str_replace( array( home_url() . '/' ), '', $hmwp_url_mapping['to'][ $index ] ) . '$',
						'to'   => str_replace( array( home_url() . '/' ), '', $hmwp_url_mapping['from'][ $index ] ),
					);
				}
			}
		}

		if ( ! empty( $rewrites ) ) {
			foreach ( $rewrites as $rewrite ) {
				if ( strpos( $rewrite['to'], 'index.php' ) === false ) {
					$rules .= '
                <rule name="WpGhost: ' . md5( $rewrite['from'] ) . '" stopProcessing="false">
                    <match url="^' . $rewrite['from'] . '" ignoreCase="false" />
                    <action type="Redirect" url="' . $rewrite['to'] . '" />
                </rule>';
				}
			}
		}

		////////////////// IIS PATH CHANGING RULES
		$rewrites = array();

		if ( ! empty( $this->_replace ) ) {
			foreach ( $this->_replace['to'] as $key => $row ) {
				if ( $this->_replace['rewrite'][ $key ] ) {
					$rewrites[] = array(
						'from' => '([_0-9a-zA-Z-]+/)?' . $this->_replace['to'][ $key ] . ( substr( $this->_replace['to'][ $key ], - 1 ) == '/' ? "(.*)" : "$" ),
						'to'   => $this->_replace['from'][ $key ] . ( substr( $this->_replace['to'][ $key ], - 1 ) == '/' ? "{R:" . ( substr_count( $this->_replace['to'][ $key ], '(' ) + 2 ) . '}' : '' ),
					);
				}
			}
		}

		if ( ! empty( $rewrites ) ) {
			foreach ( $rewrites as $rewrite ) {
				if ( strpos( $rewrite['to'], 'index.php' ) === false ) {
					$rules .= '
                <rule name="WpGhost: ' . md5( $rewrite['from'] ) . '" stopProcessing="true">
                    <match url="^' . $rewrite['from'] . '" ignoreCase="false" />
                    <action type="Rewrite" url="' . $rewrite['to'] . '" />
                </rule>';
				}
			}
		}

		return $rules . $wrules;
	}

	/**
	 * Get Lavarage Cache for IIS
	 *
	 * @return string
	 */
	public function getIISCacheRules() {
		return '
    <httpProtocol>
          <customHeaders>
            <add name="Cache-Control" value="max-age=300, must-revalidate" />
            <remove name="Vary"/>
            <add name="Vary" value="Accept-Encoding"/>
          </customHeaders>
    </httpProtocol>
    <staticContent>
       <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="365.00:00:00"/>
    </staticContent>';

	}

	/**
	 * @param $config_file
	 *
	 * @throws Exception
	 */
	public function deleteIISRules( $config_file ) {

		//Initialize WordPress Filesystem
		$wp_filesystem = HMWP_Classes_ObjController::initFilesystem();

		// If configuration file does not exist then rules also do not exist so there is nothing to delete
		if ( ! $wp_filesystem->exists( $config_file ) ) {
			return;
		}

		if ( $wp_filesystem->get_contents( $config_file ) == '' ) {
			return;
		}

		if ( ! class_exists( 'DOMDocument', false ) ) {
			return;
		}

		if ( ! HMWP_Classes_ObjController::getClass( 'HMWP_Models_Rules' )->isConfigWritable() ) {
			return;
		}

		$doc                     = new DOMDocument();
		$doc->preserveWhiteSpace = false;

		if ( $doc->load( $config_file ) === false ) {
			return;
		}

		$xpath = new DOMXPath( $doc );

		$rules = $xpath->query( '/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'WpGhost\')]' );

		if ( $rules->length > 0 ) {
			foreach ( $rules as $item ) {
				$parent = $item->parentNode;
				if ( method_exists( $parent, 'removeChild' ) ) {
					$parent->removeChild( $item );
				}
			}
		}

		$rules = $xpath->query( '/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'WPGhost\')]' );

		if ( $rules->length > 0 ) {
			foreach ( $rules as $item ) {
				$parent = $item->parentNode;
				if ( method_exists( $parent, 'removeChild' ) ) {
					$parent->removeChild( $item );
				}
			}
		}

		if ( ! HMWP_Classes_Tools::isMultisites() ) {
			$rules = $xpath->query( '/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'wordpress\')] | /configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'WordPress\')]' );

			if ( $rules->length > 0 ) {
				foreach ( $rules as $item ) {

					$parent = $item->parentNode;
					if ( method_exists( $parent, 'removeChild' ) ) {
						$parent->removeChild( $item );
					}
				}
			}
		}

		$doc->formatOutput = true;
		saveDomDocument( $doc, $config_file );

	}
	/***************************/

	/**
	 * Flush the Rules and write in htaccess or web.config
	 *
	 * @return bool
	 * @throws Exception
	 */
	public function flushRewrites() {
		$rewritecode = '';

		$home_root = HMWP_Classes_Tools::getHomeRootPath();

		$config_file = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Rules' )->getConfFile();

		$form = '<a href="' . esc_url( add_query_arg( array( 'hmwp_nonce' => wp_create_nonce( 'hmwp_manualrewrite' ), 'action'     => 'hmwp_manualrewrite' ) ) ) . '" class="btn rounded-0 btn-success save" />' . esc_html__( "Okay, I set it up", 'hide-my-wp' ) . '</a>';


		//If Windows Server
		if ( HMWP_Classes_Tools::isIIS() ) {
			$this->deleteIISRules( $config_file );
			if ( ! iis7_save_url_rewrite_rules() ) {
				$rewritecode .= $this->getIISRules( '' );

				if ( $rewritecode <> '' ) {
					/* translators: 1: Config file path wrapped in <strong> tags, 2: Preformatted rewrite rules block and form HTML. */
					HMWP_Classes_Error::setNotification( wp_kses_post( sprintf( __( 'IIS detected. You need to update your %1$s file by adding the following lines after &lt;rules&gt; tag: %2$s', 'hide-my-wp' ), '<strong>' . esc_html( $config_file ) . '</strong>', '<br /><br /><pre>' . esc_html( str_replace( '    ', ' ', $rewritecode ) ) . '</pre>' . $form ) ), 'notice', false );
					return false; //Always show IIS as manuall action
				}

			}
		} elseif ( HMWP_Classes_Tools::isWpengine() ) {
			$success = true;
			$rewritecode = '';
			$bulkrules = '';

			//Add the New Paths rules
			if ( ! empty( $this->_rewrites ) ) {
				foreach ( $this->_rewrites as $rewrite ) {
					if ( strpos( $rewrite['to'], 'wp-login.php' ) === false ) {
						if ( strpos( $rewrite['from'], '$' ) !== false ) {
							$rewritecode .= 'Source: <strong>^/' . str_replace( '$', '(.*)', $rewrite['from'] ) . '</strong> Destination: <strong>' . $rewrite['to'] . "$" . ( substr_count( $rewrite['from'], '(' ) + 1 ) . "</strong> (Internal Rule)<br />";
							$bulkrules .= '^/' . str_replace( '$', '(.*)', $rewrite['from'] ) . ' ' . $rewrite['to'] . "$" . ( substr_count( $rewrite['from'], '(' ) + 1 ) . "\n";
						}else{
							$rewritecode .= 'Source: <strong>^/' . $rewrite['from'] . '</strong> Destination: <strong>' . $rewrite['to'] . "</strong> (Internal Rule)<br />";
							$bulkrules .= '^/' . $rewrite['from'] . ' ' . $rewrite['to'] . "\n";
						}
					}
				}
			}

			if ( $rewritecode <> '' ) {
				$form .= '<button id="copyBulkRules" class="btn rounded-0 btn-default hmwp_clipboard_copy ml-2" data-clipboard-text="' . $bulkrules . '">' . esc_html__('Copy Bulk Rules', 'hide-my-wp') . '</button>';
				/* translators: 1: Opening <strong><a> tag with tutorial link and label, 2: Closing </a></strong> tag, 3: Rewrite rules block and form HTML. */
				HMWP_Classes_Error::setNotification( wp_kses_post( sprintf( __( 'WPEngine detected. Add the redirects in the Web Rules Engine %1$s', 'hide-my-wp' ), '<strong><a href="' . esc_url( 'https://wpengine.com/support/web-rules-engine/' ) . '" target="_blank" style="color: red">' . esc_html__( 'Learn How To Add the Rules', 'hide-my-wp' ) . '</a></strong> <br /><br /><pre>' . $rewritecode . '</pre>' . $form ) ), 'notice', false ); //phpcs:ignore
				$success = false; //always show the WPEngine Rules as manual action
			}

			return $success;
		} elseif ( HMWP_Classes_Tools::isFlywheel() ) {
			$success = true;

			//Add the URL Mapping rules
			if ( ! empty( $this->_umrewrites ) ) {
				foreach ( $this->_umrewrites as $rewrite ) {
					$rewritecode .= 'Source: <strong>^' . str_replace( array('.css','.js'), array('\.css','\.js'), $rewrite['from'] ) . '</strong> Destination: <strong>' . $rewrite['to'] . "</strong> Rewrite type: <strong>301 Permanent</strong>;<br />";
				}
			}

			//Add the New Paths rules
			if ( ! empty( $this->_rewrites ) ) {
				foreach ( $this->_rewrites as $rewrite ) {
					if ( strpos( $rewrite['to'], 'wp-login.php' ) === false ) {
						$rewritecode .= 'Source: <strong>^/' . str_replace( array('.css','.js'), array('\.css','\.js'), $rewrite['from'] ) . '</strong> Destination: <strong>' . $rewrite['to'] . "</strong> Rewrite type: <strong>Break</strong>;<br />";
					}
				}
			}

			if ( $rewritecode <> '' ) {
				/* translators: 1: Opening <strong><a> tag with tutorial link and label, 2: Closing </a></strong> tag, 3: Rewrite rules block and form HTML. */
				HMWP_Classes_Error::setNotification( wp_kses_post( sprintf( __( 'Flywheel detected. Add the redirects in the Flywheel Redirect rules panel %1$s.', 'hide-my-wp' ), '<strong><a href="' . esc_url( HMWP_Classes_Tools::getOption( 'hmwp_plugin_website' ) . '/kb/flywheel-server-wp-ghost-setup/' ) ) . '" target="_blank" style="color: red">' . esc_html__( 'Learn How To Add the Code', 'hide-my-wp' ) . '</a></strong> <br /><br /><pre>' . $rewritecode . '</pre>' . $form ) , 'notice', false ); //phpcs:ignore
				$success = false; //always show the Flywheel Rules as manually action
			}

			return $success;
		} elseif ( ( HMWP_Classes_Tools::isApache() || HMWP_Classes_Tools::isLitespeed() ) ) {
			//if there are no rewrites, return true
			if ( ! empty( $this->_rewrites ) ) {

				if ( HMW_DYNAMIC_FILES || ( HMWP_Classes_Tools::getOption( 'hmwp_mapping_text_show' ) && HMWP_Classes_Tools::getOption( 'hmwp_mapping_file' ) ) ) {
                    $rewritecode .= "<IfModule mod_rewrite.c>" . PHP_EOL;
                    $rewritecode .= "RewriteEngine On" . PHP_EOL;
                    $rewritecode .= "RewriteCond %{HTTP:Cookie} !(wordpress_logged_in_|" . HMWP_LOGGED_IN_COOKIE . ") [NC]" . PHP_EOL;
                    $rewritecode .= "RewriteCond %{REQUEST_URI} ^" . $home_root . HMWP_Classes_Tools::getOption( 'hmwp_wp-content_url' ) . "/[^\.]+\.[^\.]+ [NC,OR]" . PHP_EOL;
                    $rewritecode .= "RewriteCond %{REQUEST_URI} ^" . $home_root . HMWP_Classes_Tools::getOption( 'hmwp_wp-includes_url' ) . "/[^\.]+\.[^\.]+ [NC,OR]" . PHP_EOL;
                    $rewritecode .= "RewriteCond %{REQUEST_URI} ^" . $home_root . HMWP_Classes_Tools::getOption( 'hmwp_upload_url' ) . "/[^\.]+\.[^\.]+ [NC]" . PHP_EOL;
                    $rewritecode .= "RewriteRule ^([_0-9a-zA-Z-]+/)?(.*)\.(js|css|scss)$ index.php?hmwp_url=" . $home_root . "$1$2.$3" . " [QSA,L]" . PHP_EOL;
                    $rewritecode .= "</IfModule>" . PHP_EOL;
                }

				if ( HMWP_Classes_Tools::getOption( 'hmwp_file_cache' ) ) {
					$rewritecode .= '<IfModule mod_expires.c>' . PHP_EOL;
					$rewritecode .= 'ExpiresActive On' . PHP_EOL;
					$rewritecode .= 'ExpiresDefault "access plus 1 month"' . PHP_EOL;
					$rewritecode .= '# Feed' . PHP_EOL;
					$rewritecode .= 'ExpiresByType application/rss+xml "access plus 1 hour"' . PHP_EOL;
					$rewritecode .= 'ExpiresByType application/atom+xml "access plus 1 hour"' . PHP_EOL;
					$rewritecode .= '# CSS, JavaScript' . PHP_EOL;
					$rewritecode .= 'ExpiresByType text/css "access plus 1 year"' . PHP_EOL;
					$rewritecode .= 'ExpiresByType text/javascript "access plus 1 year"' . PHP_EOL;
					$rewritecode .= 'ExpiresByType application/javascript "access plus 1 year"' . PHP_EOL . PHP_EOL;
					$rewritecode .= '# Webfonts' . PHP_EOL;
					$rewritecode .= 'ExpiresByType font/ttf "access plus 1 year"' . PHP_EOL;
					$rewritecode .= 'ExpiresByType font/otf "access plus 1 year"' . PHP_EOL;
					$rewritecode .= 'ExpiresByType font/woff "access plus 1 year"' . PHP_EOL;
					$rewritecode .= 'ExpiresByType font/woff2 "access plus 1 year"' . PHP_EOL;
					$rewritecode .= 'ExpiresByType application/vnd.ms-fontobject "access plus 1 year"' . PHP_EOL . PHP_EOL;
					$rewritecode .= '# Images' . PHP_EOL;
					$rewritecode .= 'ExpiresByType image/jpeg "access plus 1 year"' . PHP_EOL;
					$rewritecode .= 'ExpiresByType image/gif "access plus 1 year"' . PHP_EOL;
					$rewritecode .= 'ExpiresByType image/png "access plus 1 year"' . PHP_EOL;
					$rewritecode .= 'ExpiresByType image/webp "access plus 1 year"' . PHP_EOL;
					$rewritecode .= 'ExpiresByType image/svg+xml "access plus 1 year"' . PHP_EOL;
					$rewritecode .= 'ExpiresByType image/x-icon "access plus 1 year"' . PHP_EOL . PHP_EOL;
					$rewritecode .= '# Video' . PHP_EOL;
					$rewritecode .= 'ExpiresByType video/mp4 "access plus 1 year"' . PHP_EOL;
					$rewritecode .= 'ExpiresByType video/mpeg "access plus 1 year"' . PHP_EOL;
					$rewritecode .= 'ExpiresByType video/webm "access plus 1 year"' . PHP_EOL;
					$rewritecode .= "</IfModule>" . PHP_EOL;
				}

				$rewritecode .= "<IfModule mod_rewrite.c>" . PHP_EOL;
				$rewritecode .= "RewriteEngine On" . PHP_EOL;

				//Add the URL Mapping rules
				if ( ! empty( $this->_umrewrites ) ) {
					foreach ( $this->_umrewrites as $rewrite ) {
						$rewritecode .= 'RewriteRule ^' . $rewrite['from'] . ' ' . $rewrite['to'] . " [QSA,NC,L]" . PHP_EOL;
					}
				}

				//Add the New Paths rules
				foreach ( $this->_rewrites as $rewrite ) {
					if ( strpos( $rewrite['to'], 'index.php' ) === false ) {
						$rewritecode .= 'RewriteRule ^' . $rewrite['from'] . ' ' . $rewrite['to'] . " [QSA,NC,L]" . PHP_EOL;
					}
				}
				$rewritecode .= "</IfModule>" . PHP_EOL ;

			}

			if ( $rewritecode <> '' ) {
				if ( ! HMWP_Classes_ObjController::getClass( 'HMWP_Models_Rules' )->writeInHtaccess( $rewritecode, 'HMWP_RULES' ) ) {
					/* translators: 1: Config file path wrapped in <strong> tags, 2: Preformatted rewrite rules block followed by form HTML. */
					HMWP_Classes_Error::setNotification( wp_kses_post( sprintf( __( 'Config file is not writable. Create the file if not exists or copy to %1$s file the following lines: %2$s', 'hide-my-wp' ), '<strong>' . esc_html( $config_file ) . '</strong>', '<br /><br /><pre># BEGIN HMWP_RULES<br />' . str_replace( '    ', ' ', $rewritecode ) . '# END HMWP_RULES</pre>' . $form ) ), 'notice', false ); //phpcs:ignore
					return false;
				}
			} else {
				HMWP_Classes_ObjController::getClass( 'HMWP_Models_Rules' )->writeInHtaccess( '', 'HMWP_RULES' );
			}

		} elseif ( HMWP_Classes_Tools::isNginx() ) {
			$cachecode = '';
			//if there are no rewrites, return true
			if ( ! empty( $this->_rewrites ) ) {

				if ( HMW_DYNAMIC_FILES || ( HMWP_Classes_Tools::getOption( 'hmwp_mapping_text_show' ) && HMWP_Classes_Tools::getOption( 'hmwp_mapping_file' ) ) ) {
                    $cachecode .= 'set $cond "";' . PHP_EOL;
                    $cachecode .= 'if ($http_cookie !~* "wordpress_logged_in_|' . HMWP_LOGGED_IN_COOKIE . '" ) {  set $cond cookie; }' . PHP_EOL;
                    $cachecode .= 'if ($request_uri ~* ^' . $home_root . HMWP_Classes_Tools::getOption( 'hmwp_wp-content_url' ) . '/[^\.]+\.[^\.]+) { set $cond "${cond}+redirect_uri"; }' . PHP_EOL;
                    $cachecode .= 'if ($request_uri ~* ^' . $home_root . HMWP_Classes_Tools::getOption( 'hmwp_wp-includes_url' ) . '/[^\.]+\.[^\.]+) { set $cond "${cond}+redirect_uri"; }' . PHP_EOL;
                    $cachecode .= 'if ($request_uri ~* ^' . $home_root . HMWP_Classes_Tools::getOption( 'hmwp_upload_url' ) . '/[^\.]+\.[^\.]+) { set $cond "${cond}+redirect_uri"; }' . PHP_EOL;
                    $cachecode .= 'if ($cond = "cookie+redirect_uri") {  rewrite ^/([_0-9a-zA-Z-]+/)?(.*)\.(js|css|scss)$ index.php?hmwp_url=/$1$2.$3 last; } ' . PHP_EOL . PHP_EOL;
                }

				if ( HMWP_Classes_Tools::getOption( 'hmwp_file_cache' ) ) {
					$cachecode .= 'location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {' . PHP_EOL;
					$cachecode .= 'expires 365d;' . PHP_EOL;
					$cachecode .= 'add_header Pragma public;' . PHP_EOL;
					$cachecode .= 'add_header Cache-Control "public";' . PHP_EOL;
					$cachecode .= '}' . PHP_EOL . PHP_EOL;
				}

				//Add the URL Mapping rules
				if ( ! empty( $this->_umrewrites ) ) {
					foreach ( $this->_umrewrites as $rewrite ) {
						$rewritecode .= 'rewrite ^/' . $rewrite['from'] . ' ' . $rewrite['to'] . ";<br />";
					}
				}

				//Add the New Paths rules
				foreach ( $this->_rewrites as $rewrite ) {

					//most servers have issue when redirecting the login path
					//let HMWP handle the login path
					if ( strpos( $rewrite['to'], 'wp-login.php' ) !== false ) {
						if ( ! defined( 'HMW_LOGIN_REWRITE_RULES' ) || ! HMW_LOGIN_REWRITE_RULES ) {
							continue;
						}
					}

					if ( strpos( $rewrite['to'], 'index.php' ) === false ) {
						if ( strpos( $rewrite['from'], '$' ) ) {
							$rewritecode .= 'rewrite ^/' . $rewrite['from'] . ' ' . $rewrite['to'] . ";<br />";
						} else {
							$rewritecode .= 'rewrite ^/' . $rewrite['from'] . ' ' . $rewrite['to'] . " last;<br />";
						}
					}
				}
			}

			if ( $rewritecode <> '' ) {
				$rewritecode = str_replace( '<br />', "\n", $rewritecode );
				$rewritecode = $cachecode . 'if (!-e $request_filename) {' . PHP_EOL . $rewritecode . '}';

				if ( ! HMWP_Classes_ObjController::getClass( 'HMWP_Models_Rules' )->writeInNginx( $rewritecode, 'HMWP_RULES' ) ) {
					/* translators: 1: Config file path wrapped in <strong> tags, 2: Preformatted rewrite rules block. */
					HMWP_Classes_Error::setNotification( wp_kses_post( sprintf( __( 'Config file is not writable. You have to added it manually at the beginning of the %1$s file: %2$s', 'hide-my-wp' ), '<strong>' . esc_html( $config_file ) . '</strong>', '<br /><br /><pre># BEGIN HMWP_RULES<br />' . str_replace( '    ', ' ', $rewritecode ) . '# END HMWP_RULES</pre>' ) ), 'notice', false ); //phpcs:ignore
					return false;
				}

			} else {
				HMWP_Classes_ObjController::getClass( 'HMWP_Models_Rules' )->writeInNginx( '', 'HMWP_RULES' );
			}
		}

		return true;
	}

	/**
	 * Not used yet
	 *
	 * @param $wp_rewrite
	 *
	 * @return mixed
	 */
	public function setRewriteIndexRules( $wp_rewrite ) {
		return $wp_rewrite;
	}

	/**
	 * Flush the changes in htaccess
	 *
	 * @throws Exception
	 */
	public function flushChanges() {

		if ( ! did_action( 'wp_loaded' ) ) {
			add_action( 'wp_loaded', array( $this, 'flushChanges' ) );
		}

		//Build the redirect table
		$this->clearRedirect()->setRewriteRules()->flushRewrites();

		//Change the rest api for the rewrite process
		add_filter( 'rest_url_prefix', array( $this, 'replace_rest_api' ) );

		//update the API URL
		rest_api_register_rewrites();

		//Flush the rules in WordPress
		flush_rewrite_rules();

		//Hook the flush process for compatibillity usage
		do_action( 'hmwp_flushed_rewrites', false );

	}

	/**
	 * Add the custom param vars for: disable HMWP and admin tabs
	 *
	 * @param $vars
	 *
	 * @return array
	 */
	public function addParams( $vars ) {
		$vars[] = HMWP_Classes_Tools::getOption( 'hmwp_disable_name' );

		return $vars;
	}

	/*******************************
	 *
	 * RENAME URLS
	 **************************************************/

	/**
	 * Filters the home URL.
	 *
	 * @param string $url The complete site URL including scheme and path.
	 * @param string $path Path relative to the site URL. Blank string if no path is specified.
	 * @param string|null $scheme Scheme to give the site URL context. Accepts 'http', 'https', 'login',
	 *                             'login_post', 'admin', 'relative' or null.
	 * @param int|null $blog_id Site ID, or null for the current site.
	 */
	public function home_url( $url, $path = '', $scheme = null ) {

		if ( ! apply_filters( 'hmwp_change_home_url', true ) ) {
			return $url;
		}

		if ( ! isset( $scheme ) ) {
			$scheme = ( ( ( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] == "on" ) || ( defined( 'FORCE_SSL_ADMIN' ) && FORCE_SSL_ADMIN ) || ( function_exists( 'is_ssl' ) && is_ssl() ) ) ? 'https' : 'http' );
			$url    = set_url_scheme( $url, $scheme );
		}

		// Get the path from the URL
		$path = wp_parse_url( $url, PHP_URL_PATH);
		if( $path <> '' && strpos($path, '/') !== false ) {
			$path = substr( $path, strrpos( $path, '/' ) + 1);
		}

		// Return the original URL is no path exists
		if( ! $path ){
			return $url;
		}

		// Get query from URL
		$query = wp_parse_url( $url, PHP_URL_QUERY );
		if ( $query <> '' ) {
			$query = '?' . $query;
		}

		if ( HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) ) {

			if ( in_array( $path, array( 'login', 'wp-login', 'wp-login.php' ) ) ) {

				// Check if disable and do not redirect to log in
				if ( HMWP_Classes_Tools::calledSafeUrl( ) ) {
					// Add the disabled param in order to work without issues
					if ( strpos( $url, HMWP_Classes_Tools::getOption( 'hmwp_disable_name' ) ) === false ) {
						if ( strpos( $url, '?' ) !== false ) {
							$url .= '&' . HMWP_Classes_Tools::getOption( 'hmwp_disable_name' );
						} else {
							$url .= '?' . HMWP_Classes_Tools::getOption( 'hmwp_disable_name' );
						}
					}
					return $url;
				}

				if ( $query == '?action=lostpassword' && HMWP_Classes_Tools::getOption( 'hmwp_lostpassword_url' ) <> '' ) {
					$url = home_url( HMWP_Classes_Tools::getOption( 'hmwp_lostpassword_url' ), $scheme );
				} elseif ( $query == '?action=register' && HMWP_Classes_Tools::getOption( 'hmwp_register_url' ) <> '' ) {
					$url = home_url( HMWP_Classes_Tools::getOption( 'hmwp_register_url' ), $scheme );
				} else {

					$url = home_url( '', $scheme );
					if ( function_exists( 'mb_stripos' ) ) {
						if ( mb_stripos( $url, '?' ) !== false ) {
							$url = substr( $url, 0, mb_stripos( $url, '?' ) );
						}
					} elseif ( stripos( $url, '?' ) !== false ) {
						$url = substr( $url, 0, stripos( $url, '?' ) );
					}

					$url .= '/' . HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) . $query;

					if ( HMWP_Classes_Tools::getValue( 'nordt' ) ) {
						$url = add_query_arg( array( 'nordt' => true ), $url );
					}
				}
			}

		}

		if ( HMWP_Classes_Tools::getDefault( 'hmwp_activate_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_activate_url' ) ) {

			if ( $path == 'wp-activate.php' ) {
				$url = site_url( '', $scheme ) . '/' . HMWP_Classes_Tools::getOption( 'hmwp_activate_url' ) . $query;
			}

		}

		return $url;

	}

	/**
	 * Filters the site URL.
	 *
	 * @param string $url The complete site URL including scheme and path.
	 * @param string $path Path relative to the site URL. Blank string if no path is specified.
	 * @param string|null $scheme Scheme to give the site URL context. Accepts 'http', 'https', 'login',
	 *                             'login_post', 'admin', 'relative' or null.
	 * @param int|null $blog_id Site ID, or null for the current site.
	 */
	public function site_url( $url, $path = '', $scheme = null ) {

		if ( ! apply_filters( 'hmwp_change_site_url', true ) ) {
			return $url;
		}

		if ( ! isset( $scheme ) ) {
			$scheme = ( ( ( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] == "on" ) || ( defined( 'FORCE_SSL_ADMIN' ) && FORCE_SSL_ADMIN ) || ( function_exists( 'is_ssl' ) && is_ssl() ) ) ? 'https' : 'http' );
			$url    = set_url_scheme( $url, $scheme );
		}

		// Get the path from the URL
		$path = wp_parse_url( $url, PHP_URL_PATH);
		if( $path <> '' && strpos($path, '/') !== false ) {
			$path = substr( $path, strrpos( $path, '/' ) + 1);
		}

		// Return the original URL is no path exists
		if( ! $path ){
			return $url;
		}

		// Get query from URL
		$query = wp_parse_url( $url, PHP_URL_QUERY );
		if ( $query <> '' ) {
			$query = '?' . $query;
		}

		if ( HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) ) {

			if ( in_array( $path, array( 'login', 'wp-login', 'wp-login.php' ) ) ) {

				// Check if disable and do not redirect to log in
				if ( HMWP_Classes_Tools::calledSafeUrl( ) ) {
					// Add the disabled param in order to work without issues
					if ( strpos( $url, HMWP_Classes_Tools::getOption( 'hmwp_disable_name' ) ) === false ) {
						if ( strpos( $url, '?' ) !== false ) {
							$url .= '&' . HMWP_Classes_Tools::getOption( 'hmwp_disable_name' );
						} else {
							$url .= '?' . HMWP_Classes_Tools::getOption( 'hmwp_disable_name' );
						}
					}
					return $url;
				}

				if ( $query == '?action=lostpassword' && HMWP_Classes_Tools::getOption( 'hmwp_lostpassword_url' ) <> '' ) {
					$url = site_url( HMWP_Classes_Tools::getOption( 'hmwp_lostpassword_url' ), $scheme );
				} elseif ( $query == '?action=register' && HMWP_Classes_Tools::getOption( 'hmwp_register_url' ) <> '' ) {
					$url = site_url( HMWP_Classes_Tools::getOption( 'hmwp_register_url' ), $scheme );
				} else {

					$url = site_url( '', $scheme );
					if ( function_exists( 'mb_stripos' ) ) {
						if ( mb_stripos( $url, '?' ) !== false ) {
							$url = substr( $url, 0, mb_stripos( $url, '?' ) );
						}
					} elseif ( stripos( $url, '?' ) !== false ) {
						$url = substr( $url, 0, stripos( $url, '?' ) );
					}

					$url .= '/' . HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) . $query;

					if ( HMWP_Classes_Tools::getValue( 'nordt' ) ) {
						$url = add_query_arg( array( 'nordt' => true ), $url );
					}
				}
			}

		}

		if ( HMWP_Classes_Tools::getDefault( 'hmwp_activate_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_activate_url' ) ) {

			if ( $path == 'wp-activate.php' ) {
				$url = site_url( '', $scheme ) . '/' . HMWP_Classes_Tools::getOption( 'hmwp_activate_url' ) . $query;
			}

		}

		return $url;
	}

	/**
	 * Get the new admin URL
	 *
	 * @param string $url
	 * @param string $path
	 * @param integer | null $blog_id
	 *
	 * @return mixed|string
	 */
	public function admin_url( $url, $path = '', $blog_id = null ) {
		$find = $replace = array();

		if ( ! defined( 'ADMIN_COOKIE_PATH' ) ) {
			return $url;
		}

		if ( HMWP_Classes_Tools::doChangePaths() ) {

			if ( HMWP_Classes_Tools::getDefault( 'hmwp_admin-ajax_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_admin-ajax_url' ) ) {
				if ( HMWP_Classes_Tools::getOption( 'hmwp_hideajax_admin' ) ) {
					$find[] = '/' . HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_admin-ajax_url' );
				} else {
					$find[] = '/' . HMWP_Classes_Tools::getDefault( 'hmwp_admin-ajax_url' );
				}
				$replace[] = '/' . HMWP_Classes_Tools::getOption( 'hmwp_admin-ajax_url' );
			}

			if ( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) ) {
				$find[]    = '/' . HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) . '/';
				$replace[] = '/' . HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) . '/';
			}

		} elseif ( strpos( $url, HMWP_Classes_Tools::getDefault( 'hmwp_admin-ajax_url' ) ) === false ) {

			if ( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) ) {
				$find[]    = '/' . HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) . '/';
				$replace[] = '/' . HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) . '/';
			}

		}

		//if there is a custom path for admin or ajax
		if ( ! empty( $find ) && ! empty( $replace ) ) {
			return str_replace( $find, $replace, $url );
		}

		//Return the admin URL
		return $url;

	}

	/**
	 * Change the admin URL for multisites
	 * Filters the network admin URL.
	 *
	 * @param string $url The complete network admin URL including scheme and path.
	 * @param string $path Path relative to the network admin URL. Blank string if
	 *                            no path is specified.
	 * @param string|null $scheme The scheme to use. Accepts 'http', 'https',
	 *                            'admin', or null. Default is 'admin', which obeys force_ssl_admin() and is_ssl().
	 */
	public function network_admin_url( $url, $path = '', $scheme = null ) {
		$find = $replace = array();

		if ( ! defined( 'ADMIN_COOKIE_PATH' ) ) {
			return $url;
		}

		if ( HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) == 'wp-admin' ) {
			return $url;
		}

		if ( HMWP_Classes_Tools::doChangePaths() ) {

			if ( HMWP_Classes_Tools::getDefault( 'hmwp_admin-ajax_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_admin-ajax_url' ) ) {
				if ( HMWP_Classes_Tools::getOption( 'hmwp_hideajax_admin' ) ) {
					$find[] = '/' . HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_admin-ajax_url' );
				} else {
					$find[] = '/' . HMWP_Classes_Tools::getDefault( 'hmwp_admin-ajax_url' );
				}
				$replace[] = '/' . HMWP_Classes_Tools::getOption( 'hmwp_admin-ajax_url' );
			}

			if ( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) ) {
				$find[]    = network_site_url( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) . '/', HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) );
				$replace[] = network_site_url( '/' . HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) . '/', HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) );
			}

		} elseif ( strpos( $url, HMWP_Classes_Tools::getDefault( 'hmwp_admin-ajax_url' ) ) === false ) {

			if ( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) ) {
				$find[]    = network_site_url( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) . '/', HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) );
				$replace[] = network_site_url( '/' . HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) . '/', HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) );
			}
		}

		//if there is a custom path for admin or ajax
		if ( ! empty( $find ) && ! empty( $replace ) ) {
			return str_replace( $find, $replace, $url );
		}

		//Return the admin URL
		return $url;

	}

	/**
	 * Change the plugin URL with the new paths
	 * for some plugins
	 *
	 * @param $url
	 * @param $path
	 * @param $plugin
	 *
	 * @return null|string|string[]
	 * @throws Exception
	 */
	public function plugin_url( $url, $path, $plugin ) {
		$plugins = array( 'rocket-lazy-load' );
		if ( ! is_admin() ) {
			if ( $plugin <> '' && $url <> '' && HMWP_Classes_Tools::searchInString( $url, $plugins ) ) {
				$url = $this->find_replace_url( $url );
			}
		}

		return $url;
	}

	/**
	 * Login/Register title
	 *
	 * @param string $title
	 *
	 * @return string
	 */
	public function login_title( $title ) {
		if ( $title <> '' ) {
			$title = str_ireplace( array(
				' &lsaquo;  &#8212; WordPress',
				'WordPress'
			), '', $title );
		}

		return $title;
	}

	/**
	 * Login Header Hook
	 *
	 * @throws Exception
	 */
	public function login_head() {
		add_filter( 'login_headerurl', array( $this, 'login_url' ), 99, 1 );
	}

	/**
	 * Get the new Login URL
	 *
	 * @param $url
	 *
	 * @return string
	 */
	public function login_url( $url ) {

		if ( HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) && strpos( $url, HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ) ) !== false ) {

			// Check if disable and do not redirect to log in
			if ( HMWP_Classes_Tools::calledSafeUrl( ) ) {
				// Add the disabled param in order to work without issues
				if ( strpos( $url, HMWP_Classes_Tools::getOption( 'hmwp_disable_name' ) ) === false ) {
					if ( strpos( $url, '?' ) !== false ) {
						$url .= '&' . HMWP_Classes_Tools::getOption( 'hmwp_disable_name' );
					} else {
						$url .= '?' . HMWP_Classes_Tools::getOption( 'hmwp_disable_name' );
					}
				}
				return $url;
			}

			$url = site_url( HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) );
		}

		return $url;
	}

	/**
	 * Hook the wp_login action from WordPress
	 *
	 * @param string $user_login
	 * @param WP_User $user
	 */
	public function wp_login( $user_login = null, $user = null ) {
		HMWP_Classes_Tools::setCurrentUserRole( $user );
	}

	/**
	 * Hook the login_init from wp-login.php
	 *
	 * @throws Exception
	 */
	public function login_init() {

		if ( HMWP_Classes_Tools::getOption( 'hmwp_remove_third_hooks' ) ) {
			//////////////////////////////// Rewrite the login style
			wp_deregister_script( 'password-strength-meter' );
			wp_deregister_script( 'user-profile' );
			wp_deregister_style( 'forms' );
			wp_deregister_style( 'l10n' );
			wp_deregister_style( 'buttons' );
			wp_deregister_style( 'login' );

            if ( is_rtl() ) {
                wp_register_style('login', _HMWP_WPLOGIN_URL_.'css/login-rtl.min.css', array( 'dashicons', 'buttons', 'forms', 'l10n' ), HMWP_VERSION_ID, false);
                wp_register_style('forms', _HMWP_WPLOGIN_URL_.'css/forms-rtl.min.css', null, HMWP_VERSION_ID, false);
                wp_register_style('buttons', _HMWP_WPLOGIN_URL_.'css/buttons.min.css', null, HMWP_VERSION_ID, false);
                wp_register_style('l10n', _HMWP_WPLOGIN_URL_.'css/l10n-rtl.min.css', null, HMWP_VERSION_ID, false);
            }else{
                wp_register_style('login', _HMWP_WPLOGIN_URL_.'css/login.min.css', array( 'dashicons', 'buttons', 'forms', 'l10n' ), HMWP_VERSION_ID, false);
                wp_register_style('forms', _HMWP_WPLOGIN_URL_.'css/forms.min.css', null, HMWP_VERSION_ID, false);
                wp_register_style('buttons', _HMWP_WPLOGIN_URL_.'css/buttons.min.css', null, HMWP_VERSION_ID, false);
                wp_register_style('l10n', _HMWP_WPLOGIN_URL_.'css/l10n.min.css', null, HMWP_VERSION_ID, false);
            }
			wp_register_script( 'password-strength-meter', _HMWP_WPLOGIN_URL_ . 'js/password-strength-meter.min.js', array(
				'jquery',
				'wp-i18n',
				'zxcvbn-async'
			), HMWP_VERSION_ID, true );
			wp_register_script( 'user-profile', _HMWP_WPLOGIN_URL_ . 'js/user-profile.min.js', array(
				'jquery',
				'password-strength-meter',
				'wp-util'
			), HMWP_VERSION_ID, true );

			wp_localize_script( 'password-strength-meter', 'pwsL10n', array(
				'unknown'  => _x( 'Password strength unknown', 'password strength', 'hide-my-wp' ),
				'short'    => _x( 'Very weak', 'password strength', 'hide-my-wp' ),
				'bad'      => _x( 'Weak', 'password strength', 'hide-my-wp' ),
				'good'     => _x( 'Medium', 'password strength', 'hide-my-wp' ),
				'strong'   => _x( 'Strong', 'password strength', 'hide-my-wp' ),
				'mismatch' => _x( 'Mismatch', 'password mismatch', 'hide-my-wp' ),
			) );

			$user_id = isset( $_GET['user_id'] ) ? (int) $_GET['user_id'] : 0; //phpcs:ignore WordPress.Security.NonceVerification.Recommended
			wp_localize_script( 'user-profile', 'userProfileL10n', array(
				'user_id' => $user_id,
				'nonce'   => wp_create_nonce( 'reset-password-for-' . $user_id ),
			) );
			/////////////////////////////////////////////////////////
		}

		// Prevent any infinite loop
		add_filter( 'wp_redirect', array( $this, 'loopCheck' ), 99, 1 );

		// Remove Clasiera theme login loop
		remove_action( "login_init", "classiera_cubiq_login_init" );
		remove_filter( "login_redirect", "loginstyle_login_redirect" );

		//If Clean Login option is active or too many redirects
		$isRedirect = HMWP_Classes_Tools::getCustomLoginURL( false );
		if ( HMWP_Classes_Tools::getValue( 'nordt' ) || $isRedirect || HMWP_Classes_Tools::getOption( 'hmwp_remove_third_hooks' ) ) {
			remove_all_actions( 'login_init' );
			remove_all_actions( 'login_redirect' );
			remove_all_actions( 'bbp_redirect_login' );

			add_action( 'login_header', function() {
				global $error;
				if ( ! empty( $error ) ) {
					unset( $error );
				}
			} );

			add_filter( 'login_headerurl', array( $this, 'login_url' ) );
			add_filter( 'login_redirect', array( $this, 'sanitize_login_redirect' ), 1, 3 );
		}

		//handle the lost password and registration redirects
		if ( HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) ) {
			add_filter( 'lostpassword_redirect', array( $this, 'lostpassword_redirect' ), 1 );
			add_filter( 'registration_redirect', array( $this, 'registration_redirect' ), 1 );

			HMWP_Classes_ObjController::getClass( 'HMWP_Models_Cookies' )->setTestCookie();
		}

		//hide language switcher on login page
		if ( HMWP_Classes_Tools::getOption( 'hmwp_disable_language_switcher' ) ) {
			add_filter( 'login_display_language_dropdown', '__return_false' );
		}

		//Hook the login page and check if the user is already logged in
		if ( HMWP_Classes_Tools::getOption( 'hmwp_logged_users_redirect' ) ) {
			//if there is a reCaptcha test, don't redirect
			if ( ! HMWP_Classes_Tools::getIsset( 'nordt' ) ) {
				$this->dashboard_redirect();
			}
		}

		do_action( 'hmwp_login_init' );
	}

	/**
	 * Hook the login page and check if the user is already logged in
	 *
	 * @return void
	 */
	public function dashboard_redirect() {
		global $current_user;
		//If the user is already logged in
		//phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( ! HMWP_Classes_Tools::getValue( 'nordt' ) && ( ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] == 'login' ) && isset( $current_user->ID ) && $current_user->ID > 0 ) {
			//redirect to admin dashboard
			if ( wp_safe_redirect( esc_url_raw( apply_filters( 'hmwp_url_login_redirect', admin_url() ) ) ) ) {
				exit;
			}
		}
	}

	/**
	 * Change the password confirm URL with the new URL
	 *
	 * @return string
	 */
	public function lostpassword_redirect() {
		return home_url( 'wp-login.php?checkemail=confirm' );
	}

	/**
	 * Change the register confirmation URL with the new URL
	 *
	 * @return string
	 */
	public function registration_redirect() {
		return home_url( 'wp-login.php?checkemail=registered' );
	}

	/**
	 * Called from WP hook to change the lost password URL
	 *
	 * @param  $url
	 *
	 * @return mixed
	 * @throws Exception
	 */
	public function lostpassword_url( $url ) {
		if ( HMWP_Classes_Tools::getOption( 'hmwp_lostpassword_url' ) <> '' ) {

			//check if the redirects are built
			$url = $this->find_replace_url( $url );
		}

		return $url;
	}

	/**
	 * Called from WP hook to change the register URL
	 *
	 * @param  $url
	 *
	 * @return mixed
	 * @throws Exception
	 */
	public function register_url( $url ) {
		if ( HMWP_Classes_Tools::getOption( 'hmwp_register_url' ) <> '' ) {

			//check if the redirects are built
			$url = $this->find_replace_url( $url );
		}

		return $url;
	}

	/**
	 * Get the new Logout URL
	 *
	 * @param string $url
	 * @param string $redirect
	 *
	 * @return string
	 */
	public function logout_url( $url, $redirect = '' ) {
		$args = array();
		if ( $url <> '' ) {
			$parsed = wp_parse_url( $url );
			if ( $parsed['query'] <> '' ) {
				@parse_str( html_entity_decode( $parsed['query'] ), $args );
			}
		}

		if ( ! isset( $args['_wpnonce'] ) ) {
			$args['_wpnonce'] = wp_create_nonce( 'log-out' );
			//correct the logout URL
			$url = add_query_arg( array( '_wpnonce' => $args['_wpnonce'] ), home_url( 'wp-login.php?action=logout', 'login' ) );
		}

		if ( HMWP_Classes_Tools::getOption( 'hmwp_logout_url' ) <> '' ) {
			//add the new URL
			$url = home_url() . '/' . add_query_arg( array( '_wpnonce' => $args['_wpnonce'] ), HMWP_Classes_Tools::getOption( 'hmwp_logout_url' ) );
		}

		return $url;
	}

	/**
	 * Get the new Author URL
	 *
	 * @param array $rewrite
	 *
	 * @return array
	 */
	public function author_url( $rewrite ) {

		if ( HMWP_Classes_Tools::getDefault( 'hmwp_author_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_author_url' ) ) {
			foreach ( $rewrite as $from => $to ) {
				$newfrom             = str_replace( HMWP_Classes_Tools::getDefault( 'hmwp_author_url' ), HMWP_Classes_Tools::getOption( 'hmwp_author_url' ), $from );
				$rewrite[ $newfrom ] = $to;
			}
		}

		return $rewrite;
	}

	/********************************
	 *
	 * HOOK REDIRECTS
	 *************************************************/

	/**
	 * Hook the logout to flush the changes set in admin
	 *
	 * @throws Exception
	 */
	public function wp_logout() {
		if ( apply_filters( 'hmwp_url_logout_redirect', false ) ) {
			$_REQUEST['redirect_to'] = apply_filters( 'hmwp_url_logout_redirect', false );
		}

		do_action( 'hmwp_wp_logout' );
	}

	/**
	 * Hook the logout referrer and logout the user
	 *
	 * @param $action
	 * @param $result
	 */
	public function check_admin_referer( $action, $result ) {

		if ( $action == "log-out" && isset( $_REQUEST['_wpnonce'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
			$adminurl = strtolower( admin_url() );
			$referer  = strtolower( wp_get_referer() );
			if ( ! $result && ! ( - 1 === $action && strpos( $referer, $adminurl ) === 0 ) ) {

				if ( function_exists( 'wp_get_current_user' ) && HMWP_Classes_Tools::isLoggedInUser() ) {

					if ( apply_filters( 'hmwp_url_logout_redirect', false ) ) {
						$_REQUEST['redirect_to'] = apply_filters( 'hmwp_url_logout_redirect', false );
					}

					$user        = wp_get_current_user();
					$redirect_to = HMWP_Classes_Tools::getValue( 'redirect_to', home_url() );
					$redirect_to = apply_filters( 'logout_redirect', $redirect_to, $redirect_to, $user );

					wp_logout();

					// Enforce same-origin redirects: external URLs fall back to home_url() to prevent open redirect (CVE-2026-7527)
					$redirect_to = apply_filters( 'hmwp_url_logout_redirect', $redirect_to );
					$redirect_to = wp_validate_redirect( $redirect_to, home_url() );

					if ( wp_safe_redirect( esc_url_raw( $redirect_to ) ) ) {
						exit;
					}
					die;

				}

				if ( wp_safe_redirect( esc_url_raw( home_url() ) ) ) {
					exit;
				}
			}


		}
	}

	/**
	 * In case of  redirects, correct the redirect links
	 *
	 * @param string $redirect The path or URL to redirect to.
	 * @param string $status The HTTP response status code to use
	 *
	 * @return string
	 * @throws Exception
	 */
	public function sanitize_redirect( $redirect, $status = '' ) {

		//correct wp-admin redirect
		if ( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) ) {
			if ( strpos( $redirect, 'wp-admin' ) !== false ) {
				$redirect = $this->admin_url( $redirect );
			}
		}

		//prevent redirect to new login
		if ( HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) ) {
			if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_newlogin' ) ) {

				//if you do hide URLs is active
				if ( HMWP_Classes_Tools::doHideURLs() ) {
					$url = ( isset( $_SERVER['REQUEST_URI'] ) ? untrailingslashit( strtok( wp_unslash( $_SERVER["REQUEST_URI"] ), '?' ) ) : false ); //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
					$path = HMWP_Classes_Tools::getRelativePath( $redirect );

					if ( strpos( $path, '/' . HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) ) !== false ) {

						if ( $url ) {

							$url = rawurldecode( $url );

							// Redirected from register when registration is off
							if ( $query = wp_parse_url( $redirect, PHP_URL_QUERY ) ) {

								if ( HMWP_Classes_Tools::getOption( 'hmwp_register_url' ) && strpos( $url, '/' . HMWP_Classes_Tools::getOption( 'hmwp_register_url' ) ) !== false ) {
									parse_str( $query, $query );

									if( isset( $query['registration'] ) && $query['registration'] == 'disabled' ){
										if ( ! HMWP_Classes_Tools::isLoggedInUser() ) {
											$this->getNotFound( $redirect );
										}
									}
								}
							}

							// Redirected from admin, login, lost password, register, disconnect, then pass
							if ( strpos( $url, '/' . HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) ) !== false ||
							     strpos( $url, '/' . HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) ) !== false ||
							     strpos( $url, '/' . HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) ) !== false ||
							     ( HMWP_Classes_Tools::getOption( 'hmwp_lostpassword_url' ) && strpos( $url, '/' . HMWP_Classes_Tools::getOption( 'hmwp_lostpassword_url' ) ) !== false ) ||
							     ( HMWP_Classes_Tools::getOption( 'hmwp_register_url' ) && strpos( $url, '/' . HMWP_Classes_Tools::getOption( 'hmwp_register_url' ) ) !== false ) ||
							     ( HMWP_Classes_Tools::getOption( 'hmwp_logout_url' ) && strpos( $url, '/' . HMWP_Classes_Tools::getOption( 'hmwp_logout_url' ) ) !== false ) ) {
								return $redirect;
							}
						}

						if ( ! HMWP_Classes_Tools::isLoggedInUser() ) {
							$this->getNotFound( $redirect );
						}
					}
				}

			}
		}

		return $redirect;

	}

	/**
	 * In case of login redirects, correct the redirect links
	 *
	 * @param string $redirect The path or URL to redirect to.
	 * @param string $path
	 * @param string $user
	 *
	 * @return string
	 * @throws Exception
	 */
	public function sanitize_login_redirect( $redirect, $path = null, $user = null ) {

		if ( HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) ) {
			if ( strpos( $redirect, 'wp-login' ) !== false ) {
				$redirect = site_url( HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) );
			}
		}

		if ( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) ) {
			if ( strpos( $redirect, 'wp-admin' ) !== false ) {
				$redirect = $this->admin_url( $redirect );
			}
		}

		//if user is logged in
		if ( isset( $user ) && isset( $user->ID ) && ! is_wp_error( $user ) ) {
			//Set the current user for custom redirects
			HMWP_Classes_Tools::setCurrentUserRole( $user );

			//overwrite the login redirect with the custom HMWP redirect
			$redirect = apply_filters( 'hmwp_url_login_redirect', $redirect );

			//If the redirect URL is external, jump to redirect
			if ( wp_parse_url( $redirect, PHP_URL_HOST ) && wp_parse_url( $redirect, PHP_URL_HOST ) <> wp_parse_url( home_url(), PHP_URL_HOST ) ) {
				if ( wp_safe_redirect( esc_url_raw( $redirect ) ) ) {
					exit;
				}
			}
		}

		//Stop loops and other hooks
		if ( HMWP_Classes_Tools::getValue( 'nordt' ) || HMWP_Classes_Tools::getOption( 'hmwp_remove_third_hooks' ) ) {

			//remove other redirect hooks
			remove_all_actions( 'login_redirect' );

			//If user is logged in
			if ( isset( $user ) && isset( $user->ID ) ) {
				if ( ! is_wp_error( $user ) && empty( $_REQUEST['reauth'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended

					//If admin redirect
					if ( ( empty( $redirect ) || $redirect == 'wp-admin/' || $redirect == admin_url() ) ) {

						// If the user doesn't belong to a blog, send them to user admin. If the user can't edit posts, send them to their profile.
						if ( HMWP_Classes_Tools::isMultisites() && ! get_active_blog_for_user( $user->ID ) && ! is_super_admin( $user->ID ) ) {
							$redirect = user_admin_url();
						} elseif ( method_exists( $user, 'has_cap' ) ) {

							if ( HMWP_Classes_Tools::isMultisites() && ! $user->has_cap( 'read' ) ) {
								$redirect = get_dashboard_url( $user->ID );
							} elseif ( ! $user->has_cap( 'edit_posts' ) ) {
								$redirect = $user->has_cap( 'read' ) ? admin_url( 'profile.php' ) : home_url();
							}

						}

						//overwrite the login redirect with the custom HMWP redirect
						$redirect = apply_filters( 'hmwp_url_login_redirect', $redirect );

						if ( wp_safe_redirect( esc_url_raw( $redirect ) ) ) {
							exit;
						}
					}

					//overwrite the login redirect with the custom HMWP redirect
					$redirect = apply_filters( 'hmwp_url_login_redirect', $redirect );

					if ( wp_safe_redirect( esc_url_raw( $redirect ) ) ) {
						exit;
					}
				}
			}
		}

		//overwrite the login redirect with the custom HMWP redirect
		return apply_filters( 'hmwp_url_login_redirect', $redirect );

	}

	/**
	 * Check if the current URL is the same with the redirect URL
	 *
	 * @param $url
	 *
	 * @return string
	 * @throws Exception
	 */
	public function loopCheck( $url ) {

		if ( isset( $_SERVER['HTTP_HOST'] ) && isset( $_SERVER['REQUEST_URI'] ) && $url <> '' ) {
			$current_url  = wp_unslash( $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
			$redirect_url = wp_parse_url( $url, PHP_URL_HOST ) . wp_parse_url( $url, PHP_URL_PATH );
			if ( $current_url <> '' && $redirect_url <> '' ) {
				if ( $current_url == $redirect_url ) {
					return add_query_arg( array( 'nordt' => true ), $url );
				} else {
					return remove_query_arg( array( 'nordt' ), $url );
				}
			}

		}

		if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_wplogin' ) || HMWP_Classes_Tools::getOption( 'hmwp_hide_login' ) ) {
			if ( HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) ) {

				//temporary deativate the change of home and site url
				add_filter( 'hmwp_change_home_url', '__return_false' );
				add_filter( 'hmwp_change_site_url', '__return_false' );

				if ( HMWP_Classes_Tools::isLoggedInUser()) {
					$paths = array(
						site_url( 'wp-login.php', 'relative' ),
						site_url( 'wp-login', 'relative' ),
					);
				} else {

					$paths = array(
						home_url( 'wp-login.php', 'relative' ),
						home_url( 'wp-login', 'relative' ),
						site_url( 'wp-login.php', 'relative' ),
						site_url( 'wp-login', 'relative' ),
					);

					if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_login' ) ) {

						$paths[] = home_url( 'login', 'relative' );
						$paths[] = site_url( 'login', 'relative' );

					}

					$paths = array_unique( $paths );
				}

				//reactivate the change of the paths in home and site url
				add_filter( 'hmwp_change_home_url', '__return_true' );
				add_filter( 'hmwp_change_site_url', '__return_true' );

				$redirect_url = wp_parse_url( $url, PHP_URL_HOST ) . wp_parse_url( $url, PHP_URL_PATH );
				if ( HMWP_Classes_Tools::searchInString( $redirect_url, $paths ) ) {
					if ( site_url( HMWP_Classes_Tools::getOption( 'hmwp_login_url' ), 'relative' ) <> $redirect_url ) {
						return add_query_arg( array( 'nordt' => true ), site_url( HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) ) );
					}
				}
			}
		}

		return $url;
	}

	/**
	 * Check Hidden pages and return 404 if needed
	 *
	 * @return void
	 * @throws Exception
	 */
	public function hideUrls() {

		// Check if is valid for moving on
		if ( HMWP_Classes_Tools::doHideURLs() ) {

			// Temporary deativate the change of home and site url
			add_filter( 'hmwp_change_home_url', '__return_false' );
			add_filter( 'hmwp_change_site_url', '__return_false' );

			$url       = untrailingslashit( strtok( wp_unslash( $_SERVER["REQUEST_URI"] ?? '' ), '?' ) ); //phpcs:ignore
			$http_post = ( isset( $_SERVER['REQUEST_METHOD'] ) && 'POST' == $_SERVER['REQUEST_METHOD'] ); //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

			// If user is logged in and is not set to hide the admin urls
			if ( HMWP_Classes_Tools::isLoggedInUser() ) {

				// Redirect if no final slash is added
				if ( isset( $_SERVER['REQUEST_URI'] ) && $_SERVER['REQUEST_URI'] == site_url( HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ), 'relative' ) ) { //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
					wp_safe_redirect( $url . '/' );
					exit();
				}

				// Hide the wp-admin for logged users only if the config file is working properly
				if ( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) &&
				     empty( (array) HMWP_Classes_Tools::getOption( 'file_mappings' ) ) && HMWP_Classes_Tools::getOption( 'hmwp_hide_admin_loggedusers' ) ) {

					// If it's an ajax call, then let the path be reached by logged users
					if ( HMWP_Classes_Tools::isAjax() ) {
						$paths = array(
							home_url( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_admin-ajax_url' ), 'relative' ),
							site_url( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) . '/' . HMWP_Classes_Tools::getDefault( 'hmwp_admin-ajax_url' ), 'relative' )
						);

						if ( HMWP_Classes_Tools::searchInString( $url, $paths ) ) {
							return;
						}
					}

					$paths = array(
						home_url( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ), 'relative' ),
						site_url( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ), 'relative' )
					);

					if ( HMWP_Classes_Tools::searchInString( $url, $paths ) ) {
						if ( ! HMWP_Classes_Tools::userCan( 'manage_options' ) ) {
							$this->getNotFound( $url );
						}
					}
				}
			} else {

				// ide the param rest route
				if ( HMWP_Classes_Tools::getOption( 'hmwp_disable_rest_api_param' ) ) {
					$this->hideRestRouteParam();
				}

				// If is set to hide the urls or not logged in
				if ( $url <> '' ) {

					/////////////////////////////////////////////////////
					// Hide Admin URL when changed
					if ( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) ) {

						if ( ! HMWP_Classes_Tools::isMultisites() && HMWP_Classes_Tools::getOption( 'hmwp_hide_newadmin' ) ) {
							if ( strpos( $url . '/', '/' . HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ) . '/' ) !== false && HMWP_Classes_Tools::getOption( 'hmwp_hide_admin' ) ) {
								if ( strpos( $url . '/', '/' . HMWP_Classes_Tools::getOption( 'hmwp_admin-ajax_url' ) . '/' ) === false ) {
									$this->getNotFound( $url, '.' );
								}
							}
						} elseif ( $_SERVER['REQUEST_URI'] == site_url( HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ), 'relative' ) ) { //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
                            // Add slash on admin path if not added
                            wp_safe_redirect( $url . '/' );
                            exit();
                        }

						$paths = array(
							home_url( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ), 'relative' ),
							home_url( 'dashboard', 'relative' ),
							home_url( 'admin', 'relative' ),
							site_url( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ), 'relative' ),
							site_url( 'dashboard', 'relative' ),
							site_url( 'admin', 'relative' ),
						);
						$paths = array_unique( $paths );

						if ( HMWP_Classes_Tools::searchInString( $url, $paths ) ) {
							if ( site_url( HMWP_Classes_Tools::getOption( 'hmwp_admin_url' ), 'relative' ) <> $url && HMWP_Classes_Tools::getOption( 'hmwp_hide_admin' ) ) {
								$this->getNotFound( $url );
							}
						}
					} elseif ( strpos( $url, '/' . HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) ) !== false && strpos( $url, admin_url( HMWP_Classes_Tools::getDefault( 'hmwp_admin-ajax_url' ), 'relative' ) ) === false && HMWP_Classes_Tools::getOption( 'hmwp_hide_admin' ) ) {
                        // Hide the URL
                        $this->getNotFound( $url , '.' );
                    }

					/////////////////////////////////////////////////////
					// Protect lost password and register
					// If POST process
					if ( $http_post ) {

						// If password reset, allow access
						if ( HMWP_Classes_Tools::getOption( 'hmwp_lostpassword_url' ) <> '' ) {
							if ( strpos( $url, '/' . HMWP_Classes_Tools::getOption( 'hmwp_lostpassword_url' ) ) !== false ) {
								$_REQUEST['action'] = 'lostpassword';
							}
						}

						// If registered, allow access
						if ( HMWP_Classes_Tools::getOption( 'hmwp_register_url' ) <> '' ) {
							if ( strpos( $url, '/' . HMWP_Classes_Tools::getOption( 'hmwp_register_url' ) ) !== false ) {
								$_REQUEST['action'] = 'register';
							}
						}

						// If there is a different login path
						if ( defined( 'HMWP_DEFAULT_LOGIN' ) ) {

							// When submit on password protect page on wp-login.php
							// Allow access to submit the password
							if ( $url == site_url( HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ), 'relative' ) ) {
								if ( 'postpass' == HMWP_Classes_Tools::getValue( 'action' ) ) {
									return;
								}
							}

						}

					} elseif ( defined( 'HMWP_DEFAULT_LOGIN' ) ) {
						// When logout process on wp-login.php
						// Allow access
						if ( $url == site_url( HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ), 'relative' ) ) {
							if ( 'true' == HMWP_Classes_Tools::getValue( 'loggedout' ) ) {
								return;
							}
						}

					}

					/////////////////////////////////////////////////////
					// Hide comments from spammers
					if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_commonfiles' ) ) {
						$files = (array) HMWP_Classes_Tools::getOption( 'hmwp_hide_commonfiles_files' );
						if ( ! empty( $files ) && ( $key = array_search( HMWP_Classes_Tools::getDefault( 'hmwp_wp-comments-post' ), $files ) ) !== false ) {
							if ( HMWP_Classes_Tools::getDefault( 'hmwp_wp-comments-post' ) <> HMWP_Classes_Tools::getOption( 'hmwp_wp-comments-post' ) ) {

								$paths = array(
									home_url( 'wp-comments-post.php', 'relative' ),
								);
								if ( HMWP_Classes_Tools::searchInString( $url, $paths ) ) {
									$this->get403Error();
								}

							}
						}
					}

					/////////////////////////////////////////////////////
					// Hide Login URL when changed
					if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_wplogin' ) || HMWP_Classes_Tools::getOption( 'hmwp_hide_login' ) ) {

						// Initiate paths
						$paths = array();

						// If the current path is not the custom login path & wp-login path is changed in HMWP
						if ( site_url( HMWP_Classes_Tools::getOption( 'hmwp_login_url' ), 'relative' ) <> $url && HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) ) {

							// Get the relative login path
							$paths = array(
                                home_url( 'wp-login.php', 'relative' ),
                                home_url( 'wp-login', 'relative' ),
                                site_url( 'wp-login.php', 'relative' ),
                                site_url( 'wp-login', 'relative' ),
							);

							if ( HMWP_Classes_Tools::getOption( 'hmwp_login_url' ) <> 'login.php' ) {
								$paths[] = home_url( 'login.php', 'relative' );
								$paths[] = site_url( 'login.php', 'relative' );
							}

							// If there is a POST on login when it's hidden
							// Allow access on CloudPanel and WP Engine to prevent errors
							if ( ! $http_post && HMWP_Classes_Tools::getOption( 'hmwp_hide_login' ) ) {
								$paths[] = home_url( 'login', 'relative' );
								$paths[] = site_url( 'login', 'relative' );
							}

						} elseif ( defined( 'HMWP_DEFAULT_LOGIN' ) && // Custom login is set in other plugins
						           site_url( HMWP_DEFAULT_LOGIN, 'relative' ) <> $url && // Current paths is different from login
						           HMWP_DEFAULT_LOGIN <> HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ) ) {

							$paths = array(
								home_url( HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ), 'relative' ),
								site_url( HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ), 'relative' ),
							);

							if ( HMWP_DEFAULT_LOGIN <> 'login.php' ) {
								$paths[] = home_url( 'login.php', 'relative' );
								$paths[] = site_url( 'login.php', 'relative' );
							}

							if ( HMWP_DEFAULT_LOGIN <> 'login' && HMWP_Classes_Tools::getOption( 'hmwp_hide_login' ) ) {
								$paths[] = home_url( 'login', 'relative' );
								$paths[] = site_url( 'login', 'relative' );
							}

						}

						// Remove duplicate paths in array
						$paths = array_unique( $paths );

						if ( ! empty( $paths ) ) {
							// Search the paths in URL and show not found
							if ( HMWP_Classes_Tools::searchInString( $url, $paths ) ) {
								$this->getNotFound( $url );
							}
						}

					}

					/////////////////////////////////////////////////////
					// Hide the author url when changed
					if ( HMWP_Classes_Tools::getDefault( 'hmwp_author_url' ) <> HMWP_Classes_Tools::getOption( 'hmwp_author_url' ) ) {
						$paths = array(
							home_url( 'author', 'relative' ) . '/',
							site_url( 'author', 'relative' ) . '/',
						);
						if ( HMWP_Classes_Tools::searchInString( $url, $paths ) ) {
							$this->getNotFound( $url );
						}
					}

					/////////////////////////////////////////////////////
					// Hide the /xmlrpc.php path when switched on
					if ( HMWP_Classes_Tools::getOption( 'hmwp_disable_xmlrpc' ) ) {
						$paths = array(
							home_url( 'xmlrpc.php', 'relative' ),
							home_url( 'wp-trackback.php', 'relative' ),
							site_url( 'xmlrpc.php', 'relative' ),
							site_url( 'wp-trackback.php', 'relative' ),
						);
						if ( HMWP_Classes_Tools::searchInString( $url, $paths ) ) {
							$this->getNotFound( $url );
						}
					}

					/////////////////////////////////////////////////////
					// Disable rest api
					if ( HMWP_Classes_Tools::getOption( 'hmwp_disable_rest_api' ) ) {
						$paths = array(
							home_url( 'wp-json', 'relative' ),
							home_url( HMWP_Classes_Tools::getOption( 'hmwp_wp-json' ), 'relative' ),
						);
						if ( HMWP_Classes_Tools::searchInString( $url, $paths ) ) {
							$this->getNotFound( $url );
						}
					}


					/////////////////////////////////////////////////////
					// Hide the common php file in case of other servers
					$paths = array(
						home_url( 'install.php', 'relative' ),
						home_url( 'upgrade.php', 'relative' ),
						home_url( 'wp-config.php', 'relative' ),
						site_url( 'install.php', 'relative' ),
						site_url( 'upgrade.php', 'relative' ),
						site_url( 'wp-config.php', 'relative' ),
					);
					if ( HMWP_Classes_Tools::searchInString( $url, $paths ) ) {
						$this->getNotFound( $url );
					}

					/////////////////////////////////////////////////////
					// Hide the wp-signup and wp-register  for WP Multisite
					if ( ! get_option( 'users_can_register' ) ) {
						$paths = array(
							home_url( 'wp-register.php', 'relative' ),
							site_url( 'wp-register.php', 'relative' ),
							home_url( 'wp-signup.php', 'relative' ),
							site_url( 'wp-signup.php', 'relative' ),
						);
						if ( HMWP_Classes_Tools::searchInString( $url, $paths ) ) {
							$this->getNotFound( $url );
						}
					}

				}

			}

			//reactivate the change of the paths in home and site url
			add_filter( 'hmwp_change_home_url', '__return_true' );
			add_filter( 'hmwp_change_site_url', '__return_true' );

		}

	}

	/**
	 * Return 404 page or redirect
	 *
	 * @param string $url Options: 404, NFError Not Found, NAError Not Available, or a specific page
	 * @param string $option
	 *
	 * @throws Exception
	 */
	public function getNotFound( $url, $option = false ) {

        if(!$option){
            $option = HMWP_Classes_Tools::getOption( 'hmwp_url_redirect' );
        }

		if ( $option == '404' ) {
			if ( HMWP_Classes_Tools::isThemeActive( 'Pro' ) ) {
				global $wp_query;
				$wp_query->is_404 = true;

				wp_safe_redirect( home_url( '404' ) );
				exit();
			} else {
				$this->get404Page();
			}
		} else if ( $option == 'NFError' ) {
			$this->get404Page();
		} else if ( $option == 'NAError' ) {
			$this->get403Error();
		} elseif ( $option == '.' ) {
			//redirect to front page
			wp_safe_redirect( home_url() );
			exit();
		} else {
			//redirect to custom page
			wp_safe_redirect( home_url( $option ) );
			exit();
		}

		die();
	}

	/**
	 * Display 404 page to bump bots and bad guys
	 *
	 * @param bool $usetheme If true force displaying basic 404 page
	 *
	 * @throws Exception
	 */
	function get404Page( $usetheme = false ) {
		global $wp_query;

		//Initialize WordPress Filesystem
		$wp_filesystem = HMWP_Classes_ObjController::initFilesystem();

		try {

			if ( function_exists( 'status_header' ) ) {
				status_header( 404 );
			} else {
				header( 'HTTP/1.1 404 Not Found', true, 404 );
			}

			if ( isset( $wp_query ) && is_object( $wp_query ) ) {
				$wp_query->set_404();
			}

			// Avoid showing load_textdomain_just_in_time on block page
			global $wp_actions;
			$wp_actions['after_setup_theme'] = 1;

			// Det threat as prevented
			add_filter( 'hmwp_threat_prevented', '__return_true');

			// Hooks to display 404 page
			do_action( 'hmwp_firewall_block', true );

			if ( $usetheme ) {
				$template = null;
				if ( function_exists( 'get_404_template' ) ) {
					$template = get_404_template();
				}
				if ( function_exists( 'apply_filters' ) ) {
					$template = apply_filters( 'hmwp_404_template', $template );
				}
				if ( $template && $wp_filesystem->exists( $template ) ) {
					ob_start();
					include $template;
					echo $this->find_replace( ob_get_clean() ); //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
					exit();
				}
			}

			nocache_headers();
			$language = 'en';
			if ( function_exists( 'get_locale' ) ) {
				$language = get_locale();
			}

			/* translators: 1: Requested URI. */
			echo '<html lang="' . esc_attr( $language ) . '"><meta<head><title>' . esc_html__( '404 Not Found', 'hide-my-wp' ) . '</title></head><body><h1>' . esc_html__( 'Page Not Found', 'hide-my-wp' ) . '</h1><p>' . sprintf( esc_html__( 'The requested URL %1$s was not found on this server.', 'hide-my-wp' ), ( isset( $_SERVER['REQUEST_URI'] ) ? esc_url( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '' ) ) . ' </p></body></html>'; //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
			exit();

		} catch ( Exception $e ) {
		}

	}

	/**
	 * Display 403 error to bump bots and bad guys
	 *
	 * @throws Exception
	 */
	function get403Error() {

		try {

			if ( function_exists( 'status_header' ) ) {
				status_header( 403 );
			} else {
				header( 'HTTP/1.1 403 Forbidden', true, 403 );
			}

			// Avoid showing load_textdomain_just_in_time on block page
			global $wp_actions;
			$wp_actions['after_setup_theme'] = 1;

			// Det threat as prevented
			add_filter( 'hmwp_threat_prevented', '__return_true');

			// Hooks to display 403 page
			do_action( 'hmwp_firewall_block', true );

			nocache_headers();
			$language = 'en';
			if ( function_exists( 'get_locale' ) ) {
				$language = get_locale();
			}

			/* translators: 1: Requested URI. */
			echo '<html lang="' . esc_attr( $language ) . '"><meta<head><title>' . esc_html__( '403 Forbidden', 'hide-my-wp' ) . '</title></head><body><h1>' . esc_html__( 'Forbidden', 'hide-my-wp' ) . '</h1><p>' . sprintf( esc_html__( 'You don\'t have the permission to access %1$s on this server.', 'hide-my-wp' ), ( isset( $_SERVER['REQUEST_URI'] ) ? esc_url( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '' ) ) . ' </p></body></html>'; //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
			exit();

		} catch ( Exception $e ) {
		}

	}

	/*************************************
	 *
	 * FIND AND REPLACE
	 *****************************************/
	/**
	 * repare the replace function
	 *
	 * @throws Exception
	 */
	public function prepareFindReplace() {
		$find = $replace = $findtext = $remplacetext = $findencoded = $findencodedfinal = $replaceencoded = $replaceencodedfinal = $findcdns = $replacecdns = $findurlmapping = $replaceurlmapping = array();

		//If there are rewrite rules
		if ( ! empty( $this->_replace ) ) {

			//If URL Mapping is activated
			if ( HMWP_Classes_Tools::getOption( 'hmwp_mapping_cdn_show' ) ) {
				if ( $cdns = HMWP_Classes_ObjController::getClass( 'HMWP_Models_Compatibility' )->findCDNServers() ) {
					//if there are CDNs added
					if ( ! empty( $cdns ) ) {

						$cdns = array_unique( $cdns ); //remove duplicates
						foreach ( $cdns as $cdn ) {
							$parsed = wp_parse_url( $cdn );

							$parsed['path'] = ( $parsed['path'] ?? '' );
							$parsed['host'] = ( $parsed['host'] ?? '' );

							$cdn = $parsed['host'] . $parsed['path'] . '/';

							//Add PORT if different from 80
							if ( isset( $parsed['port'] ) && $parsed['port'] <> 80 ) {
								$cdn = $parsed['host'] . ':' . $parsed['port'] . $parsed['path'] . '/';
							}

							$findcdn    = preg_replace( '/^/', $cdn, (array) $this->_replace['from'] );
							$replacecdn = preg_replace( '/^/', $cdn, (array) $this->_replace['to'] );

							//merge the urls
							$findcdns    = array_merge( $findcdns, $findcdn );
							$replacecdns = array_merge( $replacecdns, $replacecdn );
						}

					}
				}
			}

			//make sure the paths are without schema
			$find    = array_map( array( $this, 'addDomainUrl' ), (array) $this->_replace['from'] );
			$replace = array_map( array( $this, 'addDomainUrl' ), (array) $this->_replace['to'] );

			//make sure the main domain is added on wp multisite with subdirectories
			//used for custom wp-content, custom wp-includes, custom uploads
			//If wp-content is in a different directory root
			if ( HMWP_Classes_Tools::isMultisiteWithPath() || HMWP_Classes_Tools::isDifferentWPContentPath() ) {
				$find    = array_merge( $find, array_map( array( $this, 'addMainDomainUrl' ), (array) $this->_replace['from'] ) );
				$replace = array_merge( $replace, array_map( array( $this, 'addMainDomainUrl' ), (array) $this->_replace['to'] ) );
			}

			//change the javascript urls
			$findencoded    = array_map( array( $this, 'changeEncodedURL' ), (array) $this->_replace['from'] );
			$replaceencoded = array_map( array( $this, 'changeEncodedURL' ), (array) $this->_replace['to'] );

			//change the javascript urls
			$findencodedfinal    = array_map( array( $this, 'changeEncodedURLFinal' ), (array) $this->_replace['from'] );
			$replaceencodedfinal = array_map( array( $this, 'changeEncodedURLFinal' ), (array) $this->_replace['to'] );

		}

		//If URL Mapping is activated
		if ( HMWP_Classes_Tools::getOption( 'hmwp_mapping_url_show' ) ) {
			$hmwp_url_mapping = json_decode( HMWP_Classes_Tools::getOption( 'hmwp_url_mapping' ), true );
			if ( isset( $hmwp_url_mapping['from'] ) && ! empty( $hmwp_url_mapping['to'] ) ) {
				$findurlmapping    = $hmwp_url_mapping['from'];
				$replaceurlmapping = $hmwp_url_mapping['to'];
				unset( $hmwp_url_mapping );
			}
		}


		//merge the urls
		$this->_replace['from'] = array_merge( $findtext, $findcdns, $find, $findencoded, $findencodedfinal, $findurlmapping );
		$this->_replace['to']   = array_merge( $remplacetext, $replacecdns, $replace, $replaceencoded, $replaceencodedfinal, $replaceurlmapping );

		//listen for filters
		$this->_replace = apply_filters( 'hmwp_replace_before', $this->_replace );

	}

	/**
	 * Add the main domain into URL
	 * Used for WP Multisite with paths
	 *
	 * @param $url
	 *
	 * @return string
	 */
	public function addMainDomainUrl( $url ) {

		// Set main domain
		$mainDomain = $this->getSiteUrl();

		// If multisite with path
		if (HMWP_Classes_Tools::isMultisiteWithPath()) {
			$path = wp_parse_url( site_url(), PHP_URL_PATH );

			// Remove any path if exists
			if($path){
				$mainDomain =  str_replace( $path, '', $mainDomain );
			}
		}

		// If is missing from the path, add the main domain
		if ( strpos( $url, $mainDomain ) === false ) {
			return $mainDomain . '/' . $url;
		}

		return $url;
	}

	/**
	 * Add the domain into URL
	 *
	 * @param $url
	 *
	 * @return string
	 */
	public function addDomainUrl( $url ) {
		if ( strpos( $url, $this->getSiteUrl() ) === false ) {
			return $this->getSiteUrl() . '/' . $url;
		}

		return $url;
	}

	/**
	 * Remove the Schema from url
	 * Return slashed urls for javascript urls
	 *
	 * @param $url
	 *
	 * @return string
	 */
	public function changeEncodedURL( $url ) {
		if ( strpos( $url, $this->getSiteUrl() ) === false ) {
			return str_replace( '/', '\/', $this->getSiteUrl() . '/' . $url );
		}

		return $url;
	}

	/**
	 * @param $url
	 *
	 * @return mixed
	 */
	public function changeEncodedURLFinal( $url ) {
		if ( strpos( $url, $this->getSiteUrl() ) === false ) {
			return str_replace( '/', '\/', rtrim( $this->getSiteUrl() . '/' . $url, '/' ) );
		}

		return $url;
	}

	/**
	 * Change content
	 *
	 * @param $content
	 *
	 * @return null|string|string[]
	 * @throws Exception
	 */
	public function find_replace( $content ) {

		if ( HMWP_Classes_Tools::doChangePaths() && apply_filters( 'hmwp_process_find_replace', true ) ) {

			if ( is_string( $content ) && $content <> '' ) {

				//if the changes were made already, return the content
				if ( strpos( $content, HMWP_Classes_Tools::getDefault( 'hmwp_wp-content_url' ) ) === false && strpos( $content, HMWP_Classes_Tools::getDefault( 'hmwp_wp-includes_url' ) ) === false && $this->_replaced ) {
					return $content;
				}

				//change and replace paths
				$this->clearRedirect();
				//builder the redirects
				$this->buildRedirect();
				//make sure to include the blog url
				$this->prepareFindReplace();

				//fix the relative links before
				if ( HMWP_Classes_Tools::getOption( 'hmwp_fix_relative' ) ) {
					$content = $this->fixRelativeLinks( $content );
				}

				//Find & Replace the tags and headers
				$content = $this->replaceHeadersAndTags( $content );

				//Do the path replace for all paths
				if ( isset( $this->_replace['from'] ) && isset( $this->_replace['to'] ) && ! empty( $this->_replace['from'] ) && ! empty( $this->_replace['to'] ) ) {
					$content = str_ireplace( $this->_replace['from'], $this->_replace['to'], $content );
				}

				//If Text Mapping is activated
				if ( HMWP_Classes_Tools::getOption( 'hmwp_mapping_text_show' ) ) {
					//Replace classes and IDs
					if ( $newcontent = $this->replaceTextMapping( $content ) ) {
						$content = $newcontent;
					}
				}

			}

			//emulate other CMS on request
			$content = $this->emulateCMS( $content );

			//for debug purpose
			if ( HMWP_Classes_Tools::getValue( 'hmwp_debug' ) ) {
				$content .= '<pre>' . print_r( $this->_replace, true ) . '</pre>'; //phpcs:ignore
			}

			//Set the replacement action to prevent multiple calls
			$this->_replaced = true;
		}

		//Return the buffer
		return $content;
	}


	/**
	 * Add CMS Emulators for theme detectors
	 *
	 * @param  $content
	 *
	 * @return string|string[]|null
	 */
	public function emulateCMS( $content ) {
		$generator = '';
		$header    = array();

		//emulate other CMS
		if ( $emulate = HMWP_Classes_Tools::getOption( 'hmwp_emulate_cms' ) ) {

			if ( strpos( $emulate, 'drupal' ) !== false ) {
				switch ( $emulate ) {
					case 'drupal7':
						$generator = 'Drupal 7 (https://www.drupal.org)';
						break;
					case 'drupal':
						$generator = 'Drupal 8 (https://www.drupal.org)';
						break;
					case 'drupal9':
						$generator = 'Drupal 9 (https://www.drupal.org)';
						break;
					case 'drupal10':
						$generator = 'Drupal 10 (https://www.drupal.org)';
						break;
                    case 'drupal11':
                        $generator = 'Drupal 11 (https://www.drupal.org)';
                        break;
					default:
						$generator = 'Drupal (https://www.drupal.org)';
						break;
				}

				$header['MobileOptimized']  = '<meta name="MobileOptimized" content="width" />';
				$header['HandheldFriendly'] = '<meta name="HandheldFriendly" content="true" />';

			} elseif ( strpos( $emulate, 'joomla' ) !== false ) {
				switch ( $emulate ) {
					case 'joomla1':
						$generator = 'Joomla! 1.5 - Open Source Content Management';
						break;
					default:
						$generator = 'Joomla! - Open Source Content Management';
						break;
				}

			}

			$header['generator'] = '<meta name="generator" content="' . apply_filters( 'hmwp_emulate_cms', $generator ) . '" />';
			$header_str          = str_replace( '$', '\$', join( "\n", $header ) );
			$content             = @preg_replace( '/(<head(\s[^>]*|)>)/i', sprintf( "$1\n%s", $header_str ) . PHP_EOL, $content, 1 );
		}

		return $content;
	}


	/**
	 * Rename the paths in URL with the new ones
	 *
	 * @param  $url
	 *
	 * @return mixed
	 * @throws Exception
	 */
	public function find_replace_url( $url ) {
		if ( strpos( $url, HMWP_Classes_Tools::getDefault( 'hmwp_wp-content_url' ) ) !== false || strpos( $url, HMWP_Classes_Tools::getDefault( 'hmwp_wp-includes_url' ) ) !== false ) {

			//change and replace paths
			if ( empty( $this->_replace ) ) {
				//builder the redirects
				$this->buildRedirect();

				//make sure to include the blog url
				$this->prepareFindReplace();
			}

			if ( isset( $this->_replace['from'] ) && isset( $this->_replace['to'] ) && ! empty( $this->_replace['from'] ) && ! empty( $this->_replace['to'] ) ) {

				foreach ( $this->_replace['rewrite'] as $index => $value ) {
					//add only the paths or the design path
					if ( ( $index && isset( $this->_replace['to'][ $index ] ) && substr( $this->_replace['to'][ $index ], - 1 ) == '/' ) || strpos( $this->_replace['to'][ $index ], '/' . HMWP_Classes_Tools::getOption( 'hmwp_themes_style' ) ) ) {
						$this->_replace['from'][] = $this->_replace['from'][ $index ];
						$this->_replace['to'][]   = $this->_replace['to'][ $index ];
					}
				}

				//Don't replace include if content was already replaced
				$url = str_ireplace( $this->_replace['from'], $this->_replace['to'], $url );
			}
		}

		return $url;
	}

	/**
	 * Replace the wp-json URL is changed
	 *
	 * @param $url
	 *
	 * @return mixed
	 */
	public function replace_rest_api( $url ) {
		//Modify rest-api wp-json
		if ( HMWP_Classes_Tools::getDefault( 'hmwp_wp-json' ) <> HMWP_Classes_Tools::getOption( 'hmwp_wp-json' ) ) {
			$url = HMWP_Classes_Tools::getOption( 'hmwp_wp-json' );
		}

		return $url;
	}

	/**
	 * Change the image path to absolute when in the feed
	 *
	 * @param string $content
	 *
	 * @return string
	 */
	public function fixRelativeLinks( $content ) {
		return preg_replace_callback( array(
			'~((["\'`]))(\\\/(?!/)[^"\'`]+)(["\'`])~i',
			'~((["\'`]))(/(?!/)[^"\'`]+)(["\'`])~i',
			'~(\s(href|src|content)\s*[=|:]\s*[\"\'])([^\"\']+)([\"\'])~i',
			'~(\W(url\s*)[\(\"\']+)([^\]\)\"\']+)([\)\"\']+)~i',
			'~(([\"\']url[\"\']\s*:)\s*[\"\'])([^\"\']+)([\"\'])~i',
			'~([=|:]\s*[\"\'])(\\\/[^\"\']+)([\"\'])~i'
		), array(
			$this,
			'replaceLinks'
		), $content );
	}

	/**
	 * If relative links then transform them to absolute
	 *
	 * @param $found
	 *
	 * @return string
	 */
	public function replaceLinks( $found ) {
		$url = $found[3];

		//remove hashtags
		if( strpos( $url, '#' ) !== false ){
			$url = substr( $url, 0, strpos( $url, '#' ) );
		}

		if ( strpos( $url, '//' ) === false && strpos( $url, '\/\/' ) === false ) {
			//Change the path only if the WP common paths are found
			if ( strpos( $url, '/'. HMWP_Classes_Tools::getDefault( 'hmwp_wp-content_url' ) ) !== false || strpos( $url, '/'. HMWP_Classes_Tools::getDefault( 'hmwp_wp-includes_url' ) ) !== false || strpos( $url, '/'. HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) ) !== false || strpos( $url, '/'. HMWP_Classes_Tools::getDefault( 'hmwp_login_url' ) ) !== false ) {
				return $found[1] . $this->_rel2abs( $url ) . $found[4];
			}

		} elseif ( is_ssl() && strpos( $url, 'http:' ) !== false && strpos( $url, $this->getSiteUrl() ) !== false ) {
			//Change the schema from unsecure to secure
			return str_replace( 'http:', 'https:', $found[0] );
		}

		return $found[0];

	}

	/**
	 * Change Relative links to Absolute links
	 *
	 * @param $rel
	 *
	 * @return string
	 */
	protected function _rel2abs( $rel ) {
		$scheme    = $host = $path = '';
		$backslash = false;

		//if relative with preview dir
		if ( strpos( $rel, "../" ) !== false ) {
			return $rel;
		}

		// return if already absolute URL
		if ( wp_parse_url( $rel, PHP_URL_SCHEME ) != '' ) {
			return $rel;
		}

		// parse base URL and convert to local variables: $scheme, $host, $path
		$base_parts = wp_parse_url( home_url() );
		$site_parts = wp_parse_url( site_url() );

		// If a multilingual plugin (WPML / Polylang) extended home_url with a
		// language prefix beyond site_url, fall back to site_url — otherwise
		// /wp-content and /wp-includes get the language prefix prepended and 404.
		$home_path = isset( $base_parts['path'] ) ? $base_parts['path'] : '';
		$site_path = isset( $site_parts['path'] ) ? $site_parts['path'] : '';
		if ( $home_path !== $site_path && strpos( $home_path, $site_path ) === 0 ) {
			$base_parts = $site_parts;
		}

		extract( $base_parts );

		//add the scheme to the URL
		if ( strpos( $rel, "//" ) === 0 ) {
			return $scheme . ':' . $rel;
		}

		//if url encoded, rezolve until absolute
		if ( strpos( $rel, '\/' ) !== false ) {
			//if backslashes then change the URLs to normal
			$backslash = true;
			$rel       = str_replace( '\/', '/', $rel );
		}

		// queries and anchors
		if ( $rel[0] == '#' || $rel[0] == '?' ) {
			return home_url() . $rel;
		}

		// dirty absolute URL
		if ( $path <> '' && ( strpos( $rel, $path . '/' ) === false || strpos( $rel, $path . '/' ) > 0 ) ) {
			$abs = $host . $path . "/" . $rel;
		} else {
			$abs = $host . "/" . $rel;
		}

		// replace '//' or  '/./' or '/foo/../' with '/'
		$abs = preg_replace( "/(\/\.?\/)/", "/", $abs );
		$abs = preg_replace( "/\/(?!\.\.)[^\/]+\/\.\.\//", "/", $abs );

		// absolute URL is ready!
		if ( $backslash ) {
			return str_replace( '/', '\/', $scheme . '://' . $abs );
		} else {
			return $scheme . '://' . $abs;

		}
	}

	/**
	 * Remove the comments from source code
	 *
	 * @param $m
	 *
	 * @return string
	 */
	protected function _commentRemove( $m ) {
		return ( 0 === strpos( $m[1], '[' ) || false !== strpos( $m[1], '<![' ) ) ? $m[0] : '';
	}


	/**
	 * Remove the page headers
	 */
	public function hideHeaders() {

		//Remove Powered by, X-Cf-Powered, Server headers
		if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_unsafe_headers' ) ) {

			//Remove WordPress link from headers
			header( sprintf( '%s: %s', 'Link', '<' . home_url() . '>; rel=shortlink' ), true );

			if ( function_exists( 'header_remove' ) ) {
				header_remove( "x-powered-by" );
				header_remove( "x-cf-powered-by" );
				header_remove( "server" );
				header( 'X-Powered-By: -' );
			}
		}

		//Remove Pingback from website header
		if ( HMWP_Classes_Tools::getOption( 'hmwp_disable_xmlrpc' ) ) {

			if ( function_exists( 'header_remove' ) ) {
				header_remove( "x-pingback" );
			}

		}
	}

	/**
	 * Add all needed security headers
	 */
	public function addSecurityHeader() {

		if ( HMWP_Classes_Tools::getOption( 'hmwp_security_header' ) ) {

			$headers = (array) HMWP_Classes_Tools::getOption( 'hmwp_security_headers' );

			if ( ! empty( $headers ) ) {
				foreach ( $headers as $name => $value ) {
					if ( $value <> '' ) {
						header( $name . ": " . $value );
					}
				}
			}

		}

	}

	/**
	 * Find the text from Text Mapping in the source code
	 *
	 * @param string $content
	 * @param bool $isfile
	 *
	 * @return mixed|string|string[]|null
	 */
	public function replaceTextMapping( $content, $isfile = false ) {

		$findtextmapping = array();

		// Change the text in css and js files only for visitors
		if ( HMWP_Classes_Tools::getOption( 'hmwp_mapping_text_show' ) && HMWP_Classes_Tools::getOption( 'hmwp_mapping_file' ) &&
		     HMWP_Classes_Tools::isLoggedInUser() ) {
			return $content;
		}

		// Replace custom classes
		$hmwp_text_mapping = json_decode( HMWP_Classes_Tools::getOption( 'hmwp_text_mapping' ), true );
		if ( isset( $hmwp_text_mapping['from'] ) && ! empty( $hmwp_text_mapping['from'] ) && isset( $hmwp_text_mapping['to'] ) && ! empty( $hmwp_text_mapping['to'] ) ) {

			foreach ( $hmwp_text_mapping['to'] as &$value ) {
				if ( $value <> '' ) {
					if ( strpos( $value, '{rand}' ) !== false ) {
						$value = str_replace( '{rand}', HMWP_Classes_Tools::generateRandomString( 5 ), $value );
					} elseif ( strpos( $value, '{blank}' ) !== false ) {
						$value = str_replace( '{blank}', '', $value );
					}
				}
			}

			$this->_findtextmapping    = $hmwp_text_mapping['from'];
			$this->_replacetextmapping = $hmwp_text_mapping['to'];

			if ( ! empty( $this->_findtextmapping ) && ! empty( $this->_replacetextmapping ) ) {
				//change only the classes and ids
				if ( HMWP_Classes_Tools::getOption( 'hmwp_mapping_classes' ) ) {

					if ( $isfile ) {
						// If this change is within a CSS or JS file
						foreach ( $hmwp_text_mapping['from'] as $index => $from ) {
							$content = preg_replace( "'(?:([^/])" . addslashes( $from ) . "([^/]))'is", '$1' . $hmwp_text_mapping['to'][ $index ] . '$2', $content );
						}
					} else {
						$deep_mapping = false;
						if ( HMWP_Classes_Tools::getOption( 'hmwp_mapping_text_show' ) && HMWP_Classes_Tools::getOption( 'hmwp_mapping_file' ) ) {
							$deep_mapping = true;
						}

						// If this change is in the HTML page
						foreach ( $this->_findtextmapping as $from ) {
							$findtextmapping[] = '/\s(class|id|type|aria-labelledby|aria-controls|data-lp-type|data-elementor-type|data-widget_type)=[\'"][^\'"]*(' . addslashes( $from ) . ')[^\'"]*[\'"]/';
							if ( $deep_mapping ) {
								$findtextmapping[] = "'<(style|script)((?!src|>).)*>.*?</(style|script)>'is";
							}
							$findtextmapping[] = "'<script((?!src|>).)*>'is";
							$findtextmapping[] = "'<style[^>]*>.*?</style>'is";
							$findtextmapping[] = "'<(a|div)[^>]*data-" . addslashes( $from ) . "[^>]*[^/]>'is";
						}

						if ( ! empty( $findtextmapping ) ) {
							$content = preg_replace_callback( $findtextmapping, array( $this, 'replaceText' ), $content );
						}
					}

				} else {
					// If this change is for any found text
					$content = str_ireplace( $this->_findtextmapping, $this->_replacetextmapping, $content );
				}
			}

			unset( $hmwp_text_mapping );
		}

		return $content;
	}

	/**
	 * Find & Replace the tags and headers
	 *
	 * @param  $content
	 *
	 * @return string|string[]|null
	 */
	public function replaceHeadersAndTags( $content ) {
		$find = $replace = array();

		// Remove the admin path and wp from the prefetch/speculation-rules list (e.g. "\/wp-*.php", "\/wp-admin\/*").
		if ( strpos( $content, HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) . '/*' ) !== false ||
		     strpos( $content, HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ) . '\/*' ) !== false ) {

			$admin_url = preg_quote( HMWP_Classes_Tools::getDefault( 'hmwp_admin_url' ), '#' );

			// "\/wp-*.php" entry: element + trailing comma, then leading comma + element (for the last element in the array)
			$find[]    = '#"[^"]*\\\\?/wp\-\*\.php"\s*,#i';
			$replace[] = '';

			$find[]    = '#,\s*"[^"]*\\\\?/wp\-\*\.php"#i';
			$replace[] = '';

			// "\/wp-admin\/*" entry: element + trailing comma, then leading comma + element
			$find[]    = '#"[^"]*\\\\?/' . $admin_url . '\\\\?/\*"\s*,#i';
			$replace[] = '';

			$find[]    = '#,\s*"[^"]*\\\\?/' . $admin_url . '\\\\?/\*"#i';
			$replace[] = '';

		}

		//Remove source commets
		if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_comments' ) ) {
			$content = preg_replace_callback( '/<!--([\\s\\S]*?)-->/', array( $this, '_commentRemove' ), $content );
		}

		if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_source_map' ) ) {
			// Remove devtools source pragmas (JS)
			$find[]    = '/^[ \t]*\/\/[@#]\s*sourceMappingURL=.*$(\R)?/mi';
			$replace[] = '';
			$find[]    = '/^[ \t]*\/\/[@#]\s*sourceURL=.*$(\R)?/mi';
			$replace[] = '';

			// Remove devtools source pragmas (CSS)
			$find[]    = '/\/\*[@#]\s*sourceMappingURL=.*?\*\//is';
			$replace[] = '';
			$find[]    = '/\/\*[@#]\s*sourceURL=.*?\*\//is';
			$replace[] = '';
		}

			//Remove versions
		if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_version' ) ) {
			if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_version_random' ) ) {
				if ( HMWP_Classes_Tools::isLoggedInUser()) {
					HMWP_Classes_Tools::saveOptions( 'hmwp_hide_version_random', wp_rand( 11111, 99999 ) );
				}
				$find[]    = '/(\?|\&#038;|\&)ver=[0-9a-zA-Z\.\_\-\+]+(\&#038;|\&)/';
				$replace[] = '$1rnd=' . HMWP_Classes_Tools::getOption( 'hmwp_hide_version_random' ) . '$2';
				$find[]    = '/(\?|\&#038;|\&)ver=[0-9a-zA-Z\.\_\-\+]+("|\')/';
				$replace[] = '$1rnd=' . HMWP_Classes_Tools::getOption( 'hmwp_hide_version_random' ) . '$2';
			} else {
				$find[]    = '/(\?|\&#038;|\&)ver=[0-9a-zA-Z\.\_\-\+]+(\&#038;|\&)/';
				$replace[] = '$1';
				$find[]    = '/(\?|\&#038;|\&)ver=[0-9a-zA-Z\.\_\-\+]+("|\')/';
				$replace[] = '$2';
			}
		}

		if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_in_sitemap' ) && HMWP_Classes_Tools::getOption( 'hmwp_hide_author_in_sitemap' ) ) {
			$find[]    = '/(<\?xml-stylesheet[\s])([^>]+>)/i';
			$replace[] = '';
		}

		//Remove the Generator link
		if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_generator' ) ) {
			$find[]    = '/<meta[^>]*name=[\'"]generator[\'"][^>]*>/i';
			$replace[] = '';
		}

		//Remove WP prefetch domains that reveal the CMS
		if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_prefetch' ) ) {
			$find[]    = '/<link[^>]*rel=[\'"]dns-prefetch[\'"][^>]*w.org[^>]*>/i';
			$replace[] = '';

			$find[]    = '/<link[^>]*rel=[\'"]dns-prefetch[\'"][^>]*wp.org[^>]*>/i';
			$replace[] = '';

			$find[]    = '/<link[^>]*rel=[\'"]dns-prefetch[\'"][^>]*wordpress.org[^>]*>/i';
			$replace[] = '';
		}

		//Remove the Pingback link from source code
		if ( HMWP_Classes_Tools::getOption( 'hmwp_disable_xmlrpc' ) ) {
			$find[]    = '/(<link[\s])rel=[\'"]pingback[\'"][\s]([^>]+>)/i';
			$replace[] = '';
		}

		//remove Style IDs
		if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_styleids' ) ) {
			$find[]    = '/(<link[^>]*rel=[^>]+)[\s]id=[\'"][0-9a-zA-Z._-]+[\'"]([^>]*>)/i';
			$replace[] = '$1 $2';

			$find[]    = '/(<style[^>]*)[\s]id=[\'"][0-9a-zA-Z._-]+[\'"]([^>]*>)/i';
			$replace[] = '$1 $2';

			$find[]    = '/(<script[^>]*)[\s]id=[\'"][0-9a-zA-Z._-]+[\'"]([^>]*>)/i';
			$replace[] = '$1 $2';

			$find[]    = '/<meta[^>]*name=[\'"]msapplication-TileImage[\'"][^>]*>/i';
			$replace[] = '';
		}

		//remove the Feed from header
		if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_feed' ) ) {
			$find[]    = '/<link[^>]*rel=[\'"]alternate[\'"][^>]*type=[\'"]application\/rss\+xml[\'"][^>]*>/i';
			$replace[] = '';

			$find[]    = '/<link[^>]*type=[\'"]application\/rss\+xml[\'"][^>]*rel=[\'"]alternate[\'"][^>]*>/i';
			$replace[] = '';

			$find[]    = '/<link[^>]*type=[\'"]application\/atom\+xml[\'"][^>]*>/i';
			$replace[] = '';
		}

		//remove wp-json
		if ( HMWP_Classes_Tools::getDefault( 'hmwp_wp-json' ) <> HMWP_Classes_Tools::getOption( 'hmwp_wp-json' ) ) {
			$find[]    = '/(<link[\s])rel=[\'"]https:\/\/api.w.org\/[\'"][\s]([^>]+>)/i';
			$replace[] = '';
		}


		if ( empty( $find ) ) {
			return $content;
		}

		$result = preg_replace( $find, $replace, $content );

		// preg_replace() returns NULL on a PCRE error (e.g. pcre.backtrack_limit exceeded on large pages,
		// or invalid UTF-8 bytes combined with the /i flag). Falling back to the original content prevents
		// the whole page from rendering blank.
		return ( null === $result ) ? $content : $result;
	}

	/**
	 * Replace the current buffer by content type
	 *
	 * @throws Exception
	 */
	public function findReplaceXML() {
		//Force to change the URL for xml content types
		if ( HMWP_Classes_Tools::isContentHeader( array(
				'text/xml',
				'application/xml'
			) ) || ( isset( $_SERVER['REQUEST_URI'] ) && strpos( wp_unslash( $_SERVER['REQUEST_URI'] ), '.xml' ) !== false ) ) { //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

			//change and replace paths
			$this->clearRedirect();
			//builder the redirects
			$this->buildRedirect();
			//make sure to include the blog url
			$this->prepareFindReplace();

			$content = ob_get_contents();

			if ( $content <> '' ) {
				$content = str_ireplace( $this->_replace['from'], $this->_replace['to'], $content );

				if ( HMWP_Classes_Tools::getOption( 'hmwp_hide_author_in_sitemap' ) ) {
					$content = $this->replaceHeadersAndTags( $content );
				}

				ob_end_clean();
				echo $content;  //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
				exit();
			}

		}

	}

	/**
	 * Replace the robots file fo rsecurity
	 *
	 * @throws Exception
	 */
	public function replaceRobots() {

		//Force to change the URL for xml content types
		if ( HMWP_Classes_Tools::isContentHeader( array( 'text/plain' ) ) || ( isset( $_SERVER['REQUEST_URI'] ) && strpos( wp_unslash( $_SERVER['REQUEST_URI'] ), '.txt' ) !== false ) ) { //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

			$content = ob_get_contents();

			if ( $content <> '' ) {

				if ( HMWP_Classes_Tools::getOption( 'hmwp_robots' ) ) {

					//change and replace paths
					$this->clearRedirect();
					//builder the redirects
					$this->buildRedirect();

					$array = explode( "\n", $content );

					foreach ( $array as $index => $row ) {
						if ( strpos( $row, '/wp-admin' ) !== false || strpos( $row, '/wp-login.php' ) !== false ) {
							unset( $array[ $index ] );
						}
					}

					$content = join( "\n", $array );
					$content = str_ireplace( $this->_replace['from'], $this->_replace['to'], $content );
				}
			}

			// Add Disallow rules for banned user-agents (robots.txt)
			$banlist = HMWP_Classes_Tools::getOption( 'banlist_user_agent' );

			if ( ! is_array( $banlist ) ) {
				$banlist = json_decode( $banlist, true );
				$banlist = is_array($banlist) ? $banlist : array();
			}

			if ( ! empty( $banlist ) ) {
				// Remove empty data
				$banlist = array_filter( $banlist );
			}

			$banlist = array_values( array_filter( array_map( 'trim', $banlist ) ) );

			if ( ! empty( $banlist ) ) {

				// Build lookup of existing User-agent declarations (case-insensitive)
				$existingAgents = array();
				foreach ( explode( "\n", $content ) as $line ) {
					if ( preg_match( '~^\s*User-agent\s*:\s*(.+)\s*$~i', $line, $m ) ) {
						$agent = strtolower( trim( $m[1] ) );
						if ( $agent !== '' ) {
							$existingAgents[ $agent ] = true;
						}
					}
				}

				$add = array();

				foreach ( $banlist as $ua ) {
					$uaKey = strtolower( $ua );

					// If the UA group is missing, append it
					if ( ! isset( $existingAgents[ $uaKey ] ) ) {
						$add[] = "User-agent: {$ua}";
						$add[] = "Disallow: /";
						$add[] = "";
					}
				}

				if ( ! empty( $add ) ) {
					$content = rtrim( $content, "\n" ) . "\n\n" . join( "\n", $add );
					$content = rtrim( $content, "\n" ) . "\n";
				}
			}

			ob_end_clean();
			echo $content;  //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			exit();

		}

	}

	/**
	 * Callback for Text Mapping
	 *
	 * @param $found
	 *
	 * @return mixed
	 */
	public function replaceText( $found ) {
		$content = $found[0];
		if ( $content <> '' ) {
			$content = str_ireplace( $this->_findtextmapping, $this->_replacetextmapping, $content );
		}

		return $content;
	}

	/**
	 * Disable the emoji icons
	 */
	public function disableEmojicons() {

		// all actions related to emojis
		remove_action( 'admin_print_styles', 'print_emoji_styles' );
		remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
		remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
		remove_action( 'wp_print_styles', 'print_emoji_styles' );
		remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
		remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
		remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
		add_filter( 'emoji_svg_url', '__return_false' );

		// filter to remove TinyMCE emojis
		add_filter( 'tiny_mce_plugins', function( $plugins ) {
			if ( is_array( $plugins ) ) {
				return array_diff( $plugins, array( 'wpemoji' ) );
			} else {
				return array();
			}
		} );
	}

	/**
	 * Hides the REST API links from the head and HTTP headers.
	 *
	 * @return void
	 */
	public function hideRestApi() {
		remove_action( 'wp_head', 'rest_output_link_wp_head' );
		remove_action( 'template_redirect', 'rest_output_link_header', 11 );
	}

	/**
	 * Modify REST API endpoints to hide user listings for unauthorized users.
	 *
	 * @param  array  $endpoints  The array of registered REST API endpoints.
	 *
	 * @return array The modified array of REST API endpoints.
	 */
	public function hideRestUsers( $endpoints ) {

		// Hide the users listing from anonymous visitors only — stripping it from logged-in Editors/Authors breaks the Block Editor.
		if ( ! HMWP_Classes_ObjController::getClass( 'HMWP_Models_Cookies' )->isLoggedInCookie() ) {

			if ( isset( $endpoints['/wp/v2/users'] ) ) {
				unset( $endpoints['/wp/v2/users'] );
			}

			if ( isset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] ) ) {
				unset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] );
			}

		}

		return $endpoints;
	}

	/**
	 * Hide the 'rest_route' parameter when the REST API path is changed.
	 *
	 * @return void
	 * @throws Exception
	 */
	public function hideRestRouteParam() {
		/////////////////////////////////////////////////////
		//hide rest_route when rest api path is changed
		if ( HMWP_Classes_Tools::getValue( 'rest_route' ) ) {
			$this->getNotFound( false );
		}
	}

	/**
	 * Disable the embeds
	 */
	public function disableEmbeds() {
		global $wp;

		// Remove the embed query var and path from the end of the URLs.
		if( isset ($wp->public_query_vars ) ){
			$wp->public_query_vars = array_diff( $wp->public_query_vars, array( 'embed' ) );
		}

		// Remove the REST API endpoint.
		remove_action( 'rest_api_init', 'wp_oembed_register_route' );

		// Turn off oEmbed auto discovery.
		// Don't filter oEmbed results.
		remove_filter( 'oembed_dataparse', 'wp_filter_oembed_result' );

		// Remove oEmbed discovery links.
		remove_action( 'wp_head', 'wp_oembed_add_discovery_links' );

		// Remove oEmbed-specific JavaScript from the front-end and back-end.
		remove_action( 'wp_head', 'wp_oembed_add_host_js' );

		// Remove the oembed/1.0/embed REST route.
		add_filter( 'rest_endpoints', function ( $endpoints ){
			if( isset($endpoints['/oembed/1.0/embed']) ){
				unset( $endpoints['/oembed/1.0/embed'] );
			}
			return $endpoints;
		} );

		// Turn off oEmbed auto discovery.
		add_filter( 'embed_oembed_discover', '__return_false' );

	}

	/**
	 * Disable Windows Live Write
	 */
	public function disableManifest() {
		remove_action( 'wp_head', 'wlwmanifest_link' );
	}

	/**
	 * Disable Really Simple Discovery
	 * Disable RSD support from XML RPC
	 */
	public function disableRsd() {
		remove_action( 'wp_head', 'rsd_link' );
		remove_action( 'xmlrpc_rsd_apis', 'rest_output_rsd' );
	}

	/**
	 * Disable to commend from W3 Total Cache
	 */
	public function disableComments() {
		global $wp_super_cache_comments;
		remove_all_filters( 'w3tc_footer_comment' );
		$wp_super_cache_comments = false;
	}

	/**
	 * Replace the Error Message that contains WordPress
	 *
	 * @param string $message
	 * @param string $error
	 *
	 * @return string
	 */
	public function replace_error_message( $message, $error ) {
		if ( is_protected_endpoint() ) {
			$message = esc_html__( 'There has been a critical error on your website. Please check your site admin email inbox for instructions.', 'hide-my-wp' );
		} else {
			$message = esc_html__( 'There has been a critical error on your website.', 'hide-my-wp' );
		}

		return $message;
	}


}
