Commit realizado el 12:13:52 08-04-2024
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* The Analytics helpers.
|
||||
*
|
||||
* @since 1.0.86.2
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
use RankMath\Helper;
|
||||
use RankMath\Google\Authentication;
|
||||
use RankMath\Google\Console;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Analytics class.
|
||||
*/
|
||||
trait Analytics {
|
||||
|
||||
/**
|
||||
* Can add Analytics Frontend stats.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function can_add_frontend_stats() {
|
||||
return Authentication::is_authorized() &&
|
||||
Console::is_console_connected() &&
|
||||
Helper::has_cap( 'analytics' ) &&
|
||||
apply_filters( 'rank_math/analytics/frontend_stats', Helper::get_settings( 'general.analytics_stats' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Can add Index Status tab on Analytics page.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function can_add_index_status() {
|
||||
$profile = get_option( 'rank_math_google_analytic_profile', [] );
|
||||
if ( is_array( $profile ) && isset( $profile['enable_index_status'] ) ) {
|
||||
return $profile['enable_index_status'];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
/**
|
||||
* The API helpers.
|
||||
*
|
||||
* @since 1.0.9
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
use RankMath\Admin\Admin_Helper;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* API class.
|
||||
*/
|
||||
trait Api {
|
||||
|
||||
/**
|
||||
* Add notification.
|
||||
*
|
||||
* @param string $message Message string.
|
||||
* @param array $options Set of options.
|
||||
*/
|
||||
public static function add_notification( $message, $options = [] ) {
|
||||
$options['classes'] = ! empty( $options['classes'] ) ? $options['classes'] . ' rank-math-notice' : 'rank-math-notice';
|
||||
$notification = compact( 'message', 'options' );
|
||||
|
||||
/**
|
||||
* Filter notification message & arguments before adding.
|
||||
* Pass a falsy value to stop the notification from getting added.
|
||||
*/
|
||||
apply_filters( 'rank_math/admin/add_notification', $notification );
|
||||
|
||||
if ( empty( $notification ) || ! is_array( $notification ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
rank_math()->notification->add( $notification['message'], $notification['options'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove notification.
|
||||
*
|
||||
* @param string $notification_id Notification id.
|
||||
*/
|
||||
public static function remove_notification( $notification_id ) {
|
||||
rank_math()->notification->remove_by_id( $notification_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if notification exists.
|
||||
*
|
||||
* @param string $notification_id Notification id.
|
||||
*/
|
||||
public static function has_notification( $notification_id ) {
|
||||
return rank_math()->notification->has_notification( $notification_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Setting.
|
||||
*
|
||||
* @param string $field_id The field id to get value for.
|
||||
* @param mixed $default The default value if no field found.
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get_settings( $field_id = '', $default = false ) {
|
||||
return rank_math()->settings->get( $field_id, $default );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Auto update setting status.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function get_auto_update_setting() {
|
||||
return in_array( 'seo-by-rank-math/rank-math.php', (array) get_site_option( 'auto_update_plugins', [] ), true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle auto updates option.
|
||||
*
|
||||
* @param string $toggle New status.
|
||||
* @return void
|
||||
*/
|
||||
public static function toggle_auto_update_setting( $toggle ) {
|
||||
do_action( 'rank_math/settings/toggle_auto_update', $toggle );
|
||||
|
||||
$auto_updates = (array) get_site_option( 'auto_update_plugins', [] );
|
||||
if ( ! empty( $toggle ) && 'off' !== $toggle ) {
|
||||
$auto_updates[] = 'seo-by-rank-math/rank-math.php';
|
||||
update_site_option( 'auto_update_plugins', array_unique( $auto_updates ) );
|
||||
return;
|
||||
}
|
||||
|
||||
update_site_option( 'auto_update_plugins', array_diff( $auto_updates, [ 'seo-by-rank-math/rank-math.php' ] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add something to the JSON object.
|
||||
*
|
||||
* @param string $key Unique identifier.
|
||||
* @param mixed $value The data itself can be either a single or an array.
|
||||
* @param string $object_name Name for the JavaScript object. Passed directly, so it should be qualified JS variable.
|
||||
*/
|
||||
public static function add_json( $key, $value, $object_name = 'rankMath' ) {
|
||||
rank_math()->json->add( $key, $value, $object_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove something from the JSON object.
|
||||
*
|
||||
* @param string $key Unique identifier.
|
||||
* @param string $object_name Name for the JavaScript object. Passed directly, so it should be qualified JS variable.
|
||||
*/
|
||||
public static function remove_json( $key, $object_name = 'rankMath' ) {
|
||||
rank_math()->json->remove( $key, $object_name );
|
||||
}
|
||||
}
|
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
/**
|
||||
* The Array helpers.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author RankMath <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
use ArrayAccess;
|
||||
|
||||
/**
|
||||
* Arr class.
|
||||
*/
|
||||
class Arr {
|
||||
|
||||
/**
|
||||
* Determine whether the given value is array accessible.
|
||||
*
|
||||
* @param mixed $value Value to check.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function accessible( $value ) {
|
||||
return is_array( $value ) || $value instanceof ArrayAccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given key exists in the provided array.
|
||||
*
|
||||
* @param ArrayAccess|array $array Array to check key in.
|
||||
* @param string|int $key Key to check for.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function exists( $array, $key ) {
|
||||
if ( $array instanceof ArrayAccess ) {
|
||||
// @codeCoverageIgnoreStart
|
||||
return $array->offsetExists( $key );
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return array_key_exists( $key, $array );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether an array or [[\Traversable]] contains an element.
|
||||
*
|
||||
* This method does the same as the PHP function [in_array()](https://secure.php.net/manual/en/function.in-array.php)
|
||||
* but additionally works for objects that implement the [[\Traversable]] interface.
|
||||
*
|
||||
* @throws \InvalidArgumentException If `$array` is neither traversable nor an array.
|
||||
*
|
||||
* @param array|\Traversable $array The set of values to search.
|
||||
* @param mixed $search The value to look for.
|
||||
* @param bool $strict Whether to enable strict (`===`) comparison.
|
||||
*
|
||||
* @return bool `true` if `$search` was found in `$array`, `false` otherwise.
|
||||
*/
|
||||
public static function includes( $array, $search, $strict = true ) {
|
||||
if ( $array instanceof \Traversable ) {
|
||||
return self::includes_traversable( $array, $search, $strict );
|
||||
}
|
||||
|
||||
$is_array = is_array( $array );
|
||||
if ( ! $is_array ) {
|
||||
throw new \InvalidArgumentException( 'Argument $array must be an array or implement Traversable' );
|
||||
}
|
||||
|
||||
return $is_array ? in_array( $search, $array, $strict ) : false; // phpcs:ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Traversable contains an element.
|
||||
*
|
||||
* @param \Traversable $array The set of values to search.
|
||||
* @param mixed $search The value to look for.
|
||||
* @param bool $strict Whether to enable strict (`===`) comparison.
|
||||
*
|
||||
* @return bool `true` if `$search` was found in `$array`, `false` otherwise.
|
||||
*/
|
||||
private static function includes_traversable( $array, $search, $strict = true ) {
|
||||
foreach ( $array as $value ) {
|
||||
if ( ( $strict && $search === $value ) || $search == $value ) { // phpcs:ignore
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a single array item inside another array at a set position
|
||||
*
|
||||
* @param array $array Array to modify. Is passed by reference, and no return is needed.
|
||||
* @param array $new New array to insert.
|
||||
* @param int $position Position in the main array to insert the new array.
|
||||
*/
|
||||
public static function insert( &$array, $new, $position ) {
|
||||
$before = array_slice( $array, 0, $position - 1 );
|
||||
$after = array_diff_key( $array, $before );
|
||||
$array = array_merge( $before, $new, $after );
|
||||
}
|
||||
|
||||
/**
|
||||
* Push an item onto the beginning of an array.
|
||||
*
|
||||
* @param array $array Array to add.
|
||||
* @param mixed $value Value to add.
|
||||
* @param mixed $key Add with this key.
|
||||
*/
|
||||
public static function prepend( &$array, $value, $key = null ) {
|
||||
if ( is_null( $key ) ) {
|
||||
array_unshift( $array, $value );
|
||||
return;
|
||||
}
|
||||
|
||||
$array = [ $key => $value ] + $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update array add or delete value
|
||||
*
|
||||
* @param array $array Array to modify. Is passed by reference, and no return is needed.
|
||||
* @param array $value Value to add or delete.
|
||||
*/
|
||||
public static function add_delete_value( &$array, $value ) {
|
||||
if ( ( $key = array_search( $value, $array ) ) !== false ) { // @codingStandardsIgnoreLine
|
||||
unset( $array[ $key ] );
|
||||
return;
|
||||
}
|
||||
|
||||
$array[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an array from string.
|
||||
*
|
||||
* @param string $string The string to split.
|
||||
* @param string $separator Specifies where to break the string.
|
||||
*
|
||||
* @return array Returns an array after applying the function to each one.
|
||||
*/
|
||||
public static function from_string( $string, $separator = ',' ) {
|
||||
return array_values( array_filter( array_map( 'trim', explode( $separator, $string ) ) ) );
|
||||
}
|
||||
}
|
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
/**
|
||||
* The Attachment helpers.
|
||||
*
|
||||
* @since 0.9.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
use RankMath\Helper;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Attachment trait.
|
||||
*/
|
||||
class Attachment {
|
||||
|
||||
/**
|
||||
* Check if a post can be included in sitemap.
|
||||
*
|
||||
* @param int $attachment_id Attachment ID to check.
|
||||
* @return bool
|
||||
*/
|
||||
public static function attachment_in_sitemap( $attachment_id ) {
|
||||
if ( empty( $attachment_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$exclude_sitemap = get_post_meta( $attachment_id, 'rank_math_exclude_sitemap', true );
|
||||
|
||||
return empty( $exclude_sitemap );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate local path for an attachment image.
|
||||
* Credit: https://wordpress.stackexchange.com/a/182519
|
||||
*
|
||||
* @param int $attachment_id Attachment ID.
|
||||
* @param string $size Size.
|
||||
*/
|
||||
public static function get_scaled_image_path( $attachment_id, $size = 'thumbnail' ) {
|
||||
$file = get_attached_file( $attachment_id, true );
|
||||
if ( empty( $size ) || $size === 'full' ) {
|
||||
// For the original size get_attached_file is fine.
|
||||
return realpath( $file );
|
||||
}
|
||||
|
||||
if ( ! wp_attachment_is_image( $attachment_id ) ) {
|
||||
return false; // the ID is not referring to a media.
|
||||
}
|
||||
|
||||
$info = image_get_intermediate_size( $attachment_id, $size );
|
||||
if ( ! is_array( $info ) || ! isset( $info['file'] ) ) {
|
||||
return false; // Probably a bad size argument.
|
||||
}
|
||||
|
||||
return realpath( str_replace( wp_basename( $file ), $info['file'], $file ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs an image alt text.
|
||||
*
|
||||
* @param int $attachment_id The attachment ID.
|
||||
*
|
||||
* @return string The image alt text.
|
||||
*/
|
||||
public static function get_alt_tag( $attachment_id ) {
|
||||
return (string) get_post_meta( $attachment_id, '_wp_attachment_image_alt', true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the relative path of the image.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $img Image URL.
|
||||
*
|
||||
* @return string The expanded image URL.
|
||||
*/
|
||||
public static function get_relative_path( $img ) {
|
||||
if ( '/' !== $img[0] ) {
|
||||
return $img;
|
||||
}
|
||||
|
||||
// If it's a relative URL, it's relative to the domain, not necessarily to the WordPress install, we
|
||||
// want to preserve domain name and URL scheme (http / https) though.
|
||||
$parsed_url = wp_parse_url( home_url() );
|
||||
|
||||
return $parsed_url['scheme'] . '://' . $parsed_url['host'] . $img;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an attachment ID for a given URL.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $url The URL to find the attachment for.
|
||||
*
|
||||
* @return int The found attachment ID, or 0 if none was found.
|
||||
*/
|
||||
public static function get_by_url( $url ) {
|
||||
// Because get_by_url won't work on resized versions of images, we strip out the size part of an image URL.
|
||||
$url = preg_replace( '/(.*)-\d+x\d+\.(jpg|png|gif)$/', '$1.$2', $url );
|
||||
|
||||
$id = function_exists( 'wpcom_vip_attachment_url_to_postid' ) ? wpcom_vip_attachment_url_to_postid( $url ) : self::url_to_postid( $url );
|
||||
|
||||
return absint( $id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the attachment_url_to_postid with use of WP Cache.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @link https://dotlayer.com/20-wordpress-core-functions-that-dont-scale-and-how-to-work-around-it/
|
||||
*
|
||||
* @param string $url The attachment URL for which we want to know the Post ID.
|
||||
*
|
||||
* @return int The Post ID belonging to the attachment, 0 if not found.
|
||||
*/
|
||||
private static function url_to_postid( $url ) {
|
||||
$cache_key = sprintf( 'mythemeshop_attachment_url_post_id_%s', md5( $url ) );
|
||||
|
||||
// Set the ID based on the hashed url in the cache.
|
||||
$id = wp_cache_get( $cache_key );
|
||||
|
||||
if ( 'not_found' === $id ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ID is found in cache, return.
|
||||
if ( false !== $id ) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.VIP.RestrictedFunctions -- We use the WP COM version if we can, see above.
|
||||
$id = attachment_url_to_postid( $url );
|
||||
|
||||
if ( empty( $id ) ) {
|
||||
wp_cache_set( $cache_key, 'not_found', 'default', ( 12 * HOUR_IN_SECONDS + mt_rand( 0, ( 4 * HOUR_IN_SECONDS ) ) ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We have the Post ID, but it's not in the cache yet. We do that here and return.
|
||||
wp_cache_set( $cache_key, $id, 'default', ( 24 * HOUR_IN_SECONDS + mt_rand( 0, ( 12 * HOUR_IN_SECONDS ) ) ) );
|
||||
|
||||
return $id;
|
||||
}
|
||||
}
|
@@ -0,0 +1,753 @@
|
||||
<?php
|
||||
/**
|
||||
* The Choices helpers.
|
||||
*
|
||||
* @since 0.9.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
use RankMath\Helper;
|
||||
use RankMath\Admin\Admin_Helper;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Choices class.
|
||||
*/
|
||||
trait Choices {
|
||||
|
||||
/**
|
||||
* Gets list of overlay images for the social thumbnail.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $output Output type.
|
||||
* @return array
|
||||
*/
|
||||
public static function choices_overlay_images( $output = 'object' ) {
|
||||
$uri = rank_math()->plugin_url() . 'assets/admin/img/';
|
||||
$dir = rank_math()->plugin_dir() . 'assets/admin/img/';
|
||||
|
||||
/**
|
||||
* Allow developers to add/remove overlay images.
|
||||
*
|
||||
* @param array $images Image data as array of arrays.
|
||||
*/
|
||||
$list = apply_filters(
|
||||
'rank_math/social/overlay_images',
|
||||
[
|
||||
'play' => [
|
||||
'name' => esc_html__( 'Play icon', 'rank-math' ),
|
||||
'url' => $uri . 'icon-play.png',
|
||||
'path' => $dir . 'icon-play.png',
|
||||
],
|
||||
'gif' => [
|
||||
'name' => esc_html__( 'GIF icon', 'rank-math' ),
|
||||
'url' => $uri . 'icon-gif.png',
|
||||
'path' => $dir . 'icon-gif.png',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
// Allow custom positions.
|
||||
foreach ( $list as $name => $data ) {
|
||||
$list[ $name ]['position'] = apply_filters( 'rank_math/social/overlay_image_position', 'middle_center', $name );
|
||||
}
|
||||
|
||||
return 'names' === $output ? wp_list_pluck( $list, 'name' ) : $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get robot choices.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function choices_robots() {
|
||||
return [
|
||||
'index' => esc_html__( 'Index', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Instructs search engines to index and show these pages in the search results.', 'rank-math' ) ),
|
||||
'noindex' => esc_html__( 'No Index', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Prevents pages from being indexed and displayed in search engine result pages', 'rank-math' ) ),
|
||||
'nofollow' => esc_html__( 'No Follow', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Prevents search engines from following links on the pages', 'rank-math' ) ),
|
||||
'noarchive' => esc_html__( 'No Archive', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Prevents search engines from showing Cached links for pages', 'rank-math' ) ),
|
||||
'noimageindex' => esc_html__( 'No Image Index', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Prevents images on a page from being indexed by Google and other search engines', 'rank-math' ) ),
|
||||
'nosnippet' => esc_html__( 'No Snippet', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Prevents a snippet from being shown in the search results', 'rank-math' ) ),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get separator choices.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $current Currently saved separator if any.
|
||||
* @return array
|
||||
*/
|
||||
public static function choices_separator( $current = '' ) {
|
||||
$defaults = [ '-', '–', '—', '»', '|', '•' ];
|
||||
if ( ! $current || in_array( $current, $defaults, true ) ) {
|
||||
$current = '';
|
||||
}
|
||||
|
||||
return [
|
||||
'-' => '-',
|
||||
'–' => '–',
|
||||
'—' => '—',
|
||||
'»' => '»',
|
||||
'|' => '|',
|
||||
'•' => '•',
|
||||
$current => '<span class="custom-sep" contenteditable>' . $current . '</span>',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all accessible post types as choices.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function choices_post_types() {
|
||||
static $choices_post_types;
|
||||
|
||||
if ( ! isset( $choices_post_types ) ) {
|
||||
$choices_post_types = Helper::get_accessible_post_types();
|
||||
$choices_post_types = \array_map(
|
||||
function( $post_type ) {
|
||||
$object = get_post_type_object( $post_type );
|
||||
return $object->label;
|
||||
},
|
||||
$choices_post_types
|
||||
);
|
||||
}
|
||||
|
||||
return $choices_post_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all post types.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function choices_any_post_types() {
|
||||
|
||||
$post_types = self::choices_post_types();
|
||||
unset( $post_types['attachment'] );
|
||||
|
||||
return [ 'any' => esc_html__( 'Any', 'rank-math' ) ] + $post_types + [ 'comments' => esc_html( translate( 'Comments' ) ) ]; // phpcs:ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* Get business types as choices.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param bool $none Add none option to list.
|
||||
* @return array
|
||||
*/
|
||||
public static function choices_business_types( $none = false ) {
|
||||
$data = apply_filters(
|
||||
'rank_math/json_ld/business_types',
|
||||
[
|
||||
[
|
||||
'label' => 'Organization',
|
||||
'child' => [
|
||||
[ 'label' => 'Airline' ],
|
||||
[ 'label' => 'Consortium' ],
|
||||
[ 'label' => 'Corporation' ],
|
||||
[
|
||||
'label' => 'Educational Organization',
|
||||
'child' => [
|
||||
[ 'label' => 'College Or University' ],
|
||||
[ 'label' => 'Elementary School' ],
|
||||
[ 'label' => 'High School' ],
|
||||
[ 'label' => 'Middle School' ],
|
||||
[ 'label' => 'Preschool' ],
|
||||
[ 'label' => 'School' ],
|
||||
],
|
||||
],
|
||||
[ 'label' => 'Funding Scheme' ],
|
||||
[ 'label' => 'Government Organization' ],
|
||||
[ 'label' => 'Library System' ],
|
||||
[
|
||||
'label' => 'Local Business',
|
||||
'child' => [
|
||||
[ 'label' => 'Animal Shelter' ],
|
||||
[ 'label' => 'Archive Organization' ],
|
||||
[
|
||||
'label' => 'Automotive Business',
|
||||
'child' => [
|
||||
[ 'label' => 'Auto Body Shop' ],
|
||||
[ 'label' => 'Auto Dealer' ],
|
||||
[ 'label' => 'Auto Parts Store' ],
|
||||
[ 'label' => 'Auto Rental' ],
|
||||
[ 'label' => 'Auto Repair' ],
|
||||
[ 'label' => 'Auto Wash' ],
|
||||
[ 'label' => 'Gas Station' ],
|
||||
[ 'label' => 'Motorcycle Dealer' ],
|
||||
[ 'label' => 'Motorcycle Repair' ],
|
||||
],
|
||||
],
|
||||
[ 'label' => 'Child Care' ],
|
||||
[ 'label' => 'Dry Cleaning Or Laundry' ],
|
||||
[
|
||||
'label' => 'Emergency Service',
|
||||
'child' => [
|
||||
[ 'label' => 'Fire Station' ],
|
||||
[ 'label' => 'Hospital' ],
|
||||
[ 'label' => 'Police Station' ],
|
||||
],
|
||||
],
|
||||
[ 'label' => 'Employment Agency' ],
|
||||
[
|
||||
'label' => 'Entertainment Business',
|
||||
'child' => [
|
||||
[ 'label' => 'Adult Entertainment' ],
|
||||
[ 'label' => 'Amusement Park' ],
|
||||
[ 'label' => 'Art Gallery' ],
|
||||
[ 'label' => 'Casino' ],
|
||||
[ 'label' => 'Comedy Club' ],
|
||||
[ 'label' => 'Movie Theater' ],
|
||||
[ 'label' => 'Night Club' ],
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => 'Financial Service',
|
||||
'child' => [
|
||||
[ 'label' => 'Accounting Service' ],
|
||||
[ 'label' => 'Automated Teller' ],
|
||||
[ 'label' => 'Bank Or CreditUnion' ],
|
||||
[ 'label' => 'Insurance Agency' ],
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => 'Food Establishment',
|
||||
'child' => [
|
||||
[ 'label' => 'Bakery' ],
|
||||
[ 'label' => 'Bar Or Pub' ],
|
||||
[ 'label' => 'Brewery' ],
|
||||
[ 'label' => 'Cafe Or CoffeeShop' ],
|
||||
[ 'label' => 'Distillery' ],
|
||||
[ 'label' => 'Fast Food Restaurant' ],
|
||||
[ 'label' => 'IceCream Shop' ],
|
||||
[ 'label' => 'Restaurant' ],
|
||||
[ 'label' => 'Winery' ],
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => 'Government Office',
|
||||
'child' => [
|
||||
[ 'label' => 'Post Office' ],
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => 'Health And Beauty Business',
|
||||
'child' => [
|
||||
[ 'label' => 'Beauty Salon' ],
|
||||
[ 'label' => 'Day Spa' ],
|
||||
[ 'label' => 'Hair Salon' ],
|
||||
[ 'label' => 'Health Club' ],
|
||||
[ 'label' => 'Nail Salon' ],
|
||||
[ 'label' => 'Tattoo Parlor' ],
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => 'Home And Construction Business',
|
||||
'child' => [
|
||||
[ 'label' => 'Electrician' ],
|
||||
[ 'label' => 'General Contractor' ],
|
||||
[ 'label' => 'HVAC Business' ],
|
||||
[ 'label' => 'House Painter' ],
|
||||
[ 'label' => 'Locksmith' ],
|
||||
[ 'label' => 'Moving Company' ],
|
||||
[ 'label' => 'Plumber' ],
|
||||
[ 'label' => 'Roofing Contractor' ],
|
||||
],
|
||||
],
|
||||
[ 'label' => 'Internet Cafe' ],
|
||||
[
|
||||
'label' => 'Legal Service',
|
||||
'child' => [
|
||||
[ 'label' => 'Notary' ],
|
||||
],
|
||||
],
|
||||
[ 'label' => 'Library' ],
|
||||
[
|
||||
'label' => 'Lodging Business',
|
||||
'child' => [
|
||||
[ 'label' => 'Bed And Breakfast' ],
|
||||
[ 'label' => 'Campground' ],
|
||||
[ 'label' => 'Hostel' ],
|
||||
[ 'label' => 'Hotel' ],
|
||||
[ 'label' => 'Motel' ],
|
||||
[
|
||||
'label' => 'Resort',
|
||||
'child' => [
|
||||
[ 'label' => 'Ski Resort' ],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => 'Medical Business',
|
||||
'child' => [
|
||||
[ 'label' => 'Community Health' ],
|
||||
[ 'label' => 'Dentist' ],
|
||||
[ 'label' => 'Dermatology' ],
|
||||
[ 'label' => 'Diet Nutrition' ],
|
||||
[ 'label' => 'Emergency' ],
|
||||
[ 'label' => 'Geriatric' ],
|
||||
[ 'label' => 'Gynecologic' ],
|
||||
[ 'label' => 'Medical Clinic' ],
|
||||
[ 'label' => 'Optician' ],
|
||||
[ 'label' => 'Pharmacy' ],
|
||||
[ 'label' => 'Physician' ],
|
||||
],
|
||||
],
|
||||
[ 'label' => 'Professional Service' ],
|
||||
[ 'label' => 'Radio Station' ],
|
||||
[ 'label' => 'Real Estate Agent' ],
|
||||
[ 'label' => 'Recycling Center' ],
|
||||
[ 'label' => 'Self Storage' ],
|
||||
[ 'label' => 'Shopping Center' ],
|
||||
[
|
||||
'label' => 'Sports Activity Location',
|
||||
'child' => [
|
||||
[ 'label' => 'Bowling Alley' ],
|
||||
[ 'label' => 'Exercise Gym' ],
|
||||
[ 'label' => 'Golf Course' ],
|
||||
[ 'label' => 'Health Club' ],
|
||||
[ 'label' => 'Public Swimming Pool' ],
|
||||
[ 'label' => 'Ski Resort' ],
|
||||
[ 'label' => 'Sports Club' ],
|
||||
[ 'label' => 'Stadium Or Arena' ],
|
||||
[ 'label' => 'Tennis Complex' ],
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => 'Store',
|
||||
'child' => [
|
||||
[ 'label' => 'Auto Parts Store' ],
|
||||
[ 'label' => 'Bike Store' ],
|
||||
[ 'label' => 'Book Store' ],
|
||||
[ 'label' => 'Clothing Store' ],
|
||||
[ 'label' => 'Computer Store' ],
|
||||
[ 'label' => 'Convenience Store' ],
|
||||
[ 'label' => 'Department Store' ],
|
||||
[ 'label' => 'Electronics Store' ],
|
||||
[ 'label' => 'Florist' ],
|
||||
[ 'label' => 'Furniture Store' ],
|
||||
[ 'label' => 'Garden Store' ],
|
||||
[ 'label' => 'Grocery Store' ],
|
||||
[ 'label' => 'Hardware Store' ],
|
||||
[ 'label' => 'Hobby Shop' ],
|
||||
[ 'label' => 'Home Goods Store' ],
|
||||
[ 'label' => 'Jewelry Store' ],
|
||||
[ 'label' => 'Liquor Store' ],
|
||||
[ 'label' => 'Mens Clothing Store' ],
|
||||
[ 'label' => 'Mobile Phone Store' ],
|
||||
[ 'label' => 'Movie Rental Store' ],
|
||||
[ 'label' => 'Music Store' ],
|
||||
[ 'label' => 'Office Equipment Store' ],
|
||||
[ 'label' => 'Outlet Store' ],
|
||||
[ 'label' => 'Pawn Shop' ],
|
||||
[ 'label' => 'Pet Store' ],
|
||||
[ 'label' => 'Shoe Store' ],
|
||||
[ 'label' => 'Sporting GoodsStore' ],
|
||||
[ 'label' => 'Tire Shop' ],
|
||||
[ 'label' => 'Toy Store' ],
|
||||
[ 'label' => 'Wholesale Store' ],
|
||||
],
|
||||
],
|
||||
[ 'label' => 'Television Station' ],
|
||||
[ 'label' => 'Tourist Information Center' ],
|
||||
[ 'label' => 'Travel Agency' ],
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => 'Medical Organization',
|
||||
'child' => [
|
||||
[ 'label' => 'Diagnostic Lab' ],
|
||||
[ 'label' => 'Veterinary Care' ],
|
||||
],
|
||||
],
|
||||
[ 'label' => 'NGO' ],
|
||||
[ 'label' => 'News Media Organization' ],
|
||||
[
|
||||
'label' => 'Performing Group',
|
||||
'child' => [
|
||||
[ 'label' => 'Dance Group' ],
|
||||
[ 'label' => 'Music Group' ],
|
||||
[ 'label' => 'Theater Group' ],
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => 'Project',
|
||||
'child' => [
|
||||
[ 'label' => 'Funding Agency' ],
|
||||
[ 'label' => 'Research Project' ],
|
||||
],
|
||||
],
|
||||
[
|
||||
'label' => 'Sports Organization',
|
||||
'child' => [
|
||||
[ 'label' => 'Sports Team' ],
|
||||
],
|
||||
],
|
||||
[ 'label' => 'Workers Union' ],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$business = [];
|
||||
if ( $none ) {
|
||||
$business['off'] = 'None';
|
||||
}
|
||||
|
||||
foreach ( $data as $item ) {
|
||||
$business[ str_replace( ' ', '', $item['label'] ) ] = $item['label'];
|
||||
|
||||
if ( isset( $item['child'] ) ) {
|
||||
self::indent_child_elements( $business, $item['child'] );
|
||||
}
|
||||
}
|
||||
|
||||
return $business;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Schema types as choices.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param bool $none Add none option to the list.
|
||||
* @param string $post_type Post type.
|
||||
* @return array
|
||||
*/
|
||||
public static function choices_rich_snippet_types( $none = false, $post_type = '' ) {
|
||||
$types = [
|
||||
'article' => esc_html__( 'Article', 'rank-math' ),
|
||||
'book' => esc_html__( 'Book', 'rank-math' ),
|
||||
'course' => esc_html__( 'Course', 'rank-math' ),
|
||||
'event' => esc_html__( 'Event', 'rank-math' ),
|
||||
'jobposting' => esc_html__( 'Job Posting', 'rank-math' ),
|
||||
'music' => esc_html__( 'Music', 'rank-math' ),
|
||||
'product' => esc_html__( 'Product', 'rank-math' ),
|
||||
'recipe' => esc_html__( 'Recipe', 'rank-math' ),
|
||||
'restaurant' => esc_html__( 'Restaurant', 'rank-math' ),
|
||||
'video' => esc_html__( 'Video', 'rank-math' ),
|
||||
'person' => esc_html__( 'Person', 'rank-math' ),
|
||||
'service' => esc_html__( 'Service', 'rank-math' ),
|
||||
'software' => esc_html__( 'Software Application', 'rank-math' ),
|
||||
];
|
||||
|
||||
if ( ! empty( self::get_review_posts() ) ) {
|
||||
$types['review'] = esc_html__( 'Review (Unsupported)', 'rank-math' );
|
||||
}
|
||||
|
||||
if ( is_string( $none ) ) {
|
||||
$types = [ 'off' => $none ] + $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow developers to add/remove Schema type choices.
|
||||
*
|
||||
* @param array $types Schema types.
|
||||
* @param string $post_type Post type.
|
||||
*/
|
||||
return apply_filters( 'rank_math/settings/snippet/types', $types, $post_type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the redirection types.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function choices_redirection_types() {
|
||||
return [
|
||||
'301' => esc_html__( '301 Permanent Move', 'rank-math' ),
|
||||
'302' => esc_html__( '302 Temporary Move', 'rank-math' ),
|
||||
'307' => esc_html__( '307 Temporary Redirect', 'rank-math' ),
|
||||
'410' => esc_html__( '410 Content Deleted', 'rank-math' ),
|
||||
'451' => esc_html__( '451 Content Unavailable for Legal Reasons', 'rank-math' ),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get comparison types.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function choices_comparison_types() {
|
||||
return [
|
||||
'exact' => esc_html__( 'Exact', 'rank-math' ),
|
||||
'contains' => esc_html__( 'Contains', 'rank-math' ),
|
||||
'start' => esc_html__( 'Starts With', 'rank-math' ),
|
||||
'end' => esc_html__( 'End With', 'rank-math' ),
|
||||
'regex' => esc_html__( 'Regex', 'rank-math' ),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Post type icons.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function choices_post_type_icons() {
|
||||
/**
|
||||
* Allow developer to change post types icons.
|
||||
*
|
||||
* @param array $icons Array of available icons.
|
||||
*/
|
||||
return apply_filters(
|
||||
'rank_math/post_type_icons',
|
||||
[
|
||||
'default' => 'rm-icon rm-icon-post',
|
||||
'post' => 'rm-icon rm-icon-post',
|
||||
'page' => 'rm-icon rm-icon-page',
|
||||
'attachment' => 'rm-icon rm-icon-attachment',
|
||||
'product' => 'rm-icon rm-icon-cart',
|
||||
'web-story' => 'rm-icon rm-icon-stories',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Taxonomy icons.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function choices_taxonomy_icons() {
|
||||
/**
|
||||
* Allow developer to change taxonomies icons.
|
||||
*
|
||||
* @param array $icons Array of available icons.
|
||||
*/
|
||||
return apply_filters(
|
||||
'rank_math/taxonomy_icons',
|
||||
[
|
||||
'default' => 'rm-icon rm-icon-category',
|
||||
'category' => 'rm-icon rm-icon-category',
|
||||
'post_tag' => 'rm-icon rm-icon-tag',
|
||||
'product_cat' => 'rm-icon rm-icon-category',
|
||||
'product_tag' => 'rm-icon rm-icon-tag',
|
||||
'post_format' => 'rm-icon rm-icon-post-format',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get posts having review schema type selected.
|
||||
*/
|
||||
public static function get_review_posts() {
|
||||
global $wpdb;
|
||||
|
||||
static $posts = null;
|
||||
|
||||
if ( true === boolval( get_option( 'rank_math_review_posts_converted' ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! is_null( $posts ) ) {
|
||||
return $posts;
|
||||
}
|
||||
|
||||
$posts = get_transient( 'rank_math_any_review_posts' );
|
||||
if ( false !== $posts ) {
|
||||
return $posts;
|
||||
}
|
||||
|
||||
$meta_query = new \WP_Meta_Query(
|
||||
[
|
||||
'relation' => 'AND',
|
||||
[
|
||||
'key' => 'rank_math_rich_snippet',
|
||||
'value' => 'review',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$meta_query = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' );
|
||||
$posts = $wpdb->get_col( "SELECT {$wpdb->posts}.ID FROM $wpdb->posts {$meta_query['join']} WHERE 1=1 {$meta_query['where']} AND ({$wpdb->posts}.post_status = 'publish')" ); // phpcs:ignore
|
||||
|
||||
if ( 0 === count( $posts ) ) {
|
||||
update_option( 'rank_math_review_posts_converted', true );
|
||||
return false;
|
||||
}
|
||||
|
||||
set_transient( 'rank_math_any_review_posts', $posts, DAY_IN_SECONDS );
|
||||
|
||||
return $posts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Phones types for schema.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function choices_phone_types() {
|
||||
return [
|
||||
'customer support' => esc_html__( 'Customer Service', 'rank-math' ),
|
||||
'technical support' => esc_html__( 'Technical Support', 'rank-math' ),
|
||||
'billing support' => esc_html__( 'Billing Support', 'rank-math' ),
|
||||
'bill payment' => esc_html__( 'Bill Payment', 'rank-math' ),
|
||||
'sales' => esc_html__( 'Sales', 'rank-math' ),
|
||||
'reservations' => esc_html__( 'Reservations', 'rank-math' ),
|
||||
'credit card support' => esc_html__( 'Credit Card Support', 'rank-math' ),
|
||||
'emergency' => esc_html__( 'Emergency', 'rank-math' ),
|
||||
'baggage tracking' => esc_html__( 'Baggage Tracking', 'rank-math' ),
|
||||
'roadside assistance' => esc_html__( 'Roadside Assistance', 'rank-math' ),
|
||||
'package tracking' => esc_html__( 'Package Tracking', 'rank-math' ),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional Organization details for schema.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function choices_additional_organization_info() {
|
||||
return [
|
||||
'legalName' => esc_html__( 'Legal Name', 'rank-math' ),
|
||||
'foundingDate' => esc_html__( 'Founding Date', 'rank-math' ),
|
||||
'iso6523Code' => esc_html__( 'ISO 6523 Code', 'rank-math' ),
|
||||
'duns' => esc_html__( 'DUNS', 'rank-math' ),
|
||||
'leiCode' => esc_html__( 'LEI Code', 'rank-math' ),
|
||||
'naics' => esc_html__( 'NAICS Code', 'rank-math' ),
|
||||
'globalLocationNumber' => esc_html__( 'Global Location Number', 'rank-math' ),
|
||||
'vatID' => esc_html__( 'VAT ID', 'rank-math' ),
|
||||
'taxID' => esc_html__( 'Tax ID', 'rank-math' ),
|
||||
'numberOfEmployees' => esc_html__( 'Number of Employees', 'rank-math' ),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to indent child business types..
|
||||
*
|
||||
* @param array $business Business types array.
|
||||
* @param array $item Array of child data.
|
||||
* @param int $level Nesting level of the current iteration.
|
||||
*/
|
||||
private static function indent_child_elements( &$business, $item, $level = 1 ) {
|
||||
foreach ( $item as $child ) {
|
||||
$business[ str_replace( ' ', '', $child['label'] ) ] = str_repeat( '— ', $level ) . $child['label'];
|
||||
|
||||
if ( isset( $child['child'] ) ) {
|
||||
self::indent_child_elements( $business, $child['child'], ( $level + 1 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Country.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function choices_contentai_countries() {
|
||||
return [
|
||||
'all' => esc_html__( 'Worldwide', 'rank-math' ),
|
||||
'ar_DZ' => esc_html__( 'Algeria', 'rank-math' ),
|
||||
'es_AR' => esc_html__( 'Argentina', 'rank-math' ),
|
||||
'hy_AM' => esc_html__( 'Armenia', 'rank-math' ),
|
||||
'en_AU' => esc_html__( 'Australia', 'rank-math' ),
|
||||
'de_AT' => esc_html__( 'Austria', 'rank-math' ),
|
||||
'tr_AZ' => esc_html__( 'Azerbaijan', 'rank-math' ),
|
||||
'ar_BH' => esc_html__( 'Bahrain', 'rank-math' ),
|
||||
'en_BD' => esc_html__( 'Bangladesh', 'rank-math' ),
|
||||
'ru_BY' => esc_html__( 'Belarus', 'rank-math' ),
|
||||
'de_BE' => esc_html__( 'Belgium', 'rank-math' ),
|
||||
'es_BO' => esc_html__( 'Bolivia, Plurinational State Of', 'rank-math' ),
|
||||
'pt_BR' => esc_html__( 'Brazil', 'rank-math' ),
|
||||
'bg_BG' => esc_html__( 'Bulgaria', 'rank-math' ),
|
||||
'vi_KH' => esc_html__( 'Cambodia', 'rank-math' ),
|
||||
'en_CA' => esc_html__( 'Canada', 'rank-math' ),
|
||||
'es_CL' => esc_html__( 'Chile', 'rank-math' ),
|
||||
'es_CO' => esc_html__( 'Colombia', 'rank-math' ),
|
||||
'es_CR' => esc_html__( 'Costa Rica', 'rank-math' ),
|
||||
'hr_HR' => esc_html__( 'Croatia', 'rank-math' ),
|
||||
'el_CY' => esc_html__( 'Cyprus', 'rank-math' ),
|
||||
'cs_CZ' => esc_html__( 'Czechia', 'rank-math' ),
|
||||
'da_DK' => esc_html__( 'Denmark', 'rank-math' ),
|
||||
'es_EC' => esc_html__( 'Ecuador', 'rank-math' ),
|
||||
'ar_EG' => esc_html__( 'Egypt', 'rank-math' ),
|
||||
'es_SV' => esc_html__( 'El Salvador', 'rank-math' ),
|
||||
'et_EE' => esc_html__( 'Estonia', 'rank-math' ),
|
||||
'fi_FI' => esc_html__( 'Finland', 'rank-math' ),
|
||||
'fr_FR' => esc_html__( 'France', 'rank-math' ),
|
||||
'de_DE' => esc_html__( 'Germany', 'rank-math' ),
|
||||
'en_GH' => esc_html__( 'Ghana', 'rank-math' ),
|
||||
'el_GR' => esc_html__( 'Greece', 'rank-math' ),
|
||||
'es_GT' => esc_html__( 'Guatemala', 'rank-math' ),
|
||||
'en_HK' => esc_html__( 'Hong Kong', 'rank-math' ),
|
||||
'hu_HU' => esc_html__( 'Hungary', 'rank-math' ),
|
||||
'hi_IN' => esc_html__( 'India', 'rank-math' ),
|
||||
'id_ID' => esc_html__( 'Indonesia', 'rank-math' ),
|
||||
'en_IE' => esc_html__( 'Ireland', 'rank-math' ),
|
||||
'iw_IL' => esc_html__( 'Israel', 'rank-math' ),
|
||||
'it_IT' => esc_html__( 'Italy', 'rank-math' ),
|
||||
'ja_JP' => esc_html__( 'Japan', 'rank-math' ),
|
||||
'ar_JO' => esc_html__( 'Jordan', 'rank-math' ),
|
||||
'ru_KZ' => esc_html__( 'Kazakhstan', 'rank-math' ),
|
||||
'en_KE' => esc_html__( 'Kenya', 'rank-math' ),
|
||||
'ko_KR' => esc_html__( 'Korea, Republic Of', 'rank-math' ),
|
||||
'lv_LV' => esc_html__( 'Latvia', 'rank-math' ),
|
||||
'lt_LT' => esc_html__( 'Lithuania', 'rank-math' ),
|
||||
'tr_MK' => esc_html__( 'Macedonia, The Former Yugoslav Republic Of', 'rank-math' ),
|
||||
'en_MY' => esc_html__( 'Malaysia', 'rank-math' ),
|
||||
'en_MT' => esc_html__( 'Malta', 'rank-math' ),
|
||||
'es_MX' => esc_html__( 'Mexico', 'rank-math' ),
|
||||
'ar_MA' => esc_html__( 'Morocco', 'rank-math' ),
|
||||
'mnw_MM' => esc_html__( 'Myanmar', 'rank-math' ),
|
||||
'nl_NL' => esc_html__( 'Netherlands', 'rank-math' ),
|
||||
'en_NZ' => esc_html__( 'New Zealand', 'rank-math' ),
|
||||
'es_NI' => esc_html__( 'Nicaragua', 'rank-math' ),
|
||||
'en_NG' => esc_html__( 'Nigeria', 'rank-math' ),
|
||||
'no_NO' => esc_html__( 'Norway', 'rank-math' ),
|
||||
'en_PK' => esc_html__( 'Pakistan', 'rank-math' ),
|
||||
'es_PY' => esc_html__( 'Paraguay', 'rank-math' ),
|
||||
'es_PE' => esc_html__( 'Peru', 'rank-math' ),
|
||||
'en_PH' => esc_html__( 'Philippines', 'rank-math' ),
|
||||
'pl_PL' => esc_html__( 'Poland', 'rank-math' ),
|
||||
'pt_PT' => esc_html__( 'Portugal', 'rank-math' ),
|
||||
'ro_RO' => esc_html__( 'Romania', 'rank-math' ),
|
||||
'ru_RU' => esc_html__( 'Russian Federation', 'rank-math' ),
|
||||
'ar_SA' => esc_html__( 'Saudi Arabia', 'rank-math' ),
|
||||
'fr_SN' => esc_html__( 'Senegal', 'rank-math' ),
|
||||
'hr_RS' => esc_html__( 'Serbia', 'rank-math' ),
|
||||
'en_SG' => esc_html__( 'Singapore', 'rank-math' ),
|
||||
'sk_SK' => esc_html__( 'Slovakia', 'rank-math' ),
|
||||
'sl_SI' => esc_html__( 'Slovenia', 'rank-math' ),
|
||||
'en_ZA' => esc_html__( 'South Africa', 'rank-math' ),
|
||||
'es_ES' => esc_html__( 'Spain', 'rank-math' ),
|
||||
'en_LK' => esc_html__( 'Sri Lanka', 'rank-math' ),
|
||||
'sv_SE' => esc_html__( 'Sweden', 'rank-math' ),
|
||||
'de_CH' => esc_html__( 'Switzerland', 'rank-math' ),
|
||||
'zh-TW_TW' => esc_html__( 'Taiwan', 'rank-math' ),
|
||||
'th_TH' => esc_html__( 'Thailand', 'rank-math' ),
|
||||
'ar_TN' => esc_html__( 'Tunisia', 'rank-math' ),
|
||||
'tr_TR' => esc_html__( 'Turkey', 'rank-math' ),
|
||||
'ru_UA' => esc_html__( 'Ukraine', 'rank-math' ),
|
||||
'ar_AE' => esc_html__( 'United Arab Emirates', 'rank-math' ),
|
||||
'en_GB' => esc_html__( 'United Kingdom', 'rank-math' ),
|
||||
'en_US' => esc_html__( 'United States Of America', 'rank-math' ),
|
||||
'es_UY' => esc_html__( 'Uruguay', 'rank-math' ),
|
||||
'es_VE' => esc_html__( 'Venezuela, Bolivarian Republic Of', 'rank-math' ),
|
||||
'vi_VN' => esc_html__( 'Viet Nam', 'rank-math' ),
|
||||
];
|
||||
}
|
||||
}
|
@@ -0,0 +1,403 @@
|
||||
<?php
|
||||
/**
|
||||
* The Conditional helpers.
|
||||
*
|
||||
* @since 0.9.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
use RankMath\Helper;
|
||||
use RankMath\Admin\Admin_Helper;
|
||||
use RankMath\Helpers\Param;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Conditional class.
|
||||
*/
|
||||
trait Conditional {
|
||||
|
||||
/**
|
||||
* Check if whitelabel filter is active.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_whitelabel() {
|
||||
/**
|
||||
* Enable whitelabel.
|
||||
*
|
||||
* @param bool $whitelabel Enable whitelabel.
|
||||
*/
|
||||
return apply_filters( 'rank_math/whitelabel', false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if module is active.
|
||||
*
|
||||
* @param string $id Module ID.
|
||||
* @param boolean $check_registered Whether to check if module is among registered modules or not.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_module_active( $id, $check_registered = true ) {
|
||||
$active_modules = get_option( 'rank_math_modules', [] );
|
||||
if ( ! is_array( $active_modules ) || ( $check_registered && ! self::is_plugin_ready() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array( $id, $active_modules, true ) && ( ! $check_registered || array_key_exists( $id, rank_math()->manager->modules ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Rank Math manager is ready.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_plugin_ready() {
|
||||
return ( isset( rank_math()->manager ) && ! is_null( rank_math()->manager ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the plugin is configured.
|
||||
*
|
||||
* @param bool $value If this param is set, the option will be updated.
|
||||
* @return bool Return the option value if param is not set.
|
||||
*/
|
||||
public static function is_configured( $value = null ) {
|
||||
$key = 'rank_math_is_configured';
|
||||
if ( is_null( $value ) ) {
|
||||
$value = get_option( $key );
|
||||
return ! empty( $value );
|
||||
}
|
||||
Helper::schedule_flush_rewrite();
|
||||
update_option( $key, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the site is connected to the Rank Math API.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_site_connected() {
|
||||
$registered = Admin_Helper::get_registration_data();
|
||||
|
||||
return false !== $registered && ! empty( $registered['connected'] ) && ! empty( $registered['api_key'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the plugin is licensed properly.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_invalid_registration() {
|
||||
if ( defined( 'RANK_MATH_REGISTRATION_SKIP' ) && RANK_MATH_REGISTRATION_SKIP ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$is_skipped = Helper::is_plugin_active_for_network() ? get_blog_option( get_main_site_id(), 'rank_math_registration_skip' ) : get_option( 'rank_math_registration_skip' );
|
||||
if ( true === boolval( $is_skipped ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ! self::is_site_connected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if author archives are indexable.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_author_archive_indexable() {
|
||||
if ( true === Helper::get_settings( 'titles.disable_author_archives' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( Helper::get_settings( 'titles.author_custom_robots' ) && in_array( 'noindex', (array) Helper::get_settings( 'titles.author_robots' ), true ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the AMP module is active.
|
||||
*
|
||||
* @since 1.0.24
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_amp_active() {
|
||||
if ( ! self::is_module_active( 'amp' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( function_exists( 'ampforwp_get_setting' ) && 'rank_math' === ampforwp_get_setting( 'ampforwp-seo-selection' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if editing the file is allowed.
|
||||
*
|
||||
* @since 1.0.32
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_edit_allowed() {
|
||||
/**
|
||||
* Allow editing the robots.txt & htaccess data.
|
||||
*
|
||||
* @param bool Can edit the robots & htacess data.
|
||||
*/
|
||||
return apply_filters(
|
||||
'rank_math/can_edit_file',
|
||||
( ! defined( 'DISALLOW_FILE_EDIT' ) || ! DISALLOW_FILE_EDIT ) &&
|
||||
( ! defined( 'DISALLOW_FILE_MODS' ) || ! DISALLOW_FILE_MODS )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether to show SEO score.
|
||||
*
|
||||
* @since 1.0.32
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_score_enabled() {
|
||||
/**
|
||||
* Enable SEO Score.
|
||||
*
|
||||
* @param bool Enable SEO Score.
|
||||
*/
|
||||
return apply_filters( 'rank_math/show_score', true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is on elementor editor.
|
||||
*
|
||||
* @since 1.0.37
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_elementor_editor() {
|
||||
return 'elementor' === Param::get( 'action' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is UX Builder (used in Flatsome theme).
|
||||
*
|
||||
* @since 1.0.60
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_ux_builder() {
|
||||
return 'uxbuilder' === Param::get( 'app' ) && ! empty( Param::get( 'type' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is on Divi frontend editor.
|
||||
*
|
||||
* @since 1.0.63
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_divi_frontend_editor() {
|
||||
return function_exists( 'et_core_is_fb_enabled' ) && et_core_is_fb_enabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current editor, or false if we're not editing.
|
||||
*
|
||||
* @since 1.0.67
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get_current_editor() {
|
||||
if ( self::is_elementor_editor() ) {
|
||||
return 'elementor';
|
||||
}
|
||||
|
||||
if ( self::is_divi_frontend_editor() ) {
|
||||
return 'divi';
|
||||
}
|
||||
|
||||
if ( self::is_block_editor() && \rank_math_is_gutenberg() ) {
|
||||
return 'gutenberg';
|
||||
}
|
||||
|
||||
if ( self::is_ux_builder() ) {
|
||||
return 'uxbuilder';
|
||||
}
|
||||
|
||||
if ( Admin_Helper::is_post_edit() ) {
|
||||
return 'classic';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Advanced Mode.
|
||||
*
|
||||
* @since 1.0.43
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_advanced_mode() {
|
||||
return 'advanced' === apply_filters( 'rank_math/setup_mode', Helper::get_settings( 'general.setup_mode', 'advanced' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Breadcrumbs Enabled.
|
||||
*
|
||||
* @since 1.0.64
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_breadcrumbs_enabled() {
|
||||
return \current_theme_supports( 'rank-math-breadcrumbs' ) || Helper::get_settings( 'general.breadcrumbs' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Wizard page.
|
||||
*
|
||||
* @since 1.0.64
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_wizard() {
|
||||
return ( filter_input( INPUT_GET, 'page' ) === 'rank-math-wizard' || filter_input( INPUT_POST, 'action' ) === 'rank_math_save_wizard' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is filesystem method direct.
|
||||
*
|
||||
* @since 1.0.71.1
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_filesystem_direct() {
|
||||
if ( ! function_exists( 'get_filesystem_method' ) ) {
|
||||
require_once ABSPATH . '/wp-admin/includes/file.php';
|
||||
}
|
||||
|
||||
return 'direct' === get_filesystem_method();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is AJAX request
|
||||
*
|
||||
* @return bool Returns true when the page is loaded via ajax.
|
||||
*/
|
||||
public static function is_ajax() {
|
||||
return function_exists( 'wp_doing_ajax' ) ? wp_doing_ajax() : defined( 'DOING_AJAX' ) && DOING_AJAX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is CRON request
|
||||
*
|
||||
* @return bool Returns true when the page is loaded via cron.
|
||||
*/
|
||||
public static function is_cron() {
|
||||
return function_exists( 'wp_doing_cron' ) ? wp_doing_cron() : defined( 'DOING_CRON' ) && DOING_CRON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is auto-saving
|
||||
*
|
||||
* @return bool Returns true when the page is loaded for auto-saving.
|
||||
*/
|
||||
public static function is_autosave() {
|
||||
return defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is REST request
|
||||
*
|
||||
* @link https://wordpress.stackexchange.com/questions/221202/does-something-like-is-rest-exist/221289
|
||||
*
|
||||
* Case #1: After WP_REST_Request initialisation
|
||||
* Case #2: Support "plain" permalink settings
|
||||
* Case #3: It can happen that WP_Rewrite is not yet initialized,
|
||||
* so do this (wp-settings.php)
|
||||
* Case #4: URL Path begins with wp-json/ (your REST prefix)
|
||||
* Also supports WP installations in subfolders
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_rest() {
|
||||
global $wp_rewrite;
|
||||
|
||||
$prefix = rest_get_url_prefix();
|
||||
if (
|
||||
defined( 'REST_REQUEST' ) && REST_REQUEST || // (#1)
|
||||
isset( $_GET['rest_route'] ) && // (#2)
|
||||
0 === strpos( trim( $_GET['rest_route'], '\\/' ), $prefix, 0 )
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// (#3)
|
||||
if ( null === $wp_rewrite ) {
|
||||
$wp_rewrite = new \WP_Rewrite();
|
||||
}
|
||||
|
||||
// (#4)
|
||||
$rest_url = wp_parse_url( trailingslashit( rest_url() ) );
|
||||
$current_url = wp_parse_url( add_query_arg( [] ) );
|
||||
|
||||
if ( ! isset( $current_url['path'] ) || ! isset( $rest_url['path'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return 0 === strpos( $current_url['path'], $rest_url['path'], 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the request is heartbeat.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_heartbeat() {
|
||||
return 'heartbeat' === Param::post( 'action' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the request is from frontend.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_frontend() {
|
||||
return ! is_admin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is WooCommerce Installed
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_woocommerce_active() {
|
||||
// @codeCoverageIgnoreStart
|
||||
if ( ! function_exists( 'is_plugin_active' ) ) {
|
||||
include_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
return is_plugin_active( 'woocommerce/woocommerce.php' ) && function_exists( 'is_woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is EDD Installed
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_edd_active() {
|
||||
return class_exists( 'Easy_Digital_Downloads' );
|
||||
}
|
||||
}
|
@@ -0,0 +1,521 @@
|
||||
<?php
|
||||
/**
|
||||
* The Content_AI helpers.
|
||||
*
|
||||
* @since 1.0.112
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
use RankMath\Admin\Admin_Helper;
|
||||
use RankMath\Helpers\Str;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Content_AI class.
|
||||
*/
|
||||
trait Content_AI {
|
||||
/**
|
||||
* Content AI Outputs key.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private static $output_key = 'rank_math_content_ai_outputs';
|
||||
|
||||
/**
|
||||
* Content AI Chats key.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private static $chat_key = 'rank_math_content_ai_chats';
|
||||
|
||||
/**
|
||||
* Content AI Recent Prompts key.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private static $recent_prompt_key = 'rank_math_content_ai_recent_prompts';
|
||||
|
||||
/**
|
||||
* Content AI Prompts key.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private static $prompt_key = 'rank_math_content_ai_prompts';
|
||||
|
||||
/**
|
||||
* Content AI Prompts key.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private static $credits_key = 'rank_math_ca_credits';
|
||||
|
||||
/**
|
||||
* Get the Content AI Credits.
|
||||
*
|
||||
* @param bool $force_update Whether to send a request to API to get the new Credits value.
|
||||
* @param bool $return_error Whether to return error when request fails.
|
||||
* @param bool $migration_complete Whether the request was send after migrating the user.
|
||||
*/
|
||||
public static function get_content_ai_credits( $force_update = false, $return_error = false, $migration_complete = false ) {
|
||||
$registered = Admin_Helper::get_registration_data();
|
||||
if ( empty( $registered ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$transient = 'rank_math_content_ai_requested';
|
||||
$credits = self::get_credits();
|
||||
if ( ! $force_update || ( get_site_transient( $transient ) && ! $migration_complete ) ) {
|
||||
return $credits;
|
||||
}
|
||||
|
||||
set_site_transient( $transient, true, 20 ); // Set transient for 20 seconds.
|
||||
|
||||
$args = [
|
||||
'username' => rawurlencode( $registered['username'] ),
|
||||
'api_key' => rawurlencode( $registered['api_key'] ),
|
||||
'site_url' => rawurlencode( self::get_home_url() ),
|
||||
'embedWallet' => 'false',
|
||||
'plugin_version' => rawurlencode( rank_math()->version ),
|
||||
];
|
||||
|
||||
$url = add_query_arg(
|
||||
$args,
|
||||
CONTENT_AI_URL . '/sites/wallet'
|
||||
);
|
||||
|
||||
$response = wp_remote_get(
|
||||
$url,
|
||||
[
|
||||
'timeout' => 60,
|
||||
]
|
||||
);
|
||||
|
||||
$response_code = wp_remote_retrieve_response_code( $response );
|
||||
if ( 404 === $response_code && ! $migration_complete ) {
|
||||
return self::maybe_migrate_user( $response );
|
||||
}
|
||||
|
||||
$is_error = self::is_content_ai_error( $response, $response_code );
|
||||
if ( $is_error ) {
|
||||
|
||||
if ( in_array( $is_error, [ 'domain_limit_reached', 'account_limit_reached' ], true ) ) {
|
||||
$credits = 0;
|
||||
self::update_credits( 0 );
|
||||
}
|
||||
|
||||
return ! $return_error ? $credits : [
|
||||
'credits' => $credits,
|
||||
'error' => $is_error,
|
||||
];
|
||||
}
|
||||
|
||||
$data = wp_remote_retrieve_body( $response );
|
||||
if ( empty( $data ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$data = json_decode( $data, true );
|
||||
$data = [
|
||||
'credits' => intval( $data['availableCredits'] ?? 0 ),
|
||||
'plan' => $data['plan'] ?? '',
|
||||
'refresh_date' => $data['nextResetDate'] ?? '',
|
||||
];
|
||||
|
||||
self::update_credits( $data );
|
||||
|
||||
return $data['credits'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get Content AI Credits.
|
||||
*
|
||||
* @return int Credits data.
|
||||
*/
|
||||
public static function get_credits() {
|
||||
$credits_data = get_option( self::$credits_key, [] );
|
||||
return ! empty( $credits_data['credits'] ) ? $credits_data['credits'] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get Content AI Plan.
|
||||
*
|
||||
* @return string Content AI Plan.
|
||||
*/
|
||||
public static function get_content_ai_plan() {
|
||||
$credits_data = get_option( self::$credits_key, [] );
|
||||
return ! empty( $credits_data['plan'] ) ? strtolower( $credits_data['plan'] ) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get Content AI Refresh date.
|
||||
*
|
||||
* @return int Content AI Refresh date.
|
||||
*/
|
||||
public static function get_content_ai_refresh_date() {
|
||||
$credits_data = get_option( self::$credits_key, [] );
|
||||
return ! empty( $credits_data['refresh_date'] ) ? $credits_data['refresh_date'] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to update Content AI Credits.
|
||||
*
|
||||
* @param int $credits Credits data.
|
||||
*/
|
||||
public static function update_credits( $credits ) {
|
||||
if ( is_array( $credits ) ) {
|
||||
$credits['refresh_date'] = ! empty( $credits['refresh_date'] ) && ! is_int( $credits['refresh_date'] ) ? strtotime( $credits['refresh_date'] ) : $credits['refresh_date'];
|
||||
update_option( self::$credits_key, $credits );
|
||||
return;
|
||||
}
|
||||
|
||||
$credits_data = get_option( self::$credits_key, [] );
|
||||
if ( ! is_array( $credits_data ) ) {
|
||||
$credits_data = [ 'credits' => $credits_data ];
|
||||
}
|
||||
|
||||
$credits_data['credits'] = max( 0, $credits );
|
||||
update_option( self::$credits_key, $credits_data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get Default Schema type by post_type.
|
||||
*
|
||||
* @return string Default Schema Type.
|
||||
*/
|
||||
public static function get_outputs() {
|
||||
return get_option( self::$output_key, [] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get Default Schema type by post_type.
|
||||
*
|
||||
* @return string Default Schema Type.
|
||||
*/
|
||||
public static function get_chats() {
|
||||
return array_values( get_option( self::$chat_key, [] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get Recent prompts used in Content AI.
|
||||
*/
|
||||
public static function get_recent_prompts() {
|
||||
return get_option( self::$recent_prompt_key, [] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get prompts used in Content AI.
|
||||
*/
|
||||
public static function get_prompts() {
|
||||
return get_option( self::$prompt_key, [] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get Default Schema type by post_type.
|
||||
*
|
||||
* @return string Default Schema Type.
|
||||
*/
|
||||
public static function delete_outputs() {
|
||||
return delete_option( self::$output_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get Default Schema type by post_type.
|
||||
*
|
||||
* @param string $endpoint API endpoint.
|
||||
* @param array $output API output.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function update_outputs( $endpoint, $output ) {
|
||||
$outputs = self::get_outputs();
|
||||
|
||||
$output = array_map(
|
||||
function( $item ) use ( $endpoint ) {
|
||||
return [
|
||||
'key' => $endpoint,
|
||||
'output' => $item,
|
||||
];
|
||||
},
|
||||
$output
|
||||
);
|
||||
|
||||
$output = isset( $output['faqs'] ) ? [ current( $output ) ] : $output;
|
||||
$outputs = array_merge( $output, $outputs );
|
||||
$outputs = array_slice( $outputs, 0, 50 );
|
||||
update_option( self::$output_key, $outputs, false );
|
||||
|
||||
return self::get_outputs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get Default Schema type by post_type.
|
||||
*
|
||||
* @param array $answer API endpoint.
|
||||
* @param array $question API output.
|
||||
* @param int $session Chat session.
|
||||
* @param boolean $is_new Whether its a new chat.
|
||||
* @param boolean $is_regenerating Is regenerating the Chat message.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function update_chats( $answer, $question, $session = 0, $is_new = false, $is_regenerating = false ) {
|
||||
$chats = self::get_chats();
|
||||
|
||||
$data = [
|
||||
[
|
||||
'role' => 'assistant',
|
||||
'content' => $answer,
|
||||
],
|
||||
[
|
||||
'role' => 'user',
|
||||
'content' => $question['content'],
|
||||
],
|
||||
];
|
||||
|
||||
if ( $is_new ) {
|
||||
array_unshift( $chats, $data );
|
||||
} else {
|
||||
if ( ! isset( $chats[ $session ] ) ) {
|
||||
$chats[ $session ] = [];
|
||||
}
|
||||
|
||||
if ( $is_regenerating ) {
|
||||
unset( $chats[ $session ][0], $chats[ $session ][1] );
|
||||
}
|
||||
|
||||
$chats[ $session ] = array_merge(
|
||||
$data,
|
||||
$chats[ $session ]
|
||||
);
|
||||
}
|
||||
|
||||
$chats = array_slice( $chats, 0, 50 );
|
||||
|
||||
update_option( self::$chat_key, array_values( $chats ), false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to update the Recent prompts data.
|
||||
*
|
||||
* @param string $prompt Prompt name.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function update_recent_prompts( $prompt ) {
|
||||
$prompts = self::get_recent_prompts();
|
||||
|
||||
array_unshift( $prompts, $prompt );
|
||||
|
||||
$prompts = array_slice( array_filter( array_unique( $prompts ) ), 0, 10 );
|
||||
return update_option( self::$recent_prompt_key, $prompts, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to save the default prompts data.
|
||||
*
|
||||
* @param array $prompts Prompt data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function save_default_prompts( $prompts ) {
|
||||
$saved_prompts = self::get_prompts();
|
||||
$custom_prompts = ! is_array( $saved_prompts ) ? [] : array_map(
|
||||
function( $prompt ) {
|
||||
return $prompt['PromptCategory'] === 'custom' ? $prompt : false;
|
||||
},
|
||||
$saved_prompts
|
||||
);
|
||||
|
||||
if ( ! empty( $custom_prompts ) ) {
|
||||
$custom_prompts = array_values( array_filter( $custom_prompts ) );
|
||||
}
|
||||
|
||||
$prompts = array_merge( $prompts, $custom_prompts );
|
||||
update_option( self::$prompt_key, $prompts );
|
||||
|
||||
return $prompts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to update the prompts data.
|
||||
*
|
||||
* @param string $prompt Prompt name.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function update_prompts( $prompt ) {
|
||||
$prompts = self::get_prompts();
|
||||
|
||||
$prompts[] = $prompt;
|
||||
update_option( self::$prompt_key, $prompts, false );
|
||||
|
||||
return self::get_prompts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to delete the prompts.
|
||||
*
|
||||
* @param string $prompt_name Prompt name.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function delete_prompt( $prompt_name ) {
|
||||
$prompts = self::get_prompts();
|
||||
$prompts = array_map(
|
||||
function ( $elem ) use ( $prompt_name ) {
|
||||
return $elem['PromptName'] !== $prompt_name ? $elem : false;
|
||||
},
|
||||
$prompts
|
||||
);
|
||||
|
||||
update_option( self::$prompt_key, array_filter( $prompts ), false );
|
||||
|
||||
return self::get_prompts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get Default Schema type by post_type.
|
||||
*
|
||||
* @param string $index Group index key.
|
||||
*
|
||||
* @return string Default Schema Type.
|
||||
*/
|
||||
public static function delete_chats( $index ) {
|
||||
$chats = self::get_chats();
|
||||
unset( $chats[ $index ] );
|
||||
|
||||
return update_option( self::$chat_key, $chats, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get default language based on the site language.
|
||||
*
|
||||
* @return string Default language.
|
||||
*/
|
||||
public static function content_ai_default_language() {
|
||||
$locale = get_locale();
|
||||
$languages = array_filter(
|
||||
[
|
||||
'Spanish' => Str::starts_with( 'es_', $locale ),
|
||||
'French' => Str::starts_with( 'fr_', $locale ),
|
||||
'German' => 'de_DE_formal' === $locale,
|
||||
'Italian' => Str::starts_with( 'it_', $locale ),
|
||||
'Dutch' => Str::starts_with( 'de_', $locale ),
|
||||
'Portuguese' => Str::starts_with( 'pt_', $locale ),
|
||||
'Russian' => Str::starts_with( 'ru_', $locale ),
|
||||
'Chinese' => Str::starts_with( 'zh_', $locale ),
|
||||
'Korean' => Str::starts_with( 'ko_', $locale ),
|
||||
'UK English' => 'en_GB' === $locale,
|
||||
'Japanese' => 'ja' === $locale,
|
||||
'Bulgarian' => 'bg_BG' === $locale,
|
||||
'Czech' => 'cs_CZ' === $locale,
|
||||
'Danish' => 'da_DK' === $locale,
|
||||
'Estonian' => 'et' === $locale,
|
||||
'Finnish' => 'fi' === $locale,
|
||||
'Greek' => 'el' === $locale,
|
||||
'Hebrew' => 'he_IL' === $locale,
|
||||
'Hungarian' => 'hu_HU' === $locale,
|
||||
'Indonesian' => 'id_ID' === $locale,
|
||||
'Latvian' => 'lv' === $locale,
|
||||
'Lithuanian' => 'lt_LT' === $locale,
|
||||
'Norwegian' => in_array( $locale, [ 'nb_NO', 'nn_NO' ], true ),
|
||||
'Polish' => 'pl_PL' === $locale,
|
||||
'Romanian' => 'ro_RO' === $locale,
|
||||
'Slovak' => 'sk_SK' === $locale,
|
||||
'Slovenian' => 'sl_SI' === $locale,
|
||||
'Swedish' => 'sv_SE' === $locale,
|
||||
]
|
||||
);
|
||||
|
||||
return ! empty( $languages ) ? current( array_keys( $languages ) ) : 'US English';
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get different error codes we get from the API
|
||||
*
|
||||
* @return array Array of error codes with messages.
|
||||
*/
|
||||
public static function get_content_ai_errors() {
|
||||
return [
|
||||
'not_connected' => esc_html__( 'Please connect your account to use the Content AI.', 'rank-math' ),
|
||||
'plugin_update_required' => esc_html__( 'Please update the Rank Math SEO plugin to the latest version to use this feature.', 'rank-math' ),
|
||||
'upgrade_required' => esc_html__( 'This feature is only available for Content AI subscribers.', 'rank-math' ),
|
||||
'rate_limit_exceeded' => esc_html__( 'Oops! Too many requests in a short time. Please try again after some time.', 'rank-math' ),
|
||||
'domain_limit_reached' => esc_html__( 'You\'ve used up all available credits for this domain.', 'rank-math' ),
|
||||
'account_limit_reached' => esc_html__( 'You\'ve used up all available credits from the connected account.', 'rank-math' ),
|
||||
'content_filter' => esc_html__( 'Please revise the entered values in the fields as they are not secure. Make the required adjustments and try again.', 'rank-math' ),
|
||||
'api_content_filter' => esc_html__( 'The output was stopped as it was identified as potentially unsafe by the content filter.', 'rank-math' ),
|
||||
'could_not_generate' => esc_html__( 'Could not generate. Please try again later.', 'rank-math' ),
|
||||
'invalid_key' => esc_html__( 'Invalid API key. Please check your API key or reconnect the site and try again.', 'rank-math' ),
|
||||
'not_found' => esc_html__( 'User wallet not found.', 'rank-math' ),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* User migration request.
|
||||
*/
|
||||
public static function migrate_user_to_nest_js() {
|
||||
$registered = Admin_Helper::get_registration_data();
|
||||
if ( empty( $registered ) || empty( $registered['username'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$res = wp_remote_post(
|
||||
CONTENT_AI_URL . '/migrate',
|
||||
[
|
||||
'headers' => [
|
||||
'Content-type' => 'application/json',
|
||||
],
|
||||
'body' => wp_json_encode( [ 'username' => $registered['username'] ] ),
|
||||
]
|
||||
);
|
||||
|
||||
$res_code = wp_remote_retrieve_response_code( $res );
|
||||
if ( is_wp_error( $res ) || 400 <= $res_code ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = json_decode( wp_remote_retrieve_body( $res ), true );
|
||||
$migration_status = $data['status'] ?? '';
|
||||
|
||||
return in_array( $migration_status, [ 'added', 'migration_not_needed' ], true ) ? 'completed' : $migration_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to return the error message.
|
||||
*
|
||||
* @param array $response API response.
|
||||
* @param int $response_code API response code.
|
||||
*/
|
||||
public static function is_content_ai_error( $response, $response_code ) {
|
||||
$data = wp_remote_retrieve_body( $response );
|
||||
$data = ! empty( $data ) ? json_decode( $data, true ) : [];
|
||||
if ( is_wp_error( $response ) || 200 !== $response_code || empty( $data ) ) {
|
||||
return ! empty( $data['err_key'] ) ? $data['err_key'] : 'could_not_generate';
|
||||
}
|
||||
|
||||
return ! empty( $data['error'] ) ? $data['error']['code'] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate user depending on the error received in the response
|
||||
*
|
||||
* @param array $response API response.
|
||||
*/
|
||||
private static function maybe_migrate_user( $response ) {
|
||||
$data = json_decode( wp_remote_retrieve_body( $response ), true );
|
||||
if ( empty( $data['err_key'] ) || 'not_found' !== $data['err_key'] ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$status = self::migrate_user_to_nest_js();
|
||||
if ( 'completed' === $status ) {
|
||||
return self::get_content_ai_credits( true, false, true );
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
/**
|
||||
* DB helpers.
|
||||
*
|
||||
* @since 1.0.9
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
use RankMath\Admin\Database\Database;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* DB class.
|
||||
*/
|
||||
class DB {
|
||||
|
||||
/**
|
||||
* Check and fix collation of table and columns.
|
||||
*
|
||||
* @param string $table Table name (without prefix).
|
||||
* @param array $columns Columns.
|
||||
* @param string $set_collation Collation.
|
||||
*/
|
||||
public static function check_collation( $table, $columns = 'all', $set_collation = null ) {
|
||||
global $wpdb;
|
||||
$changed_collations = 0;
|
||||
|
||||
$prefixed = $wpdb->prefix . $table;
|
||||
|
||||
$sql = "SHOW TABLES LIKE '{$wpdb->prefix}%'";
|
||||
$res = $wpdb->get_col( $sql ); // phpcs:ignore
|
||||
if ( ! in_array( $prefixed, $res, true ) ) {
|
||||
return $changed_collations;
|
||||
}
|
||||
|
||||
// Collation to set.
|
||||
$collate = $set_collation ? $set_collation : self::get_default_collation();
|
||||
|
||||
$sql = "SHOW CREATE TABLE `{$prefixed}`";
|
||||
$res = $wpdb->get_row( $sql ); // phpcs:ignore
|
||||
|
||||
$table_collate = $res->{'Create Table'};
|
||||
|
||||
// Determine current collation value.
|
||||
$current_collate = '';
|
||||
if ( preg_match( '/COLLATE=([a-zA-Z0-9_-]+)/', $table_collate, $matches ) ) {
|
||||
$current_collate = $matches[1];
|
||||
}
|
||||
|
||||
// If collation is not set or is incorrect, fix it.
|
||||
if ( ! $current_collate || $current_collate !== $collate ) {
|
||||
$sql = "ALTER TABLE `{$prefixed}` COLLATE={$collate}";
|
||||
error_log( sprintf( 'Rank Math: Changing collation of `%1$s` table from %2$s to %3$s. SQL: "%4$s"', $prefixed, $current_collate, $collate, $sql ) ); // phpcs:ignore
|
||||
$wpdb->query( $sql ); // phpcs:ignore
|
||||
$changed_collations++;
|
||||
}
|
||||
|
||||
// Now handle columns if needed.
|
||||
if ( ! $columns ) {
|
||||
return $changed_collations;
|
||||
}
|
||||
|
||||
$sql = "SHOW FULL COLUMNS FROM {$prefixed}";
|
||||
$res = $wpdb->get_results( $sql, ARRAY_A ); // phpcs:ignore
|
||||
if ( ! $res ) {
|
||||
return $changed_collations;
|
||||
}
|
||||
|
||||
$columns = 'all' === $columns ? wp_list_pluck( $res, 'Field' ) : $columns;
|
||||
|
||||
foreach ( $res as $col ) {
|
||||
if ( ! in_array( $col['Field'], $columns, true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$current_collate = $col['Collation'];
|
||||
if ( ! $current_collate || $current_collate === $collate ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$null = 'NO' === $col['Null'] ? 'NOT NULL' : 'NULL';
|
||||
$default = ! empty( $col['Default'] ) ? "DEFAULT '{$col['Default']}'" : '';
|
||||
|
||||
$sql = "ALTER TABLE `{$prefixed}` MODIFY `{$col['Field']}` {$col['Type']} COLLATE {$collate} {$null} {$default}";
|
||||
error_log( sprintf( 'Rank Math: Changing collation of `%1$s`.`%2$s` column from %3$s to %4$s. SQL: "%5$s"', $prefixed, $col['Field'], $current_collate, $collate, $sql ) ); // phpcs:ignore
|
||||
$wpdb->query( $sql ); // phpcs:ignore
|
||||
$changed_collations++;
|
||||
}
|
||||
|
||||
return $changed_collations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get collation of a specific table.
|
||||
*
|
||||
* @param string $table Table name.
|
||||
* @return string
|
||||
*/
|
||||
public static function get_table_collation( $table ) {
|
||||
global $wpdb;
|
||||
|
||||
$sql = "SHOW CREATE TABLE `{$wpdb->prefix}{$table}`";
|
||||
$res = $wpdb->get_row( $sql ); // phpcs:ignore
|
||||
|
||||
if ( ! $res ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$table_collate = $res->{'Create Table'};
|
||||
|
||||
// Determine current collation value.
|
||||
$current_collate = '';
|
||||
if ( preg_match( '/COLLATE=([a-zA-Z0-9_-]+)/', $table_collate, $matches ) ) {
|
||||
$current_collate = $matches[1];
|
||||
}
|
||||
|
||||
return $current_collate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default collation.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_default_collation() {
|
||||
if ( defined( 'DB_COLLATE' ) && DB_COLLATE ) {
|
||||
return DB_COLLATE;
|
||||
}
|
||||
|
||||
$posts_table_collation = self::get_table_collation( 'posts' );
|
||||
if ( $posts_table_collation ) {
|
||||
return $posts_table_collation;
|
||||
}
|
||||
|
||||
return 'utf8mb4_unicode_ci';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a Database instance by table name.
|
||||
*
|
||||
* @param string $table_name A Database instance id.
|
||||
*
|
||||
* @return Database Database object instance.
|
||||
*/
|
||||
public static function query_builder( $table_name ) {
|
||||
return Database::table( $table_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if table exists in db or not.
|
||||
*
|
||||
* @param string $table_name Table name to check for existance.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function check_table_exists( $table_name ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $wpdb->prefix . $table_name ) ) ) === $wpdb->prefix . $table_name ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if table has more rows than X.
|
||||
*
|
||||
* @since 1.1.16
|
||||
*
|
||||
* @param string $table_name Table name to check.
|
||||
* @param int $limit Number of rows to check against.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function table_size_exceeds( $table_name, $limit ) {
|
||||
global $wpdb;
|
||||
|
||||
$check_table = $wpdb->query( "SELECT 1 FROM {$table_name} LIMIT {$limit}, 1" );
|
||||
|
||||
return ! empty( $check_table );
|
||||
}
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* The Editor helpers.
|
||||
*
|
||||
* @since 1.0.9
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
use RankMath\Helper;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Editor class.
|
||||
*/
|
||||
class Editor {
|
||||
|
||||
/**
|
||||
* Can add editor.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function can_add_editor() {
|
||||
return Helper::has_cap( 'onpage_general' ) ||
|
||||
Helper::has_cap( 'onpage_advanced' ) ||
|
||||
Helper::has_cap( 'onpage_snippet' ) ||
|
||||
Helper::has_cap( 'onpage_social' );
|
||||
}
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* The HTML helpers.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author RankMath <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
/**
|
||||
* HTML class.
|
||||
*/
|
||||
class HTML {
|
||||
|
||||
/**
|
||||
* Extract attributes from a html tag.
|
||||
*
|
||||
* @param string $elem Extract attributes from tag.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function extract_attributes( $elem ) {
|
||||
$regex = '#([^\s=]+)\s*=\s*(\'[^<\']*\'|"[^<"]*")#';
|
||||
preg_match_all( $regex, $elem, $attributes, PREG_SET_ORDER );
|
||||
|
||||
$new = [];
|
||||
$remaining = $elem;
|
||||
foreach ( $attributes as $attribute ) {
|
||||
$val = substr( $attribute[2], 1, -1 );
|
||||
$new[ $attribute[1] ] = $val;
|
||||
$remaining = str_replace( $attribute[0], '', $remaining );
|
||||
}
|
||||
|
||||
// Chop off tag name.
|
||||
$remaining = preg_replace( '/<[^\s]+/', '', $remaining, 1 );
|
||||
// Check for empty attributes without values.
|
||||
$regex = '/([^<][\w\d:_-]+)[\s>]/i';
|
||||
preg_match_all( $regex, $remaining, $attributes, PREG_SET_ORDER );
|
||||
foreach ( $attributes as $attribute ) {
|
||||
$new[ trim( $attribute[1] ) ] = null;
|
||||
}
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate html attribute string for array.
|
||||
*
|
||||
* @param array $attributes Contains key/value pair to generate a string.
|
||||
* @param string $prefix If you want to append a prefic before every key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function attributes_to_string( $attributes = [], $prefix = '' ) {
|
||||
|
||||
// Early Bail!
|
||||
if ( empty( $attributes ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$out = '';
|
||||
foreach ( $attributes as $key => $value ) {
|
||||
if ( true === $value || false === $value ) {
|
||||
$value = $value ? 'true' : 'false';
|
||||
}
|
||||
|
||||
$out .= ' ' . esc_html( $prefix . $key );
|
||||
if ( null === $value ) {
|
||||
continue;
|
||||
}
|
||||
$out .= sprintf( '="%s"', esc_attr( $value ) );
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* The Locale helpers.
|
||||
*
|
||||
* @since 1.0.9
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Locale class.
|
||||
*/
|
||||
class Locale {
|
||||
|
||||
/**
|
||||
* Get site language.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_site_language() {
|
||||
return self::get_language( get_locale() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the language part of a given locale, defaults to english when the $locale is empty.
|
||||
*
|
||||
* @param string $locale The locale to get the language of.
|
||||
*
|
||||
* @return string The language part of the locale.
|
||||
*/
|
||||
public static function get_language( $locale = null ) {
|
||||
$language = 'en';
|
||||
|
||||
if ( empty( $locale ) || ! is_string( $locale ) ) {
|
||||
return $language;
|
||||
}
|
||||
|
||||
$locale_parts = explode( '_', $locale );
|
||||
|
||||
if ( ! empty( $locale_parts[0] ) ) {
|
||||
$language = $locale_parts[0];
|
||||
}
|
||||
|
||||
return $language;
|
||||
}
|
||||
}
|
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/**
|
||||
* The Options helpers.
|
||||
*
|
||||
* @since 0.9.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Options class.
|
||||
*/
|
||||
trait Options {
|
||||
|
||||
/**
|
||||
* Option handler.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $key Option to perform action.
|
||||
* @param mixed $value Pass null to get option,
|
||||
* Pass false to delete option,
|
||||
* Pass value to update option.
|
||||
* @return mixed
|
||||
*/
|
||||
public static function option( $key, $value = null ) {
|
||||
$key = 'rank_math_' . $key;
|
||||
|
||||
if ( false === $value ) {
|
||||
return delete_option( $key );
|
||||
}
|
||||
|
||||
if ( is_null( $value ) ) {
|
||||
return get_option( $key, [] );
|
||||
}
|
||||
|
||||
return update_option( $key, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize option value.
|
||||
*
|
||||
* @param mixed $value Value to normalize.
|
||||
* @return mixed
|
||||
*/
|
||||
public static function normalize_data( $value ) {
|
||||
|
||||
if ( 'true' === $value || 'on' === $value ) {
|
||||
$value = true;
|
||||
} elseif ( 'false' === $value || 'off' === $value ) {
|
||||
$value = false;
|
||||
} elseif ( '0' === $value || '1' === $value ) {
|
||||
$value = intval( $value );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update settings.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param array|null $general Array to update settings.
|
||||
* @param array|null $titles Array to update settings.
|
||||
* @param array|null $sitemap Array to update settings.
|
||||
*/
|
||||
public static function update_all_settings( $general, $titles, $sitemap ) {
|
||||
|
||||
if ( ! is_null( $general ) ) {
|
||||
update_option( 'rank-math-options-general', $general );
|
||||
}
|
||||
|
||||
if ( ! is_null( $titles ) ) {
|
||||
update_option( 'rank-math-options-titles', $titles );
|
||||
}
|
||||
|
||||
if ( ! is_null( $sitemap ) ) {
|
||||
update_option( 'rank-math-options-sitemap', $sitemap );
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* The Helper class that provides easy access to accessing params from $_GET, $_POST and $_REQUEST.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author RankMath <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
/**
|
||||
* Param class.
|
||||
*/
|
||||
class Param {
|
||||
|
||||
/**
|
||||
* Get field from query string.
|
||||
*
|
||||
* @param string $id Field id to get.
|
||||
* @param mixed $default Default value to return if field is not found.
|
||||
* @param int $filter The ID of the filter to apply.
|
||||
* @param int $flag The ID of the flag to apply.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get( $id, $default = false, $filter = FILTER_DEFAULT, $flag = [] ) {
|
||||
return filter_has_var( INPUT_GET, $id ) ? filter_input( INPUT_GET, $id, $filter, $flag ) : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field from FORM post.
|
||||
*
|
||||
* @param string $id Field id to get.
|
||||
* @param mixed $default Default value to return if field is not found.
|
||||
* @param int $filter The ID of the filter to apply.
|
||||
* @param int $flag The ID of the flag to apply.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function post( $id, $default = false, $filter = FILTER_DEFAULT, $flag = [] ) {
|
||||
return filter_has_var( INPUT_POST, $id ) ? filter_input( INPUT_POST, $id, $filter, $flag ) : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field from request.
|
||||
*
|
||||
* @param string $id Field id to get.
|
||||
* @param mixed $default Default value to return if field is not found.
|
||||
* @param int $filter The ID of the filter to apply.
|
||||
* @param int $flag The ID of the flag to apply.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function request( $id, $default = false, $filter = FILTER_DEFAULT, $flag = [] ) {
|
||||
return isset( $_REQUEST[ $id ] ) ? filter_var( $_REQUEST[ $id ], $filter, $flag ) : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field from FORM server.
|
||||
*
|
||||
* @param string $id Field id to get.
|
||||
* @param mixed $default Default value to return if field is not found.
|
||||
* @param int $filter The ID of the filter to apply.
|
||||
* @param int $flag The ID of the flag to apply.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function server( $id, $default = false, $filter = FILTER_DEFAULT, $flag = [] ) {
|
||||
return isset( $_SERVER[ $id ] ) ? filter_var( $_SERVER[ $id ], $filter, $flag ) : $default;
|
||||
}
|
||||
}
|
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
/**
|
||||
* The Post_Type helpers.
|
||||
*
|
||||
* @since 0.9.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
use RankMath\Helper;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Post Type class.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
trait Post_Type {
|
||||
|
||||
/**
|
||||
* Check if post is indexable.
|
||||
*
|
||||
* @param int $post_id Post ID to check.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_post_indexable( $post_id ) {
|
||||
if ( true === self::is_post_excluded( $post_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$robots = self::is_post_meta_indexable( $post_id );
|
||||
if ( is_bool( $robots ) ) {
|
||||
return $robots;
|
||||
}
|
||||
|
||||
$post_type = get_post_type( $post_id );
|
||||
$robots = Helper::get_settings( 'titles.pt_' . $post_type . '_custom_robots' );
|
||||
$robots = false === $robots ? Helper::get_settings( 'titles.robots_global' ) : Helper::get_settings( 'titles.pt_' . $post_type . '_robots' );
|
||||
|
||||
return in_array( 'noindex', (array) $robots, true ) ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if post is indexable by meta.
|
||||
*
|
||||
* @param int $post_id Post ID to check.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private static function is_post_meta_indexable( $post_id ) {
|
||||
$robots = Helper::get_post_meta( 'robots', $post_id );
|
||||
if ( empty( $robots ) || ! is_array( $robots ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( in_array( 'index', $robots, true ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return in_array( 'noindex', $robots, true ) ? false : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if post is explicitly excluded.
|
||||
*
|
||||
* @param int $post_id Post ID to check.
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_post_excluded( $post_id ) {
|
||||
static $posts_to_exclude;
|
||||
|
||||
if ( ! isset( $posts_to_exclude ) ) {
|
||||
$posts_to_exclude = wp_parse_id_list( Helper::get_settings( 'sitemap.exclude_posts' ) );
|
||||
$posts_to_exclude = apply_filters( 'rank_math/sitemap/posts_to_exclude', $posts_to_exclude );
|
||||
}
|
||||
|
||||
return in_array( $post_id, $posts_to_exclude, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if post type is indexable.
|
||||
*
|
||||
* @param string $post_type Post type to check.
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_post_type_indexable( $post_type ) {
|
||||
if ( Helper::get_settings( 'titles.pt_' . $post_type . '_custom_robots' ) ) {
|
||||
if ( in_array( 'noindex', (array) Helper::get_settings( 'titles.pt_' . $post_type . '_robots' ), true ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return Helper::get_settings( 'sitemap.pt_' . $post_type . '_sitemap' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if post type is accessible.
|
||||
*
|
||||
* @param string $post_type Post type to check.
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_post_type_accessible( $post_type ) {
|
||||
return in_array( $post_type, self::get_allowed_post_types(), true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post type label.
|
||||
*
|
||||
* @param string $post_type Post type name.
|
||||
* @param bool $singular Get singular label.
|
||||
* @return string|false
|
||||
*/
|
||||
public static function get_post_type_label( $post_type, $singular = false ) {
|
||||
$object = get_post_type_object( $post_type );
|
||||
if ( ! $object ) {
|
||||
return false;
|
||||
}
|
||||
return ! $singular ? $object->labels->name : $object->labels->singular_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post types that are public and not set to noindex.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return array All the accessible post types.
|
||||
*/
|
||||
public static function get_accessible_post_types() {
|
||||
static $accessible_post_types;
|
||||
|
||||
if ( isset( $accessible_post_types ) && did_action( 'wp_loaded' ) ) {
|
||||
return $accessible_post_types;
|
||||
}
|
||||
|
||||
$accessible_post_types = get_post_types( [ 'public' => true ] );
|
||||
$accessible_post_types = array_filter( $accessible_post_types, 'is_post_type_viewable' );
|
||||
|
||||
/**
|
||||
* Changing the list of accessible post types.
|
||||
*
|
||||
* @api array $accessible_post_types The post types.
|
||||
*/
|
||||
$accessible_post_types = apply_filters( 'rank_math/excluded_post_types', $accessible_post_types );
|
||||
|
||||
if ( ! is_array( $accessible_post_types ) ) {
|
||||
$accessible_post_types = [];
|
||||
}
|
||||
|
||||
return $accessible_post_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get accessible post types.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_allowed_post_types() {
|
||||
static $rank_math_allowed_post_types;
|
||||
|
||||
if ( isset( $rank_math_allowed_post_types ) ) {
|
||||
return $rank_math_allowed_post_types;
|
||||
}
|
||||
|
||||
$rank_math_allowed_post_types = [];
|
||||
foreach ( self::get_accessible_post_types() as $post_type ) {
|
||||
if ( false === apply_filters( 'rank_math/metabox/add_seo_metabox', Helper::get_settings( 'titles.pt_' . $post_type . '_add_meta_box', true ) ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$rank_math_allowed_post_types[] = $post_type;
|
||||
}
|
||||
|
||||
return $rank_math_allowed_post_types;
|
||||
}
|
||||
}
|
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/**
|
||||
* The Schema helpers.
|
||||
*
|
||||
* @since 1.0.62
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
use RankMath\Helper;
|
||||
use RankMath\Admin\Admin_Helper;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Schema class.
|
||||
*/
|
||||
trait Schema {
|
||||
/**
|
||||
* Function to get Default Schema type by post_type.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @param boolean $return_valid Whether to return valid schema type which can be used on the frontend.
|
||||
* @param boolean $sanitize Return santized Schema type.
|
||||
*
|
||||
* @return string Default Schema Type.
|
||||
*/
|
||||
public static function get_default_schema_type( $post_id, $return_valid = false, $sanitize = false ) {
|
||||
if ( metadata_exists( 'post', $post_id, 'rank_math_rich_snippet' ) || ! self::can_use_default_schema( $post_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$post_type = get_post_type( $post_id );
|
||||
if ( ! in_array( $post_type, Helper::get_accessible_post_types(), true ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$schema = Helper::get_settings( "titles.pt_{$post_type}_default_rich_snippet" );
|
||||
if ( ! $schema ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( 'article' === $schema ) {
|
||||
/**
|
||||
* Filter: Allow changing the default schema type.
|
||||
*
|
||||
* @param string $schema Schema type.
|
||||
* @param string $post_type Post type.
|
||||
* @param int $post_id Post ID.
|
||||
*/
|
||||
$schema = apply_filters(
|
||||
'rank_math/schema/default_type',
|
||||
Helper::get_settings( "titles.pt_{$post_type}_default_article_type" ),
|
||||
$post_type,
|
||||
$post_id
|
||||
);
|
||||
}
|
||||
|
||||
if ( class_exists( 'WooCommerce' ) && 'product' === $post_type ) {
|
||||
$schema = 'WooCommerceProduct';
|
||||
}
|
||||
|
||||
if ( class_exists( 'Easy_Digital_Downloads' ) && 'download' === $post_type ) {
|
||||
$schema = 'EDDProduct';
|
||||
}
|
||||
|
||||
if ( $return_valid && ! in_array( $schema, [ 'Article', 'NewsArticle', 'BlogPosting', 'WooCommerceProduct', 'EDDProduct' ], true ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $sanitize ? self::sanitize_schema_title( $schema ) : $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize schema title.
|
||||
*
|
||||
* @param string $schema Schema.
|
||||
* @param boolean $translate Whether to return the translated string.
|
||||
* @return string
|
||||
*/
|
||||
public static function sanitize_schema_title( $schema, $translate = true ) {
|
||||
if ( in_array( $schema, [ 'BlogPosting', 'NewsArticle' ], true ) ) {
|
||||
return $translate ? esc_html__( 'Article', 'rank-math' ) : esc_html( 'Article' );
|
||||
}
|
||||
|
||||
if ( 'WooCommerceProduct' === $schema ) {
|
||||
return $translate ? esc_html__( 'WooCommerce Product', 'rank-math' ) : esc_html( 'WooCommerce Product' );
|
||||
}
|
||||
|
||||
if ( 'EDDProduct' === $schema ) {
|
||||
return $translate ? esc_html__( 'EDD Product', 'rank-math' ) : esc_html( 'EDD Product' );
|
||||
}
|
||||
|
||||
if ( 'VideoObject' === $schema ) {
|
||||
return $translate ? esc_html__( 'Video', 'rank-math' ) : esc_html( 'Video' );
|
||||
}
|
||||
|
||||
if ( 'JobPosting' === $schema ) {
|
||||
return $translate ? esc_html__( 'Job Posting', 'rank-math' ) : esc_html( 'Job Posting' );
|
||||
}
|
||||
|
||||
if ( 'SoftwareApplication' === $schema ) {
|
||||
return $translate ? esc_html__( 'Software Application', 'rank-math' ) : esc_html( 'Software Application' );
|
||||
}
|
||||
|
||||
if ( 'MusicGroup' === $schema || 'MusicAlbum' === $schema ) {
|
||||
return $translate ? esc_html__( 'Music', 'rank-math' ) : esc_html( 'Music' );
|
||||
}
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Whether to use default schema.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @return bool
|
||||
*/
|
||||
public static function can_use_default_schema( $post_id ) {
|
||||
$pages = array_map(
|
||||
'absint',
|
||||
array_filter(
|
||||
[
|
||||
Helper::get_settings( 'titles.local_seo_about_page' ),
|
||||
Helper::get_settings( 'titles.local_seo_contact_page' ),
|
||||
get_option( 'page_for_posts' ),
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
return ! in_array( (int) $post_id, $pages, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to use default Product schema on WooCommerce pages.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function can_use_default_product_schema() {
|
||||
return apply_filters( 'rank_math/schema/use_default_product', true );
|
||||
}
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* The Security wrappers.
|
||||
*
|
||||
* @since 1.0.41.3
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Security class.
|
||||
*/
|
||||
class Security {
|
||||
|
||||
/**
|
||||
* Add query arg
|
||||
*
|
||||
* @param mixed ...$args Array of arguments.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function add_query_arg( ...$args ) {
|
||||
return esc_url( add_query_arg( ...$args ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add query arg
|
||||
*
|
||||
* @param mixed ...$args Array of arguments.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function add_query_arg_raw( ...$args ) {
|
||||
return esc_url_raw( add_query_arg( ...$args ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an item or items from a query string.
|
||||
*
|
||||
* @param string|array $key (Required) Query key or keys to remove.
|
||||
* @param string|boolean $query When false uses the current URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function remove_query_arg( $key, $query = false ) {
|
||||
return esc_url( remove_query_arg( $key, $query ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an item or items from a query string.
|
||||
*
|
||||
* @param string|array $key (Required) Query key or keys to remove.
|
||||
* @param string|boolean $query When false uses the current URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function remove_query_arg_raw( $key, $query = false ) {
|
||||
return esc_url_raw( remove_query_arg( $key, $query ) );
|
||||
}
|
||||
}
|
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
/**
|
||||
* The Sitepress helpers.
|
||||
*
|
||||
* @since 1.0.40
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Sitepress class.
|
||||
*/
|
||||
class Sitepress {
|
||||
|
||||
/**
|
||||
* Has filter removed.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $has_get_category = false;
|
||||
|
||||
/**
|
||||
* Has filter removed.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $has_get_term = false;
|
||||
|
||||
/**
|
||||
* Has filter removed.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $has_terms_clauses = false;
|
||||
|
||||
/**
|
||||
* Has filter removed.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $has_get_terms_args = false;
|
||||
|
||||
/**
|
||||
* Has home_url filter removed.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $has_home_url = false;
|
||||
|
||||
|
||||
/**
|
||||
* Main instance
|
||||
*
|
||||
* Ensure only one instance is loaded or can be loaded.
|
||||
*
|
||||
* @return Sitepress
|
||||
*/
|
||||
public static function get() {
|
||||
static $instance;
|
||||
|
||||
if ( is_null( $instance ) && ! ( $instance instanceof Sitepress ) ) {
|
||||
$instance = new Sitepress();
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove term filters.
|
||||
*/
|
||||
public function remove_term_filters() {
|
||||
if ( ! $this->is_active() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sitepress = $this->get_var();
|
||||
|
||||
$this->has_get_category = remove_filter( 'category_link', [ $sitepress, 'category_link_adjust_id' ], 1 );
|
||||
$this->has_get_term = remove_filter( 'get_term', [ $sitepress, 'get_term_adjust_id' ], 1 );
|
||||
$this->has_terms_clauses = remove_filter( 'terms_clauses', [ $sitepress, 'terms_clauses' ] );
|
||||
$this->has_get_terms_args = remove_filter( 'get_terms_args', [ $sitepress, 'get_terms_args_filter' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore term filters.
|
||||
*/
|
||||
public function restore_term_filters() {
|
||||
if ( ! $this->is_active() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sitepress = $this->get_var();
|
||||
|
||||
if ( $this->has_get_category ) {
|
||||
$this->has_get_category = false;
|
||||
add_filter( 'category_link', [ $sitepress, 'category_link_adjust_id' ], 1, 1 );
|
||||
}
|
||||
|
||||
if ( $this->has_get_term ) {
|
||||
$this->has_get_term = false;
|
||||
add_filter( 'get_term', [ $sitepress, 'get_term_adjust_id' ], 1, 1 );
|
||||
}
|
||||
|
||||
if ( $this->has_terms_clauses ) {
|
||||
$this->has_terms_clauses = false;
|
||||
add_filter( 'terms_clauses', [ $sitepress, 'terms_clauses' ], 10, 3 );
|
||||
}
|
||||
|
||||
if ( $this->has_get_terms_args ) {
|
||||
$this->has_get_terms_args = false;
|
||||
add_filter( 'get_terms_args', [ $sitepress, 'get_terms_args_filter' ], 10, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove home_url filter.
|
||||
*/
|
||||
public function remove_home_url_filter() {
|
||||
if ( ! $this->is_active() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $wpml_url_filters;
|
||||
$this->has_home_url = remove_filter( 'home_url', [ $wpml_url_filters, 'home_url_filter' ], -10 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore home_url filter.
|
||||
*/
|
||||
public function restore_home_url_filter() {
|
||||
if ( ! $this->is_active() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $this->has_home_url ) {
|
||||
global $wpml_url_filters;
|
||||
$this->has_home_url = false;
|
||||
add_filter( 'home_url', [ $wpml_url_filters, 'home_url_filter' ], -10, 4 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is plugin active.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_active() {
|
||||
return isset( $GLOBALS['sitepress'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sitepress global variable.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function get_var() {
|
||||
return $GLOBALS['sitepress'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete cached tax permalink.
|
||||
*
|
||||
* @param int $term_id The term ID.
|
||||
* @param string $taxonomy The taxonomy name.
|
||||
* @return void
|
||||
*/
|
||||
public function delete_cached_tax_permalink( $term_id, $taxonomy ) {
|
||||
if ( ! $this->is_active() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_cache_delete(
|
||||
md5( wp_json_encode( [ $term_id, $taxonomy, false ] ) ),
|
||||
'icl_tax_permalink_filter'
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,247 @@
|
||||
<?php
|
||||
/**
|
||||
* The String helpers.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author RankMath <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
/**
|
||||
* Str class.
|
||||
*/
|
||||
class Str {
|
||||
|
||||
/**
|
||||
* Validates whether the passed variable is a empty string.
|
||||
*
|
||||
* @param mixed $variable The variable to validate.
|
||||
*
|
||||
* @return bool Whether or not the passed value is a non-empty string.
|
||||
*/
|
||||
public static function is_empty( $variable ) {
|
||||
return empty( $variable ) || ! is_string( $variable );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates whether the passed variable is a non-empty string.
|
||||
*
|
||||
* @param mixed $variable The variable to validate.
|
||||
*
|
||||
* @return bool Whether or not the passed value is a non-empty string.
|
||||
*/
|
||||
public static function is_non_empty( $variable ) {
|
||||
return is_string( $variable ) && '' !== $variable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the string contains the given value.
|
||||
*
|
||||
* @param string $needle The sub-string to search for.
|
||||
* @param string $haystack The string to search.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function contains( $needle, $haystack ) {
|
||||
return self::is_non_empty( $needle ) ? strpos( $haystack, $needle ) !== false : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the string begins with the given value.
|
||||
*
|
||||
* @param string $needle The sub-string to search for.
|
||||
* @param string $haystack The string to search.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function starts_with( $needle, $haystack ) {
|
||||
return '' === $needle || substr( $haystack, 0, strlen( $needle ) ) === (string) $needle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the string end with the given value.
|
||||
*
|
||||
* @param string $needle The sub-string to search for.
|
||||
* @param string $haystack The string to search.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function ends_with( $needle, $haystack ) {
|
||||
return '' === $needle || substr( $haystack, -strlen( $needle ) ) === (string) $needle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the string for desired comparison.
|
||||
*
|
||||
* @param string $needle The sub-string to search for.
|
||||
* @param string $haystack The string to search.
|
||||
* @param string $comparison The type of comparison.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function comparison( $needle, $haystack, $comparison = '' ) {
|
||||
|
||||
$hash = [
|
||||
'regex' => 'preg_match',
|
||||
'end' => [ __CLASS__, 'ends_with' ],
|
||||
'start' => [ __CLASS__, 'starts_with' ],
|
||||
'contains' => [ __CLASS__, 'contains' ],
|
||||
];
|
||||
|
||||
if ( $comparison && isset( $hash[ $comparison ] ) ) {
|
||||
return call_user_func( $hash[ $comparison ], $needle, $haystack );
|
||||
}
|
||||
|
||||
// Exact.
|
||||
return $needle === $haystack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string to array with defined seprator.
|
||||
*
|
||||
* @param string $str String to convert.
|
||||
* @param string $sep Seprator.
|
||||
*
|
||||
* @return bool|array
|
||||
*/
|
||||
public static function to_arr( $str, $sep = ',' ) {
|
||||
$parts = explode( $sep, trim( $str ) );
|
||||
|
||||
return empty( $parts ) ? false : $parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string to array, weed out empty elements and whitespaces.
|
||||
*
|
||||
* @param string $str User-defined list.
|
||||
* @param string $sep_pattern Separator pattern for regex.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function to_arr_no_empty( $str, $sep_pattern = '\r\n|[\r\n]' ) {
|
||||
$array = empty( $str ) ? [] : preg_split( '/' . $sep_pattern . '/', $str, -1, PREG_SPLIT_NO_EMPTY );
|
||||
$array = array_filter( array_map( 'trim', $array ) );
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function transforms the php.ini notation for numbers (like '2M') to an integer.
|
||||
*
|
||||
* @param string $size The size.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function let_to_num( $size ) {
|
||||
$char = substr( $size, -1 );
|
||||
$ret = substr( $size, 0, -1 );
|
||||
|
||||
// @codingStandardsIgnoreStart
|
||||
switch ( strtoupper( $char ) ) {
|
||||
case 'P':
|
||||
$ret *= 1024;
|
||||
case 'T':
|
||||
$ret *= 1024;
|
||||
case 'G':
|
||||
$ret *= 1024;
|
||||
case 'M':
|
||||
$ret *= 1024;
|
||||
case 'K':
|
||||
$ret *= 1024;
|
||||
}
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a number to K, M, B, etc.
|
||||
*
|
||||
* @param int|double $number Number which to convert to pretty string.
|
||||
* @param int $precision Decimal places in the human-readable format.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function human_number( $number, $precision = 1 ) {
|
||||
|
||||
if ( ! is_numeric( $number ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$negative = '';
|
||||
if ( abs( $number ) != $number ) {
|
||||
$negative = '-';
|
||||
$number = abs( $number );
|
||||
}
|
||||
|
||||
if ( $number < 1000 ) {
|
||||
return $negative ? -1 * $number : $number;
|
||||
}
|
||||
|
||||
$unit = intval( log( $number, 1000 ) );
|
||||
$units = [ '', 'K', 'M', 'B', 'T', 'Q' ];
|
||||
|
||||
if ( array_key_exists( $unit, $units ) ) {
|
||||
return sprintf( '%s%s%s', $negative, rtrim( number_format( $number / pow( 1000, $unit ), $precision ), '.0' ), $units[ $unit ] );
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate text for given length.
|
||||
*
|
||||
* @param {string} $str Text to truncate.
|
||||
* @param {number} $length Length to truncate for.
|
||||
* @param {string} $append Append to the end if string is truncated.
|
||||
*
|
||||
* @return {string} Truncated text.
|
||||
*/
|
||||
public static function truncate( $str, $length = 110, $append = '' ) {
|
||||
$str = wp_strip_all_tags( $str, true );
|
||||
$strlen = mb_strlen( $str );
|
||||
$excerpt = mb_substr( $str, 0, $length );
|
||||
|
||||
// Remove part of an entity at the end.
|
||||
$excerpt = preg_replace( '/&[^;\s]{0,6}$/', '', $excerpt );
|
||||
if ( $str !== $excerpt ) {
|
||||
$strrpos = function_exists( 'mb_strrpos' ) ? 'mb_strrpos' : 'strrpos';
|
||||
$excerpt = mb_substr( $str, 0, $strrpos( trim( $excerpt ), ' ' ) );
|
||||
}
|
||||
|
||||
if ( $strlen > $length ) {
|
||||
$excerpt .= $append;
|
||||
}
|
||||
|
||||
return $excerpt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multibyte ucwords.
|
||||
*
|
||||
* @param string $string String to convert.
|
||||
*/
|
||||
public static function mb_ucwords( $string ) {
|
||||
if ( ! function_exists( 'mb_convert_case' ) || ! function_exists( 'mb_detect_encoding' ) || mb_detect_encoding( $string ) !== 'UTF-8' ) {
|
||||
return ucwords( $string );
|
||||
}
|
||||
|
||||
$words = preg_split( '/([\s]+)/u', $string, -1, PREG_SPLIT_DELIM_CAPTURE );
|
||||
$ucwords = '';
|
||||
foreach ( $words as $word ) {
|
||||
if ( is_numeric( $word ) ) {
|
||||
$ucwords .= $word;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! empty( $word[0] ) ) {
|
||||
$ucwords .= preg_match( '/[\p{L}]/u', $word[0] ) ? mb_strtoupper( $word[0], 'UTF-8' ) . mb_substr( $word, 1, mb_strlen( $word ), 'UTF-8' ) : $word;
|
||||
}
|
||||
}
|
||||
|
||||
return $ucwords;
|
||||
}
|
||||
}
|
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
/**
|
||||
* The Taxonomy helpers.
|
||||
*
|
||||
* @since 0.9.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
use RankMath\Helper;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Taxonomy class.
|
||||
*/
|
||||
trait Taxonomy {
|
||||
|
||||
/**
|
||||
* Is term indexable.
|
||||
*
|
||||
* @param WP_Term $term Term to check.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_term_indexable( $term ) {
|
||||
$robots = self::is_term_meta_indexable( $term );
|
||||
if ( is_bool( $robots ) ) {
|
||||
return $robots;
|
||||
}
|
||||
|
||||
$robots = Helper::get_settings( 'titles.tax_' . $term->taxonomy . '_custom_robots' );
|
||||
$robots = false === $robots ? Helper::get_settings( 'titles.robots_global' ) : Helper::get_settings( 'titles.tax_' . $term->taxonomy . '_robots' );
|
||||
|
||||
return in_array( 'noindex', (array) $robots, true ) ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is term indexable by meta.
|
||||
*
|
||||
* @param WP_Term $term Term to check.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private static function is_term_meta_indexable( $term ) {
|
||||
$robots = Helper::get_term_meta( 'robots', $term, $term->taxonomy );
|
||||
if ( empty( $robots ) || ! is_array( $robots ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( in_array( 'index', $robots, true ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return in_array( 'noindex', $robots, true ) ? false : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if taxonomy is indexable.
|
||||
*
|
||||
* @param string $taxonomy Taxonomy to check.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_taxonomy_indexable( $taxonomy ) {
|
||||
if ( Helper::get_settings( 'titles.tax_' . $taxonomy . '_custom_robots' ) ) {
|
||||
if ( in_array( 'noindex', (array) Helper::get_settings( 'titles.tax_' . $taxonomy . '_robots' ), true ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return Helper::get_settings( 'sitemap.tax_' . $taxonomy . '_sitemap' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the taxonomies that are public and not set to noindex.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return array All the accessible taxonomies.
|
||||
*/
|
||||
public static function get_accessible_taxonomies() {
|
||||
static $accessible_taxonomies;
|
||||
|
||||
if ( isset( $accessible_taxonomies ) && did_action( 'wp_loaded' ) ) {
|
||||
return $accessible_taxonomies;
|
||||
}
|
||||
|
||||
$accessible_taxonomies = get_taxonomies( [ 'public' => true ], 'objects' );
|
||||
$accessible_taxonomies = self::filter_exclude_taxonomies( $accessible_taxonomies );
|
||||
|
||||
if ( ! is_array( $accessible_taxonomies ) ) {
|
||||
$accessible_taxonomies = [];
|
||||
}
|
||||
|
||||
return $accessible_taxonomies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get accessible taxonomies.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_allowed_taxonomies() {
|
||||
static $rank_math_allowed_taxonomies;
|
||||
|
||||
if ( isset( $rank_math_allowed_taxonomies ) ) {
|
||||
return $rank_math_allowed_taxonomies;
|
||||
}
|
||||
|
||||
$rank_math_allowed_taxonomies = [];
|
||||
foreach ( self::get_accessible_taxonomies() as $taxonomy => $object ) {
|
||||
if ( false === Helper::get_settings( 'titles.tax_' . $taxonomy . '_add_meta_box' ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$rank_math_allowed_taxonomies[] = $taxonomy;
|
||||
}
|
||||
|
||||
return $rank_math_allowed_taxonomies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get taxonomies attached to a post type.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $post_type Post type to get taxonomy data for.
|
||||
* @param string $output (Optional) Output type can be `names`, `objects`, `choices`.
|
||||
* @param boolean $filter (Optional) Whether to filter taxonomies.
|
||||
*
|
||||
* @return boolean|array
|
||||
*/
|
||||
public static function get_object_taxonomies( $post_type, $output = 'choices', $filter = true ) {
|
||||
if ( 'names' === $output ) {
|
||||
return get_object_taxonomies( $post_type );
|
||||
}
|
||||
|
||||
$taxonomies = get_object_taxonomies( $post_type, 'objects' );
|
||||
$taxonomies = self::filter_exclude_taxonomies( $taxonomies, $filter );
|
||||
|
||||
if ( 'objects' === $output ) {
|
||||
return $taxonomies;
|
||||
}
|
||||
|
||||
return empty( $taxonomies ) ? false : [ 'off' => esc_html__( 'None', 'rank-math' ) ] + wp_list_pluck( $taxonomies, 'label', 'name' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter taxonomies using
|
||||
* `is_taxonomy_viewable` function
|
||||
* 'rank_math_excluded_taxonomies' filter
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param array|object $taxonomies Collection of taxonomies to filter.
|
||||
* @param boolean $filter (Optional) Whether to filter taxonomies.
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public static function filter_exclude_taxonomies( $taxonomies, $filter = true ) {
|
||||
$taxonomies = $filter ? array_filter( $taxonomies, [ __CLASS__, 'is_taxonomy_viewable' ] ) : $taxonomies;
|
||||
|
||||
/**
|
||||
* Filter: 'rank_math_excluded_taxonomies' - Allow changing the accessible taxonomies.
|
||||
*
|
||||
* @api array $taxonomies The public taxonomies.
|
||||
*/
|
||||
$taxonomies = apply_filters( 'rank_math/excluded_taxonomies', $taxonomies );
|
||||
|
||||
return $taxonomies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether a taxonomy is viewable.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string|WP_Taxonomy $taxonomy Taxonomy name or object.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_taxonomy_viewable( $taxonomy ) {
|
||||
if ( is_scalar( $taxonomy ) ) {
|
||||
$taxonomy = get_taxonomy( $taxonomy );
|
||||
if ( ! $taxonomy ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $taxonomy->name ) && 'wp_pattern_category' === $taxonomy->name ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* For categories and tags, we check for the 'public' parameter.
|
||||
* For others, we use the 'publicly_queryable' parameter.
|
||||
*/
|
||||
return $taxonomy->publicly_queryable || ( $taxonomy->_builtin && $taxonomy->public );
|
||||
}
|
||||
}
|
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
/**
|
||||
* The URL helpers.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author RankMath <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
use RankMath\Helpers\Str;
|
||||
use RankMath\Helpers\Param;
|
||||
|
||||
/**
|
||||
* Url class.
|
||||
*/
|
||||
class Url {
|
||||
|
||||
/**
|
||||
* Simple check for validating a URL, it must start with http:// or https://.
|
||||
* and pass FILTER_VALIDATE_URL validation.
|
||||
*
|
||||
* @param string $url to check.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_url( $url ) {
|
||||
if ( ! is_string( $url ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Must start with http:// or https://.
|
||||
if ( 0 !== strpos( $url, 'http://' ) && 0 !== strpos( $url, 'https://' ) && 0 !== strpos( $url, '//' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for scheme first, if it's missing then add it.
|
||||
if ( 0 === strpos( $url, '//' ) ) {
|
||||
$url = 'http:' . $url;
|
||||
}
|
||||
|
||||
// Must pass validation.
|
||||
return false !== filter_var( trailingslashit( $url ), FILTER_VALIDATE_URL ) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a url is relative.
|
||||
*
|
||||
* @param string $url URL string to check.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_relative( $url ) {
|
||||
return ( 0 !== strpos( $url, 'http' ) && 0 !== strpos( $url, '//' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a url is external.
|
||||
*
|
||||
* @param string $url URL string to check. This should be a absolute URL.
|
||||
* @param string $domain If wants to use some other domain not home_url().
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_external( $url, $domain = false ) {
|
||||
if ( empty( $url ) || '#' === $url[0] ) { // Link to current page.
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( self::is_affiliate( $url ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( '/' === $url[0] ) { // Link to current page or relative link.
|
||||
return false;
|
||||
}
|
||||
|
||||
$domain = self::get_domain( $domain ? $domain : home_url() );
|
||||
if ( Str::contains( $domain, $url ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a link is an affiliate link.
|
||||
*
|
||||
* @param string $url URL string to check. This should be a absolute URL.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_affiliate( $url ) {
|
||||
if ( empty( $url ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter: 'wp_helpers_is_affiliate_link' - Allows developer to consider a link as affiliate.
|
||||
*
|
||||
* @param bool $value Default false.
|
||||
* @param string $url URL.
|
||||
*/
|
||||
return apply_filters( 'wp_helpers_is_affiliate_link', false, $url );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current url.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_current_url() {
|
||||
return self::get_scheme() . '://' . self::get_host() . self::get_port() . Param::server( 'REQUEST_URI' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get url scheme.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_scheme() {
|
||||
return is_ssl() ? 'https' : 'http';
|
||||
}
|
||||
|
||||
/**
|
||||
* Some setups like HTTP_HOST, some like SERVER_NAME, it's complicated.
|
||||
*
|
||||
* @link http://stackoverflow.com/questions/2297403/http-host-vs-server-name
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return string the HTTP_HOST or SERVER_NAME
|
||||
*/
|
||||
public static function get_host() {
|
||||
$host = Param::server( 'HTTP_HOST' );
|
||||
if ( false !== $host ) {
|
||||
return $host;
|
||||
}
|
||||
|
||||
$name = Param::server( 'SERVER_NAME' );
|
||||
if ( false !== $name ) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current request port.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_port() {
|
||||
$port = Param::server( 'SERVER_PORT' );
|
||||
$has_port = $port && ! in_array( $port, [ '80', '443' ], true );
|
||||
return $has_port ? ':' . $port : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parent domain
|
||||
*
|
||||
* @param string $url Url to parse.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_domain( $url ) {
|
||||
$pieces = wp_parse_url( $url );
|
||||
$domain = isset( $pieces['host'] ) ? $pieces['host'] : '';
|
||||
|
||||
if ( Str::contains( 'localhost', $domain ) ) {
|
||||
return 'localhost';
|
||||
}
|
||||
|
||||
if ( preg_match( '/(?P<domain>[a-zÀ-ž0-9][a-zÀ-ž0-9\-]{1,63}\.[a-zÀ-ž\.]{2,15})$/ui', $domain, $regs ) ) {
|
||||
return $regs['domain'];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,728 @@
|
||||
<?php
|
||||
/**
|
||||
* The WordPress helpers.
|
||||
*
|
||||
* @since 0.9.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Helpers
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Helpers;
|
||||
|
||||
use RankMath\Post;
|
||||
use RankMath\Term;
|
||||
use RankMath\User;
|
||||
use RankMath\Helper;
|
||||
use RankMath\Role_Manager\Capability_Manager;
|
||||
use RankMath\Helpers\Str;
|
||||
use RankMath\Helpers\Param;
|
||||
use RankMath\Helpers\Security;
|
||||
use stdClass;
|
||||
use WP_Screen;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* WordPress class.
|
||||
*/
|
||||
trait WordPress {
|
||||
|
||||
/**
|
||||
* Wraps wp_safe_redirect to add header.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $location The path to redirect to.
|
||||
* @param int $status Status code to use.
|
||||
*/
|
||||
public static function redirect( $location, $status = 302 ) {
|
||||
wp_safe_redirect( $location, $status, 'Rank Math' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the current user has a specific capability.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @see current_user_can()
|
||||
*
|
||||
* @param string $capability Capability name.
|
||||
* @return boolean Whether the current user has the given capability.
|
||||
*/
|
||||
public static function has_cap( $capability ) {
|
||||
return current_user_can( 'rank_math_' . str_replace( '-', '_', $capability ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post meta value.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $key Internal key of the value to get (without prefix).
|
||||
* @param integer $post_id Post ID of the post to get the value for.
|
||||
* @param string $default Default value to use.
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get_post_meta( $key, $post_id = 0, $default = '' ) {
|
||||
return Post::get_meta( $key, $post_id, $default );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get term meta value.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $key Internal key of the value to get (without prefix).
|
||||
* @param mixed $term Term to get the meta value for either (string) term name, (int) term ID or (object) term.
|
||||
* @param string $taxonomy Name of the taxonomy to which the term is attached.
|
||||
* @param string $default Default value to use.
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get_term_meta( $key, $term = 0, $taxonomy = '', $default = '' ) {
|
||||
return Term::get_meta( $key, $term, $taxonomy, $default );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user meta value.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $key Internal key of the value to get (without prefix).
|
||||
* @param mixed $user User to get the meta value for either (int) user ID or (object) user.
|
||||
* @param string $default Default value to use.
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get_user_meta( $key, $user = 0, $default = '' ) {
|
||||
return User::get_meta( $key, $user, $default );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get admin url.
|
||||
*
|
||||
* @param string $page Page id.
|
||||
* @param array $args Pass arguments to query string.
|
||||
* @return string
|
||||
*/
|
||||
public static function get_admin_url( $page = '', $args = [] ) {
|
||||
$page = $page ? 'rank-math-' . $page : 'rank-math';
|
||||
$args = wp_parse_args( $args, [ 'page' => $page ] );
|
||||
|
||||
return Security::add_query_arg_raw( $args, admin_url( 'admin.php' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Rank Math Connect URL.
|
||||
*
|
||||
* @since 1.0.19
|
||||
* @return string
|
||||
*/
|
||||
public static function get_connect_url() {
|
||||
$args = [
|
||||
'page' => 'rank-math',
|
||||
'view' => 'help',
|
||||
];
|
||||
if ( ! is_multisite() ) {
|
||||
return Security::add_query_arg_raw( $args, admin_url( 'admin.php' ) );
|
||||
}
|
||||
|
||||
// Makes sure the plugin functions are defined before trying to use them.
|
||||
if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
|
||||
require_once ABSPATH . '/wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
return is_plugin_active_for_network( plugin_basename( RANK_MATH_FILE ) ) ?
|
||||
Security::add_query_arg_raw( $args, network_admin_url( 'admin.php' ) ) :
|
||||
Security::add_query_arg_raw( $args, admin_url( 'admin.php' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Rank Math Dashboard url.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_dashboard_url() {
|
||||
$site_type = get_transient( '_rank_math_site_type' );
|
||||
$business_type = [ 'news', 'business', 'webshop', 'otherbusiness' ];
|
||||
|
||||
if ( in_array( $site_type, $business_type, true ) ) {
|
||||
return self::get_admin_url( 'options-titles#setting-panel-local' );
|
||||
}
|
||||
return admin_url( 'admin.php?page=rank-math&view=modules' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active capabilities.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_roles_capabilities() {
|
||||
$data = [];
|
||||
$caps = Capability_Manager::get()->get_capabilities( true );
|
||||
|
||||
foreach ( self::get_roles() as $slug => $role ) {
|
||||
self::get_role_capabilities( $slug, $caps, $data );
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active capabilities for role.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $slug Role slug.
|
||||
* @param array $caps Array of capabilities.
|
||||
* @param array $data Data instance.
|
||||
*/
|
||||
private static function get_role_capabilities( $slug, $caps, &$data ) {
|
||||
$role = get_role( $slug );
|
||||
if ( ! $role ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$slug = esc_attr( $slug );
|
||||
foreach ( $caps as $cap ) {
|
||||
if ( $role->has_cap( $cap ) ) {
|
||||
$data[ $slug ][] = $cap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set capabilities to role.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param array $roles Data.
|
||||
*/
|
||||
public static function set_capabilities( $roles ) {
|
||||
$caps = Capability_Manager::get()->get_capabilities( true );
|
||||
foreach ( self::get_roles() as $slug => $role ) {
|
||||
self::set_role_capabilities( $slug, $caps, $roles );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set capabilities for role.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $slug Role slug.
|
||||
* @param array $caps Array of capabilities.
|
||||
* @param array $roles Data.
|
||||
*/
|
||||
private static function set_role_capabilities( $slug, $caps, $roles ) {
|
||||
$role = get_role( $slug );
|
||||
if ( ! $role ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$roles[ $slug ] = isset( $roles[ $slug ] ) && is_array( $roles[ $slug ] ) ? array_flip( $roles[ $slug ] ) : [];
|
||||
foreach ( $caps as $cap ) {
|
||||
$func = isset( $roles[ $slug ], $roles[ $slug ][ $cap ] ) ? 'add_cap' : 'remove_cap';
|
||||
$role->$func( $cap );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a rewrite flush to happen.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function schedule_flush_rewrite() {
|
||||
update_option( 'rank_math_flush_rewrite', 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post thumbnail with fallback as
|
||||
* 1. Post thumbnail.
|
||||
* 2. First image in content.
|
||||
* 3. Facebook image if any
|
||||
* 4. Twitter image if any.
|
||||
* 5. Default open graph image set in option panel.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param int|WP_Post $post_id Post ID or WP_Post object.
|
||||
* @param string|array $size Image size. Accepts any valid image size, or an array of width and height values in pixels.
|
||||
* @return false|array Returns an array (url, width, height, is_intermediate), or false, if no image is available.
|
||||
*/
|
||||
public static function get_thumbnail_with_fallback( $post_id, $size = 'thumbnail' ) {
|
||||
if ( has_post_thumbnail( $post_id ) ) {
|
||||
$thumbnail_id = get_post_thumbnail_id( $post_id );
|
||||
$image = (array) wp_get_attachment_image_src( $thumbnail_id, $size );
|
||||
if ( ! empty( array_filter( $image ) ) ) {
|
||||
$image['caption'] = $image ? get_post_meta( $thumbnail_id, '_wp_attachment_image_alt', true ) : '';
|
||||
}
|
||||
|
||||
return self::validate_image_data( $image );
|
||||
}
|
||||
|
||||
preg_match_all( '/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', get_the_content(), $matches );
|
||||
$matches = array_filter( $matches );
|
||||
if ( ! empty( $matches ) ) {
|
||||
return [ $matches[1][0], 200, 200 ];
|
||||
}
|
||||
|
||||
$fb_image = Helper::get_post_meta( 'facebook_image_id', $post_id );
|
||||
$tw_image = Helper::get_post_meta( 'twitter_image_id', $post_id, Helper::get_settings( 'titles.open_graph_image_id' ) );
|
||||
$og_image = $fb_image ? $fb_image : $tw_image;
|
||||
if ( ! $og_image ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$image = wp_get_attachment_image_src( $og_image, $size );
|
||||
$image['caption'] = $image ? get_post_meta( $og_image, '_wp_attachment_image_alt', true ) : '';
|
||||
return self::validate_image_data( $image );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if plugin is network active
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_plugin_active_for_network() {
|
||||
if ( ! is_multisite() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Makes sure the plugin is defined before trying to use it.
|
||||
if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
|
||||
require_once ABSPATH . '/wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
if ( ! is_plugin_active_for_network( plugin_basename( RANK_MATH_FILE ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to validate & format ISO 8601 duration.
|
||||
*
|
||||
* @param string $iso8601 Duration which need to be converted to seconds.
|
||||
* @return string
|
||||
*
|
||||
* @since 1.0.21
|
||||
*/
|
||||
public static function get_formatted_duration( $iso8601 ) {
|
||||
$end = substr( $iso8601, -1 );
|
||||
if ( ! in_array( $end, [ 'D', 'H', 'M', 'S' ], true ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// The format starts with the letter P, for "period".
|
||||
return ( ! Str::starts_with( 'P', $iso8601 ) ) ? 'PT' . $iso8601 : $iso8601;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get robots default.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_robots_defaults() {
|
||||
$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : new stdClass();
|
||||
$robots = Helper::get_settings( 'titles.robots_global', [] );
|
||||
|
||||
if ( $screen instanceof WP_Screen ) {
|
||||
if ( in_array( $screen->base, [ 'post', 'edit' ], true ) && isset( $screen->post_type ) && Helper::get_settings( "titles.pt_{$screen->post_type}_custom_robots" ) ) {
|
||||
$robots = Helper::get_settings( "titles.pt_{$screen->post_type}_robots", [] );
|
||||
}
|
||||
|
||||
if ( in_array( $screen->base, [ 'term', 'edit-tags' ], true ) && isset( $screen->taxonomy ) && Helper::get_settings( "titles.tax_{$screen->taxonomy}_custom_robots" ) ) {
|
||||
$robots = Helper::get_settings( "titles.tax_{$screen->taxonomy}_robots", [] );
|
||||
}
|
||||
|
||||
if ( in_array( $screen->base, [ 'profile', 'user-edit' ], true ) && Helper::get_settings( 'titles.author_custom_robots' ) ) {
|
||||
$robots = Helper::get_settings( 'titles.author_robots', [] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_array( $robots ) && ! in_array( 'noindex', $robots, true ) ) {
|
||||
$robots[] = 'index';
|
||||
}
|
||||
|
||||
return $robots;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get advanced robots default.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_advanced_robots_defaults() {
|
||||
$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : new stdClass();
|
||||
$advanced_robots = Helper::get_settings( 'titles.advanced_robots_global', [] );
|
||||
|
||||
if ( $screen instanceof WP_Screen ) {
|
||||
|
||||
if ( 'post' === $screen->base && Helper::get_settings( "titles.pt_{$screen->post_type}_custom_robots" ) ) {
|
||||
$advanced_robots = Helper::get_settings( "titles.pt_{$screen->post_type}_advanced_robots", [] );
|
||||
}
|
||||
|
||||
if ( 'term' === $screen->base && Helper::get_settings( "titles.tax_{$screen->taxonomy}_custom_robots" ) ) {
|
||||
$advanced_robots = Helper::get_settings( "titles.tax_{$screen->taxonomy}_advanced_robots", [] );
|
||||
}
|
||||
|
||||
if ( in_array( $screen->base, [ 'profile', 'user-edit' ], true ) && Helper::get_settings( 'titles.author_custom_robots' ) ) {
|
||||
$advanced_robots = Helper::get_settings( 'titles.author_advanced_robots', [] );
|
||||
}
|
||||
}
|
||||
|
||||
return $advanced_robots;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert timestamp and ISO to date.
|
||||
*
|
||||
* @param string $value Value to convert.
|
||||
* @param boolean $include_timezone Whether to include timezone.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function convert_date( $value, $include_timezone = false ) {
|
||||
if ( Str::contains( 'T', $value ) ) {
|
||||
$value = \strtotime( $value );
|
||||
}
|
||||
|
||||
return $include_timezone ? date_i18n( 'Y-m-d H:i-T', $value ) : date_i18n( 'Y-m-d H:i', $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to convert ISO 8601 duration to seconds.
|
||||
* For example "PT1H12M24S" becomes 5064.
|
||||
*
|
||||
* @param string $iso8601 Duration which need to be converted to seconds.
|
||||
* @return int
|
||||
*/
|
||||
public static function duration_to_seconds( $iso8601 ) {
|
||||
$end = substr( $iso8601, -1 );
|
||||
if ( ! in_array( $end, [ 'D', 'H', 'M', 'S' ], true ) ) {
|
||||
$iso8601 = $iso8601 . 'S';
|
||||
}
|
||||
$iso8601 = ! Str::starts_with( 'P', $iso8601 ) ? 'PT' . $iso8601 : $iso8601;
|
||||
|
||||
preg_match( '/^P([0-9]+D|)?T?([0-9]+H|)?([0-9]+M|)?([0-9]+S|)?$/', $iso8601, $matches );
|
||||
if ( empty( $matches ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return array_sum(
|
||||
[
|
||||
absint( $matches[1] ) * DAY_IN_SECONDS,
|
||||
absint( $matches[2] ) * HOUR_IN_SECONDS,
|
||||
absint( $matches[3] ) * MINUTE_IN_SECONDS,
|
||||
absint( $matches[4] ),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Id block editor enabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_block_editor() {
|
||||
// Check WordPress version.
|
||||
if ( version_compare( get_bloginfo( 'version' ), '5.0.0', '<' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : false;
|
||||
|
||||
if ( ! $screen instanceof WP_Screen ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( method_exists( $screen, 'is_block_editor' ) ) {
|
||||
return $screen->is_block_editor();
|
||||
}
|
||||
|
||||
if ( 'post' === $screen->base ) {
|
||||
return self::use_block_editor_for_post_type( $screen->post_type );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Image data. Remove empty values and add default height and width to image
|
||||
*
|
||||
* @param array $image The Image data.
|
||||
* @return array Array of image data
|
||||
*
|
||||
* @since 1.0.64
|
||||
*/
|
||||
private static function validate_image_data( $image ) {
|
||||
$image = array_filter( $image );
|
||||
if ( empty( $image ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$image[1] = isset( $image[1] ) ? $image[1] : 200;
|
||||
$image[2] = isset( $image[2] ) ? $image[2] : 200;
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a post type is compatible with the block editor.
|
||||
*
|
||||
* @param string $post_type The post type.
|
||||
*
|
||||
* @return bool Whether the post type can be edited with the block editor.
|
||||
*/
|
||||
private static function use_block_editor_for_post_type( $post_type ) {
|
||||
if ( ! post_type_exists( $post_type ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! post_type_supports( $post_type, 'editor' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$post_type_object = get_post_type_object( $post_type );
|
||||
if ( $post_type_object && ! $post_type_object->show_in_rest ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter whether a post is able to be edited in the block editor.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @param bool $use_block_editor Whether the post type can be edited or not. Default true.
|
||||
* @param string $post_type The post type being checked.
|
||||
*/
|
||||
return apply_filters( 'use_block_editor_for_post_type', true, $post_type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate classes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function classnames() {
|
||||
$args = func_get_args();
|
||||
|
||||
$data = array_reduce(
|
||||
$args,
|
||||
function( $carry, $arg ) {
|
||||
if ( is_array( $arg ) ) {
|
||||
return array_merge( $carry, $arg );
|
||||
}
|
||||
|
||||
$carry[] = $arg;
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
$classes = array_map(
|
||||
function ( $key, $value ) {
|
||||
$condition = $value;
|
||||
$return = $key;
|
||||
|
||||
if ( is_int( $key ) ) {
|
||||
$condition = null;
|
||||
$return = $value;
|
||||
}
|
||||
|
||||
$is_array = is_array( $return );
|
||||
$is_object = is_object( $return );
|
||||
$is_stringable_type = ! $is_array && ! $is_object;
|
||||
$is_stringable_object = $is_object && method_exists( $return, '__toString' );
|
||||
|
||||
if ( ! $is_stringable_type && ! $is_stringable_object ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( is_null( $condition ) ) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
return $condition ? $return : null;
|
||||
},
|
||||
array_keys( $data ),
|
||||
array_values( $data )
|
||||
);
|
||||
|
||||
$classes = array_filter( $classes );
|
||||
|
||||
return implode( ' ', $classes );
|
||||
}
|
||||
|
||||
/**
|
||||
* An helper function get the home_url without the WPML language parameter.
|
||||
*
|
||||
* @param string $path Path relative to the home URL.
|
||||
* @param string $scheme Scheme to give the home URL context.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_home_url( $path = '', $scheme = null ) {
|
||||
Sitepress::get()->remove_home_url_filter();
|
||||
$home_url = home_url( $path, $scheme );
|
||||
Sitepress::get()->restore_home_url_filter();
|
||||
|
||||
return $home_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get roles.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $output How to return roles.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_roles( $output = 'names' ) {
|
||||
$wp_roles = wp_roles();
|
||||
|
||||
if ( 'names' !== $output ) {
|
||||
return $wp_roles->roles;
|
||||
}
|
||||
|
||||
return $wp_roles->get_names();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the sitename.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_site_name() {
|
||||
return wp_strip_all_tags( get_bloginfo( 'name' ), true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get action from request.
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function get_request_action() {
|
||||
if ( empty( $_REQUEST['action'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( '-1' === $_REQUEST['action'] && ! empty( $_REQUEST['action2'] ) ) {
|
||||
$_REQUEST['action'] = $_REQUEST['action2'];
|
||||
}
|
||||
|
||||
return sanitize_key( $_REQUEST['action'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates the WordPress filesystem for use.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function get_filesystem() {
|
||||
global $wp_filesystem;
|
||||
|
||||
if ( empty( $wp_filesystem ) ) {
|
||||
require_once ABSPATH . '/wp-admin/includes/file.php';
|
||||
WP_Filesystem();
|
||||
}
|
||||
|
||||
return $wp_filesystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current post type.
|
||||
*
|
||||
* This function has some fallback strategies to get the current screen post type.
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public static function get_post_type() {
|
||||
global $pagenow;
|
||||
|
||||
$post_type = self::post_type_from_globals();
|
||||
if ( false !== $post_type ) {
|
||||
return $post_type;
|
||||
}
|
||||
|
||||
$post_type = self::post_type_from_request();
|
||||
if ( false !== $post_type ) {
|
||||
return $post_type;
|
||||
}
|
||||
|
||||
return 'post-new.php' === $pagenow ? 'post' : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post type from global variables
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
private static function post_type_from_globals() {
|
||||
global $post, $typenow, $current_screen;
|
||||
|
||||
if ( $post && $post->post_type ) {
|
||||
return $post->post_type;
|
||||
}
|
||||
|
||||
if ( $typenow ) {
|
||||
return $typenow;
|
||||
}
|
||||
|
||||
if ( $current_screen && $current_screen->post_type ) {
|
||||
return $current_screen->post_type;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post type from request variables
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
private static function post_type_from_request() {
|
||||
|
||||
if ( $post_type = Param::request( 'post_type' ) ) { // phpcs:ignore
|
||||
return sanitize_key( $post_type );
|
||||
}
|
||||
|
||||
if ( $post_id = Param::request( 'post_ID', 0, FILTER_VALIDATE_INT ) ) { // phpcs:ignore
|
||||
return get_post_type( $post_id );
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if ( $post = Param::get( 'post' ) ) { // phpcs:ignore
|
||||
return get_post_type( $post );
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip all shortcodes active or orphan.
|
||||
*
|
||||
* @param string $content Content to remove shortcodes from.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function strip_shortcodes( $content ) {
|
||||
if ( ! Str::contains( '[', $content ) ) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
// Remove Caption shortcode.
|
||||
$content = \preg_replace( '#\s*\[caption[^]]*\].*?\[/caption\]\s*#is', '', $content );
|
||||
|
||||
return preg_replace( '~\[\/?.*?\]~s', '', $content );
|
||||
}
|
||||
}
|
@@ -0,0 +1 @@
|
||||
<?php // Silence is golden.
|
Reference in New Issue
Block a user