ProShell v2.0
Dashboard
Server Info
Server: 158.106.128.192
PHP: 8.2.33
home
planet5
public_html
bansibaba.com
wp-includes
2026-09-16 10:28:19
Editing: class-frontend.php
Cancel
Save Changes
<?php /** * WPSEO plugin file. * * @package WPSEO\Frontend */ use Yoast\WP\SEO\Helpers\Author_Archive_Helper; /** * Main frontend class for Yoast SEO, responsible for the SEO output as well as removing * default WordPress output. */ class WPSEO_Frontend { /** * Instance of this class. * * @var object */ public static $instance; /** * Toggle indicating whether output buffering has been started. * * @var bool */ private $ob_started = false; /** * Holds the canonical URL for the current page. * * @var string */ private $canonical = null; /** * Holds the canonical URL for the current page that cannot be overriden by a manual canonical input. * * @var string */ private $canonical_no_override = null; /** * Holds the canonical URL for the current page without pagination. * * @var string */ private $canonical_unpaged = null; /** * Holds the pages meta description. * * @var string */ private $metadesc = null; /** * Holds the generated title for the page. * * @var string */ private $title = null; /** * An instance of the WPSEO_Frontend_Page_Type class. * * @var WPSEO_Frontend_Page_Type */ protected $frontend_page_type; /** * An instance of the WPSEO_WooCommerce_Shop_Page class. * * @var WPSEO_WooCommerce_Shop_Page */ protected $woocommerce_shop_page; /** * Default title with replace-vars. * * @var string */ public static $default_title = '%%title%% %%sep%% %%sitename%%'; /** * Class constructor. * * Adds and removes a lot of filters. */ protected function __construct() { add_action( 'wp_head', [ $this, 'front_page_specific_init' ], 0 ); add_action( 'wp_head', [ $this, 'head' ], 1 ); // The head function here calls action wpseo_head, to which we hook all our functionality. add_action( 'wpseo_head', [ $this, 'debug_mark' ], 2 ); add_action( 'wpseo_head', [ $this, 'metadesc' ], 6 ); add_action( 'wpseo_head', [ $this, 'robots' ], 10 ); add_action( 'wpseo_head', [ $this, 'canonical' ], 20 ); add_action( 'wpseo_head', [ $this, 'adjacent_rel_links' ], 21 ); // Remove actions that we will handle through our wpseo_head call, and probably change the output of. remove_action( 'wp_head', 'rel_canonical' ); remove_action( 'wp_head', 'index_rel_link' ); remove_action( 'wp_head', 'start_post_rel_link' ); remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head' ); remove_action( 'wp_head', 'noindex', 1 ); // When using WP 4.4, just use the new hook. add_filter( 'pre_get_document_title', [ $this, 'title' ], 15 ); add_filter( 'wp_title', [ $this, 'title' ], 15, 3 ); add_filter( 'thematic_doctitle', [ $this, 'title' ], 15 ); add_action( 'wp', [ $this, 'page_redirect' ], 99 ); add_action( 'template_redirect', [ $this, 'noindex_robots' ] ); add_filter( 'loginout', [ $this, 'nofollow_link' ] ); add_filter( 'register', [ $this, 'nofollow_link' ] ); // Add support for shortcodes to category descriptions. add_filter( 'category_description', [ $this, 'custom_category_descriptions_add_shortcode_support' ] ); // Fix the WooThemes woo_title() output. add_filter( 'woo_title', [ $this, 'fix_woo_title' ], 99 ); if ( WPSEO_Options::get( 'disable-date', false ) || WPSEO_Options::get( 'disable-author', false ) || WPSEO_Options::get( 'disable-post_format', false ) ) { add_action( 'wp', [ $this, 'archive_redirect' ] ); } add_action( 'template_redirect', [ $this, 'attachment_redirect' ], 1 ); add_filter( 'the_content_feed', [ $this, 'embed_rssfooter' ] ); add_filter( 'the_excerpt_rss', [ $this, 'embed_rssfooter_excerpt' ] ); // For WordPress functions below 4.4. if ( WPSEO_Options::get( 'forcerewritetitle', false ) && ! current_theme_supports( 'title-tag' ) ) { add_action( 'template_redirect', [ $this, 'force_rewrite_output_buffer' ], 99999 ); add_action( 'wp_footer', [ $this, 'flush_cache' ], - 1 ); } if ( WPSEO_Options::get( 'title_test', 0 ) > 0 ) { add_filter( 'wpseo_title', [ $this, 'title_test_helper' ] ); } $this->woocommerce_shop_page = new WPSEO_WooCommerce_Shop_Page(); $integrations = [ new WPSEO_Frontend_Primary_Category(), new WPSEO_Schema(), new WPSEO_Handle_404(), new WPSEO_Remove_Reply_To_Com(), new WPSEO_OpenGraph_OEmbed(), $this->woocommerce_shop_page, ]; foreach ( $integrations as $integration ) { $integration->register_hooks(); } } /** * Initialize the functions that only need to run on the frontpage. */ public function front_page_specific_init() { if ( ! is_front_page() ) { return; } add_action( 'wpseo_head', [ $this, 'webmaster_tools_authentication' ], 90 ); } /** * Resets the entire class so canonicals, titles etc can be regenerated. */ public function reset() { self::$instance = null; foreach ( get_class_vars( __CLASS__ ) as $name => $default ) { switch ( $name ) { // Clear the class instance to be re-initialized. case 'instance': self::$instance = null; break; // Exclude these properties from being reset. case 'woocommerce_shop_page': case 'default_title': break; // Reset property to the class default. default: $this->$name = $default; break; } } WPSEO_Options::ensure_options_exist(); } /** * Get the singleton instance of this class. * * @return WPSEO_Frontend */ public static function get_instance() { if ( ! ( self::$instance instanceof self ) ) { self::$instance = new self(); } return self::$instance; } /** * Override Woo's title with our own. * * @param string $title Title string. * * @return string */ public function fix_woo_title( $title ) { return $this->title( $title ); } /** * Used for static home and posts pages as well as singular titles. * * @param object|null $object If filled, object to get the title for. * * @return string */ public function get_content_title( $object = null ) { if ( $object === null ) { $object = $GLOBALS['wp_query']->get_queried_object(); } $title = $this->get_seo_title( $object ); if ( $title !== '' ) { return $title; } $post_type = ( isset( $object->post_type ) ? $object->post_type : $object->query_var ); return $this->get_title_from_options( 'title-' . $post_type, $object ); } /** * Retrieves the SEO title set in the SEO widget. * * @param null $object Object to retrieve the title from. * * @return string The SEO title for the specified object, or queried object if not supplied. */ public function get_seo_title( $object = null ) { if ( $object === null ) { $object = $GLOBALS['wp_query']->get_queried_object(); } if ( ! is_object( $object ) ) { return $this->get_title_from_options( 'title-404-wpseo' ); } $title = $this->get_seo_meta_value( 'title', $object->ID ); if ( $title !== '' ) { return $this->replace_vars( $title, $object ); } return $title; } /** * Used for category, tag, and tax titles. * * @return string */ public function get_taxonomy_title() { $object = $GLOBALS['wp_query']->get_queried_object(); $title = WPSEO_Taxonomy_Meta::get_term_meta( $object, $object->taxonomy, 'title' ); if ( is_string( $title ) && $title !== '' ) { return $this->replace_vars( $title, $object ); } return $this->get_title_from_options( 'title-tax-' . $object->taxonomy, $object ); } /** * Used for author titles. * * @return string */ public function get_author_title() { $author_id = get_query_var( 'author' ); $title = trim( get_the_author_meta( 'wpseo_title', $author_id ) ); if ( $title !== '' ) { return $this->replace_vars( $title, [] ); } return $this->get_title_from_options( 'title-author-wpseo' ); } /** * Simple function to use to pull data from $options. * * All titles pulled from options will be run through the $this->replace_vars function. * * @param string $index Name of the page to get the title from the settings for. * @param object|array $var_source Possible object to pull variables from. * * @return string */ public function get_title_from_options( $index, $var_source = [] ) { $template = WPSEO_Options::get( $index, '' ); if ( $template === '' ) { if ( is_singular() ) { return $this->replace_vars( self::$default_title, $var_source ); } return ''; } return $this->replace_vars( $template, $var_source ); } /** * Get the default title for the current page. * * This is the fallback title generator used when a title hasn't been set for the specific content, taxonomy, author * details, or in the options. It scrubs off any present prefix before or after the title (based on $seplocation) in * order to prevent duplicate seperations from appearing in the title (this happens when a prefix is supplied to the * wp_title call on singular pages). * * @param string $sep The separator used between variables. * @param string $seplocation Whether the separator should be left or right. * @param string $title Possible title that's already set. * * @return string */ public function get_default_title( $sep, $seplocation, $title = '' ) { if ( 'right' === $seplocation ) { $regex = '`\s*' . preg_quote( trim( $sep ), '`' ) . '\s*`u'; } else { $regex = '`^\s*' . preg_quote( trim( $sep ), '`' ) . '\s*`u'; } $title = preg_replace( $regex, '', $title ); if ( ! is_string( $title ) || ( is_string( $title ) && $title === '' ) ) { $title = WPSEO_Utils::get_site_name(); $title = $this->add_paging_to_title( $sep, $seplocation, $title ); $title = $this->add_to_title( $sep, $seplocation, $title, wp_strip_all_tags( get_bloginfo( 'description' ), true ) ); return $title; } $title = $this->add_paging_to_title( $sep, $seplocation, $title ); $title = $this->add_to_title( $sep, $seplocation, $title, wp_strip_all_tags( get_bloginfo( 'name' ), true ) ); return $title; } /** * This function adds paging details to the title. * * @param string $sep Separator used in the title. * @param string $seplocation Whether the separator should be left or right. * @param string $title The title to append the paging info to. * * @return string */ public function add_paging_to_title( $sep, $seplocation, $title ) { global $wp_query; if ( ! empty( $wp_query->query_vars['paged'] ) && $wp_query->query_vars['paged'] > 1 ) { return $this->add_to_title( $sep, $seplocation, $title, $wp_query->query_vars['paged'] . '/' . $wp_query->max_num_pages ); } return $title; } /** * Add part to title, while ensuring that the $seplocation variable is respected. * * @param string $sep Separator used in the title. * @param string $seplocation Whether the separator should be left or right. * @param string $title The title to append the title_part to. * @param string $title_part The part to append to the title. * * @return string */ public function add_to_title( $sep, $seplocation, $title, $title_part ) { if ( 'right' === $seplocation ) { return $title . $sep . $title_part; } return $title_part . $sep . $title; } /** * Main title function. * * @param string $title Title that might have already been set. * @param string $separator Separator determined in theme (unused). * @param string $separator_location Whether the separator should be left or right. * * @return string */ public function title( $title, $separator = '', $separator_location = '' ) { if ( is_null( $this->title ) ) { $this->title = $this->generate_title( $title, $separator_location ); } return $this->title; } /** * Main title generation function. * * @param string $title Title that might have already been set. * @param string $separator_location Whether the separator should be left or right. * * @return string */ private function generate_title( $title, $separator_location ) { if ( is_feed() ) { return $title; } $separator = $this->replace_vars( '%%sep%%', [] ); $separator = ' ' . trim( $separator ) . ' '; if ( '' === trim( $separator_location ) ) { $separator_location = ( is_rtl() ) ? 'left' : 'right'; } // This needs to be kept track of in order to generate // default titles for singular pages. $original_title = $title; // This flag is used to determine if any additional // processing should be done to the title after the // main section of title generation completes. $modified_title = true; // This variable holds the page-specific title part // that is used to generate default titles. $title_part = ''; if ( WPSEO_Frontend_Page_Type::is_home_static_page() ) { $title = $this->get_content_title(); } elseif ( WPSEO_Frontend_Page_Type::is_home_posts_page() ) { $title = $this->get_title_from_options( 'title-home-wpseo' ); } elseif ( $this->woocommerce_shop_page->is_shop_page() ) { $title = $this->get_woocommerce_title(); if ( ! is_string( $title ) || $title === '' ) { $title = $this->get_post_type_archive_title( $separator, $separator_location ); } } elseif ( WPSEO_Frontend_Page_Type::is_simple_page() ) { $post = get_post( WPSEO_Frontend_Page_Type::get_simple_page_id() ); $title = $this->get_content_title( $post ); if ( ! is_string( $title ) || '' === $title ) { $title_part = $original_title; } } elseif ( is_search() ) { $title = $this->get_title_from_options( 'title-search-wpseo' ); if ( ! is_string( $title ) || '' === $title ) { /* translators: %s expands to the search phrase. */ $title_part = sprintf( __( 'Search for "%s"', 'wordpress-seo' ), esc_html( get_search_query() ) ); } } elseif ( is_category() || is_tag() || is_tax() ) { $title = $this->get_taxonomy_title(); if ( ! is_string( $title ) || '' === $title ) { if ( is_category() ) { $title_part = single_cat_title( '', false ); } elseif ( is_tag() ) { $title_part = single_tag_title( '', false ); } else { $title_part = single_term_title( '', false ); if ( $title_part === '' ) { $term = $GLOBALS['wp_query']->get_queried_object(); $title_part = $term->name; } } } } elseif ( is_author() ) { $title = $this->get_author_title(); if ( ! is_string( $title ) || '' === $title ) { $title_part = get_the_author_meta( 'display_name', get_query_var( 'author' ) ); } } elseif ( is_post_type_archive() ) { $title = $this->get_post_type_archive_title( $separator, $separator_location ); } elseif ( is_archive() ) { $title = $this->get_title_from_options( 'title-archive-wpseo' ); // @todo [JRF => Yoast] Should these not use the archive default if no title found ? // WPSEO_Options::get_default( 'wpseo_titles', 'title-archive-wpseo' ) // Replacement would be needed! if ( empty( $title ) ) { if ( is_month() ) { /* translators: %s expands to a time period, i.e. month name, year or specific date. */ $title_part = sprintf( __( '%s Archives', 'wordpress-seo' ), single_month_title( ' ', false ) ); } elseif ( is_year() ) { /* translators: %s expands to a time period, i.e. month name, year or specific date. */ $title_part = sprintf( __( '%s Archives', 'wordpress-seo' ), get_query_var( 'year' ) ); } elseif ( is_day() ) { /* translators: %s expands to a time period, i.e. month name, year or specific date. */ $title_part = sprintf( __( '%s Archives', 'wordpress-seo' ), get_the_date() ); } else { $title_part = __( 'Archives', 'wordpress-seo' ); } } } elseif ( is_404() ) { $title = $this->get_title_from_options( 'title-404-wpseo' ); // @todo [JRF => Yoast] Should these not use the 404 default if no title found ? // WPSEO_Options::get_default( 'wpseo_titles', 'title-404-wpseo' ) // Replacement would be needed! if ( empty( $title ) ) { $title_part = __( 'Page not found', 'wordpress-seo' ); } } else { // In case the page type is unknown, leave the title alone. $modified_title = false; // If you would like to generate a default title instead, // the following code could be used // $title_part = $title; // instead of the line above. } if ( ( $modified_title && empty( $title ) ) || ! empty( $title_part ) ) { $title = $this->get_default_title( $separator, $separator_location, $title_part ); } if ( defined( 'ICL_LANGUAGE_CODE' ) && false !== strpos( $title, ICL_LANGUAGE_CODE ) ) { $title = str_replace( ' @' . ICL_LANGUAGE_CODE, '', $title ); } /** * Filter: 'wpseo_title' - Allow changing the Yoast SEO <title> output. * * @api string $title The page title being put out. */ return esc_html( wp_strip_all_tags( stripslashes( apply_filters( 'wpseo_title', $title ) ), true ) ); } /** * Function used when title needs to be force overridden. * * @return string */ public function force_wp_title() { global $wp_query; $old_wp_query = null; if ( ! $wp_query->is_main_query() ) { $old_wp_query = $wp_query; wp_reset_query(); } $title = $this->title( '' ); if ( ! empty( $old_wp_query ) ) { $GLOBALS['wp_query'] = $old_wp_query; unset( $old_wp_query ); } return $title; } /** * Outputs or returns the debug marker, which is also used for title replacement when force rewrite is active. * * @return string The marker that will be echoed. */ public function debug_mark() { $marker = $this->get_debug_mark(); echo "\n${marker}\n"; return ''; } /** * Returns the debug marker, which is also used for title replacement when force rewrite is active. * * @return string The generated marker. */ public function get_debug_mark() { return sprintf( '<!-- This site is optimized with the %1$s %2$s - https://yoast.com/wordpress/plugins/seo/ -->', esc_html( $this->head_product_name() ), /** * Filter: 'wpseo_hide_version' - can be used to hide the Yoast SEO version in the debug marker (only available in Yoast SEO Premium). * * @api bool */ ( ( apply_filters( 'wpseo_hide_version', false ) && $this->is_premium() ) ? '' : 'v' . WPSEO_VERSION ) ); } /** * Output Webmaster Tools authentication strings. */ public function webmaster_tools_authentication() { // Baidu. $this->webmaster_tools_helper( 'baiduverify', 'baidu-site-verification' ); // Bing. $this->webmaster_tools_helper( 'msverify', 'msvalidate.01' ); // Google. $this->webmaster_tools_helper( 'googleverify', 'google-site-verification' ); // Pinterest. $this->webmaster_tools_helper( 'pinterestverify', 'p:domain_verify' ); // Yandex. $this->webmaster_tools_helper( 'yandexverify', 'yandex-verification' ); } /** * Helper function for authentication. * * @param string $option_key Option key. * @param string $tag_name The tag name. * * @return void */ private function webmaster_tools_helper( $option_key, $tag_name ) { $auth = WPSEO_Options::get( $option_key, '' ); if ( $auth !== '' ) { printf( '<meta name="%1$s" content="%2$s" />' . "\n", $tag_name, $auth ); } } /** * Main wrapper function attached to wp_head. This combines all the output on the frontend of the Yoast SEO plugin. */ public function head() { global $wp_query; $old_wp_query = null; if ( ! $wp_query->is_main_query() ) { $old_wp_query = $wp_query; wp_reset_query(); } /** * Action: 'wpseo_head' - Allow other plugins to output inside the Yoast SEO section of the head section. */ do_action( 'wpseo_head' ); echo $this->show_closing_debug_mark(); if ( ! empty( $old_wp_query ) ) { $GLOBALS['wp_query'] = $old_wp_query; unset( $old_wp_query ); } } /** * Retrieves the meta robots value. * * @return string */ public function get_robots() { global $wp_query, $post; $robots = []; $robots['index'] = 'index'; $robots['follow'] = 'follow'; $robots['other'] = []; if ( is_object( $post ) && WPSEO_Frontend_Page_Type::is_simple_page() ) { $private = 'private' === $post->post_status; $noindex = ! WPSEO_Post_Type::is_post_type_indexable( $post->post_type ); if ( $noindex || $private ) { $robots['index'] = 'noindex'; } $robots = $this->robots_for_single_post( $robots, WPSEO_Frontend_Page_Type::get_simple_page_id() ); } else { if ( is_search() || is_404() ) { $robots['index'] = 'noindex'; } elseif ( is_tax() || is_tag() || is_category() ) { $term = $wp_query->get_queried_object(); if ( is_object( $term ) && ( WPSEO_Options::get( 'noindex-tax-' . $term->taxonomy, false ) ) ) { $robots['index'] = 'noindex'; } // Three possible values, index, noindex and default, do nothing for default. $term_meta = WPSEO_Taxonomy_Meta::get_term_meta( $term, $term->taxonomy, 'noindex' ); if ( is_string( $term_meta ) && 'default' !== $term_meta ) { $robots['index'] = $term_meta; } if ( $this->is_multiple_terms_query() ) { $robots['index'] = 'noindex'; } } elseif ( is_author() ) { if ( WPSEO_Options::get( 'noindex-author-wpseo', false ) ) { $robots['index'] = 'noindex'; } $curauth = $wp_query->get_queried_object(); $author_archive = new Author_Archive_Helper(); $user_has_posts = ( (int) count_user_posts( $curauth->ID, $author_archive->get_author_archive_post_types(), true ) ) > 0; if ( WPSEO_Options::get( 'noindex-author-noposts-wpseo', false ) && ! $user_has_posts ) { $robots['index'] = 'noindex'; } if ( get_user_meta( $curauth->ID, 'wpseo_noindex_author', true ) === 'on' ) { $robots['index'] = 'noindex'; } } elseif ( is_date() && WPSEO_Options::get( 'noindex-archive-wpseo', false ) ) { $robots['index'] = 'noindex'; } elseif ( is_home() ) { $page_for_posts = get_option( 'page_for_posts' ); if ( $page_for_posts ) { $robots = $this->robots_for_single_post( $robots, $page_for_posts ); } unset( $page_for_posts ); } elseif ( is_post_type_archive() ) { $post_type = $this->get_queried_post_type(); if ( WPSEO_Options::get( 'noindex-ptarchive-' . $post_type, false ) ) { $robots['index'] = 'noindex'; } } unset( $robot ); } // Force override to respect the WP settings. if ( '0' === (string) get_option( 'blog_public' ) || isset( $_GET['replytocom'] ) ) { $robots['index'] = 'noindex'; } $robotsstr = $robots['index'] . ',' . $robots['follow']; if ( $robots['other'] !== [] ) { $robots['other'] = array_unique( $robots['other'] ); // @todo Most likely no longer needed, needs testing. $robotsstr .= ',' . implode( ',', $robots['other'] ); } $robotsstr = preg_replace( '`^index,follow,?`', '', $robotsstr ); $robotsstr = str_replace( [ 'noodp,', 'noodp' ], '', $robotsstr ); if ( strpos( $robotsstr, 'noindex' ) === false && strpos( $robotsstr, 'nosnippet' ) === false ) { if ( $robotsstr !== '' ) { $robotsstr .= ', '; } $robotsstr .= 'max-snippet:-1, max-image-preview:large, max-video-preview:-1'; } /** * Filter: 'wpseo_robots' - Allows filtering of the meta robots output of Yoast SEO. * * @api string $robotsstr The meta robots directives to be echoed. */ $robotsstr = apply_filters( 'wpseo_robots', $robotsstr ); return $robotsstr; } /** * Outputs the meta robots value. * * @return string */ public function robots() { $robotsstr = $this->get_robots(); if ( is_string( $robotsstr ) && $robotsstr !== '' ) { echo '<meta name="robots" content="', esc_attr( $robotsstr ), '"/>', "\n"; } // If a page has a noindex, it should _not_ have a canonical, as these are opposing indexing directives. if ( strpos( $robotsstr, 'noindex' ) !== false ) { remove_action( 'wpseo_head', [ $this, 'canonical' ], 20 ); } return $robotsstr; } /** * Determine $robots values for a single post. * * @param array $robots Robots data array. * @param int $post_id The post ID for which to determine the $robots values, defaults to current post. * * @return array */ public function robots_for_single_post( $robots, $post_id = 0 ) { $noindex = $this->get_seo_meta_value( 'meta-robots-noindex', $post_id ); if ( $noindex === '1' ) { $robots['index'] = 'noindex'; } elseif ( $noindex === '2' ) { $robots['index'] = 'index'; } if ( $this->get_seo_meta_value( 'meta-robots-nofollow', $post_id ) === '1' ) { $robots['follow'] = 'nofollow'; } $meta_robots_adv = $this->get_seo_meta_value( 'meta-robots-adv', $post_id ); if ( $meta_robots_adv !== '' && ( $meta_robots_adv !== '-' && $meta_robots_adv !== 'none' ) ) { $meta_robots_adv = explode( ',', $meta_robots_adv ); foreach ( $meta_robots_adv as $robot ) { $robots['other'][] = $robot; } unset( $robot ); } unset( $meta_robots_adv ); return $robots; } /** * This function normally outputs the canonical but is also used in other places to retrieve * the canonical URL for the current page. * * @param bool $echo Whether or not to output the canonical element. * @param bool $un_paged Whether or not to return the canonical with or without pagination added to the URL. * @param bool $no_override Whether or not to return a manually overridden canonical. * * @return string $canonical */ public function canonical( $echo = true, $un_paged = false, $no_override = false ) { if ( is_null( $this->canonical ) ) { $this->generate_canonical(); } $canonical = $this->canonical; if ( $un_paged ) { $canonical = $this->canonical_unpaged; } elseif ( $no_override ) { $canonical = $this->canonical_no_override; } if ( $echo === false ) { return $canonical; } if ( is_string( $canonical ) && '' !== $canonical ) { echo '<link rel="canonical" href="' . esc_url( $canonical, null, 'other' ) . '" />' . "\n"; } } /** * This function normally outputs the canonical but is also used in other places to retrieve * the canonical URL for the current page. * * @return void */ private function generate_canonical() { $canonical = false; $canonical_override = false; // Set decent canonicals for homepage, singulars and taxonomy pages. if ( is_singular() ) { $obj = get_queried_object(); $canonical = get_permalink( $obj->ID ); $this->canonical_unpaged = $canonical; $canonical_override = $this->get_seo_meta_value( 'canonical' ); // Fix paginated pages canonical, but only if the page is truly paginated. if ( get_query_var( 'page' ) > 1 ) { $num_pages = ( substr_count( $obj->post_content, '<!--nextpage-->' ) + 1 ); if ( $num_pages && get_query_var( 'page' ) <= $num_pages ) { if ( ! $GLOBALS['wp_rewrite']->using_permalinks() ) { $canonical = add_query_arg( 'page', get_query_var( 'page' ), $canonical ); } else { $canonical = user_trailingslashit( trailingslashit( $canonical ) . get_query_var( 'page' ) ); } } } } else { if ( is_search() ) { $search_query = get_search_query(); // Regex catches case when /search/page/N without search term is itself mistaken for search term. R. if ( ! empty( $search_query ) && ! preg_match( '|^page/\d+$|', $search_query ) ) { $canonical = get_search_link(); } } elseif ( is_front_page() ) { $canonical = WPSEO_Utils::home_url(); } elseif ( WPSEO_Frontend_Page_Type::is_posts_page() ) { $posts_page_id = get_option( 'page_for_posts' ); $canonical = $this->get_seo_meta_value( 'canonical', $posts_page_id ); if ( empty( $canonical ) ) { $canonical = get_permalink( $posts_page_id ); } } elseif ( is_tax() || is_tag() || is_category() ) { $term = get_queried_object(); if ( ! empty( $term ) && ! $this->is_multiple_terms_query() ) { $canonical_override = WPSEO_Taxonomy_Meta::get_term_meta( $term, $term->taxonomy, 'canonical' ); $term_link = get_term_link( $term, $term->taxonomy ); if ( ! is_wp_error( $term_link ) ) { $canonical = $term_link; } } } elseif ( is_post_type_archive() ) { $post_type = $this->get_queried_post_type(); $canonical = get_post_type_archive_link( $post_type ); } elseif ( is_author() ) { $canonical = get_author_posts_url( get_query_var( 'author' ), get_query_var( 'author_name' ) ); } elseif ( is_archive() ) { if ( is_date() ) { if ( is_day() ) { $canonical = get_day_link( get_query_var( 'year' ), get_query_var( 'monthnum' ), get_query_var( 'day' ) ); } elseif ( is_month() ) { $canonical = get_month_link( get_query_var( 'year' ), get_query_var( 'monthnum' ) ); } elseif ( is_year() ) { $canonical = get_year_link( get_query_var( 'year' ) ); } } } $this->canonical_unpaged = $canonical; if ( $canonical && get_query_var( 'paged' ) > 1 ) { global $wp_rewrite; if ( ! $wp_rewrite->using_permalinks() ) { if ( is_front_page() ) { $canonical = trailingslashit( $canonical ); } $canonical = add_query_arg( 'paged', get_query_var( 'paged' ), $canonical ); } else { if ( is_front_page() ) { $canonical = WPSEO_Sitemaps_Router::get_base_url( '' ); } $canonical = user_trailingslashit( trailingslashit( $canonical ) . trailingslashit( $wp_rewrite->pagination_base ) . get_query_var( 'paged' ) ); } } } $this->canonical_no_override = $canonical; if ( is_string( $canonical ) && $canonical !== '' ) { // Force canonical links to be absolute, relative is NOT an option. if ( WPSEO_Utils::is_url_relative( $canonical ) === true ) { $canonical = $this->base_url( $canonical ); } } if ( is_string( $canonical_override ) && $canonical_override !== '' ) { $canonical = $canonical_override; } /** * Filter: 'wpseo_canonical' - Allow filtering of the canonical URL put out by Yoast SEO. * * @api string $canonical The canonical URL. */ $this->canonical = apply_filters( 'wpseo_canonical', $canonical ); } /** * Parse the home URL setting to find the base URL for relative URLs. * * @param string $path Optional path string. * * @return string */ private function base_url( $path = null ) { $url = get_option( 'home' ); $parts = wp_parse_url( $url ); $base_url = trailingslashit( $parts['scheme'] . '://' . $parts['host'] ); if ( ! is_null( $path ) ) { $base_url .= ltrim( $path, '/' ); } return $base_url; } /** * Adds 'prev' and 'next' links to archives. * * @link http://googlewebmastercentral.blogspot.com/2011/09/pagination-with-relnext-and-relprev.html * @since 1.0.3 */ public function adjacent_rel_links() { /** * Filter: 'wpseo_disable_adjacent_rel_links' - Allows disabling of Yoast adjacent links if this is being handled by other code. * * @api bool $links_generated Indicates if other code has handled adjacent links. */ if ( true === apply_filters( 'wpseo_disable_adjacent_rel_links', false ) ) { return; } if ( is_singular() ) { $this->rel_links_single(); return; } $this->rel_links_archive(); } /** * Output the rel next/prev links for a single post / page. * * @return void */ protected function rel_links_single() { $num_pages = 1; $queried_object = get_queried_object(); if ( ! empty( $queried_object ) ) { $num_pages = ( substr_count( $queried_object->post_content, '<!--nextpage-->' ) + 1 ); } if ( $num_pages === 1 ) { return; } $page = max( 1, (int) get_query_var( 'page' ) ); $url = get_permalink( get_queried_object_id() ); if ( $page > 1 ) { $this->adjacent_rel_link( 'prev', $url, ( $page - 1 ), 'page' ); } if ( $page < $num_pages ) { $this->adjacent_rel_link( 'next', $url, ( $page + 1 ), 'page' ); } } /** * Output the rel next/prev links for an archive page. */ protected function rel_links_archive() { $url = $this->canonical( false, true, true ); if ( ! is_string( $url ) || $url === '' ) { return; } $paged = max( 1, (int) get_query_var( 'paged' ) ); if ( $paged === 2 ) { $this->adjacent_rel_link( 'prev', $url, ( $paged - 1 ) ); } // Make sure to use index.php when needed, done after paged == 2 check so the prev links to homepage will not have index.php erroneously. if ( is_front_page() ) { $url = WPSEO_Sitemaps_Router::get_base_url( '' ); } if ( $paged > 2 ) { $this->adjacent_rel_link( 'prev', $url, ( $paged - 1 ) ); } if ( $paged < $GLOBALS['wp_query']->max_num_pages ) { $this->adjacent_rel_link( 'next', $url, ( $paged + 1 ) ); } } /** * Get adjacent pages link for archives. * * @since 1.0.2 * @since 7.1 Added $query_arg parameter for single post/page pagination. * * @param string $rel Link relationship, prev or next. * @param string $url The un-paginated URL of the current archive. * @param string $page The page number to add on to $url for the $link tag. * @param string $query_arg Optional. The argument to use to set for the page to load. * * @return void */ private function adjacent_rel_link( $rel, $url, $page, $query_arg = 'paged' ) { global $wp_rewrite; if ( ! $wp_rewrite->using_permalinks() ) { if ( $page > 1 ) { $url = add_query_arg( $query_arg, $page, $url ); } } else { if ( $page > 1 ) { $url = user_trailingslashit( trailingslashit( $url ) . $this->get_pagination_base() . $page ); } } /** * Filter: 'wpseo_adjacent_rel_url' - Allow changing the URL for rel output by Yoast SEO. * * @api string $url The URL that's going to be output for $rel. * * @param string $rel Link relationship, prev or next. */ $url = apply_filters( 'wpseo_adjacent_rel_url', $url, $rel ); /** * Filter: 'wpseo_' . $rel . '_rel_link' - Allow changing link rel output by Yoast SEO. * * @api string $unsigned The full `<link` element. */ $link = apply_filters( 'wpseo_' . $rel . '_rel_link', '<link rel="' . esc_attr( $rel ) . '" href="' . esc_url( $url ) . "\" />\n" ); if ( is_string( $link ) && $link !== '' ) { echo $link; } } /** * Return the base for pagination. * * @return string The pagination base. */ private function get_pagination_base() { // If the current page is the frontpage, pagination should use /base/. $base = ''; if ( ! is_singular() || WPSEO_Frontend_Page_Type::is_home_static_page() ) { $base = trailingslashit( $GLOBALS['wp_rewrite']->pagination_base ); } return $base; } /** * Outputs the meta description element or returns the description text. * * @param bool $echo Echo or return output flag. * * @return string */ public function metadesc( $echo = true ) { if ( is_null( $this->metadesc ) ) { $this->generate_metadesc(); } if ( $echo === false ) { return $this->metadesc; } if ( is_string( $this->metadesc ) && $this->metadesc !== '' ) { echo '<meta name="description" content="', esc_attr( wp_strip_all_tags( stripslashes( $this->metadesc ) ) ), '"/>', "\n"; return ''; } if ( current_user_can( 'wpseo_manage_options' ) && is_singular() ) { echo '<!-- '; printf( /* Translators: %1$s resolves to the SEO menu item, %2$s resolves to the Search Appearance submenu item. */ esc_html__( 'Admin only notice: this page does not show a meta description because it does not have one, either write it for this page specifically or go into the [%1$s - %2$s] menu and set up a template.', 'wordpress-seo' ), esc_html__( 'SEO', 'wordpress-seo' ), esc_html__( 'Search Appearance', 'wordpress-seo' ) ); echo ' -->' . "\n"; } } /** * Generates the meta description text. */ private function generate_metadesc() { global $post, $wp_query; $metadesc = ''; $metadesc_override = false; $post_type = ''; $template = ''; if ( is_object( $post ) && ( isset( $post->post_type ) && $post->post_type !== '' ) ) { $post_type = $post->post_type; } if ( $this->woocommerce_shop_page->is_shop_page() ) { $post = get_post( $this->woocommerce_shop_page->get_shop_page_id() ); $post_type = $this->get_queried_post_type(); if ( ( $metadesc === '' && $post_type !== '' ) && WPSEO_Options::get( 'metadesc-ptarchive-' . $post_type, '' ) !== '' ) { $template = WPSEO_Options::get( 'metadesc-ptarchive-' . $post_type ); $term = $post; } $metadesc_override = $this->get_seo_meta_value( 'metadesc', $post->ID ); } elseif ( WPSEO_Frontend_Page_Type::is_simple_page() ) { $post = get_post( WPSEO_Frontend_Page_Type::get_simple_page_id() ); $post_type = isset( $post->post_type ) ? $post->post_type : ''; if ( ( $metadesc === '' && $post_type !== '' ) && WPSEO_Options::get( 'metadesc-' . $post_type, '' ) !== '' ) { $template = WPSEO_Options::get( 'metadesc-' . $post_type ); $term = $post; } if ( is_object( $post ) ) { $metadesc_override = $this->get_seo_meta_value( 'metadesc', $post->ID ); } } else { if ( is_search() ) { $metadesc = ''; } elseif ( WPSEO_Frontend_Page_Type::is_home_posts_page() ) { $template = WPSEO_Options::get( 'metadesc-home-wpseo' ); $term = []; if ( empty( $template ) ) { $template = get_bloginfo( 'description' ); } } elseif ( WPSEO_Frontend_Page_Type::is_home_static_page() ) { $metadesc = $this->get_seo_meta_value( 'metadesc' ); if ( ( $metadesc === '' && $post_type !== '' ) && WPSEO_Options::get( 'metadesc-' . $post_type, '' ) !== '' ) { $template = WPSEO_Options::get( 'metadesc-' . $post_type ); } } elseif ( is_category() || is_tag() || is_tax() ) { $term = $wp_query->get_queried_object(); $metadesc_override = WPSEO_Taxonomy_Meta::get_term_meta( $term, $term->taxonomy, 'desc' ); if ( is_object( $term ) && isset( $term->taxonomy ) && WPSEO_Options::get( 'metadesc-tax-' . $term->taxonomy, '' ) !== '' ) { $template = WPSEO_Options::get( 'metadesc-tax-' . $term->taxonomy ); } } elseif ( is_author() ) { $author_id = get_query_var( 'author' ); $metadesc = get_the_author_meta( 'wpseo_metadesc', $author_id ); if ( ( ! is_string( $metadesc ) || $metadesc === '' ) && WPSEO_Options::get( 'metadesc-author-wpseo', '' ) !== '' ) { $template = WPSEO_Options::get( 'metadesc-author-wpseo' ); } } elseif ( is_post_type_archive() ) { $post_type = $this->get_queried_post_type(); if ( WPSEO_Options::get( 'metadesc-ptarchive-' . $post_type, '' ) !== '' ) { $template = WPSEO_Options::get( 'metadesc-ptarchive-' . $post_type ); } } elseif ( is_archive() ) { $template = WPSEO_Options::get( 'metadesc-archive-wpseo' ); } // If we're on a paginated page, and the template doesn't change for paginated pages, bail. if ( ( ! is_string( $metadesc ) || $metadesc === '' ) && get_query_var( 'paged' ) && get_query_var( 'paged' ) > 1 && $template !== '' ) { if ( strpos( $template, '%%page' ) === false ) { $metadesc = ''; } } } $post_data = $post; if ( is_string( $metadesc_override ) && '' !== $metadesc_override ) { $metadesc = $metadesc_override; if ( isset( $term ) ) { $post_data = $term; } } elseif ( ( ! is_string( $metadesc ) || '' === $metadesc ) && '' !== $template ) { if ( ! isset( $term ) ) { $term = $wp_query->get_queried_object(); } $metadesc = $template; $post_data = $term; } $metadesc = $this->replace_vars( $metadesc, $post_data ); /** * Filter: 'wpseo_metadesc' - Allow changing the Yoast SEO meta description sentence. * * @api string $metadesc The description sentence. */ $this->metadesc = apply_filters( 'wpseo_metadesc', trim( $metadesc ) ); } /** * Based on the redirect meta value, this function determines whether it should redirect the current post / page. * * @return boolean */ public function page_redirect() { if ( is_singular() ) { global $post; if ( ! isset( $post ) || ! is_object( $post ) ) { return false; } $redir = $this->get_seo_meta_value( 'redirect', $post->ID ); if ( $redir !== '' ) { wp_redirect( $redir, 301, 'Yoast SEO' ); exit; } } return false; } /** * Outputs noindex values for the current page. */ public function noindex_page() { remove_action( 'wpseo_head', [ $this, 'canonical' ], 20 ); echo '<meta name="robots" content="noindex" />', "\n"; } /** * Send a Robots HTTP header preventing URL from being indexed in the search results while allowing search engines * to follow the links in the object at the URL. * * @since 1.1.7 * @return boolean Boolean indicating whether the noindex header was sent. */ public function noindex_robots() { if ( ( is_robots() ) && headers_sent() === false ) { header( 'X-Robots-Tag: noindex, follow', true ); return true; } return false; } /** * Adds rel="nofollow" to a link, only used for login / registration links. * * @param string $input The link element as a string. * * @return string */ public function nofollow_link( $input ) { return str_replace( '<a ', '<a rel="nofollow" ', $input ); } /** * When certain archives are disabled, this redirects those to the homepage. * * @return boolean False when no redirect was triggered. */ public function archive_redirect() { global $wp_query; if ( ( WPSEO_Options::get( 'disable-date', false ) && $wp_query->is_date ) || ( WPSEO_Options::get( 'disable-author', false ) && $wp_query->is_author ) || ( WPSEO_Options::get( 'disable-post_format', false ) && $wp_query->is_tax( 'post_format' ) ) ) { $this->redirect( get_bloginfo( 'url' ), 301 ); return true; } return false; } /** * If the option to disable attachment URLs is checked, this performs the redirect to the attachment. * * @return bool Returns succes status. */ public function attachment_redirect() { if ( WPSEO_Options::get( 'disable-attachment', false ) === false ) { return false; } if ( ! is_attachment() ) { return false; } /** * Allow the developer to change the target redirection URL for attachments. * * @api string $attachment_url The attachment URL for the queried object. * @api object $queried_object The queried object. * * @since 7.5.3 */ $url = apply_filters( 'wpseo_attachment_redirect_url', wp_get_attachment_url( get_queried_object_id() ), get_queried_object() ); if ( ! empty( $url ) ) { $this->do_attachment_redirect( $url ); return true; } return false; } /** * Performs the redirect from the attachment page to the image file itself. * * @param string $attachment_url The attachment image url. * * @return void */ public function do_attachment_redirect( $attachment_url ) { wp_redirect( $attachment_url, 301, 'Yoast SEO' ); exit; } /** * Replaces the possible RSS variables with their actual values. * * @param string $content The RSS content that should have the variables replaced. * * @return string */ public function rss_replace_vars( $content ) { global $post; /** * Allow the developer to determine whether or not to follow the links * in the bits Yoast SEO adds to the RSS feed, defaults to true. * * @api bool $unsigned Whether or not to follow the links in RSS feed, defaults to true. * * @since 1.4.20 */ $no_follow = apply_filters( 'nofollow_rss_links', true ); $no_follow_attr = ''; if ( $no_follow === true ) { $no_follow_attr = 'rel="nofollow" '; } $author_link = ''; if ( is_object( $post ) ) { $author_link = '<a ' . $no_follow_attr . 'href="' . esc_url( get_author_posts_url( $post->post_author ) ) . '">' . esc_html( get_the_author() ) . '</a>'; } $post_link = '<a ' . $no_follow_attr . 'href="' . esc_url( get_permalink() ) . '">' . esc_html( get_the_title() ) . '</a>'; $blog_link = '<a ' . $no_follow_attr . 'href="' . esc_url( get_bloginfo( 'url' ) ) . '">' . esc_html( get_bloginfo( 'name' ) ) . '</a>'; $blog_desc_link = '<a ' . $no_follow_attr . 'href="' . esc_url( get_bloginfo( 'url' ) ) . '">' . esc_html( get_bloginfo( 'name' ) ) . ' - ' . esc_html( get_bloginfo( 'description' ) ) . '</a>'; $content = stripslashes( trim( $content ) ); $content = str_replace( '%%AUTHORLINK%%', $author_link, $content ); $content = str_replace( '%%POSTLINK%%', $post_link, $content ); $content = str_replace( '%%BLOGLINK%%', $blog_link, $content ); $content = str_replace( '%%BLOGDESCLINK%%', $blog_desc_link, $content ); return $content; } /** * Adds the RSS footer (or header) to the full RSS feed item. * * @param string $content Feed item content. * * @return string */ public function embed_rssfooter( $content ) { return $this->embed_rss( $content, 'full' ); } /** * Adds the RSS footer (or header) to the excerpt RSS feed item. * * @param string $content Feed item excerpt. * * @return string */ public function embed_rssfooter_excerpt( $content ) { return $this->embed_rss( $content, 'excerpt' ); } /** * Adds the RSS footer and/or header to an RSS feed item. * * @since 1.4.14 * * @param string $content Feed item content. * @param string $context Feed item context, either 'excerpt' or 'full'. * * @return string */ public function embed_rss( $content, $context = 'full' ) { /** * Filter: 'wpseo_include_rss_footer' - Allow the RSS footer to be dynamically shown/hidden. * * @api boolean $show_embed Indicates if the RSS footer should be shown or not. * * @param string $context The context of the RSS content - 'full' or 'excerpt'. */ if ( ! apply_filters( 'wpseo_include_rss_footer', true, $context ) ) { return $content; } if ( is_feed() ) { $before = ''; $after = ''; if ( WPSEO_Options::get( 'rssbefore', '' ) !== '' ) { $before = wpautop( $this->rss_replace_vars( WPSEO_Options::get( 'rssbefore' ) ) ); } if ( WPSEO_Options::get( 'rssafter', '' ) !== '' ) { $after = wpautop( $this->rss_replace_vars( WPSEO_Options::get( 'rssafter' ) ) ); } if ( $before !== '' || $after !== '' ) { if ( ( isset( $context ) && $context === 'excerpt' ) && trim( $content ) !== '' ) { $content = wpautop( $content ); } $content = $before . $content . $after; } } return $content; } /** * Used in the force rewrite functionality this retrieves the output, replaces the title with the proper SEO * title and then flushes the output. */ public function flush_cache() { global $wp_query; if ( $this->ob_started !== true ) { return false; } $content = ob_get_clean(); $head_end = stripos( $content, '/head>' ); $old_wp_query = $wp_query; wp_reset_query(); // Only replace the debug marker when it is hooked. if ( $head_end && $this->show_debug_marker() ) { $title = $this->title( '' ); $debug_mark = $this->get_debug_mark(); /* * Find all titles in the head, strip them out and add the new one in within the debug marker, * so it's easily identified whether a site uses force rewrite. */ $head = preg_replace( '/<title.*?\/title>/si', '', substr( $content, 0, $head_end ) ); $head = str_replace( $debug_mark, $debug_mark . PHP_EOL . '<title>' . esc_html( $title ) . '</title>', $head ); $content = $head . substr( $content, $head_end ); } $GLOBALS['wp_query'] = $old_wp_query; echo $content; return true; } /** * Starts the output buffer so it can later be fixed by flush_cache(). */ public function force_rewrite_output_buffer() { $this->ob_started = true; ob_start(); } /** * Get the product name in the head section. * * @return string */ private function head_product_name() { if ( $this->is_premium() ) { return 'Yoast SEO Premium plugin'; } return 'Yoast SEO plugin'; } /** * Check if this plugin is the premium version of WPSEO. * * @return bool */ protected function is_premium() { return WPSEO_Utils::is_yoast_seo_premium(); } /** * Check if term archive query is for multiple terms (/term-1,term2/ or /term-1+term-2/). * * @return bool */ protected function is_multiple_terms_query() { global $wp_query; if ( ! is_tax() && ! is_tag() && ! is_category() ) { return false; } $term = get_queried_object(); $queried_terms = $wp_query->tax_query->queried_terms; if ( empty( $queried_terms[ $term->taxonomy ]['terms'] ) ) { return false; } return count( $queried_terms[ $term->taxonomy ]['terms'] ) > 1; } /** * Wraps wp_safe_redirect to allow testing for redirects. * * @param string $location The path to redirect to. * @param int $status Status code to use. */ public function redirect( $location, $status = 302 ) { wp_safe_redirect( $location, $status, 'Yoast SEO' ); exit; } /** * Checks if the debug mark action has been added. * * @return bool True when the action exists. */ protected function show_debug_marker() { return has_action( 'wpseo_head', [ $this, 'debug_mark' ] ) !== false; } /** * Shows the closing debug mark. * * @return string The closing debug mark comment. */ protected function show_closing_debug_mark() { if ( ! $this->show_debug_marker() ) { return ''; } return sprintf( "<!-- / %s. -->\n\n", esc_html( $this->head_product_name() ) ); } /** * Builds the title for a post type archive. * * @param string $separator The title separator. * @param string $separator_location The location of the title separator. * * @return string The title to use on a post type archive. */ protected function get_post_type_archive_title( $separator, $separator_location ) { $post_type = $this->get_queried_post_type(); $title = $this->get_title_from_options( 'title-ptarchive-' . $post_type ); if ( ! is_string( $title ) || '' === $title ) { $post_type_obj = get_post_type_object( $post_type ); $title_part = ''; if ( isset( $post_type_obj->labels->menu_name ) ) { $title_part = $post_type_obj->labels->menu_name; } elseif ( isset( $post_type_obj->name ) ) { $title_part = $post_type_obj->name; } $title = $this->get_default_title( $separator, $separator_location, $title_part ); } return $title; } /** * Retrieves the WooCommerce title. * * @return string The WooCommerce title. */ protected function get_woocommerce_title() { $shop_page_id = $this->woocommerce_shop_page->get_shop_page_id(); $post = get_post( $shop_page_id ); $title = $this->get_seo_title( $post ); if ( is_string( $title ) && $title !== '' ) { return $title; } if ( $shop_page_id !== -1 && is_archive() ) { $title = $this->get_template( 'title-' . $post->post_type ); $title = $this->replace_vars( $title, $post ); } return $title; } /** * Retrieves a template from the options. * * @param string $template The template to retrieve. * * @return string The set template. */ protected function get_template( $template ) { return WPSEO_Options::get( $template ); } /** * Retrieves the queried post type. * * @return string The queried post type. */ protected function get_queried_post_type() { $post_type = get_query_var( 'post_type' ); if ( is_array( $post_type ) ) { $post_type = reset( $post_type ); } return $post_type; } /** * Retrieves the SEO Meta value for the supplied key and optional post. * * @param string $key The key to retrieve. * @param int $post_id Optional. The post to retrieve the key for. * * @return string Meta value. */ protected function get_seo_meta_value( $key, $post_id = 0 ) { return WPSEO_Meta::get_value( $key, $post_id ); } /** * Replaces the dynamic variables in a string. * * @param string $string The string to replace the variables in. * @param array $args The object some of the replacement values might come from, * could be a post, taxonomy or term. * @param array $omit Variables that should not be replaced by this function. * * @return string The replaced string. */ protected function replace_vars( $string, $args, $omit = [] ) { $replacer = new WPSEO_Replace_Vars(); return $replacer->replace( $string, $args, $omit ); } /** * Adds shortcode support to category descriptions. * * @param string $desc String to add shortcodes in. * * @return string Content with shortcodes filtered out. */ public function custom_category_descriptions_add_shortcode_support( $desc ) { // Wrap in output buffering to prevent shortcodes that echo stuff instead of return from breaking things. ob_start(); $desc = do_shortcode( $desc ); ob_end_clean(); return $desc; } /* ********************* DEPRECATED METHODS ********************* */ /** * Outputs the meta keywords element. * * @deprecated 6.3 * @codeCoverageIgnore * * @return void */ public function metakeywords() { if ( function_exists( 'wp_get_current_user' ) && current_user_can( 'manage_options' ) ) { _deprecated_function( 'WPSEO_Frontend::metakeywords', '6.3' ); } } /** * Removes unneeded query variables from the URL. * * @deprecated 7.0 * @codeCoverageIgnore * * @return void */ public function clean_permalink() { // As this is a frontend method, we want to make sure it is not displayed for non-logged in users. if ( function_exists( 'wp_get_current_user' ) && current_user_can( 'manage_options' ) ) { _deprecated_function( 'WPSEO_Frontend::clean_permalink', '7.0' ); } } /** * Trailing slashes for everything except is_single(). * * @deprecated 7.0 * @codeCoverageIgnore */ public function add_trailingslash() { // As this is a frontend method, we want to make sure it is not displayed for non-logged in users. if ( function_exists( 'wp_get_current_user' ) && current_user_can( 'manage_options' ) ) { _deprecated_function( 'WPSEO_Frontend::add_trailingslash', '7.0', null ); } } /** * Removes the ?replytocom variable from the link, replacing it with a #comment-<number> anchor. * * @deprecated 7.0 * @codeCoverageIgnore * * @param string $link The comment link as a string. * * @return string The modified link. */ public function remove_reply_to_com( $link ) { _deprecated_function( 'WPSEO_Frontend::remove_reply_to_com', '7.0', 'WPSEO_Remove_Reply_To_Com::remove_reply_to_com' ); $remove_replytocom = new WPSEO_Remove_Reply_To_Com(); return $remove_replytocom->remove_reply_to_com( $link ); } /** * Redirects out the ?replytocom variables. * * @deprecated 7.0 * @codeCoverageIgnore * * @return boolean True when redirect has been done. */ public function replytocom_redirect() { _deprecated_function( 'WPSEO_Frontend::replytocom_redirect', '7.0', 'WPSEO_Remove_Reply_To_Com::replytocom_redirect' ); $remove_replytocom = new WPSEO_Remove_Reply_To_Com(); return $remove_replytocom->replytocom_redirect(); } /** * Determine whether this is the homepage and shows posts. * * @deprecated 7.7 * @codeCoverageIgnore * * @return bool Whether or not the current page is the homepage that displays posts. */ public function is_home_posts_page() { _deprecated_function( __FUNCTION__, '7.7', 'WPSEO_Frontend_Page_Type::is_home_posts_page' ); return WPSEO_Frontend_Page_Type::is_home_posts_page(); } /** * Determine whether the this is the static frontpage. * * @deprecated 7.7 * @codeCoverageIgnore * * @return bool Whether or not the current page is a static frontpage. */ public function is_home_static_page() { _deprecated_function( __FUNCTION__, '7.7', 'WPSEO_Frontend_Page_Type::is_home_static_page' ); return WPSEO_Frontend_Page_Type::is_home_static_page(); } /** * Determine whether this is the posts page, when it's not the frontpage. * * @deprecated 7.7 * @codeCoverageIgnore * * @return bool Whether or not it's a non-frontpage, posts page. */ public function is_posts_page() { _deprecated_function( __FUNCTION__, '7.7', 'WPSEO_Frontend_Page_Type::is_posts_page' ); return WPSEO_Frontend_Page_Type::is_posts_page(); } /** * Function used in testing whether the title should be force rewritten or not. * * @deprecated 9.6 * @codeCoverageIgnore * * @param string $title Title string. * * @return string */ public function title_test_helper( $title ) { _deprecated_function( __METHOD__, 'WPSEO 9.6' ); return $title; } /** * Output the rel=publisher code on every page of the site. * * @deprecated 10.1.3 * @codeCoverageIgnore * * @return boolean Boolean indicating whether the publisher link was printed. */ public function publisher() { _deprecated_function( __METHOD__, 'WPSEO 10.1.3' ); return false; } }
Upload Files
Cancel
Upload
Create New
Cancel
Create
Change Permissions
Cancel
Save
Change Date
Cancel
Save
Rename Item
Cancel
Save
Confirm Delete
Are you sure you want to delete the selected items?
Cancel
Delete