%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /var/www/pn/wp-content/plugins/autodescription/inc/classes/
Upload File :
Create Path :
Current File : //var/www/pn/wp-content/plugins/autodescription/inc/classes/generate-title.class.php

<?php
/**
 * @package The_SEO_Framework\Classes\Facade\Generate_Title
 * @subpackage The_SEO_Framework\Getters\Title
 */

namespace The_SEO_Framework;

\defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;

/**
 * The SEO Framework plugin
 * Copyright (C) 2015 - 2021 Sybre Waaijer, CyberWire B.V. (https://cyberwire.nl/)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as published
 * by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Class The_SEO_Framework\Generate_Title
 *
 * Generates title SEO data based on content.
 *
 * NOTE: Don't supply $args in any of the methods for non-term taxomies, like author archives.
 *       ID collision isn't accounted for in these scenarios.
 *
 * @since 2.8.0
 */
class Generate_Title extends Generate_Description {

	/**
	 * Returns the meta title from custom fields. Falls back to autogenerated title.
	 *
	 * @since 3.1.0
	 * @since 3.2.2 No longer double-escapes the custom field title.
	 * @since 4.1.0 Added the third $social parameter.
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 * @uses $this->get_custom_field_title()
	 * @uses $this->get_generated_title()
	 *
	 * @param array|null $args   The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                           Leave null to autodetermine query.
	 * @param bool       $escape Whether to escape the title.
	 * @param bool       $social Whether the title is meant for social display.
	 * @return string The real title output.
	 */
	public function get_title( $args = null, $escape = true, $social = false ) {

		$title = $this->get_custom_field_title( $args, false, $social )
			  ?: $this->get_generated_title( $args, false, $social );

		return $escape ? $this->escape_title( $title ) : $title;
	}

	/**
	 * Returns the custom user-inputted title.
	 *
	 * @since 3.1.0
	 * @since 4.0.0 Moved the filter to a separated method.
	 * @since 4.1.0 Added the third $social parameter.
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 *
	 * @param array|null $args   The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                           Leave null to autodetermine query.
	 * @param bool       $escape Whether to escape the title.
	 * @param bool       $social Whether the title is meant for social display.
	 * @return string The custom field title.
	 */
	public function get_custom_field_title( $args = null, $escape = true, $social = false ) {

		$title = $this->get_filtered_raw_custom_field_title( $args );

		if ( $title ) {
			if ( $this->use_title_protection( $args ) )
				$this->merge_title_protection( $title, $args );

			if ( $this->use_title_pagination( $args ) )
				$this->merge_title_pagination( $title );

			if ( $this->use_title_branding( $args, $social ) )
				$this->merge_title_branding( $title, $args );
		}

		return $escape ? $this->escape_title( $title ) : $title;
	}

	/**
	 * Returns the autogenerated meta title.
	 *
	 * @since 3.1.0
	 * @since 3.2.4 1. Added check for title protection.
	 *              2. Moved check for title pagination.
	 * @since 4.0.0 Moved the filter to a separated method.
	 * @since 4.1.0 Added the third $social parameter.
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 * @uses $this->s_title_raw() : This is the same method used to prepare custom title on save.
	 * @uses $this->get_filtered_raw_generated_title()
	 *
	 * @param array|null $args   The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                           Leave null to autodetermine query.
	 * @param bool       $escape Whether to escape the title.
	 * @param bool       $social Whether the title is meant for social display.
	 * @return string The generated title output.
	 */
	public function get_generated_title( $args = null, $escape = true, $social = false ) {

		$title = $this->get_filtered_raw_generated_title( $args );

		if ( $this->use_title_protection( $args ) )
			$this->merge_title_protection( $title, $args );

		if ( $this->use_title_pagination( $args ) )
			$this->merge_title_pagination( $title );

		if ( $this->use_title_branding( $args, $social ) )
			$this->merge_title_branding( $title, $args );

		$title = $this->s_title_raw( $title );

		return $escape ? $this->escape_title( $title ) : $title;
	}

	/**
	 * Returns the raw filtered custom field meta title.
	 *
	 * @since 4.0.0
	 * @since 4.2.0 1. The first parameter can now be voided.
	 *              2. The first parameter is now rectified, so you can leave out indexes.
	 *              3. Now supports the `$args['pta']` index.
	 *
	 * @param array|null $args   The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                           Leave null to autodetermine query.
	 * @return string The raw generated title output.
	 */
	public function get_filtered_raw_custom_field_title( $args = null ) {

		if ( null !== $args )
			$this->fix_generation_args( $args );

		/**
		 * Filters the title from custom field, if any.
		 *
		 * @since 3.1.0
		 * @since 4.2.0 Now supports the `$args['pta']` index.
		 *
		 * @param string     $title The title.
		 * @param array|null $args  The query arguments. Contains 'id', 'taxonomy', and 'pta'.
		 *                          Is null when query is autodetermined.
		 */
		return (string) \apply_filters_ref_array(
			'the_seo_framework_title_from_custom_field',
			[
				$this->get_raw_custom_field_title( $args ),
				$args,
			]
		);
	}

	/**
	 * Returns the raw filtered autogenerated meta title.
	 *
	 * @since 4.0.0
	 * @since 4.2.0 1. The first parameter can now be voided.
	 *              2. The first parameter is now rectified, so you can leave out indexes.
	 *              3. Now supports the `$args['pta']` index.
	 *
	 * @param array|null $args   The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                           Leave null to autodetermine query.
	 * @return string The raw generated title output.
	 */
	public function get_filtered_raw_generated_title( $args = null ) {

		if ( null !== $args )
			$this->fix_generation_args( $args );

		/**
		 * Filters the title from query.
		 *
		 * @NOTE: This filter doesn't consistently run on the SEO Settings page.
		 *        You may want to avoid this filter for the homepage and pta, by returning the default value.
		 * @since 3.1.0
		 * @since 4.2.0 Now supports the `$args['pta']` index.
		 * @param string     $title The title.
		 * @param array|null $args  The query arguments. Contains 'id', 'taxonomy', and 'pta'.
		 *                          Is null when query is autodetermined.
		 */
		return (string) \apply_filters_ref_array(
			'the_seo_framework_title_from_generation',
			[
				$this->get_raw_generated_title( $args ),
				$args,
			]
		);
	}

	/**
	 * Returns the Twitter meta title.
	 * Falls back to Open Graph title.
	 *
	 * @since 3.0.4
	 * @since 3.1.0 1. The first parameter now expects an array.
	 *              2. Now tries to get the homepage social titles.
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 *
	 * @param array|null $args   The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                           Leave null to autodetermine query.
	 * @param bool       $escape Whether to escape the title.
	 * @return string Twitter Title.
	 */
	public function get_twitter_title( $args = null, $escape = true ) {

		$title = $this->get_twitter_title_from_custom_field( $args, false )
			  ?: $this->get_generated_twitter_title( $args, false );

		return $escape ? $this->escape_title( $title ) : $title;
	}

	/**
	 * Returns the Twitter meta title from custom field.
	 * Falls back to Open Graph title.
	 *
	 * @since 3.1.0
	 * @see $this->get_twitter_title()
	 *
	 * @param array|null $args   The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 * @param bool       $escape Whether to escape the title.
	 * @return string Twitter Title.
	 */
	protected function get_twitter_title_from_custom_field( $args, $escape ) {

		if ( null === $args ) {
			$title = $this->get_custom_twitter_title_from_query();
		} else {
			$this->fix_generation_args( $args );
			$title = $this->get_custom_twitter_title_from_args( $args );
		}

		return $escape ? $this->escape_title( $title ) : $title;
	}

	/**
	 * Returns the Twitter meta title from custom field, based on query.
	 * Falls back to Open Graph title.
	 *
	 * @since 3.1.0
	 * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
	 * @since 4.0.0 Added term meta item checks.
	 * @since 4.2.0 Can now return custom post type archive titles.
	 * @see $this->get_twitter_title()
	 * @see $this->get_twitter_title_from_custom_field()
	 *
	 * @return string Twitter Title.
	 */
	protected function get_custom_twitter_title_from_query() {

		$title = '';

		if ( $this->is_real_front_page() ) {
			if ( $this->is_static_frontpage() ) {
				$title = $this->get_option( 'homepage_twitter_title' )
					  ?: $this->get_post_meta_item( '_twitter_title' )
					  ?: $this->get_option( 'homepage_og_title' )
					  ?: $this->get_post_meta_item( '_open_graph_title' )
					  ?: '';
			} else {
				$title = $this->get_option( 'homepage_twitter_title' )
					  ?: $this->get_option( 'homepage_og_title' )
					  ?: '';
			}
		} elseif ( $this->is_singular() ) {
			$title = $this->get_post_meta_item( '_twitter_title' )
				  ?: $this->get_post_meta_item( '_open_graph_title' )
				  ?: '';
		} elseif ( $this->is_term_meta_capable() ) {
			$title = $this->get_term_meta_item( 'tw_title' )
				  ?: $this->get_term_meta_item( 'og_title' )
				  ?: '';
		} elseif ( \is_post_type_archive() ) {
			$title = $this->get_post_type_archive_meta_item( 'tw_title' )
				  ?: $this->get_post_type_archive_meta_item( 'og_title' )
				  ?: '';
		}

		return $title;
	}

	/**
	 * Returns the Twitter meta title from custom field, based on arguments.
	 * Falls back to Open Graph title.
	 *
	 * @since 3.1.0
	 * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
	 * @since 4.0.0 Added term meta item checks.
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 * @see $this->get_twitter_title()
	 * @see $this->get_twitter_title_from_custom_field()
	 *
	 * @param array|null $args The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 * @return string Twitter Title.
	 */
	protected function get_custom_twitter_title_from_args( $args ) {

		if ( $args['taxonomy'] ) {
			$title = $this->get_term_meta_item( 'tw_title', $args['id'] )
				  ?: $this->get_term_meta_item( 'og_title', $args['id'] )
				  ?: '';
		} elseif ( $args['pta'] ) {
			$title = $this->get_post_type_archive_meta_item( 'tw_title', $args['pta'] )
				  ?: $this->get_post_type_archive_meta_item( 'og_title', $args['pta'] )
				  ?: '';
		} else {
			if ( $this->is_static_frontpage( $args['id'] ) ) {
				$title = $this->get_option( 'homepage_twitter_title' )
					  ?: $this->get_post_meta_item( '_twitter_title', $args['id'] )
					  ?: $this->get_option( 'homepage_og_title' )
					  ?: $this->get_post_meta_item( '_open_graph_title', $args['id'] )
					  ?: '';
			} elseif ( $this->is_real_front_page_by_id( $args['id'] ) ) {
				$title = $this->get_option( 'homepage_twitter_title' )
					  ?: $this->get_option( 'homepage_og_title' )
					  ?: '';
			} else {
				$title = $this->get_post_meta_item( '_twitter_title', $args['id'] )
					  ?: $this->get_post_meta_item( '_open_graph_title', $args['id'] )
					  ?: '';
			}
		}

		return $title;
	}

	/**
	 * Returns the autogenerated Twitter meta title.
	 * Falls back to meta title.
	 *
	 * @since 3.0.4
	 * @since 3.1.0 The first parameter now expects an array.
	 * @since 4.1.0 Now appends the "social" argument when getting the title.
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 * @uses $this->get_title()
	 *
	 * @param array|null $args   The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                           Leave null to autodetermine query.
	 * @param bool       $escape Whether to escape the title.
	 * @return string The generated Twitter Title.
	 */
	public function get_generated_twitter_title( $args = null, $escape = true ) {
		return $this->get_title( $args, $escape, true );
	}

	/**
	 * Returns the Open Graph meta title.
	 * Falls back to meta title.
	 *
	 * @since 3.0.4
	 * @since 3.1.0 1. The first parameter now expects an array.
	 *              2. Now tries to get the homepage social title.
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 * @uses $this->get_generated_open_graph_title()
	 *
	 * @param array|null $args   The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                           Leave null to autodetermine query.
	 * @param bool       $escape Whether to escape the title.
	 * @return string Open Graph Title.
	 */
	public function get_open_graph_title( $args = null, $escape = true ) {

		$title = $this->get_open_graph_title_from_custom_field( $args, false )
			  ?: $this->get_generated_open_graph_title( $args, false );

		return $escape ? $this->escape_title( $title ) : $title;
	}

	/**
	 * Returns the Open Graph meta title from custom field.
	 * Falls back to meta title.
	 *
	 * @since 3.1.0
	 * @see $this->get_open_graph_title()
	 *
	 * @param array|null $args   The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 * @param bool       $escape Whether to escape the title.
	 * @return string Open Graph Title.
	 */
	protected function get_open_graph_title_from_custom_field( $args, $escape ) {

		if ( null === $args ) {
			$title = $this->get_custom_open_graph_title_from_query();
		} else {
			$this->fix_generation_args( $args );
			$title = $this->get_custom_open_graph_title_from_args( $args );
		}

		return $escape ? $this->escape_title( $title ) : $title;
	}

	/**
	 * Returns the Twitter meta title from custom field, based on query.
	 * Falls back to meta title.
	 *
	 * @since 3.1.0
	 * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
	 * @since 4.0.0 Added term meta item checks.
	 * @since 4.2.0 Can now return custom post type archive titles.
	 * @see $this->get_open_graph_title()
	 * @see $this->get_open_graph_title_from_custom_field()
	 *
	 * @return string Open Graph Title.
	 */
	protected function get_custom_open_graph_title_from_query() {

		$title = '';
		if ( $this->is_real_front_page() ) {
			if ( $this->is_static_frontpage() ) {
				$title = $this->get_option( 'homepage_og_title' )
					  ?: $this->get_post_meta_item( '_open_graph_title' )
					  ?: '';
			} else {
				$title = $this->get_option( 'homepage_og_title' ) ?: '';
			}
		} elseif ( $this->is_singular() ) {
			$title = $this->get_post_meta_item( '_open_graph_title' ) ?: '';
		} elseif ( $this->is_term_meta_capable() ) {
			$title = $this->get_term_meta_item( 'og_title' ) ?: '';
		} elseif ( \is_post_type_archive() ) {
			$title = $this->get_post_type_archive_meta_item( 'og_title' ) ?: '';
		}

		return $title;
	}

	/**
	 * Returns the Open Graph meta title from custom field, based on query.
	 * Falls back to meta title.
	 *
	 * @since 3.1.0
	 * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
	 * @since 4.0.0 Added term meta item checks.
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 * @see $this->get_open_graph_title()
	 * @see $this->get_open_graph_title_from_custom_field()
	 *
	 * @param array|null $args The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 * @return string Open Graph Title.
	 */
	protected function get_custom_open_graph_title_from_args( $args ) {

		if ( $args['taxonomy'] ) {
			$title = $this->get_term_meta_item( 'og_title', $args['id'] ) ?: '';
		} elseif ( $args['pta'] ) {
			$title = $this->get_post_type_archive_meta_item( 'og_title', $args['pta'] ) ?: '';
		} else {
			if ( $this->is_static_frontpage( $args['id'] ) ) {
				$title = $this->get_option( 'homepage_og_title' )
					  ?: $this->get_post_meta_item( '_open_graph_title', $args['id'] )
					  ?: '';
			} elseif ( $this->is_real_front_page_by_id( $args['id'] ) ) {
				$title = $this->get_option( 'homepage_og_title' ) ?: '';
			} else {
				$title = $this->get_post_meta_item( '_open_graph_title', $args['id'] ) ?: '';
			}
		}

		return $title;
	}

	/**
	 * Returns the autogenerated Open Graph meta title. Falls back to meta title.
	 * Falls back to meta title.
	 *
	 * @since 3.0.4
	 * @since 3.1.0 The first parameter now expects an array.
	 * @since 4.1.0 Now appends the "social" argument when getting the title.
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 * @uses $this->get_title()
	 *
	 * @param array|null $args   The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                           Leave null to autodetermine query.
	 * @param bool       $escape Whether to escape the title.
	 * @return string The generated Open Graph Title.
	 */
	public function get_generated_open_graph_title( $args = null, $escape = true ) {
		return $this->get_title( $args, $escape, true );
	}

	/**
	 * Returns the custom user-inputted title.
	 *
	 * This doesn't use the taxonomy arguments, because, wonderously, WordPress
	 * finally admits through their code that terms can be queried using only IDs.
	 *
	 * @since 3.1.0
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 * @internal But, feel free to use it.
	 *
	 * @param array|null $args The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                         Leave null to autodetermine query.
	 * @return string The custom field title, if it exists.
	 */
	public function get_raw_custom_field_title( $args = null ) {

		$title = '';

		if ( null === $args ) {
			$title = $this->get_custom_field_title_from_query();
		} else {
			$this->fix_generation_args( $args );
			$title = $this->get_custom_field_title_from_args( $args );
		}

		return $title;
	}

	/**
	 * Gets a custom title, based on current query, without additions or prefixes.
	 *
	 * @since 3.1.0
	 * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
	 * @since 4.2.0 Can now return custom post type archive titles.
	 * @internal
	 * @see $this->get_raw_custom_field_title()
	 *
	 * @return string The custom title.
	 */
	protected function get_custom_field_title_from_query() {

		$title = '';

		if ( $this->is_real_front_page() ) {
			if ( $this->is_static_frontpage() ) {
				$title = $this->get_option( 'homepage_title' )
					  ?: $this->get_post_meta_item( '_genesis_title' )
					  ?: '';
			} else {
				$title = $this->get_option( 'homepage_title' ) ?: '';
			}
		} elseif ( $this->is_singular() ) {
			$title = $this->get_post_meta_item( '_genesis_title' ) ?: '';
		} elseif ( $this->is_term_meta_capable() ) {
			$title = $this->get_term_meta_item( 'doctitle' ) ?: '';
		} elseif ( \is_post_type_archive() ) {
			/**
			 * @since 4.0.6
			 * @since 4.2.0 Deprecated.
			 * @deprecated Use options instead.
			 * @param string $title The post type archive title.
			 */
			$title = (string) \apply_filters_deprecated(
				'the_seo_framework_pta_title',
				[ $this->get_post_type_archive_meta_item( 'doctitle' ) ],
				'4.2.0 of The SEO Framework'
			) ?: '';
		}

		return $title;
	}

	/**
	 * Gets a custom title, based on input arguments query, without additions or prefixes.
	 *
	 * @since 3.1.0
	 * @since 3.1.4 Now uses the 'id' to get custom singular title.
	 * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 * @internal
	 * @see $this->get_raw_custom_field_title()
	 *
	 * @param array $args The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 * @return string The custom title.
	 */
	protected function get_custom_field_title_from_args( $args ) {

		if ( $args['taxonomy'] ) {
			$title = $this->get_term_meta_item( 'doctitle', $args['id'] ) ?: '';
		} elseif ( $args['pta'] ) {
			$title = $this->get_post_type_archive_meta_item( 'doctitle', $args['pta'] ) ?: '';
		} else {
			if ( $this->is_static_frontpage( $args['id'] ) ) {
				$title = $this->get_option( 'homepage_title' )
					  ?: $this->get_post_meta_item( '_genesis_title', $args['id'] )
					  ?: '';
			} elseif ( $this->is_real_front_page_by_id( $args['id'] ) ) {
				$title = $this->get_option( 'homepage_title' ) ?: '';
			} else {
				$title = $this->get_post_meta_item( '_genesis_title', $args['id'] ) ?: '';
			}
		}

		return $title;
	}

	/**
	 * Generates a title, based on expected or current query, without additions or prefixes.
	 *
	 * @since 3.1.0
	 * @since 4.2.0 1. Added memoization.
	 *              2. Now supports the `$args['pta']` index.
	 * @uses $this->generate_title_from_query()
	 * @uses $this->generate_title_from_args()
	 *
	 * @param array|null $args The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                         Leave null to autodetermine query.
	 * @return string The generated title.
	 */
	public function get_raw_generated_title( $args = null ) {

		// phpcs:ignore, WordPress.CodeAnalysis.AssignmentInCondition -- I know.
		if ( null !== $memo = memo( null, $args ) ) return $memo;

		$this->remove_default_title_filters( false, $args );

		if ( null === $args ) {
			$title = $this->generate_title_from_query();
		} else {
			$this->fix_generation_args( $args );
			$title = $this->generate_title_from_args( $args );
		}

		$this->reset_default_title_filters();

		return memo( $title ?: $this->get_static_untitled_title(), $args );
	}

	/**
	 * Removes default title filters, for consistent output and sanitation.
	 * Memoizes the filters removed, so it can add them back on reset.
	 *
	 * Performance test: 0.007ms per remove+reset on PHP 8.0, single core VPN.
	 *
	 * @since 3.1.0
	 * @since 4.1.0 Added a second parameter, $args, to help soften the burden of this method.
	 * @internal Only to be used within $this->get_raw_generated_title()
	 *
	 * @param bool       $reset Whether to reset the removed filters.
	 * @param array|null $args  The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                          Leave null to autodetermine query.
	 */
	protected function remove_default_title_filters( $reset = false, $args = null ) {

		static $filtered = [];

		if ( $reset ) {
			foreach ( $filtered as $tag => $functions )
				foreach ( $functions as $function => $priorities )
					foreach ( $priorities as $priority )
						\add_filter( $tag, $function, $priority );

			// Reset filters.
			$filtered = [];
		} else {
			if ( null === $args ) {
				$filters = [ 'single_post_title', 'single_cat_title', 'single_tag_title' ];
			} else {
				$this->fix_generation_args( $args );

				if ( 'category' === $args['taxonomy'] ) {
					$filters = [ 'single_cat_title' ];
				} elseif ( 'post_tag' === $args['taxonomy'] ) {
					$filters = [ 'single_tag_title' ];
				} else {
					$filters = [ 'single_post_title' ];
				}
			}

			/**
			 * Texturization happens when outputting and saving the title; however,
			 * we want the raw title, so we won't find unexplainable issues later.
			 */
			$functions = [ 'wptexturize' ];

			if ( ! $this->get_option( 'title_strip_tags' ) )
				$functions[] = 'strip_tags';

			foreach ( $filters as $tag ) {
				foreach ( $functions as $function ) {
					// Only grab 10 of these. Yes, one might transform still on the 11th.
					$it = 10;
					$i  = 0;
					// phpcs:ignore, WordPress.CodeAnalysis.AssignmentInCondition
					while ( $priority = \has_filter( $tag, $function ) ) {
						$filtered[ $tag ][ $function ][] = $priority;
						\remove_filter( $tag, $function, $priority );
						// Some noob might've destroyed \WP_Hook. Safeguard.
						if ( ++$i > $it ) break 1;
					}
				}
			}
		}
	}

	/**
	 * Resets default title filters, for consistent output and sanitation.
	 *
	 * @since 3.1.0
	 * @internal Only to be used within $this->get_raw_generated_title()
	 * @uses $this->remove_default_title_filters()
	 */
	protected function reset_default_title_filters() {
		$this->remove_default_title_filters( true );
	}

	/**
	 * Generates a title, based on current query, without additions or prefixes.
	 *
	 * @since 3.1.0
	 * @since 4.2.0 Flipped order of query tests.
	 * @internal
	 * @see $this->get_raw_generated_title()
	 *
	 * @return string The generated title.
	 */
	protected function generate_title_from_query() {

		$title = '';

		if ( $this->is_404() ) {
			$title = $this->get_static_404_title();
		} elseif ( $this->is_search() ) {
			$title = $this->get_generated_search_query_title();
		} elseif ( $this->is_real_front_page() ) {
			$title = $this->get_static_front_page_title();
		} elseif ( $this->is_singular() ) {
			$title = $this->get_generated_single_post_title();
		} elseif ( $this->is_archive() ) {
			$title = $this->get_generated_archive_title();
		}

		return $title;
	}

	/**
	 * Generates a title, based on expected query, without additions or prefixes.
	 *
	 * @since 3.1.0
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 * @internal
	 * @see $this->get_raw_generated_title()
	 *
	 * @param array $args The query arguments. Required. Accepts 'id', 'taxonomy', and 'pta'.
	 * @return string The generated title. Empty if query can't be replicated.
	 */
	protected function generate_title_from_args( $args ) {

		$title = '';

		if ( $args['taxonomy'] ) {
			$title = $this->get_generated_archive_title( \get_term( $args['id'], $args['taxonomy'] ) );
		} elseif ( $args['pta'] ) {
			$title = $this->get_generated_archive_title( \get_post_type_object( $args['pta'] ) );
		} else {
			if ( $this->is_real_front_page_by_id( $args['id'] ) ) {
				$title = $this->get_static_front_page_title();
			} else {
				$title = $this->get_generated_single_post_title( $args['id'] );
			}
		}

		return $title;
	}

	/**
	 * Generates front page title.
	 *
	 * This is an alias of get_blogname(). The difference is that this is used for
	 * the front-page title output solely, whereas the other one has a mixed usage.
	 *
	 * @since 3.1.0
	 * @since 4.2.0 1. Now listens to the new `site_title` option.
	 *              2. Now applies filters.
	 *
	 * @return string The generated front page title.
	 */
	public function get_static_front_page_title() {
		return $this->get_blogname();
	}

	/**
	 * Returns the archive title. Also works in admin.
	 *
	 * @NOTE Taken from WordPress core. Altered to work for metadata.
	 * @see WP Core get_the_archive_title()
	 *
	 * @since 3.1.0
	 * @since 4.0.2 Now asserts the correct tag taxonomy condition.
	 * @since 4.0.5 1: Now no longer uses `get_the_author()` to fetch the author's display name,
	 *                 but uses the provided term object instead.
	 *              2: The first parameter now accepts `\WP_User` objects.
	 * @since 4.1.2 Now supports WP 5.5 archive titles.
	 *
	 * @param \WP_Term|\WP_User|\WP_Post_Type|\WP_Error|null $object The Term object or error.
	 *                                                               Leave null to autodetermine query.
	 * @return string|string[] The generated archive title, not escaped.
	 *                         When $get is 'admin', it returns an map of [prefix,title].
	 */
	public function get_generated_archive_title( $object = null ) {

		if ( $object && \is_wp_error( $object ) )
			return '';

		[ $title ] = $this->get_raw_generated_archive_title_items( $object );

		return $title;
	}

	/**
	 * Returns the archive title items. Also works in admin.
	 *
	 * @NOTE Taken from WordPress core. Altered to work for metadata.
	 * @see WP Core get_the_archive_title()
	 *
	 * @since 4.2.0
	 *
	 * @param \WP_Term|\WP_User|\WP_Post_Type|null $object The Term object.
	 *                                                     Leave null to autodetermine query.
	 * @return String[$title,$prefix,$title_without_prefix] The generated archive title items, not escaped.
	 */
	public function get_raw_generated_archive_title_items( $object = null ) {

		$filterobject = $object ?? \get_queried_object();

		/**
		 * @since 2.6.0
		 *
		 * @param string                          $title  The short circuit title.
		 * @param \WP_Term|\WP_User|\WP_Post_Type $object The archive object.
		 */
		$title = (string) \apply_filters_deprecated(
			'the_seo_framework_the_archive_title',
			[
				'',
				$filterobject,
			],
			'4.2.0 of The SEO Framework',
			'the_seo_framework_generated_archive_title_prefix and the_seo_framework_generated_archive_title'
		);

		if ( $title )
			return [ $title, '', $title ];

		[ $title, $prefix ] = $object
			? $this->get_generate_archive_title_from_term( $object )
			: $this->get_generate_archive_title_from_query();

		$title_without_prefix = $title;

		if ( $this->use_generated_archive_prefix( $object ) ) {
			/**
			 * Filters the archive title prefix.
			 * This is a sibling of WordPress's `get_the_archive_title_prefix`,
			 * but then without the HTML, and runs optionally, based on site-settings,
			 * and then with the second paramter: `$object`.
			 *
			 * @since 4.2.0
			 *
			 * @param string                          $prefix  Archive title prefix.
			 * @param \WP_Term|\WP_User|\WP_Post_Type $object The archive object.
			 */
			$prefix = \apply_filters_ref_array(
				'the_seo_framework_generated_archive_title_prefix',
				[
					$prefix,
					$filterobject,
				]
			);

			if ( $prefix ) {
				$title = sprintf(
					/* translators: 1: Title prefix. 2: Title. */
					\_x( '%1$s %2$s', 'archive title', 'default' ),
					$prefix,
					$title
				);
			}
		}

		/**
		 * Filters the archive title.
		 * This is a sibling of WordPress's `get_the_archive_title`,
		 * but then without the HTML.
		 *
		 * @since 3.0.4
		 * @since 4.2.0 Added the `$prefix` and `$origintitle_without_prefixal_title` parameters.
		 *
		 * @param string                          $title                Archive title to be displayed.
		 * @param \WP_Term|\WP_User|\WP_Post_Type $object               The archive object.
		 * @param string                          $title_without_prefix Archive title without prefix.
		 * @param string                          $prefix               Archive title prefix.
		 */
		$title = \apply_filters_ref_array(
			'the_seo_framework_generated_archive_title',
			[
				$title,
				$filterobject,
				$title_without_prefix,
				$prefix,
			]
		);

		return [ $title, $prefix, $title_without_prefix ];
	}

	/**
	 * Returns the generated archive title by evaluating the input Term only.
	 *
	 * @since 4.2.0
	 * @see $this->get_generate_archive_title_from_term() which evaluates from arguments.
	 *
	 * @return string[$title,$prefix] The title and prefix.
	 */
	protected function get_generate_archive_title_from_query() {

		$title  = \__( 'Archives', 'default' );
		$prefix = '';

		if ( $this->is_category() ) {
			$title  = $this->get_generated_single_term_title( \get_queried_object() );
			$prefix = \_x( 'Category:', 'category archive title prefix', 'default' );
		} elseif ( $this->is_tag() ) {
			$title  = $this->get_generated_single_term_title( \get_queried_object() );
			$prefix = \_x( 'Tag:', 'tag archive title prefix', 'default' );
		} elseif ( $this->is_author() ) {
			$title  = \get_queried_object()->display_name ?? '';
			$prefix = \_x( 'Author:', 'author archive title prefix', 'default' );
		} elseif ( $this->is_date() ) {
			if ( $this->is_year() ) {
				$title  = \get_the_date( \_x( 'Y', 'yearly archives date format', 'default' ) );
				$prefix = \_x( 'Year:', 'date archive title prefix', 'default' );
			} elseif ( $this->is_month() ) {
				$title  = \get_the_date( \_x( 'F Y', 'monthly archives date format', 'default' ) );
				$prefix = \_x( 'Month:', 'date archive title prefix', 'default' );
			} elseif ( $this->is_day() ) {
				$title  = \get_the_date( \_x( 'F j, Y', 'daily archives date format', 'default' ) );
				$prefix = \_x( 'Day:', 'date archive title prefix', 'default' );
			}
		} elseif ( \is_tax( 'post_format' ) ) {
			if ( \is_tax( 'post_format', 'post-format-aside' ) ) {
				$title = \_x( 'Asides', 'post format archive title', 'default' );
			} elseif ( \is_tax( 'post_format', 'post-format-gallery' ) ) {
				$title = \_x( 'Galleries', 'post format archive title', 'default' );
			} elseif ( \is_tax( 'post_format', 'post-format-image' ) ) {
				$title = \_x( 'Images', 'post format archive title', 'default' );
			} elseif ( \is_tax( 'post_format', 'post-format-video' ) ) {
				$title = \_x( 'Videos', 'post format archive title', 'default' );
			} elseif ( \is_tax( 'post_format', 'post-format-quote' ) ) {
				$title = \_x( 'Quotes', 'post format archive title', 'default' );
			} elseif ( \is_tax( 'post_format', 'post-format-link' ) ) {
				$title = \_x( 'Links', 'post format archive title', 'default' );
			} elseif ( \is_tax( 'post_format', 'post-format-status' ) ) {
				$title = \_x( 'Statuses', 'post format archive title', 'default' );
			} elseif ( \is_tax( 'post_format', 'post-format-audio' ) ) {
				$title = \_x( 'Audio', 'post format archive title', 'default' );
			} elseif ( \is_tax( 'post_format', 'post-format-chat' ) ) {
				$title = \_x( 'Chats', 'post format archive title', 'default' );
			}
		} elseif ( \is_post_type_archive() ) {
			$title  = $this->get_generated_post_type_archive_title();
			$prefix = \_x( 'Archives:', 'post type archive title prefix', 'default' );
		} elseif ( $this->is_tax() ) {
			$term = \get_queried_object();

			if ( $term ) {
				$title  = $this->get_generated_single_term_title( $term );
				$prefix = sprintf(
					/* translators: %s: Taxonomy singular name. */
					\_x( '%s:', 'taxonomy term archive title prefix', 'default' ),
					$this->get_tax_type_label( $term->taxonomy ?? '' )
				);
			}
		}

		return [ $title, $prefix ];
	}

	/**
	 * Returns the generated archive title by evaluating the input Term only.
	 *
	 * @since 4.2.0
	 * @see $this->get_generate_archive_title_from_query() which evalutates the query only.
	 *
	 * @param \WP_Term|\WP_User $term The Term object.
	 * @return string[$title,$prefix] The title and prefix.
	 */
	protected function get_generate_archive_title_from_term( $term ) {

		$title  = \__( 'Archives', 'default' );
		$prefix = '';

		if ( ! empty( $term->taxonomy ) ) {
			$title = $this->get_generated_single_term_title( $term );

			switch ( $term->taxonomy ) :
				case 'category':
					$prefix = \_x( 'Category:', 'category archive title prefix', 'default' );
					break;
				case 'post_tag':
					$prefix = \_x( 'Tag:', 'tag archive title prefix', 'default' );
					break;
				default:
					$prefix = sprintf(
						/* translators: %s: Taxonomy singular name. */
						\_x( '%s:', 'taxonomy term archive title prefix', 'default' ),
						$this->get_tax_type_label( $term->taxonomy )
					);
					break;
			endswitch;
		} elseif ( $term instanceof \WP_User && isset( $term->display_name ) ) {
			$title  = $term->display_name;
			$prefix = \_x( 'Author:', 'author archive title prefix', 'default' );
		} elseif ( $term instanceof \WP_Post_Type && isset( $term->name ) ) {
			$title  = $this->get_generated_post_type_archive_title( $term->name );
			$prefix = \_x( 'Archives:', 'post type archive title prefix', 'default' );
		}

		return [ $title, $prefix ];
	}

	/**
	 * Returns Post Title from ID.
	 *
	 * @NOTE Taken from WordPress core. Altered to work in the Admin area.
	 * @see WP Core single_post_title()
	 *
	 * @since 3.1.0
	 *
	 * @param int|\WP_Post $id The Post ID or post object.
	 * @return string The generated post title.
	 */
	public function get_generated_single_post_title( $id = 0 ) {

		//? Home queries can be tricky. Use get_the_real_ID to be certain.
		$_post = \get_post( $id ?: $this->get_the_real_ID() );

		if ( isset( $_post->post_title ) ) {
			/**
			 * Filters the page title for a single post.
			 *
			 * @since WP Core 0.71
			 *
			 * @param string   $_post_title The single post page title.
			 * @param \WP_Post $_post       The current queried object as returned by get_queried_object().
			 */
			$title = \apply_filters( 'single_post_title', $_post->post_title, $_post );
		}

		return $title ?? '';
	}

	/**
	 * Fetches single term title.
	 *
	 * It can autodetermine the term; so, perform your checks prior calling.
	 *
	 * Taken from WordPress core. Altered to work in the Admin area.
	 *
	 * @see WP Core single_term_title()
	 *
	 * @since 3.1.0
	 * @since 4.0.0 No longer redundantly tests the query, now only uses the term input or queried object.
	 * @since 4.0.2 Now asserts the correct tag taxonomy condition.
	 *
	 * @param null|\WP_Term $term The term name, required in the admin area.
	 * @return string The generated single term title.
	 */
	public function get_generated_single_term_title( $term = null ) {

		if ( \is_null( $term ) )
			$term = \get_queried_object();

		if ( ! isset( $term->name ) ) return '';

		switch ( $term->category ) :
			case 'category':
				/**
				 * Filter the category archive page title.
				 *
				 * @since WP Core 2.0.10
				 *
				 * @param string $term_name Category name for archive being displayed.
				 */
				$term_name = \apply_filters( 'single_cat_title', $term->name );
				break;
			case 'post_tag':
				/**
				 * Filter the tag archive page title.
				 *
				 * @since WP Core 2.3.0
				 *
				 * @param string $term_name Tag name for archive being displayed.
				 */
				$term_name = \apply_filters( 'single_tag_title', $term->name );
				break;
			default:
				/**
				 * Filter the custom taxonomy archive page title.
				 *
				 * @since WP Core 3.1.0
				 *
				 * @param string $term_name Term name for archive being displayed.
				 */
				$term_name = \apply_filters( 'single_term_title', $term->name );
				break;
		endswitch;

		return $term_name;
	}

	/**
	 * Fetches single term title.
	 *
	 * @NOTE Taken from WordPress core. Altered to work in the Admin area.
	 * @see WP Core post_type_archive_title()
	 *
	 * @since 3.1.0
	 * @since 4.2.0 Now actually works in the admin area, provided you forward $post_type.
	 *
	 * @param string $post_type The post type.
	 * @return string The generated post type archive title.
	 */
	public function get_generated_post_type_archive_title( $post_type = '' ) {

		if ( ! $post_type && ! \is_post_type_archive() )
			return '';

		$post_type = $post_type ?: $this->get_current_post_type();

		if ( \is_array( $post_type ) )
			$post_type = reset( $post_type );

		if ( ! \in_array( $post_type, $this->get_public_post_type_archives(), true ) )
			return '';

		/**
		 * Filters the post type archive title.
		 *
		 * @since WP Core 3.1.0
		 *
		 * @param string $post_type_name Post type 'name' label.
		 * @param string $post_type      Post type.
		 */
		$title = \apply_filters_ref_array(
			'post_type_archive_title',
			[
				$this->get_post_type_label( $post_type, false ),
				$post_type,
			]
		);

		return $title;
	}

	/**
	 * Returns untitled title.
	 *
	 * @since 3.1.0
	 *
	 * @return string The untitled title.
	 */
	public function get_static_untitled_title() {
		return \__( 'Untitled', 'default' );
	}

	/**
	 * Returns search title.
	 *
	 * @since 3.1.0
	 *
	 * @return string The generated search title, partially escaped.
	 */
	public function get_generated_search_query_title() {
		/* translators: %s: search phrase */
		return sprintf( \__( 'Search Results for &#8220;%s&#8221;', 'default' ), \get_search_query( true ) );
	}

	/**
	 * Returns 404 title.
	 *
	 * @since 2.6.0
	 * @since 3.1.0 No longer accepts parameters, nor has conditions.
	 *
	 * @return string The generated 404 title.
	 */
	public function get_static_404_title() {
		/**
		 * @since 2.5.2
		 * @param string $title The 404 title.
		 */
		return (string) \apply_filters( 'the_seo_framework_404_title', '404' );
	}

	/**
	 * Merges title branding, when allowed.
	 *
	 * @since 3.1.0
	 * @since 3.1.2 Added strict taxonomical check.
	 * @since 3.1.3 Fixed conditional logic.
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 * @uses $this->get_title_branding_from_query()
	 * @uses $this->get_title_branding_from_args()
	 *
	 * @param string     $title The title. Passed by reference.
	 * @param array|null $args  The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                          Leave null to autodetermine query.
	 */
	public function merge_title_branding( &$title, $args = null ) {

		if ( null === $args ) {
			$data = $this->get_title_branding_from_query();
		} else {
			$this->fix_generation_args( $args );
			$data = $this->get_title_branding_from_args( $args );
		}

		$title    = trim( $title );
		$addition = trim( $data['addition'] );

		if ( $addition && $title ) {
			$sep = $this->get_title_separator();

			if ( 'left' === $data['seplocation'] ) {
				$title = "$addition $sep $title";
			} else {
				$title = "$title $sep $addition";
			}
		}
	}

	/**
	 * Returns the addition and seplocation from query.
	 *
	 * @since 3.2.2
	 * @see $this->merge_title_branding();
	 *
	 * @return array { 'addition', 'seplocation' }
	 */
	protected function get_title_branding_from_query() {

		if ( $this->is_real_front_page() ) {
			$addition    = $this->get_home_title_additions();
			$seplocation = $this->get_home_title_seplocation();
		} else {
			$addition    = $this->get_blogname();
			$seplocation = $this->get_title_seplocation();
		}

		return compact( 'addition', 'seplocation' );
	}

	/**
	 * Returns the addition and seplocation from arguments.
	 *
	 * @since 3.2.2
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 * @see $this->merge_title_branding();
	 *
	 * @param array $args The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 * @return array { 'addition', 'seplocation' }
	 */
	protected function get_title_branding_from_args( $args ) {

		if ( ! $args['taxonomy'] && ! $args['pta'] && $this->is_real_front_page_by_id( $args['id'] ) ) {
			$addition    = $this->get_home_title_additions();
			$seplocation = $this->get_home_title_seplocation();
		} else {
			$addition    = $this->get_blogname();
			$seplocation = $this->get_title_seplocation();
		}

		return compact( 'addition', 'seplocation' );
	}

	/**
	 * Merges pagination with the title, if paginated.
	 *
	 * @since 3.1.0
	 * @since 3.1.2 Now uses the registered default translation.
	 *
	 * @param string $title The title. Passed by reference.
	 */
	public function merge_title_pagination( &$title ) {

		$page  = $this->page();
		$paged = $this->paged();

		if ( $paged >= 2 || $page >= 2 ) {
			$sep = $this->get_title_separator();

			// phpcs:ignore, WordPress.WP.I18n -- WP didn't add translator code either.
			$paging = sprintf( \__( 'Page %s', 'default' ), max( $paged, $page ) );

			if ( \is_rtl() ) {
				$title = "$paging $sep $title";
			} else {
				$title = "$title $sep $paging";
			}
		}
	}

	/**
	 * Merges title protection prefixes.
	 *
	 * @since 3.1.0
	 * @since 3.1.2 Added strict taxonomical checks for title protection.
	 * @since 3.1.3 Fixed conditional logic.
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 * @see $this->merge_title_prefixes()
	 *
	 * @param string     $title The title. Passed by reference.
	 * @param array|null $args  The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                          Leave null to autodetermine query.
	 * @return void
	 */
	public function merge_title_protection( &$title, $args = null ) {

		if ( null === $args ) {
			$id  = $this->get_the_real_ID();
			$run = $this->is_singular();
		} else {
			$this->fix_generation_args( $args );
			$id  = $args['id'];
			$run = ! $args['taxonomy'] && ! $args['pta'];
		}

		if ( $run ) return;

		$post = $id ? \get_post( $id ) : null;

		if ( isset( $post->post_password ) && '' !== $post->post_password ) {
			/**
			 * Filters the text prepended to the post title of private posts.
			 *
			 * The filter is only applied on the front end.
			 *
			 * @since WP Core 2.8.0
			 *
			 * @param string  $prepend Text displayed before the post title.
			 *                         Default 'Private: %s'.
			 * @param WP_Post $post    Current post object.
			 */
			// phpcs:ignore, WordPress.WP.I18n -- WordPress doesn't have a comment, either.
			$protected_title_format = (string) \apply_filters( 'protected_title_format', \__( 'Protected: %s', 'default' ), $post );
			$title                  = sprintf( $protected_title_format, $title );
		} elseif ( isset( $post->post_status ) && 'private' === $post->post_status ) {
			/**
			 * Filters the text prepended to the post title of private posts.
			 *
			 * The filter is only applied on the front end.
			 *
			 * @since WP Core 2.8.0
			 *
			 * @param string  $prepend Text displayed before the post title.
			 *                         Default 'Private: %s'.
			 * @param WP_Post $post    Current post object.
			 */
			// phpcs:ignore, WordPress.WP.I18n -- WordPress doesn't have a comment, either.
			$private_title_format = (string) \apply_filters( 'private_title_format', \__( 'Private: %s', 'default' ), $post );
			$title                = sprintf( $private_title_format, $title );
		}
	}

	/**
	 * Gets Title Separator.
	 * Memoizes the return value.
	 *
	 * @since 2.6.0
	 *
	 * @return string The Separator, unescaped.
	 */
	public function get_title_separator() {
		static $sep;
		/**
		 * @since 2.3.9
		 * @param string $eparator The title separator
		 */
		return isset( $sep )
			? $sep
			: $sep = (string) \apply_filters( 'the_seo_framework_title_separator', $this->get_separator( 'title' ) );
	}

	/**
	 * Returns title separator location.
	 *
	 * @since 2.6.0
	 * @since 3.1.0 1. Removed the first $seplocation parameter.
	 *              2. The first parameter is now $home
	 *              3. Removed caching.
	 *              4. Removed filters.
	 * @since 4.0.0 The homepage option's return value is now reversed from expected.
	 *
	 * @param bool $home The home separator location.
	 * @return string The separator location.
	 */
	public function get_title_seplocation( $home = false ) {
		return $home ? $this->get_option( 'home_title_location' ) : $this->get_option( 'title_location' );
	}

	/**
	 * Gets Title Seplocation for the homepage.
	 *
	 * @since 2.6.0
	 * @since 3.1.0 Removed first parameter.
	 * @since 4.0.0 Left is now right, and right is now left.
	 *
	 * @return string The Seplocation for the homepage.
	 */
	public function get_home_title_seplocation() {
		return $this->get_title_seplocation( true );
	}

	/**
	 * Determines whether to add or remove title protection prefixes.
	 *
	 * @since 3.2.4
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 * NOTE: This does not guarantee that protection is to be added. Only that it will be considered. Bad method name.
	 * @see $this->merge_title_protection()
	 *
	 * @param array|null $args The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                         Leave null to autodetermine query.
	 * @return bool True when prefixes are allowed.
	 */
	public function use_title_protection( $args = null ) {

		if ( null === $args ) {
			$use = $this->is_singular();
		} else {
			$this->fix_generation_args( $args );
			$use = $args && ! $args['taxonomy'] && ! $args['pta'];
		}

		return $use;
	}

	/**
	 * Determines whether to add or remove title pagination additions.
	 *
	 * @since 3.2.4
	 * NOTE: This does not guarantee that pagination is to be added. Only that it will be considered. Bad method name.
	 * @see $this->merge_title_pagination()
	 *
	 * @param array|null $args The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                         Leave null to autodetermine query.
	 * @return bool True when additions are allowed.
	 */
	public function use_title_pagination( $args = null ) {

		//? Only add pagination if the query is autodetermined, and on a real page.
		if ( null === $args ) {
			if ( $this->is_404() || \is_admin() ) {
				$use = false;
			} else {
				$use = true;
			}
		} else {
			$use = false;
		}

		return $use;
	}

	/**
	 * Determines whether to add or remove title branding additions.
	 *
	 * @since 3.1.0
	 * @since 3.1.2 1. Added filter.
	 *              2. Added strict taxonomical check.
	 * @since 3.2.2 Now differentiates from query and parameter input.
	 * @since 4.1.0 Added the second $social parameter.
	 * @since 4.2.0 Now supports the `$args['pta']` index.
	 * @see $this->merge_title_branding()
	 * @uses $this->use_title_branding_from_query()
	 * @uses $this->use_title_branding_from_args()
	 *
	 * @param array|null  $args  The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 *                           Leave null to autodetermine query.
	 * @param bool|string $social Whether the title is meant for social display.
	 *                            Also accepts string 'og' and 'twitter' for future proofing.
	 * @return bool True when additions are allowed.
	 */
	public function use_title_branding( $args = null, $social = false ) {

		// If social, test its option first.
		$use = $social ? ! $this->get_option( 'social_title_rem_additions' ) : true;

		// Reevaluate from general title settings, overriding social.
		if ( $use ) {
			if ( null === $args ) {
				$use = $this->use_title_branding_from_query();
			} else {
				$this->fix_generation_args( $args );
				$use = $this->use_title_branding_from_args( $args );
			}
		}

		/**
		 * @since 3.1.2
		 * @since 4.1.0 Added the third $social parameter.
		 * @param string     $use    Whether to use branding.
		 * @param array|null $args   The query arguments. Contains 'id', 'taxonomy', and 'pta'.
		 *                           Is null when query is autodetermined.
		 * @param bool       $social Whether the title is meant for social display.
		 */
		return \apply_filters_ref_array(
			'the_seo_framework_use_title_branding',
			[
				$use,
				$args,
				(bool) $social,
			]
		);
	}

	/**
	 * Determines whether to add or remove title branding additions in the query.
	 *
	 * @since 3.2.2
	 * @since 4.0.0 Added use_taxonomical_title_branding() check.
	 * @since 4.0.2 Removed contemned \is_post_type_archive() check for taxonomical branding.
	 * @since 4.2.0 Can now test for custom post type archive branding.
	 * @see $this->use_title_branding()
	 *
	 * @return bool
	 */
	protected function use_title_branding_from_query() {

		if ( $this->is_real_front_page() ) {
			$use = $this->use_home_page_title_tagline();
		} elseif ( $this->is_singular() ) {
			$use = $this->use_singular_title_branding();
		} elseif ( $this->is_term_meta_capable() ) {
			$use = $this->use_taxonomical_title_branding();
		} elseif ( \is_post_type_archive() ) {
			$use = $this->use_post_type_archive_title_branding();
		} else {
			$use = ! $this->get_option( 'title_rem_additions' );
		}

		return $use;
	}

	/**
	 * Determines whether to add or remove title branding additions from provided arguments.
	 *
	 * @since 3.2.2
	 * @since 4.0.0 Added use_taxonomical_title_branding() check.
	 * @since 4.2.0 1. Now supports the `$args['pta']` index.
	 *              2. Now tests for custom post type archive branding.
	 * @see $this->use_title_branding()
	 *
	 * @param array $args The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
	 * @return bool
	 */
	protected function use_title_branding_from_args( $args ) {

		if ( $args['taxonomy'] ) {
			$use = $this->use_taxonomical_title_branding( $args['id'] );
		} elseif ( $args['pta'] ) {
			$use = $this->use_post_type_archive_title_branding( $args['pta'] );
		} else {
			if ( $this->is_real_front_page_by_id( $args['id'] ) ) {
				$use = $this->use_home_page_title_tagline();
			} else {
				$use = $this->use_singular_title_branding( $args['id'] );
			}
		}

		return $use;
	}

	/**
	 * Determines whether to use the autogenerated archive title prefix or not.
	 *
	 * @since 3.1.0
	 * @since 4.0.5 1: Added first parameter `$term`.
	 *              2: Added filter.
	 *
	 * @param \WP_Term|\WP_User|\WP_Post_Type|null $term The Term object. Leave null to autodermine query.
	 * @return bool
	 */
	public function use_generated_archive_prefix( $term = null ) {

		$term = $term ?? \get_queried_object();
		$use  = ! $this->get_option( 'title_rem_prefixes' );

		/**
		 * @since 4.0.5
		 * @param string                          $use  Whether to use branding.
		 * @param \WP_Term|\WP_User|\WP_Post_Type $term The current term.
		 */
		return \apply_filters_ref_array( 'the_seo_framework_use_archive_prefix', [ $use, $term ] );
	}

	/**
	 * Determines whether to add homepage tagline.
	 *
	 * @since 2.6.0
	 * @since 3.0.4 Now checks for `$this->get_home_title_additions()`.
	 *
	 * @return bool
	 */
	public function use_home_page_title_tagline() {
		return $this->get_option( 'homepage_tagline' ) && $this->get_home_title_additions();
	}

	/**
	 * Determines whether to add the title tagline for the post.
	 *
	 * @since 3.1.0
	 *
	 * @param int $id The post ID. Optional.
	 * @return bool
	 */
	public function use_singular_title_branding( $id = 0 ) {
		return ! $this->get_post_meta_item( '_tsf_title_no_blogname', $id ) && ! $this->get_option( 'title_rem_additions' );
	}

	/**
	 * Determines whether to add the title tagline for the term.
	 *
	 * @since 4.0.0
	 *
	 * @param int $id The term ID. Optional.
	 * @return bool
	 */
	public function use_taxonomical_title_branding( $id = 0 ) {
		return ! $this->get_term_meta_item( 'title_no_blog_name', $id ) && ! $this->get_option( 'title_rem_additions' );
	}

	/**
	 * Determines whether to add the title tagline for the pta.
	 *
	 * @since 4.2.0
	 *
	 * @param string $pta The post type archive. Optional.
	 * @return bool
	 */
	public function use_post_type_archive_title_branding( $pta = '' ) {
		return ! $this->get_post_type_archive_meta_item( 'title_no_blog_name', $pta ) && ! $this->get_option( 'title_rem_additions' );
	}

	/**
	 * Returns the homepage additions (tagline) from option or bloginfo, when set.
	 * Memoizes the return value.
	 *
	 * @since 4.1.0
	 * @uses $this->get_blogdescription(), that method already trims.
	 *
	 * @return string The trimmed tagline.
	 */
	public function get_home_title_additions() {
		return memo() ?? memo(
			$this->s_title_raw(
				$this->get_option( 'homepage_title_tagline' )
				?: $this->get_blogdescription()
				?: ''
			)
		);
	}
}

Zerion Mini Shell 1.0