Commit realizado el 12:13:52 08-04-2024

This commit is contained in:
Pagina Web Monito
2024-04-08 12:13:55 -04:00
commit 0c33094de9
7815 changed files with 1365694 additions and 0 deletions

View File

@@ -0,0 +1,285 @@
<?php
/**
* Advanced variable replacer.
*
* @since 1.0.33
* @package RankMath
* @subpackage RankMath\Replace_Variables
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Replace_Variables;
use RankMath\Paper\Paper;
use RankMath\Helpers\Str;
defined( 'ABSPATH' ) || exit;
/**
* Advanced_Variables class.
*/
class Advanced_Variables extends Author_Variables {
/**
* Setup advanced variables.
*/
public function setup_advanced_variables() {
$post = $this->get_post();
$this->register_replacement(
'id',
[
'name' => esc_html__( 'Post ID', 'rank-math' ),
'description' => esc_html__( 'ID of the current post/page', 'rank-math' ),
'variable' => 'id',
'example' => ! empty( $post ) ? $post->ID : __( 'Post ID', 'rank-math' ),
],
[ $this, 'get_id' ]
);
$keyword = $this->get_focus_keyword();
$this->register_replacement(
'focuskw',
[
'name' => esc_html__( 'Focus Keyword', 'rank-math' ),
'description' => esc_html__( 'Focus Keyword of the current post', 'rank-math' ),
'variable' => 'focuskw',
'example' => \is_null( $keyword ) ? '' : $keyword,
],
[ $this, 'get_focus_keyword' ]
);
$this->register_replacement(
'keywords',
[
'name' => esc_html__( 'Focus Keywords', 'rank-math' ),
'description' => esc_html__( 'Focus Keywords of the current post', 'rank-math' ),
'variable' => 'keywords',
'example' => $this->get_focus_keywords(),
],
[ $this, 'get_focus_keywords' ]
);
$this->register_replacement(
'customfield',
[
'name' => esc_html__( 'Custom Field (advanced)', 'rank-math' ),
'description' => esc_html__( 'Custom field value.', 'rank-math' ),
'variable' => 'customfield(field-name)',
'example' => esc_html__( 'Custom field value', 'rank-math' ),
'nocache' => true,
],
[ $this, 'get_customfield' ]
);
$this->setup_paging_variables();
$this->setup_post_types_variables();
}
/**
* Setup paging variables.
*/
private function setup_paging_variables() {
$this->register_replacement(
'page',
[
'name' => esc_html__( 'Page', 'rank-math' ),
'description' => esc_html__( 'Page number with context (i.e. page 2 of 4). Only displayed on page 2 and above.', 'rank-math' ),
'variable' => 'page',
'example' => ' page 2 of 4',
],
[ $this, 'get_page' ]
);
$this->register_replacement(
'pagenumber',
[
'name' => esc_html__( 'Page Number', 'rank-math' ),
'description' => esc_html__( 'Current page number', 'rank-math' ),
'variable' => 'pagenumber',
'example' => '4',
],
[ $this, 'get_pagenumber' ]
);
$this->register_replacement(
'pagetotal',
[
'name' => esc_html__( 'Max Pages', 'rank-math' ),
'description' => esc_html__( 'Max pages number', 'rank-math' ),
'variable' => 'pagetotal',
'example' => '4',
],
[ $this, 'get_pagetotal' ]
);
}
/**
* Setup post types variables.
*/
private function setup_post_types_variables() {
$this->register_replacement(
'pt_single',
[
'name' => esc_html__( 'Post Type Name Singular', 'rank-math' ),
'description' => esc_html__( 'Name of current post type (singular)', 'rank-math' ),
'variable' => 'pt_single',
'example' => esc_html__( 'Product', 'rank-math' ),
],
[ $this, 'get_post_type_single' ]
);
$this->register_replacement(
'pt_plural',
[
'name' => esc_html__( 'Post Type Name Plural', 'rank-math' ),
'description' => esc_html__( 'Name of current post type (plural)', 'rank-math' ),
'variable' => 'pt_plural',
'example' => esc_html__( 'Products', 'rank-math' ),
],
[ $this, 'get_post_type_plural' ]
);
}
/**
* Get the numeric post ID.
*
* @return string|null
*/
public function get_id() {
return ! empty( $this->args->ID ) ? $this->args->ID : null;
}
/**
* Get the focus keyword.
*
* @return string|null
*/
public function get_focus_keyword() {
$keywords = '';
if ( ! empty( $this->args->ID ) ) {
$keywords = get_post_meta( $this->args->ID, 'rank_math_focus_keyword', true );
}
if ( ! empty( $this->args->term_id ) ) {
$keywords = get_term_meta( $this->args->term_id, 'rank_math_focus_keyword', true );
}
$keywords = explode( ',', $keywords );
if ( '' !== $keywords[0] ) {
return $keywords[0];
}
return null;
}
/**
* Get Focus keywords.
*
* @return string
*/
public function get_focus_keywords() {
if ( is_singular() || is_category() || is_tag() || is_tax() ) {
return Paper::get()->get_keywords();
}
$keywords = '';
if ( ! empty( $this->args->ID ) ) {
$keywords = get_post_meta( $this->args->ID, 'rank_math_focus_keyword', true );
}
if ( ! empty( $this->args->term_id ) ) {
$keywords = get_term_meta( $this->args->term_id, 'rank_math_focus_keyword', true );
}
return $keywords;
}
/**
* Get the current page number as a string (i.e. "page 1 of 5").
*
* @return string
*/
public function get_page() {
$sep = $this->get_sep();
$max = $this->determine_max_pages();
$page = $this->determine_page_number();
if ( $max > 1 && $page > 1 ) {
/* translators: %1$d: current page number, %2$d: max pages. */
return sprintf( $sep . ' ' . __( 'Page %1$d of %2$d', 'rank-math' ), $page, $max );
}
return null;
}
/**
* Get only the page number (without context).
*
* @return string|null
*/
public function get_pagenumber() {
$page = $this->determine_page_number();
return $page > 0 ? (string) $page : null;
}
/**
* Get the max page number.
*
* @return string|null
*/
public function get_pagetotal() {
$max = $this->determine_max_pages();
return $max > 0 ? (string) $max : null;
}
/**
* Get a specific custom field value.
*
* @param string $name The name of the custom field to retrieve.
* @return string|null
*/
public function get_customfield( $name ) {
if ( Str::is_empty( $name ) ) {
return null;
}
if ( ! empty( get_query_var( 'sitemap' ) ) && 'locations' !== get_query_var( 'sitemap' ) ) {
return null;
}
if ( is_author() ) {
return get_user_meta( $this->args->ID, $name, true );
}
if ( is_category() || is_tag() || is_tax() ) {
return get_term_meta( $this->args->term_id, $name, true );
}
return is_singular() || ! empty( $this->args->post_type ) ? get_post_meta( $this->args->ID, $name, true ) : null;
}
/**
* Get the post type "single" label.
*
* @return string|null
*/
public function get_post_type_single() {
$name = $this->determine_post_type_label( 'single' );
return '' !== $name ? $name : null;
}
/**
* Get the post type "plural" label.
*
* @return string|null
*/
public function get_post_type_plural() {
$name = $this->determine_post_type_label( 'plural' );
return '' !== $name ? $name : null;
}
}

View File

@@ -0,0 +1,125 @@
<?php
/**
* Author variable replacer.
*
* @since 1.0.33
* @package RankMath
* @subpackage RankMath\Replace_Variables
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Replace_Variables;
use RankMath\Admin\Admin_Helper;
defined( 'ABSPATH' ) || exit;
/**
* Author_Variables class.
*/
class Author_Variables extends Term_Variables {
/**
* Hold counter variable data.
*
* @var array
*/
protected $counters = [];
/**
* Setup author variables.
*/
public function setup_author_variables() {
global $user_id;
if ( ! Admin_Helper::is_user_edit() ) {
$user_id = get_current_user_id();
}
if ( $this->is_post_edit ) {
$post = $this->get_post();
$author = get_userdata( $post->post_author );
}
$this->register_replacement(
'userid',
[
'name' => esc_html__( 'Author ID', 'rank-math' ),
'description' => esc_html__( 'Author\'s user ID of the current post, page or author archive.', 'rank-math' ),
'variable' => 'userid',
'example' => $this->is_post_edit ? $post->post_author : $user_id,
],
[ $this, 'get_userid' ]
);
$this->register_replacement(
'name',
[
'name' => esc_html__( 'Post Author', 'rank-math' ),
'description' => esc_html__( 'Display author\'s nicename of the current post, page or author archive.', 'rank-math' ),
'variable' => 'name',
'example' => $this->is_post_edit && $author ? $author->display_name : get_the_author_meta( 'display_name', $user_id ),
],
[ $this, 'get_name' ]
);
$this->register_replacement(
'post_author',
[
'name' => esc_html__( 'Post Author', 'rank-math' ),
'description' => esc_html__( 'Display author\'s nicename of the current post, page or author archive.', 'rank-math' ),
'variable' => 'post_author',
'example' => $this->is_post_edit && $author ? $author->display_name : get_the_author_meta( 'display_name', $user_id ),
],
[ $this, 'get_name' ]
);
$this->register_replacement(
'user_description',
[
'name' => esc_html__( 'Author Description', 'rank-math' ),
'description' => esc_html__( 'Author\'s biographical info of the current post, page or author archive.', 'rank-math' ),
'variable' => 'user_description',
'example' => get_the_author_meta( 'description', $user_id ),
],
[ $this, 'get_user_description' ]
);
}
/**
* Get the post author's user ID to use as a replacement.
*
* @return string
*/
public function get_userid() {
$user_id = ! empty( $this->args->post_author ) ? $this->args->post_author : get_query_var( 'author' );
if ( $user_id ) {
return $user_id;
}
return get_query_var( 'bbp_user_id' );
}
/**
* Get the post author's "nice name" to use as a replacement.
*
* @return string|null
*/
public function get_name() {
$user_id = $this->get_userid();
$name = get_the_author_meta( 'display_name', $user_id );
return '' !== $name ? $name : null;
}
/**
* Get the post author's user description to use as a replacement.
*
* @return string|null
*/
public function get_user_description() {
$user_id = $this->get_userid();
$description = get_the_author_meta( 'description', $user_id );
return '' !== $description ? $description : null;
}
}

View File

@@ -0,0 +1,278 @@
<?php
/**
* Variable replacement base.
*
* @since 1.0.33
* @package RankMath
* @subpackage RankMath\Replace_Variables
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Replace_Variables;
use RankMath\Post;
use RankMath\Traits\Hooker;
use RankMath\Helpers\Str;
defined( 'ABSPATH' ) || exit;
/**
* Base class.
*/
class Base {
use Hooker;
/**
* Current post.
*
* @var object
*/
public $post;
/**
* Current args.
*
* @var object
*/
public $args;
/**
* Get a comma separated list of the post's terms.
*
* @param int $id ID of the post.
* @param string $taxonomy The taxonomy to get the terms from.
* @param bool $return_single Return the first term only.
* @param array $args Array of arguments.
* @param string $field The term field to return.
*
* @return string Either a single term field or a comma delimited list of terms.
*/
protected function get_terms( $id, $taxonomy, $return_single = false, $args = [], $field = 'name' ) {
$output = $this->get_queried_term_object();
if ( '' === $output && ! empty( $id ) && ! empty( $taxonomy ) ) {
$output = $this->get_the_terms( $id, $taxonomy, $return_single, $args, $field );
}
/**
* Filter: Allows changing the `%category%` and `%tag%` terms lists.
*
* @param string $output The terms list, comma separated.
* @param string $taxonomy The taxonomy of the terms.
*/
return $this->do_filter( 'vars/terms', $output, $taxonomy );
}
/**
* Get the selected term, if we're on a taxonomy archive.
*
* @return string
*/
private function get_queried_term_object() {
if ( is_category() || is_tag() || is_tax() ) {
$term = $GLOBALS['wp_query']->get_queried_object();
if ( is_object( $term ) && isset( $term->name ) ) {
return $term->name;
}
}
return '';
}
/**
* Get the post's terms.
*
* @param int $id ID of the post.
* @param string $taxonomy The taxonomy to get the terms from.
* @param bool $return_single Return the first term only.
* @param array $args Array of arguments.
* @param string $field The term field to return.
*
* @return string Either a single term field or a comma delimited list of terms.
*/
private function get_the_terms( $id, $taxonomy, $return_single = false, $args = [], $field = 'name' ) {
$args = wp_parse_args(
$args,
[
'limit' => 99,
'separator' => ', ',
'exclude' => [],
]
);
if ( ! empty( $args['exclude'] ) ) {
$args['exclude'] = array_map( 'intval', explode( ',', $args['exclude'] ) );
}
$terms = get_the_terms( $id, $taxonomy );
if ( is_wp_error( $terms ) || empty( $terms ) ) {
return '';
}
array_splice( $terms, $args['limit'] );
$output = [];
$terms = $this->filter_exclude( $terms, $args['exclude'] );
if ( empty( $terms ) ) {
return '';
}
return $return_single ? $terms[0]->{$field} :
join( $args['separator'], wp_list_pluck( $terms, $field ) );
}
/**
* Filter terms for exclude.
*
* @param array $terms Terms to filter.
* @param array $exclude Terms to exclude.
*
* @return array
*/
protected function filter_exclude( $terms, $exclude ) {
if ( empty( $exclude ) ) {
return $terms;
}
return array_filter(
$terms,
function( $term ) use ( $exclude ) {
return in_array( $term->term_id, $exclude, true ) ? false : true;
}
);
}
/**
* Get the current post type.
*
* @return string Post type name.
*/
protected function get_queried_post_type() {
$post_type = get_post_type();
if ( false !== $post_type ) {
return $post_type;
}
$post_type = get_query_var( 'post_type' );
return is_array( $post_type ) ? reset( $post_type ) : $post_type;
}
/**
* Get post `object`.
*
* @return WP_Post
*/
protected function get_post() {
if ( isset( $this->post ) ) {
return $this->post;
}
$this->post = get_post( Post::is_shop_page() ? Post::get_shop_page_id() : null );
if ( is_null( $this->post ) ) {
$posts = get_posts(
[
'fields' => 'id',
'posts_per_page' => 1,
'post_type' => [ 'post', 'page' ],
]
);
$this->post = isset( $posts[0] ) ? $posts[0] : null;
}
if ( is_null( $this->post ) ) {
$this->post = new \WP_Post(
(object) [
'ID' => 0,
'post_title' => __( 'Example Post title', 'rank-math' ),
]
);
}
return $this->post;
}
/**
* Determine the page number of the current post/page/CPT.
*
* @return int|null
*/
protected function determine_page_number() {
$page_number = is_singular() ? get_query_var( 'page' ) : get_query_var( 'paged' );
if ( 0 === $page_number || '' === $page_number ) {
return 1;
}
return $page_number;
}
/**
* Determine the max num of pages of the current post/page/CPT.
*
* @return int|null
*/
protected function determine_max_pages() {
global $wp_query, $post;
if ( is_singular() && isset( $post->post_content ) ) {
return ( substr_count( $post->post_content, '<!--nextpage-->' ) + 1 );
}
return empty( $wp_query->max_num_pages ) ? 1 : $wp_query->max_num_pages;
}
/**
* Get the appropriate post type label for the current request.
*
* @param string $request Requested label type, "singular" or "plural".
*
* @return string|null
*/
protected function determine_post_type_label( $request = 'single' ) {
$post_type = $this->get_post_type();
if ( empty( $post_type ) ) {
return null;
}
$object = get_post_type_object( $post_type );
if ( 'single' === $request && isset( $object->labels->singular_name ) ) {
return $object->labels->singular_name;
}
if ( 'plural' === $request && isset( $object->labels->name ) ) {
return $object->labels->name;
}
return $object->name;
}
/**
* Get post type for current quried object.
*
* @return string
*/
protected function get_post_type() {
$post_type = $this->get_post_type_from_query();
return is_array( $post_type ) ? reset( $post_type ) : $post_type;
}
/**
* Get post type from query.
*
* @return string
*/
protected function get_post_type_from_query() {
global $wp_query;
if ( isset( $wp_query->query_vars['post_type'] ) && ( Str::is_non_empty( $wp_query->query_vars['post_type'] ) || ( is_array( $wp_query->query_vars['post_type'] ) && [] !== $wp_query->query_vars['post_type'] ) ) ) {
return $wp_query->query_vars['post_type'];
}
if ( isset( $this->args->post_type ) && Str::is_non_empty( $this->args->post_type ) ) {
return $this->args->post_type;
}
return $wp_query->get_queried_object()->post_type;
}
}

View File

@@ -0,0 +1,453 @@
<?php
/**
* Basic variable replacer.
*
* @since 1.0.33
* @package RankMath
* @subpackage RankMath\Replace_Variables
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Replace_Variables;
use RankMath\Helper;
use RankMath\Helpers\Str;
defined( 'ABSPATH' ) || exit;
/**
* Basic_Variables class.
*/
class Basic_Variables extends Cache {
/**
* Hold counter variable data.
*
* @var array
*/
protected $counters = [];
/**
* Is on post edit screen.
*
* @var bool
*/
public $is_post_edit = false;
/**
* Is on term edit screen.
*
* @var bool
*/
public $is_term_edit = false;
/**
* Is on user edit screen.
*
* @var bool
*/
protected $is_user_edit = false;
/**
* Setup basic variables.
*/
public function setup_basic_variables() {
$this->register_replacement(
'sep',
[
'name' => esc_html__( 'Separator Character', 'rank-math' ),
'description' => esc_html__( 'Separator character, as set in the Title Settings', 'rank-math' ),
'variable' => 'sep',
'example' => $this->get_sep(),
],
[ $this, 'get_sep' ]
);
$this->register_replacement(
'search_query',
[
'name' => esc_html__( 'Search Query', 'rank-math' ),
'description' => esc_html__( 'Search query (only available on search results page)', 'rank-math' ),
'variable' => 'search_query',
'example' => esc_html__( 'example search', 'rank-math' ),
],
[ $this, 'get_search_query' ]
);
$this->register_replacement(
'count',
[
'name' => esc_html__( 'Counter', 'rank-math' ),
'description' => esc_html__( 'Starts at 1 and increments by 1.', 'rank-math' ),
'variable' => 'count(varname)',
'example' => '2',
'nocache' => true,
],
[ $this, 'get_count' ]
);
$this->register_replacement(
'filename',
[
'name' => esc_html__( 'File Name', 'rank-math' ),
'description' => esc_html__( 'File Name of the attachment', 'rank-math' ),
'variable' => 'filename',
'example' => 'Sunrise at Maldives',
'nocache' => true,
],
[ $this, 'get_filename' ]
);
$this->setup_site_variables();
$this->setup_date_variables();
$this->setup_time_variables();
$this->setup_organization_variables();
}
/**
* Setup site info variables.
*/
private function setup_site_variables() {
$this->register_replacement(
'sitename',
[
'name' => esc_html__( 'Site Title', 'rank-math' ),
'description' => esc_html__( 'Title of the site', 'rank-math' ),
'variable' => 'sitename',
'example' => $this->get_sitename(),
],
[ $this, 'get_sitename' ]
);
$this->register_replacement(
'sitedesc',
[
'name' => esc_html__( 'Site Description', 'rank-math' ),
'description' => esc_html__( 'Description of the site', 'rank-math' ),
'variable' => 'sitedesc',
'example' => $this->get_sitedesc(),
],
[ $this, 'get_sitedesc' ]
);
}
/**
* Setup date variables.
*/
private function setup_date_variables() {
$this->register_replacement(
'currentdate',
[
'name' => esc_html__( 'Current Date', 'rank-math' ),
'description' => esc_html__( 'Current server date', 'rank-math' ),
'variable' => 'currentdate',
'example' => $this->get_current_date(),
],
[ $this, 'get_current_date' ]
);
$this->register_replacement(
'currentday',
[
'name' => esc_html__( 'Current Day', 'rank-math' ),
'description' => esc_html__( 'Current server day', 'rank-math' ),
'variable' => 'currentday',
'example' => $this->get_current_day(),
],
[ $this, 'get_current_day' ]
);
$this->register_replacement(
'currentmonth',
[
'name' => esc_html__( 'Current Month', 'rank-math' ),
'description' => esc_html__( 'Current server month', 'rank-math' ),
'variable' => 'currentmonth',
'example' => $this->get_current_month(),
],
[ $this, 'get_current_month' ]
);
$this->register_replacement(
'currentyear',
[
'name' => esc_html__( 'Current Year', 'rank-math' ),
'description' => esc_html__( 'Current server year', 'rank-math' ),
'variable' => 'currentyear',
'example' => $this->get_current_year(),
],
[ $this, 'get_current_year' ]
);
}
/**
* Setup time variables.
*/
private function setup_time_variables() {
$this->register_replacement(
'currenttime',
[
'name' => esc_html__( 'Current Time', 'rank-math' ),
'description' => esc_html__( 'Current server time', 'rank-math' ),
'variable' => 'currenttime',
'example' => $this->get_current_time(),
],
[ $this, 'get_current_time' ]
);
$this->register_replacement(
'currenttime_args',
[
'name' => esc_html__( 'Current Time (advanced)', 'rank-math' ),
'description' => esc_html__( 'Current server time with custom formatting pattern.', 'rank-math' ),
'variable' => 'currenttime(F jS, Y)',
'example' => $this->get_current_time( 'F jS, Y' ),
],
[ $this, 'get_current_time' ]
);
}
/**
* Setup site info variables.
*/
private function setup_organization_variables() {
$this->register_replacement(
'org_name',
[
'name' => esc_html__( 'Organization Name', 'rank-math' ),
'description' => esc_html__( 'The Organization Name added in Local SEO Settings.', 'rank-math' ),
'variable' => 'org_name',
'example' => $this->get_sitename(),
],
[ $this, 'get_org_name' ]
);
$this->register_replacement(
'org_logo',
[
'name' => esc_html__( 'Organization Logo', 'rank-math' ),
'description' => esc_html__( 'Organization Logo added in Local SEO Settings.', 'rank-math' ),
'variable' => 'org_logo',
'example' => $this->get_org_logo(),
],
[ $this, 'get_org_logo' ]
);
$this->register_replacement(
'org_url',
[
'name' => esc_html__( 'Organization URL', 'rank-math' ),
'description' => esc_html__( 'Organization URL added in Local SEO Settings.', 'rank-math' ),
'variable' => 'org_url',
'example' => $this->get_org_url(),
],
[ $this, 'get_org_url' ]
);
}
/**
* Get the separator to use as a replacement.
*
* @return string
*/
public function get_sep() {
$sep = $this->do_filter( 'settings/title_separator', Helper::get_settings( 'titles.title_separator' ) );
return htmlentities( $sep, ENT_COMPAT, 'UTF-8', false );
}
/**
* Get the site name to use as a replacement.
*
* @return string|null
*/
public function get_sitename() {
if ( $this->in_cache( 'sitename' ) ) {
return $this->get_cache( 'sitename' );
}
$sitename = wp_strip_all_tags( get_bloginfo( 'name' ), true );
if ( '' !== $sitename ) {
$this->set_cache( 'sitename', $sitename );
}
return $sitename;
}
/**
* Get the site tag line to use as a replacement.
*
* @return string|null
*/
public function get_sitedesc() {
if ( $this->in_cache( 'sitedesc' ) ) {
return $this->get_cache( 'sitedesc' );
}
$sitedesc = wp_strip_all_tags( get_bloginfo( 'description' ) );
if ( '' !== $sitedesc ) {
$this->set_cache( 'sitedesc', $sitedesc );
}
return $sitedesc;
}
/**
* Get the current search query to use as a replacement.
*
* @return string|null
*/
public function get_search_query() {
if ( $this->in_cache( 'search_query' ) ) {
return $this->get_cache( 'search_query' );
}
$search = get_search_query();
if ( '' !== $search ) {
$this->set_cache( 'search_query', $search );
}
return $search;
}
/**
* Get the counter for the given variable.
*
* @param string $name The name of field.
*
* @return string|null
*/
public function get_count( $name ) {
if ( ! is_string( $name ) ) {
return null;
}
if ( ! isset( $this->counters[ $name ] ) ) {
$this->counters[ $name ] = 0;
}
return ++$this->counters[ $name ];
}
/**
* Get the filename of the attachment to use as a replacement.
*
* @return string|null
*/
public function get_filename() {
if ( empty( $this->args->filename ) ) {
return null;
}
$name = \pathinfo( $this->args->filename );
// Remove size if embedded.
$name = explode( '-', $name['filename'] );
if ( Str::contains( 'x', end( $name ) ) ) {
array_pop( $name );
}
// Format filename.
$name = join( ' ', $name );
$name = trim( str_replace( '_', ' ', $name ) );
return '' !== $name ? $name : null;
}
/**
* Get the current time to use as a replacement.
*
* @param string $format (Optional) PHP date format.
*
* @return string
*/
public function get_current_time( $format = '' ) {
$format = $format ? $format : get_option( 'time_format' );
return $this->date_i18n( $format );
}
/**
* Get the current date to use as a replacement.
*
* @param string $format (Optional) PHP date format.
*
* @return string
*/
public function get_current_date( $format = '' ) {
$format = $format ? $format : get_option( 'date_format' );
return $this->date_i18n( $format );
}
/**
* Get the current day to use as a replacement.
*
* @return string
*/
public function get_current_day() {
return $this->date_i18n( 'j' );
}
/**
* Get the current month to use as a replacement.
*
* @return string
*/
public function get_current_month() {
return $this->date_i18n( 'F' );
}
/**
* Get the current year to use as a replacement.
*
* @return string
*/
public function get_current_year() {
return $this->date_i18n( 'Y' );
}
/**
* Get the Organization Name to use as a replacement.
*
* @return string
*/
public function get_org_name() {
return Helper::get_settings( 'titles.knowledgegraph_name', get_bloginfo( 'name' ) );
}
/**
* Get the Organization Logo to use as a replacement.
*
* @return string
*/
public function get_org_logo() {
return Helper::get_settings( 'titles.knowledgegraph_logo', '' );
}
/**
* Get the Organization URL to use as a replacement.
*
* @return string
*/
public function get_org_url() {
return Helper::get_settings( 'titles.url', home_url() );
}
/**
* Return localized date.
*
* @param string $format (Optional) PHP date format.
*
* @return string
*/
private function date_i18n( $format = '' ) {
$key = 'date_i18n_' . sanitize_key( $format );
if ( $this->in_cache( $key ) ) {
return $this->get_cache( $key );
}
$date = date_i18n( $format );
$this->set_cache( $key, $date );
return $date;
}
}

View File

@@ -0,0 +1,58 @@
<?php
/**
* Variable replacement base.
*
* @since 1.0.33
* @package RankMath
* @subpackage RankMath\Replace_Variables
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Replace_Variables;
defined( 'ABSPATH' ) || exit;
/**
* Cache class.
*/
class Cache extends Base {
/**
* Cache holder.
*
* @var array
*/
private $cache = [];
/**
* Get from cache.
*
* @param string $id ID to get from cache.
*
* @return mixed
*/
protected function get_cache( $id ) {
return isset( $this->cache[ $id ] ) ? $this->cache[ $id ] : '';
}
/**
* In cache.
*
* @param string $id ID to get from cache.
*
* @return bool
*/
protected function in_cache( $id ) {
return isset( $this->cache[ $id ] );
}
/**
* Save into cache.
*
* @param string $id ID to get from cache.
* @param mixed $value Value to save.
*/
protected function set_cache( $id, $value ) {
$this->cache[ $id ] = $value;
}
}

View File

@@ -0,0 +1,318 @@
<?php
/**
* Variable replacer.
*
* Replace '%variables%' in strings based on context.
*
* @since 1.0.33
* @package RankMath
* @subpackage RankMath\Replace_Variables
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Replace_Variables;
use RankMath\Helper;
use RankMath\Helpers\Str;
use RankMath\Helpers\Param;
use RankMath\Admin\Admin_Helper;
defined( 'ABSPATH' ) || exit;
/**
* Manager class.
*/
class Manager extends Post_Variables {
/**
* Register variable replacements.
*
* @var array
*/
protected $replacements = [];
/**
* Removed non replaced variables.
*
* @var bool
*/
public $remove_non_replaced = true;
/**
* Is variable setup.
*
* @var bool
*/
private $is_setup = false;
/**
* Hold arguments.
*
* @var array
*/
public $args = [];
/**
* Hold arguments temporarily.
*
* @var array
*/
protected $tmp_args = [];
/**
* Class constructor.
*/
public function __construct() {
$action = is_admin() ? 'admin_enqueue_scripts' : 'wp';
$priority = is_admin() ? 5 : 25;
$this->action( $action, 'setup', $priority );
}
/**
* Register variables
*
* For developers see rank_math_register_var_replacement().
*
* @param string $id Uniquer ID of variable, for example custom.
* @param array $args Array with additional name, description, variable and example values for the variable.
* @param mixed $callback Replacement callback. Should return value, not output it.
*
* @return bool Replacement was registered successfully or not.
*/
public function register_replacement( $id, $args = [], $callback = false ) {
if ( ! $this->is_unique_id( $id ) ) {
return false;
}
$variable = Variable::from( $id, $args );
$variable->set_callback( $callback );
$this->replacements[ $id ] = $variable;
return true;
}
/**
* Check if variable ID is valid and unique before further processing.
*
* @param string $id Variable ID.
*
* @return bool Whether the variable is valid or not.
*/
private function is_unique_id( $id ) {
if ( false === preg_match( '`^[A-Z0-9_-]+$`i', $id ) ) {
trigger_error( esc_html__( 'Variable names can only contain alphanumeric characters, underscores and dashes.', 'rank-math' ), E_USER_WARNING );
return false;
}
if ( isset( $this->replacements[ $id ] ) ) {
trigger_error( esc_html__( 'The variable has already been registered.', 'rank-math' ), E_USER_WARNING );
return false;
}
return true;
}
/**
* Should we setup variables or not.
*
* @return bool
*/
private function should_we_setup() {
if ( Helper::is_ux_builder() ) {
return false;
}
global $wp_customize;
if ( isset( $wp_customize ) || $this->is_setup ) {
return false;
}
$current_screen = \function_exists( 'get_current_screen' ) ? get_current_screen() : false;
if (
$current_screen instanceof \WP_Screen &&
\in_array( $current_screen->base, [ 'themes' ], true )
) {
return false;
}
return true;
}
/**
* Set up replacement variables.
*/
public function setup() {
if ( ! $this->should_we_setup() ) {
return;
}
// Variable setuped.
$this->is_setup = true;
// Internal variables.
$current_screen = \function_exists( 'get_current_screen' ) ? get_current_screen() : false;
if ( $current_screen instanceof \WP_Screen ) {
$screen_base = $current_screen->base;
$this->is_post_edit = is_admin() && 'post' === $screen_base;
$this->is_term_edit = is_admin() && 'term' === $screen_base;
$this->is_user_edit = is_admin() && ( 'profile' === $screen_base || 'user-edit' === $screen_base );
}
/**
* Filter: strip variables which don't have a replacement.
*
* @param bool $final
*/
$this->remove_non_replaced = $this->do_filter( 'vars/remove_nonreplaced', true );
// Setup internal variables.
$this->setup_basic_variables();
$this->setup_post_variables();
$this->setup_term_variables();
$this->setup_author_variables();
$this->setup_advanced_variables();
// Setup custom fields.
if ( $this->is_post_edit || $this->is_term_edit || $this->is_user_edit ) {
Helper::add_json( 'customFields', $this->get_custom_fields() );
Helper::add_json( 'customTerms', $this->get_custom_taxonomies() );
}
/**
* Action: 'rank_math/vars/register_extra_replacements' - Allows adding extra variables.
*/
$this->do_action( 'vars/register_extra_replacements' );
}
/**
* Setup JSON for use in ui.
*/
public function setup_json() {
$json = [];
foreach ( $this->replacements as $id => $variable ) {
$json[ $id ] = $variable->to_array();
}
Helper::add_json( 'variables', $this->do_filter( 'vars/replacements', $json ) );
}
/**
* Get replacements.
*
* @return array
*/
public function get_replacements() {
return $this->replacements;
}
/**
* Set arguments.
*
* @param array $args The object some of the replacement values might come from,
* could be a post, taxonomy or term.
*/
public function set_arguments( $args = [] ) {
if ( ! empty( $args ) ) {
$this->tmp_args = $this->args;
$this->args = $args;
}
}
/**
* Reset arguments.
*/
public function reset_arguments() {
$this->args = $this->tmp_args;
}
/**
* Get custom fields.
*
* @return array
*/
private function get_custom_fields() {
$metas = [];
if ( $this->is_user_edit ) {
global $user_id;
$metas = get_metadata( 'user', $user_id );
} elseif ( $this->is_post_edit ) {
$metas = get_metadata( 'post', $this->args->ID );
} elseif ( $this->is_term_edit ) {
$term_id = Param::request( 'tag_ID', 0, FILTER_VALIDATE_INT );
$metas = get_metadata( 'term', $term_id );
}
if ( empty( $metas ) ) {
return [];
}
$json = [];
foreach ( $metas as $meta_key => $meta_value ) {
if ( Str::starts_with( '_', $meta_key ) || Str::starts_with( 'rank_math_', $meta_key ) ) {
continue;
}
$json[ $meta_key ] = $meta_value[0];
}
return $json;
}
/**
* Get custom taxonomies.
*
* @return array
*/
private function get_custom_taxonomies() {
$taxonomies = get_post_taxonomies( $this->args->ID );
if ( empty( $taxonomies ) ) {
return [];
}
$json = [];
foreach ( $taxonomies as $taxonomy ) {
if ( in_array( $taxonomy, [ 'category', 'post_tag' ], true ) ) {
continue;
}
$name = ucwords( str_replace( [ '_', '-' ], ' ', $taxonomy ) );
/* translators: Taxonomy name. */
$title = sprintf( __( '%s Title', 'rank-math' ), $name );
/* translators: Taxonomy name. */
$desc = sprintf( __( '%s Description', 'rank-math' ), $name );
$this->register_replacement(
"term_{$taxonomy}",
[
'name' => $title,
'description' => esc_html__( 'Custom Term title.', 'rank-math' ),
'variable' => "customterm({$taxonomy})",
'example' => $title,
],
[ $this, 'get_custom_term' ]
);
$this->register_replacement(
"term_{$taxonomy}_desc",
[
'name' => $desc,
'description' => esc_html__( 'Custom Term description.', 'rank-math' ),
'variable' => "customterm_desc({$taxonomy})",
'example' => $desc,
],
[ $this, 'get_custom_term_desc' ]
);
$term = $this->get_custom_term( $taxonomy );
$term_desc = $this->get_custom_term_desc( $taxonomy );
$json[ $taxonomy ] = $term ? $term : $title;
$json[ "{$taxonomy}_desc" ] = $term_desc ? $term_desc : $desc;
}
return $json;
}
}

View File

@@ -0,0 +1,593 @@
<?php
/**
* Post variable replacer.
*
* @since 1.0.33
* @package RankMath
* @subpackage RankMath\Replace_Variables
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Replace_Variables;
use RankMath\Helper;
use RankMath\Helpers\Str;
use RankMath\Post;
use RankMath\Paper\Paper;
defined( 'ABSPATH' ) || exit;
/**
* Post_Variables class.
*/
class Post_Variables extends Advanced_Variables {
/**
* Setup post variables.
*/
public function setup_post_variables() {
$this->args = (object) wp_parse_args( array_filter( (array) $this->get_post() ), $this->get_defaults() );
$this->register_replacement(
'title',
[
'name' => esc_html__( 'Post Title', 'rank-math' ),
'description' => esc_html__( 'Title of the current post/page', 'rank-math' ),
'variable' => 'title',
'example' => $this->get_title(),
'nocache' => true,
],
[ $this, 'get_title' ]
);
$this->register_replacement(
'parent_title',
[
'name' => esc_html__( 'Post Title of parent page', 'rank-math' ),
'description' => esc_html__( 'Title of the parent page of the current post/page', 'rank-math' ),
'variable' => 'parent_title',
'example' => $this->get_parent_title(),
],
[ $this, 'get_parent_title' ]
);
$this->register_replacement(
'excerpt',
[
'name' => esc_html__( 'Post Excerpt', 'rank-math' ),
'description' => esc_html__( 'Excerpt of the current post (or auto-generated if it does not exist)', 'rank-math' ),
'variable' => 'excerpt',
'example' => $this->get_excerpt(),
'nocache' => true,
],
[ $this, 'get_excerpt' ]
);
$this->register_replacement(
'excerpt_only',
[
'name' => esc_html__( 'Post Excerpt', 'rank-math' ),
'description' => esc_html__( 'Excerpt of the current post (without auto-generation)', 'rank-math' ),
'variable' => 'excerpt_only',
'example' => $this->is_post_edit && $this->args->post_excerpt ? $this->args->post_excerpt : esc_html__( 'Post Excerpt Only', 'rank-math' ),
'nocache' => true,
],
[ $this, 'get_excerpt_only' ]
);
$this->register_replacement(
'seo_title',
[
'name' => esc_html__( 'SEO Title', 'rank-math' ),
'description' => esc_html__( 'Custom or Generated SEO Title of the current post/page', 'rank-math' ),
'variable' => 'seo_title',
'example' => $this->get_title(),
'nocache' => true,
],
[ $this, 'get_seo_title' ]
);
$this->register_replacement(
'seo_description',
[
'name' => esc_html__( 'SEO Description', 'rank-math' ),
'description' => esc_html__( 'Custom or Generated SEO Description of the current post/page', 'rank-math' ),
'variable' => 'seo_description',
'example' => $this->get_excerpt(),
'nocache' => true,
],
[ $this, 'get_seo_description' ]
);
$this->register_replacement(
'url',
[
'name' => esc_html__( 'Post URL', 'rank-math' ),
'description' => esc_html__( 'URL of the current post/page', 'rank-math' ),
'variable' => 'url',
'example' => $this->get_url(),
],
[ $this, 'get_url' ]
);
$this->register_replacement(
'post_thumbnail',
[
'name' => esc_html__( 'Post Thumbnail', 'rank-math' ),
'description' => esc_html__( 'Current Post Thumbnail', 'rank-math' ),
'variable' => 'post_thumbnail',
'example' => $this->get_post_thumbnail(),
'nocache' => true,
],
[ $this, 'get_post_thumbnail' ]
);
$this->setup_post_dates_variables();
$this->setup_post_category_variables();
$this->setup_post_tags_variables();
}
/**
* Setup post dates variables.
*/
public function setup_post_dates_variables() {
$this->register_replacement(
'date',
[
'name' => esc_html__( 'Date Published', 'rank-math' ),
'description' => wp_kses_post( __( 'Publication date of the current post/page <strong>OR</strong> specified date on date archives', 'rank-math' ) ),
'variable' => 'date',
'example' => $this->is_post_edit ? get_the_date() : current_time( get_option( 'date_format' ) ),
'nocache' => true,
],
[ $this, 'get_date' ]
);
$this->register_replacement(
'modified',
[
'name' => esc_html__( 'Date Modified', 'rank-math' ),
'description' => esc_html__( 'Last modification date of the current post/page', 'rank-math' ),
'variable' => 'modified',
'example' => $this->is_post_edit ? get_the_modified_date() : current_time( get_option( 'date_format' ) ),
'nocache' => true,
],
[ $this, 'get_modified' ]
);
$this->register_replacement(
'date_args',
[
'name' => esc_html__( 'Date Published (advanced)', 'rank-math' ),
'description' => esc_html__( 'Publish date with custom formatting pattern.', 'rank-math' ),
'variable' => 'date(F jS, Y)',
'example' => date_i18n( 'F jS, Y' ),
],
[ $this, 'get_date' ]
);
$this->register_replacement(
'modified_args',
[
'name' => esc_html__( 'Date Modified (advanced)', 'rank-math' ),
'description' => esc_html__( 'Modified date with custom formatting pattern.', 'rank-math' ),
'variable' => 'modified(F jS, Y)',
'example' => date_i18n( 'F jS, Y' ),
],
[ $this, 'get_modified' ]
);
}
/**
* Setup post category variables.
*/
public function setup_post_category_variables() {
$category = $this->get_category();
$categories = $this->get_categories();
$this->register_replacement(
'category',
[
'name' => esc_html__( 'Post Category', 'rank-math' ),
'description' => wp_kses_post( __( 'First category (alphabetically) associated to the current post <strong>OR</strong> current category on category archives', 'rank-math' ) ),
'variable' => 'category',
'example' => $category ? $category : esc_html__( 'Example Category', 'rank-math' ),
],
[ $this, 'get_category' ]
);
$this->register_replacement(
'categories',
[
'name' => esc_html__( 'Post Categories', 'rank-math' ),
'description' => esc_html__( 'Comma-separated list of categories associated to the current post', 'rank-math' ),
'variable' => 'categories',
'example' => $categories ? $categories : esc_html__( 'Example Category 1, Example Category 2', 'rank-math' ),
],
[ $this, 'get_categories' ]
);
$this->register_replacement(
'categories_args',
[
'name' => esc_html__( 'Categories (advanced)', 'rank-math' ),
'description' => esc_html__( 'Output list of categories associated to the current post, with customization options.', 'rank-math' ),
'variable' => 'categories(limit=3&separator= | &exclude=12,23)',
'example' => $categories ? $categories : esc_html__( 'Example Category 1, Example Category 2', 'rank-math' ),
],
[ $this, 'get_categories' ]
);
$this->register_replacement(
'primary_taxonomy_terms',
[
'name' => esc_html__( 'Primary Terms', 'rank-math' ),
'variable' => 'primary_taxonomy_terms',
'description' => esc_html__( 'Output list of terms from the primary taxonomy associated to the current post.', 'rank-math' ),
'example' => $this->get_primary_taxonomy_terms(),
],
[ $this, 'get_primary_taxonomy_terms' ]
);
}
/**
* Setup post tags variables.
*/
public function setup_post_tags_variables() {
$tag = $this->get_tag();
$tags = $this->get_tags();
$this->register_replacement(
'tag',
[
'name' => esc_html__( 'Post Tag', 'rank-math' ),
'description' => wp_kses_post( __( 'First tag (alphabetically) associated to the current post <strong>OR</strong> current tag on tag archives', 'rank-math' ) ),
'variable' => 'tag',
'example' => $tag ? $tag : esc_html__( 'Example Tag', 'rank-math' ),
'nocache' => true,
],
[ $this, 'get_tag' ]
);
$this->register_replacement(
'tags',
[
'name' => esc_html__( 'Post Tags', 'rank-math' ),
'description' => esc_html__( 'Comma-separated list of tags associated to the current post', 'rank-math' ),
'variable' => 'tags',
'example' => $tags ? $tags : esc_html__( 'Example Tag 1, Example Tag 2', 'rank-math' ),
'nocache' => true,
],
[ $this, 'get_tags' ]
);
$this->register_replacement(
'tags_args',
[
'name' => esc_html__( 'Tags (advanced)', 'rank-math' ),
'description' => esc_html__( 'Output list of tags associated to the current post, with customization options.', 'rank-math' ),
'variable' => 'tags(limit=3&separator= | &exclude=12,23)',
'example' => $tags ? $tags : esc_html__( 'Example Tag 1 | Example Tag 2', 'rank-math' ),
'nocache' => true,
],
[ $this, 'get_tags' ]
);
}
/**
* Get the title of the post to use as a replacement.
*
* @return string|null
*/
public function get_title() {
// Get post type name as Title.
if ( is_post_type_archive() && ! Post::is_shop_page() ) {
$post_type = $this->get_queried_post_type();
return get_post_type_object( $post_type )->labels->name;
}
return Str::is_non_empty( $this->args->post_title ) ? stripslashes( $this->args->post_title ) : null;
}
/**
* Custom or Generated SEO Title
*
* @return string
*/
public function get_seo_title() {
if ( is_singular() || is_category() || is_tag() || is_tax() ) {
return Paper::get()->get_title();
}
$object = $this->args;
// Early Bail!
if ( empty( $object ) || empty( $object->ID ) ) {
return '';
}
$title = Post::get_meta( 'title', $object->ID );
if ( '' !== $title ) {
return $title;
}
return Paper::get_from_options( "pt_{$object->post_type}_title", $object, '%title% %sep% %sitename%' );
}
/**
* Custom or Generated SEO Description
*
* @return string
*/
public function get_seo_description() {
if ( is_singular() || is_category() || is_tag() || is_tax() ) {
return Paper::get()->get_description();
}
$object = $this->args;
// Early Bail!
if ( empty( $object ) || empty( $object->ID ) ) {
return '';
}
$description = Post::get_meta( 'description', $object->ID );
if ( '' !== $description ) {
return $description;
}
return Paper::get_from_options( "pt_{$object->post_type}_description", $object, '%excerpt%' );
}
/**
* Get the parent page title of the current page/CPT to use as a replacement.
*
* @return string|null
*/
public function get_parent_title() {
$on_screen = is_singular() || is_admin();
$has_parent = isset( $this->args->post_parent ) && 0 !== $this->args->post_parent;
return $on_screen && $has_parent ? get_the_title( $this->args->post_parent ) : null;
}
/**
* Get the post excerpt to use as a replacement. It will be auto-generated if it does not exist.
*
* @return string|null
*/
public function get_excerpt() {
$object = $this->args;
// Early Bail!
if ( empty( $object ) ) {
return '';
}
return ! empty( $object->post_excerpt ) ? wp_strip_all_tags( $object->post_excerpt ) : $this->get_post_content( $object );
}
/**
* Get the post excerpt to use as a replacement (without auto-generating).
*
* @return string|null
*/
public function get_excerpt_only() {
$has = '' !== $this->args->post_excerpt && ! empty( $this->args->ID ) && ! post_password_required( $this->args->ID );
return $has ? wp_strip_all_tags( $this->args->post_excerpt ) : null;
}
/**
* Get the date of the post to use as a replacement.
*
* @param string $format (Optional) PHP date format.
* @return string|null
*/
public function get_date( $format = '' ) {
if ( is_array( $format ) && empty( $format ) ) {
$format = '';
}
if ( '' !== $this->args->post_date ) {
$format = $format ? $format : get_option( 'date_format' );
return mysql2date( $format, $this->args->post_date, true );
}
if ( ! empty( get_query_var( 'day' ) ) ) {
return get_the_date( $format );
}
$replacement = single_month_title( ' ', false );
if ( Str::is_non_empty( $replacement ) ) {
return $replacement;
}
return ! empty( get_query_var( 'year' ) ) ? get_query_var( 'year' ) : null;
}
/**
* Get the post modified time to use as a replacement.
*
* @param string $format (Optional) PHP date format.
* @return string|null
*/
public function get_modified( $format = '' ) {
if ( ! empty( $this->args->post_modified ) && ! empty( $this->args->post_date ) ) {
$modified = strtotime( $this->args->post_date ) > strtotime( $this->args->post_modified ) ? $this->args->post_date : $this->args->post_modified;
$format = $format ? $format : get_option( 'date_format' );
return mysql2date( $format, $modified, true );
}
return null;
}
/**
* Get the post category to use as a replacement.
*
* @return string|null
*/
public function get_category() {
if ( ! empty( $this->args->ID ) ) {
$cat = $this->get_terms( $this->args->ID, 'category', true );
if ( '' !== $cat ) {
return $cat;
}
}
return ! empty( $this->args->cat_name ) ? $this->args->cat_name : null;
}
/**
* Get the comma-separate post categories to use as a replacement.
*
* @param array $args Array of arguments.
* @return string|null
*/
public function get_categories( $args = [] ) {
if ( ! empty( $this->args->ID ) ) {
$cat = $this->get_terms( $this->args->ID, 'category', false, $args );
if ( '' !== $cat ) {
return $cat;
}
}
return null;
}
/**
* Get the current tag to use as a replacement.
*
* @return string|null
*/
public function get_tag() {
if ( ! empty( $this->args->ID ) ) {
$tags = $this->get_terms( $this->args->ID, 'post_tag', true );
if ( '' !== $tags ) {
return $tags;
}
}
return null;
}
/**
* Get the current tags to use as a replacement.
*
* @param array $args Arguments for get_terms().
* @return string|null
*/
public function get_tags( $args = [] ) {
if ( ! empty( $this->args->ID ) ) {
$tags = $this->get_terms( $this->args->ID, 'post_tag', false, $args );
if ( '' !== $tags ) {
return $tags;
}
}
return null;
}
/**
* Get the comma separated post terms.
*
* @return string|null
*/
public function get_primary_taxonomy_terms() {
if ( empty( $this->args->ID ) ) {
return;
}
$post_type = get_post_type( $this->args->ID );
$main_tax = Helper::get_settings( "titles.pt_{$post_type}_primary_taxonomy" );
if ( ! $main_tax ) {
return;
}
$terms = wp_get_object_terms(
$this->args->ID,
$main_tax,
[ 'fields' => 'names' ]
);
if ( is_wp_error( $terms ) || empty( $terms ) ) {
return;
}
return implode( ', ', $terms );
}
/**
* Get the auto generated post content.
*
* @param array $object Post Object.
* @return string|null
*/
private function get_post_content( $object ) {
if ( empty( $object->post_content ) ) {
return '';
}
$keywords = Post::get_meta( 'focus_keyword', $object->ID );
$post_content = Paper::should_apply_shortcode() ? do_shortcode( $object->post_content ) : $object->post_content;
$post_content = \preg_replace( '/<!--[\s\S]*?-->/iu', '', $post_content );
$post_content = wpautop( Helper::strip_shortcodes( $post_content ) );
$post_content = wp_kses( $post_content, [ 'p' => [] ] );
// Remove empty paragraph tags.
$post_content = preg_replace( '/<p[^>]*>(\s|&nbsp;)*<\/p>/', '', $post_content );
// 4. Paragraph with the focus keyword.
if ( ! empty( $keywords ) ) {
$primary_keyword = explode( ',', $keywords );
$primary_keyword = trim( $primary_keyword[0] );
$regex = '/<p>(.*' . str_replace( [ ',', ' ', '/' ], [ '|', '.', '\/' ], $primary_keyword ) . '.*)<\/p>/iu';
\preg_match_all( $regex, $post_content, $matches );
if ( isset( $matches[1], $matches[1][0] ) ) {
return $matches[1][0];
}
}
// 5. The First paragraph of the content.
\preg_match_all( '/<p>(.*)<\/p>/iu', $post_content, $matches );
return isset( $matches[1], $matches[1][0] ) ? $matches[1][0] : $post_content;
}
/**
* Default post data.
*
* @return array
*/
private function get_defaults() {
$defaults = Replacer::$defaults;
if ( $this->is_post_edit ) {
$defaults['post_author'] = 'Author Name';
$defaults['post_content'] = 'Post content';
$defaults['post_title'] = 'Post Title';
}
return $defaults;
}
/**
* Get the canonical URL to use as a replacement.
*
* @return string|null
*/
public function get_url() {
return Paper::get()->get_canonical() ? Paper::get()->get_canonical() : get_the_permalink( $this->args->ID );
}
/**
* Get the the post thumbnail to use as a replacement.
*
* @return string|null
*/
public function get_post_thumbnail() {
if ( ! has_post_thumbnail( $this->args->ID ) ) {
return '';
}
$image = wp_get_attachment_image_src( get_post_thumbnail_id( $this->args->ID ), 'full' );
return ! empty( $image ) ? $image[0] : '';
}
}

View File

@@ -0,0 +1,338 @@
<?php
/**
* Variable replacement functionality.
*
* @since 1.0.33
* @package RankMath
* @subpackage RankMath\Replace_Variables
* @author Rank Math <support@rankmath.com>
*
* @copyright Copyright (C) 2008-2019, Yoast BV
* The following code is a derivative work of the code from the Yoast(https://github.com/Yoast/wordpress-seo/), which is licensed under GPL v3.
*/
namespace RankMath\Replace_Variables;
use RankMath\Helper;
use RankMath\Helpers\Str;
use RankMath\Paper\Paper;
defined( 'ABSPATH' ) || exit;
/**
* Replacer class.
*/
class Replacer {
/**
* Do not process the same string over and over again.
*
* @var array
*/
public static $replacements_cache = [];
/**
* Non-cacheable replacements.
*
* @var array
*/
public static $non_cacheable_replacements;
/**
* Default post data.
*
* @var array
*/
public static $defaults = [
'ID' => '',
'name' => '',
'post_author' => '',
'post_content' => '',
'post_date' => '',
'post_excerpt' => '',
'post_modified' => '',
'post_title' => '',
'taxonomy' => '',
'term_id' => '',
'term404' => '',
'filename' => '',
];
/**
* Arguments.
*
* @var object
*/
public static $args;
/**
* Process post content once.
*
* @var array
*/
public static $content_processed = [];
/**
* Exclude variables.
*
* @var array
*/
public $exclude = [];
/**
* Replace `%variables%` with context-dependent value.
*
* @param string $string The string containing the %variables%.
* @param array $args Context object, can be post, taxonomy or term.
* @param array $exclude Excluded variables won't be replaced.
*
* @return string
*/
public function replace( $string, $args = [], $exclude = [] ) {
$string = wp_strip_all_tags( $string );
// Bail early.
if ( ! Str::contains( '%', $string ) ) {
return $string;
}
if ( Str::ends_with( ' %sep%', $string ) ) {
$string = substr( $string, 0, -5 );
}
$this->pre_replace( $args, $exclude );
$replacements = $this->set_up_replacements( $string );
/**
* Filter: Allow customizing the replacements.
*
* @param array $replacements The replacements.
* @param array $args The object some of the replacement values might come from,
* could be a post, taxonomy or term.
*/
$replacements = apply_filters( 'rank_math/replacements', $replacements, self::$args );
// Do the replacements.
if ( is_array( $replacements ) && [] !== $replacements ) {
$string = str_replace( array_keys( $replacements ), array_values( $replacements ), $string );
}
if ( isset( $replacements['%sep%'] ) && Str::is_non_empty( $replacements['%sep%'] ) ) {
$q_sep = preg_quote( $replacements['%sep%'], '`' );
$string = preg_replace( '`' . $q_sep . '(?:\s*' . $q_sep . ')*`u', $replacements['%sep%'], $string );
}
// Remove excess whitespace.
return preg_replace( '[\s\s+]', ' ', $string );
}
/**
* Run prior to replacement.
*
* @param array $args Context object, can be post, taxonomy or term.
* @param array $exclude Excluded variables won't be replaced.
*/
private function pre_replace( $args, $exclude ) {
if ( is_array( $exclude ) ) {
$this->exclude = $exclude;
}
self::$args = (object) array_merge( self::$defaults, (array) $args );
$this->process_content();
}
/**
* Process content only once, because it's expensive.
*
* @return void
*/
private function process_content() {
if ( ! isset( self::$content_processed[ self::$args->ID ]['post_content'] ) ) {
self::$content_processed[ self::$args->ID ]['post_content'] = Paper::should_apply_shortcode() ? do_shortcode( self::$args->post_content ) : Helper::strip_shortcodes( self::$args->post_content );
self::$content_processed[ self::$args->ID ]['post_excerpt'] = Paper::should_apply_shortcode() ? do_shortcode( self::$args->post_excerpt ) : Helper::strip_shortcodes( self::$args->post_excerpt );
}
self::$args->post_content = self::$content_processed[ self::$args->ID ]['post_content'];
self::$args->post_excerpt = self::$content_processed[ self::$args->ID ]['post_excerpt'];
}
/**
* Get the replacements for the variables.
*
* @param string $string String to parse for variables.
*
* @return array Retrieved replacements.
*/
private function set_up_replacements( $string ) {
if ( $this->has_cache( $string ) ) {
return $this->get_cache( $string );
}
$replacements = [];
if ( ! preg_match_all( '/%(([a-z0-9_-]+)\(([^)]*)\)|[^\s]+)%/iu', $string, $matches ) ) {
$this->set_cache( $string, $replacements );
return $replacements;
}
foreach ( $matches[1] as $index => $variable_id ) {
$value = $this->get_variable_value( $matches, $index, $variable_id );
if ( false !== $value ) {
$replacements[ $matches[0][ $index ] ] = $value;
}
unset( $variable );
}
$this->set_cache( $string, $replacements );
return $replacements;
}
/**
* Get non-cacheable variables.
*
* @return array
*/
private function get_non_cacheable_variables() {
if ( ! is_null( self::$non_cacheable_replacements ) ) {
return self::$non_cacheable_replacements;
}
$non_cacheable = [];
foreach ( rank_math()->variables->get_replacements() as $variable ) {
if ( ! $variable->is_cacheable() ) {
$non_cacheable[] = $variable->get_id();
}
}
/**
* Filter: Allow changing the non-cacheable variables.
*
* @param array $non_cacheable The non-cacheable variable IDs.
*/
self::$non_cacheable_replacements = apply_filters( 'rank_math/replacements/non_cacheable', $non_cacheable );
return self::$non_cacheable_replacements;
}
/**
* Check if we have cache for a string.
*
* @param string $string String to check.
*
* @return bool
*/
private function has_cache( $string ) {
return isset( self::$replacements_cache[ md5( $string ) ] );
}
/**
* Get cache for a string. Handles non-cacheable variables.
*
* @param string $string String to get cache for.
*
* @return array
*/
private function get_cache( $string ) {
$non_cacheable = $this->get_non_cacheable_variables();
$replacements = self::$replacements_cache[ md5( $string ) ];
if ( empty( $non_cacheable ) ) {
return $replacements;
}
foreach ( $replacements as $key => $value ) {
$id = explode( '(', trim( $key, '%' ) )[0];
if ( ! in_array( $id, $non_cacheable, true ) ) {
continue;
}
$var_args = '';
$parts = explode( '(', trim( $key, '%)' ) );
if ( isset( $parts[1] ) ) {
$var_args = $this->normalize_args( $parts[1] );
}
$replacements[ $key ] = $this->get_variable_by_id( $id, $var_args )->run_callback( $var_args, self::$args );
}
return $replacements;
}
/**
* Set cache for a string.
*
* @param string $string String to set cache for.
*
* @param array $cache Cache to set.
*/
private function set_cache( $string, $cache ) {
self::$replacements_cache[ md5( $string ) ] = $cache;
}
/**
* Get variable value.
*
* @param array $matches Regex matches found in the string.
* @param int $index Index of the matched.
* @param string $id Variable id.
*
* @return mixed
*/
private function get_variable_value( $matches, $index, $id ) {
// Don't set up excluded replacements.
if ( isset( $matches[0][ $index ] ) && in_array( $matches[0][ $index ], $this->exclude, true ) ) {
return false;
}
$has_args = ! empty( $matches[2][ $index ] ) && ! empty( $matches[3][ $index ] );
$id = $has_args ? $matches[2][ $index ] : $id;
$var_args = $has_args ? $this->normalize_args( $matches[3][ $index ] ) : [];
$variable = $this->get_variable_by_id( $id, $var_args );
if ( is_null( $variable ) ) {
return rank_math()->variables->remove_non_replaced ? '' : false;
}
return $variable->run_callback( $var_args, self::$args );
}
/**
* Find variable.
*
* @param string $id Variable id.
* @param array $args Array of arguments.
*
* @return Variable|null
*/
private function get_variable_by_id( $id, $args ) {
if ( ! isset( rank_math()->variables ) ) {
return null;
}
$replacements = rank_math()->variables->get_replacements();
if ( isset( $replacements[ $id ] ) ) {
return $replacements[ $id ];
}
if ( ! empty( $args ) && isset( $replacements[ $id . '_args' ] ) ) {
return $replacements[ $id . '_args' ];
}
return null;
}
/**
* Convert arguments string to arguments array.
*
* @param string $string The string that needs to be converted.
*
* @return array
*/
private function normalize_args( $string ) {
$string = wp_specialchars_decode( $string );
if ( ! Str::contains( '=', $string ) ) {
return $string;
}
return wp_parse_args( $string, [] );
}
}

View File

@@ -0,0 +1,135 @@
<?php
/**
* Term variable replacer.
*
* @since 1.0.33
* @package RankMath
* @subpackage RankMath\Replace_Variables
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Replace_Variables;
use RankMath\Helpers\Str;
use RankMath\Helpers\Param;
defined( 'ABSPATH' ) || exit;
/**
* Term_Variables class.
*/
class Term_Variables extends Basic_Variables {
/**
* Setup term variables.
*/
public function setup_term_variables() {
if ( $this->is_term_edit ) {
$tag_id = Param::request( 'tag_ID', 0, FILTER_VALIDATE_INT );
$term = get_term( $tag_id, $GLOBALS['taxnow'], OBJECT );
$this->args = $term;
}
$this->register_replacement(
'term',
[
'name' => esc_html__( 'Current Term', 'rank-math' ),
'description' => esc_html__( 'Current term name', 'rank-math' ),
'variable' => 'term',
'example' => $this->is_term_edit ? $term->name : esc_html__( 'Example Term', 'rank-math' ),
'nocache' => true,
],
[ $this, 'get_term' ]
);
$this->register_replacement(
'term_description',
[
'name' => esc_html__( 'Term Description', 'rank-math' ),
'description' => esc_html__( 'Current term description', 'rank-math' ),
'variable' => 'term_description',
'example' => $this->is_term_edit ? wp_strip_all_tags( term_description( $term ), true ) : esc_html__( 'Example Term Description', 'rank-math' ),
],
[ $this, 'get_term_description' ]
);
$this->register_replacement(
'customterm',
[
'name' => esc_html__( 'Custom Term (advanced)', 'rank-math' ),
'description' => esc_html__( 'Custom term value.', 'rank-math' ),
'variable' => 'customterm(taxonomy-name)',
'example' => esc_html__( 'Custom term value', 'rank-math' ),
],
[ $this, 'get_custom_term' ]
);
$this->register_replacement(
'customterm_desc',
[
'name' => esc_html__( 'Custom Term description', 'rank-math' ),
'description' => esc_html__( 'Custom Term description.', 'rank-math' ),
'variable' => 'customterm_desc(taxonomy-name)',
'example' => esc_html__( 'Custom Term description.', 'rank-math' ),
],
[ $this, 'get_custom_term_desc' ]
);
}
/**
* Get the term name to use as a replacement.
*
* @return string|null
*/
public function get_term() {
global $wp_query;
if ( is_category() || is_tag() || is_tax() ) {
return $wp_query->queried_object->name;
}
return ! empty( $this->args->taxonomy ) && ! empty( $this->args->name ) ? $this->args->name : null;
}
/**
* Get the term description to use as a replacement.
*
* @return string|null
*/
public function get_term_description() {
global $wp_query;
if ( is_category() || is_tag() || is_tax() ) {
return $wp_query->queried_object->description;
}
if ( ! isset( $this->args->term_id ) || empty( $this->args->taxonomy ) ) {
return null;
}
$term_desc = get_term_field( 'description', $this->args->term_id, $this->args->taxonomy );
return '' !== $term_desc ? Str::truncate( $term_desc, 160 ) : null;
}
/**
* Get a custom taxonomy term to use as a replacement.
*
* @param string $taxonomy The name of the taxonomy.
*
* @return string|null
*/
public function get_custom_term( $taxonomy ) {
return Str::is_non_empty( $taxonomy ) ? $this->get_terms( $this->args->ID, $taxonomy, true, [], 'name' ) : null;
}
/**
* Get a custom taxonomy term description to use as a replacement.
*
* @param string $taxonomy The name of the taxonomy.
*
* @return string|null
*/
public function get_custom_term_desc( $taxonomy ) {
return Str::is_non_empty( $taxonomy ) ? $this->get_terms( $this->args->ID, $taxonomy, true, [], 'description' ) : null;
}
}

View File

@@ -0,0 +1,218 @@
<?php
/**
* Variable model.
*
* Replace '%variables%' in strings based on context.
*
* @since 1.0.33
* @package RankMath
* @subpackage RankMath\Replace_Variables
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Replace_Variables;
defined( 'ABSPATH' ) || exit;
/**
* Variable class.
*/
class Variable {
/**
* Required properties.
*
* @var array
*/
private static $required = [ 'name', 'description', 'variable' ];
/**
* The unique id.
*
* @var string
*/
protected $id;
/**
* The name of the variabe.
*
* @var string
*/
protected $name;
/**
* The description of the variable.
*
* @var string
*/
protected $description;
/**
* The variable to use.
*
* @var string
*/
protected $variable;
/**
* The example for the variable.
*
* @var string
*/
protected $example;
/**
* The callback to get the replacement value.
*
* @var mixed
*/
protected $callback;
/**
* The variable is cacheable or not.
*
* @var bool
*/
protected $cacheable = true;
/**
* Create variable from array.
*
* @throws \InvalidArgumentException If `$id` is empty.
*
* @param string $id Unique id of variable.
* @param array $args Array of values.
*
* @return Variable
*/
public static function from( $id, $args ) {
if ( empty( $id ) ) {
throw new \InvalidArgumentException( __( 'The $id variable is required.', 'rank-math' ) );
}
$variable = new Variable();
$variable->id = $id;
$variable->example = isset( $args['example'] ) ? $args['example'] : __( 'Example', 'rank-math' );
foreach ( self::$required as $key ) {
if ( ! isset( $args[ $key ] ) ) {
/* translators: variable name */
throw new \InvalidArgumentException( sprintf( __( 'The $%1$s is required for variable %2$s.', 'rank-math' ), $key, $id ) );
}
$variable->$key = $args[ $key ];
}
if ( isset( $args['nocache'] ) && $args['nocache'] ) {
$variable->cacheable = false;
}
return $variable;
}
/**
* Returns the id.
*
* @return string
*/
public function get_id() {
return $this->id;
}
/**
* Returns the name.
*
* @return string
*/
public function get_name() {
return $this->name;
}
/**
* Returns the description.
*
* @return string
*/
public function get_description() {
return $this->description;
}
/**
* Returns the variable.
*
* @return string
*/
public function get_variable() {
return $this->variable;
}
/**
* Returns the example.
*
* @return string
*/
public function get_example() {
return $this->example;
}
/**
* Set example.
*
* @param string $example New example.
*/
public function set_example( $example ) {
$this->example = $example;
}
/**
* Set callback.
*
* @param mixed $callback New callback.
*/
public function set_callback( $callback ) {
$this->callback = $callback;
}
/**
* Run callback.
*
* @param array $var_args Array of arguments passed with variable.
* @param array $args The object some of the replacement values might come from,
* could be a post, taxonomy or term.
*
* @return mixed
*/
public function run_callback( $var_args, $args = [] ) {
rank_math()->variables->set_arguments( $args );
$value = ! empty( $this->callback ) ? call_user_func( $this->callback, $var_args, $args ) :
apply_filters( 'rank_math/vars/' . $this->get_id(), $var_args, $this );
rank_math()->variables->reset_arguments();
return $value;
}
/**
* Convert object to array.
*
* @return array Object as array.
*/
public function to_array() {
$arr = [];
foreach ( [ 'name', 'description', 'variable', 'example' ] as $key ) {
$arr[ $key ] = $this->$key;
}
return $arr;
}
/**
* Returns the variable is cacheable or not.
*
* @return bool
*/
public function is_cacheable() {
return $this->cacheable;
}
}