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

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

View File

@@ -0,0 +1,264 @@
<?php
/**
* Facebook locale data.
*
* @since 0.9.0
* @package RankMath
* @subpackage RankMath\OpenGraph
* @author Rank Math <support@rankmath.com>
*
* @copyright Copyright (C) 2008-2019, Yoast BV
* The following code is a derivative work of the code from the Yoast(https://github.com/Yoast/wordpress-seo/), which is licensed under GPL v3.
*/
namespace RankMath\OpenGraph;
defined( 'ABSPATH' ) || exit;
/**
* Facebook class.
*/
class Facebook_Locale {
/**
* Supported locales
*
* @link https://developers.facebook.com/docs/messenger-platform/messenger-profile/supported-locales/
*
* @var array
*/
const FACEBOOK_LOCALES = [
'af_ZA', // Afrikaans.
'ak_GH', // Akan.
'am_ET', // Amharic.
'ar_AR', // Arabic.
'as_IN', // Assamese.
'ay_BO', // Aymara.
'az_AZ', // Azerbaijani.
'be_BY', // Belarusian.
'bg_BG', // Bulgarian.
'bp_IN', // Bhojpuri.
'bn_IN', // Bengali.
'br_FR', // Breton.
'bs_BA', // Bosnian.
'ca_ES', // Catalan.
'cb_IQ', // Sorani Kurdish.
'ck_US', // Cherokee.
'co_FR', // Corsican.
'cs_CZ', // Czech.
'cx_PH', // Cebuano.
'cy_GB', // Welsh.
'da_DK', // Danish.
'de_DE', // German.
'el_GR', // Greek.
'en_GB', // English (UK).
'en_PI', // English (Pirate).
'en_UD', // English (Upside Down).
'en_US', // English (US).
'em_ZM',
'eo_EO', // Esperanto.
'es_ES', // Spanish (Spain).
'es_LA', // Spanish.
'es_MX', // Spanish (Mexico).
'et_EE', // Estonian.
'eu_ES', // Basque.
'fa_IR', // Persian.
'fb_LT', // Leet Speak.
'ff_NG', // Fulah.
'fi_FI', // Finnish.
'fo_FO', // Faroese.
'fr_CA', // French (Canada).
'fr_FR', // French (France).
'fy_NL', // Frisian.
'ga_IE', // Irish.
'gl_ES', // Galician.
'gn_PY', // Guarani.
'gu_IN', // Gujarati.
'gx_GR', // Classical Greek.
'ha_NG', // Hausa.
'he_IL', // Hebrew.
'hi_IN', // Hindi.
'hr_HR', // Croatian.
'hu_HU', // Hungarian.
'ht_HT', // Haitian Creole.
'hy_AM', // Armenian.
'id_ID', // Indonesian.
'ig_NG', // Igbo.
'is_IS', // Icelandic.
'it_IT', // Italian.
'ik_US',
'iu_CA',
'ja_JP', // Japanese.
'ja_KS', // Japanese (Kansai).
'jv_ID', // Javanese.
'ka_GE', // Georgian.
'kk_KZ', // Kazakh.
'km_KH', // Khmer.
'kn_IN', // Kannada.
'ko_KR', // Korean.
'ks_IN', // Kashmiri.
'ku_TR', // Kurdish (Kurmanji).
'ky_KG', // Kyrgyz.
'la_VA', // Latin.
'lg_UG', // Ganda.
'li_NL', // Limburgish.
'ln_CD', // Lingala.
'lo_LA', // Lao.
'lt_LT', // Lithuanian.
'lv_LV', // Latvian.
'mg_MG', // Malagasy.
'mi_NZ', // Maori.
'mk_MK', // Macedonian.
'ml_IN', // Malayalam.
'mn_MN', // Mongolian.
'mr_IN', // Marathi.
'ms_MY', // Malay.
'mt_MT', // Maltese.
'my_MM', // Burmese.
'nb_NO', // Norwegian (bokmal).
'nd_ZW', // Ndebele.
'ne_NP', // Nepali.
'nl_BE', // Dutch (Belgie).
'nl_NL', // Dutch.
'nn_NO', // Norwegian (nynorsk).
'nr_ZA', // Southern Ndebele.
'ns_ZA', // Northern Sotho.
'ny_MW', // Chewa.
'om_ET', // Oromo.
'or_IN', // Oriya.
'pa_IN', // Punjabi.
'pl_PL', // Polish.
'ps_AF', // Pashto.
'pt_BR', // Portuguese (Brazil).
'pt_PT', // Portuguese (Portugal).
'qc_GT', // Quiché.
'qu_PE', // Quechua.
'qr_GR',
'qz_MM', // Burmese (Zawgyi).
'rm_CH', // Romansh.
'ro_RO', // Romanian.
'ru_RU', // Russian.
'rw_RW', // Kinyarwanda.
'sa_IN', // Sanskrit.
'sc_IT', // Sardinian.
'se_NO', // Northern Sami.
'si_LK', // Sinhala.
'su_ID', // Sundanese.
'sk_SK', // Slovak.
'sl_SI', // Slovenian.
'sn_ZW', // Shona.
'so_SO', // Somali.
'sq_AL', // Albanian.
'sr_RS', // Serbian.
'ss_SZ', // Swazi.
'st_ZA', // Southern Sotho.
'sv_SE', // Swedish.
'sw_KE', // Swahili.
'sy_SY', // Syriac.
'sz_PL', // Silesian.
'ta_IN', // Tamil.
'te_IN', // Telugu.
'tg_TJ', // Tajik.
'th_TH', // Thai.
'tk_TM', // Turkmen.
'tl_PH', // Filipino.
'tl_ST', // Klingon.
'tn_BW', // Tswana.
'tr_TR', // Turkish.
'ts_ZA', // Tsonga.
'tt_RU', // Tatar.
'tz_MA', // Tamazight.
'uk_UA', // Ukrainian.
'ur_PK', // Urdu.
'uz_UZ', // Uzbek.
've_ZA', // Venda.
'vi_VN', // Vietnamese.
'wo_SN', // Wolof.
'xh_ZA', // Xhosa.
'yi_DE', // Yiddish.
'yo_NG', // Yoruba.
'zh_CN', // Simplified Chinese (China).
'zh_HK', // Traditional Chinese (Hong Kong).
'zh_TW', // Traditional Chinese (Taiwan).
'zu_ZA', // Zulu.
'zz_TR', // Zazaki.
];
/**
* Catch some weird locales served out by WP that are not easily doubled up.
*
* @param string $locale Current site locale.
*
* @return string
*/
public static function sanitize( $locale ) {
$fix_locales = [
'ca' => 'ca_ES',
'en' => 'en_US',
'el' => 'el_GR',
'et' => 'et_EE',
'ja' => 'ja_JP',
'sq' => 'sq_AL',
'uk' => 'uk_UA',
'vi' => 'vi_VN',
'zh' => 'zh_CN',
'te' => 'te_IN',
'ur' => 'ur_PK',
'cy' => 'cy_GB',
'eu' => 'eu_ES',
'th' => 'th_TH',
'af' => 'af_ZA',
'hy' => 'hy_AM',
'gu' => 'gu_IN',
'kn' => 'kn_IN',
'mr' => 'mr_IN',
'kk' => 'kk_KZ',
'lv' => 'lv_LV',
'sw' => 'sw_KE',
'tl' => 'tl_PH',
'ps' => 'ps_AF',
'as' => 'as_IN',
];
if ( isset( $fix_locales[ $locale ] ) ) {
$locale = $fix_locales[ $locale ];
}
// Convert locales like "es" to "es_ES", in case that works for the given locale (sometimes it does).
if ( 2 === strlen( $locale ) ) {
$locale = self::join( $locale );
}
return $locale;
}
/**
* Validate with locales FB supports.
*
* Check to see if the locale is a valid FB one, if not, use en_US as a fallback.
*
* @param string $locale Current site locale.
*
* @return string
*/
public static function validate( $locale ) {
if ( in_array( $locale, self::FACEBOOK_LOCALES, true ) ) {
return $locale;
}
$locale = self::join( substr( $locale, 0, 2 ) );
return in_array( $locale, self::FACEBOOK_LOCALES, true ) ? $locale : 'en_US';
}
/**
* Join locale to make full locale.
*
* @param string $locale Locale to join.
*
* @return string
*/
private static function join( $locale ) {
return strtolower( $locale ) . '_' . strtoupper( $locale );
}
}

View File

@@ -0,0 +1,347 @@
<?php
/**
* This code adds the Facebook metadata.
*
* @since 0.9.0
* @package RankMath
* @subpackage RankMath\OpenGraph
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\OpenGraph;
use RankMath\Helper;
use RankMath\Paper\Paper;
use RankMath\Helpers\Str;
defined( 'ABSPATH' ) || exit;
/**
* Facebook class.
*/
class Facebook extends OpenGraph {
/**
* Network slug.
*
* @var string
*/
public $network = 'facebook';
/**
* Metakey prefix.
*
* @var string
*/
public $prefix = 'facebook';
/**
* The Constructor.
*/
public function __construct() {
$this->hooks();
add_filter( 'jetpack_enable_open_graph', '__return_false' );
parent::__construct();
}
/**
* Hooks.
*/
private function hooks() {
if ( isset( $GLOBALS['fb_ver'] ) || class_exists( 'Facebook_Loader', false ) ) {
$this->filter( 'fb_meta_tags', 'facebook_filter', 10, 1 );
return;
}
$this->filter( 'language_attributes', 'add_namespace', 15 );
$this->action( 'rank_math/opengraph/facebook', 'locale', 1 );
$this->action( 'rank_math/opengraph/facebook', 'type', 5 );
$this->action( 'rank_math/opengraph/facebook', 'title', 10 );
$this->action( 'rank_math/opengraph/facebook', 'description', 11 );
$this->action( 'rank_math/opengraph/facebook', 'url', 12 );
$this->action( 'rank_math/opengraph/facebook', 'site_name', 13 );
$this->action( 'rank_math/opengraph/facebook', 'website', 14 );
$this->action( 'rank_math/opengraph/facebook', 'site_owner', 20 );
$this->action( 'rank_math/opengraph/facebook', 'image', 30 );
}
/**
* Filter the Facebook plugins metadata.
*
* @param array $meta_tags The array to fix.
* @return array
*/
public function facebook_filter( $meta_tags ) {
$meta_tags['http://ogp.me/ns#type'] = $this->type( false );
$meta_tags['http://ogp.me/ns#title'] = $this->title( false );
// Filter the locale too because the Facebook plugin locale code is not as good as ours.
$meta_tags['http://ogp.me/ns#locale'] = $this->locale( false );
$desc = $this->description( false );
if ( ! empty( $desc ) ) {
$meta_tags['http://ogp.me/ns#description'] = $desc;
}
return $meta_tags;
}
/**
* Adds prefix attributes to the <html> tag.
*
* @param string $input The input namespace string.
* @return string
*/
public function add_namespace( $input ) {
return $input . ' prefix="og: https://ogp.me/ns#"';
}
/**
* Output the locale, doing some conversions to make sure the proper Facebook locale is outputted.
*
* @see http://www.facebook.com/translations/FacebookLocales.xml for the list of supported locales
* @link https://developers.facebook.com/docs/reference/opengraph/object-type/article/
*
* @param bool $echo Whether to echo or return the locale.
* @return string
*/
public function locale( $echo = true ) {
$locale = get_locale();
$locale = Facebook_Locale::sanitize( $locale );
$locale = Facebook_Locale::validate( $locale );
if ( $echo ) {
$this->tag( 'og:locale', $locale );
}
return $locale;
}
/**
* Output the OpenGraph type.
*
* @link https://developers.facebook.com/docs/reference/opengraph/object-type/object/
*
* @param bool $echo Whether to echo or return the type.
* @return string
*/
public function type( $echo = true ) {
$type = $this->get_type();
if ( is_singular() ) {
if ( 'article' === $type && ! is_front_page() ) {
$this->action( 'rank_math/opengraph/facebook', 'article_author', 15 );
$this->action( 'rank_math/opengraph/facebook', 'tags', 16 );
$this->action( 'rank_math/opengraph/facebook', 'category', 17 );
}
$this->action( 'rank_math/opengraph/facebook', 'publish_date', 19 );
}
/**
* Allow changing the OpenGraph type of the page.
*
* @param string $type The OpenGraph type string.
*/
$type = $this->do_filter( 'opengraph/type', $type );
if ( Str::is_non_empty( $type ) && $echo ) {
$this->tag( 'og:type', $type );
}
return $type;
}
/**
* Get type.
*
* @return string
*/
private function get_type() {
if ( is_front_page() || is_home() ) {
return 'website';
}
if ( is_author() ) {
return 'profile';
}
return $this->is_product() ? 'product' : 'article';
}
/**
* Outputs the SEO title as OpenGraph title.
*
* @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.
*
* @link https://developers.facebook.com/docs/reference/opengraph/object-type/article/
*
* @param bool $echo Whether or not to echo the output.
*
* @return string
*/
public function title( $echo = true ) {
$title = trim( $this->get_title() );
if ( $echo ) {
$this->tag( 'og:title', $title );
}
return $title;
}
/**
* Output the OpenGraph description, specific OG description first, if not, grab the meta description.
*
* @param bool $echo Whether to echo or return the description.
* @return string
*/
public function description( $echo = true ) {
$desc = trim( $this->get_description() );
if ( $echo ) {
$this->tag( 'og:description', $desc );
}
return $desc;
}
/**
* Output the canonical URL for the OpenGraph URL.
*
* @link https://developers.facebook.com/docs/reference/opengraph/object-type/article/
*/
public function url() {
/**
* Filter the OpenGraph URL.
*/
$url = $this->do_filter( 'opengraph/url', esc_url( Paper::get()->get_canonical() ) );
$this->tag( 'og:url', $url );
}
/**
* Output the site name straight from the blog info.
*/
public function site_name() {
$this->tag( 'og:site_name', Helper::get_settings( 'titles.website_name', get_bloginfo( 'name' ) ) );
}
/**
* Outputs the websites FB page.
*
* @link https://developers.facebook.com/blog/post/2013/06/19/platform-updates--new-open-graph-tags-for-media-publishers-and-more/
* @link https://developers.facebook.com/docs/reference/opengraph/object-type/article/
*/
public function website() {
$site = Helper::get_settings( 'titles.social_url_facebook' );
if ( 'article' === $this->type( false ) && '' !== $site ) {
$this->tag( 'article:publisher', $site );
}
}
/**
* Outputs the site owner.
*
* @link https://developers.facebook.com/docs/reference/opengraph/object-type/article/
*/
public function site_owner() {
$app_id = Helper::get_settings( 'titles.facebook_app_id' );
if ( 0 !== absint( $app_id ) ) {
$this->tag( 'fb:app_id', $app_id );
return;
}
$admins = Helper::get_settings( 'titles.facebook_admin_id' );
if ( '' !== trim( $admins ) ) {
$this->tag( 'fb:admins', $admins );
return;
}
}
/**
* Create new Image class and get the images to set the `og:image`.
*
* @param string|bool $image Optional. Image URL.
*/
public function image( $image = false ) {
$images = new Image( $image, $this );
$images->show();
}
/**
* Outputs the authors FB page.
*
* @link https://developers.facebook.com/blog/post/2013/06/19/platform-updates--new-open-graph-tags-for-media-publishers-and-more/
* @link https://developers.facebook.com/docs/reference/opengraph/object-type/article/
*/
public function article_author() {
$this->tag( 'article:author', $this->get_author() );
}
/**
* Output the article tags as `article:tag` tags.
*/
public function tags() {
$tags = get_the_tags();
if ( is_wp_error( $tags ) || empty( $tags ) ) {
return;
}
foreach ( $tags as $tag ) {
$this->tag( 'article:tag', $tag->name );
}
}
/**
* Output the article category as an `article:section` tag.
*/
public function category() {
$terms = get_the_category();
if ( is_wp_error( $terms ) || empty( $terms ) ) {
return;
}
// We can only show one section here, so we take the first one.
$this->tag( 'article:section', $terms[0]->name );
}
/**
* Output the article publish and last modification date.
*/
public function publish_date() {
$post = get_post();
$pub = mysql2date( DATE_W3C, $post->post_date, false );
$mod = mysql2date( DATE_W3C, $post->post_modified, false );
if ( strtotime( $mod ) > strtotime( $pub ) ) {
$this->tag( 'og:updated_time', $mod );
}
}
/**
* Get author.
*
* @return string
*/
private function get_author() {
$author = Helper::get_user_meta( 'facebook_author', $GLOBALS['post']->post_author );
if ( $author ) {
return $author;
}
$author = get_user_meta( $GLOBALS['post']->post_author, 'facebook', true );
if ( $author ) {
return $author;
}
return Helper::get_settings( 'titles.facebook_author_urls' );
}
/**
* Is WooCommerce product
*
* @return bool
*/
private function is_product() {
return function_exists( 'is_woocommerce' ) && function_exists( 'is_product' ) && is_product();
}
}

View File

@@ -0,0 +1,707 @@
<?php
/**
* This code adds the OpenGraph Image parser.
*
* @since 0.9.0
* @package RankMath
* @subpackage RankMath\OpenGraph
* @author Rank Math <support@rankmath.com>
*
* @copyright Copyright (C) 2008-2019, Yoast BV
* The following code is a derivative work of the code from the Yoast(https://github.com/Yoast/wordpress-seo/), which is licensed under GPL v3.
*/
namespace RankMath\OpenGraph;
use RankMath\Helper;
use RankMath\Post;
use RankMath\Traits\Hooker;
use RankMath\Helpers\Str;
use RankMath\Helpers\Url;
use RankMath\Helpers\Attachment;
defined( 'ABSPATH' ) || exit;
/**
* Image class.
*/
class Image {
use Hooker;
/**
* Holds network slug.
*
* @var array
*/
private $network;
/**
* Holds the images that have been put out as OG image.
*
* @var array
*/
private $images = [];
/**
* Holds the OpenGraph instance.
*
* @var OpenGraph
*/
private $opengraph;
/**
* The parameters we have for Facebook images.
*
* @var array
*/
private $usable_dimensions = [
'min_width' => 200,
'max_width' => 2000,
'min_height' => 200,
'max_height' => 2000,
];
/**
* The Constructor.
*
* @param string $image (Optional) The image URL.
* @param OpenGraph $opengraph (Optional) The OpenGraph object..
*/
public function __construct( $image = false, $opengraph = null ) {
$this->opengraph = $opengraph;
$this->network = $opengraph->network;
// If an image was not supplied or could not be added.
if ( Str::is_non_empty( $image ) ) {
$this->add_image_by_url( $image );
}
if ( ! post_password_required() ) {
$this->set_images();
}
}
/**
* Outputs the images.
*/
public function show() {
foreach ( $this->get_images() as $image => $image_meta ) {
$this->image_tag( $image_meta );
$this->image_meta( $image_meta );
}
}
/**
* Return the images array.
*
* @return array
*/
public function get_images() {
return $this->images;
}
/**
* Check whether we have images or not.
*
* @return bool
*/
public function has_images() {
return ! empty( $this->images );
}
/**
* Generate secret key for safer image URLs.
*
* @param int $id The attachment ID.
* @param string $type Overlay type.
*/
public function generate_secret( $id, $type ) {
return md5( $id . $type . wp_salt( 'nonce' ) );
}
/**
* Outputs an image tag based on whether it's https or not.
*
* @param array $image_meta Image metadata.
*/
private function image_tag( $image_meta ) {
$overlay = $this->opengraph->get_overlay_image();
$og_image = $image_meta['url'];
if ( $overlay && ! empty( $image_meta['id'] ) ) {
$secret = $this->generate_secret( $image_meta['id'], $overlay );
$og_image = admin_url( "admin-ajax.php?action=rank_math_overlay_thumb&id={$image_meta['id']}&type={$overlay}&hash={$secret}" );
}
$this->opengraph->tag( 'og:image', esc_url_raw( $og_image ) );
// Add secure URL if detected. Not all services implement this, so the regular one also needs to be rendered.
if ( Str::starts_with( 'https://', $og_image ) ) {
$this->opengraph->tag( 'og:image:secure_url', esc_url_raw( $og_image ) );
}
}
/**
* Output the image metadata.
*
* @param array $image_meta Image meta data to output.
*/
private function image_meta( $image_meta ) {
$image_tags = [ 'width', 'height', 'alt', 'type' ];
foreach ( $image_tags as $key ) {
if ( ! empty( $image_meta[ $key ] ) ) {
$this->opengraph->tag( 'og:image:' . $key, $image_meta[ $key ] );
}
}
}
/**
* Adds an image based on a given URL, and attempts to be smart about it.
*
* @param string $url The given URL.
*/
public function add_image_by_url( $url ) {
if ( empty( $url ) ) {
return;
}
$attachment_id = Attachment::get_by_url( $url );
if ( $attachment_id > 0 ) {
$this->add_image_by_id( $attachment_id );
return;
}
$this->add_image( [ 'url' => $url ] );
}
/**
* Adds an image to the list by attachment ID.
*
* @param int $attachment_id The attachment ID to add.
*/
public function add_image_by_id( $attachment_id ) {
if ( ! wp_attachment_is_image( $attachment_id ) ) {
return;
}
$variations = $this->get_variations( $attachment_id );
// If we are left without variations, there is no valid variation for this attachment.
if ( empty( $variations ) ) {
return;
}
// The variations are ordered so the first variations is by definition the best one.
$attachment = $variations[0];
if ( $attachment ) {
// In the past `add_image` accepted an image url, so leave this for backwards compatibility.
if ( Str::is_non_empty( $attachment ) ) {
$attachment = [ 'url' => $attachment ];
}
$attachment['alt'] = Attachment::get_alt_tag( $attachment_id );
$this->add_image( $attachment );
}
}
/**
* Display an OpenGraph image tag.
*
* @param string $attachment Source URL to the image.
*/
public function add_image( $attachment = '' ) {
// In the past `add_image` accepted an image url, so leave this for backwards compatibility.
if ( Str::is_non_empty( $attachment ) ) {
$attachment = [ 'url' => $attachment ];
}
$validate_image = true;
/**
* Allow changing the OpenGraph image.
* The dynamic part of the hook name, $this->network, is the network slug (facebook, twitter).
*
* @param string $img The image we are about to add.
*/
$filter_image_url = trim( $this->do_filter( "opengraph/{$this->network}/image", isset( $attachment['url'] ) ? $attachment['url'] : '' ) );
if ( ! empty( $filter_image_url ) && ( empty( $attachment['url'] ) || $filter_image_url !== $attachment['url'] ) ) {
$attachment = [ 'url' => $filter_image_url ];
$validate_image = false;
}
/**
* Secondary filter to allow changing the whole array.
* The dynamic part of the hook name, $this->network, is the network slug (facebook, twitter).
* This makes it possible to change the image ID too, to allow for image overlays.
*
* @param array $attachment The image we are about to add.
*/
$attachment = $this->do_filter( "opengraph/{$this->network}/image_array", $attachment );
if ( ! is_array( $attachment ) || empty( $attachment['url'] ) ) {
return;
}
// Validate image only when it is not added using the opengraph filter.
if ( $validate_image ) {
$attachment_url = explode( '?', $attachment['url'] );
if ( ! empty( $attachment_url ) ) {
$attachment['url'] = $attachment_url[0];
}
// If the URL ends in `.svg`, we need to return.
if ( ! $this->is_valid_image_url( $attachment['url'] ) ) {
return;
}
}
$image_url = $attachment['url'];
if ( empty( $image_url ) ) {
return;
}
if ( Url::is_relative( $image_url ) ) {
$image_url = Attachment::get_relative_path( $image_url );
}
if ( array_key_exists( $image_url, $this->images ) ) {
return;
}
$attachment['url'] = $image_url;
if ( empty( $attachment['alt'] ) && is_singular() ) {
$attachment['alt'] = $this->get_attachment_alt();
}
$this->images[ $image_url ] = $attachment;
}
/**
* Get attachment alt with fallback
*
* @return string
*/
private function get_attachment_alt() {
global $post;
$focus_keywords = Helper::get_post_meta( 'focus_keyword', $post->ID );
if ( ! empty( $focus_keywords ) ) {
$focus_keywords = explode( ',', $focus_keywords );
return $focus_keywords[0];
}
return get_the_title();
}
/**
* Check if page is front page or singular and call the corresponding functions.
*/
private function set_images() {
/**
* Allow developers to add images to the OpenGraph tags.
*
* The dynamic part of the hook name. $this->network, is the network slug.
*
* @param Image The current object.
*/
$this->do_action( "opengraph/{$this->network}/add_images", $this );
switch ( true ) {
case is_front_page():
$this->set_front_page_image();
break;
case is_home():
$this->set_posts_page_image();
break;
case is_attachment():
$this->set_attachment_page_image();
break;
case is_singular() || Post::is_shop_page():
$this->set_singular_image();
break;
case is_post_type_archive():
$this->set_archive_image();
break;
case is_category():
case is_tag():
case is_tax():
$this->set_taxonomy_image();
break;
case is_author():
$this->set_author_image();
break;
}
/**
* Allow developers to add images to the OpenGraph tags.
*
* The dynamic part of the hook name. $this->network, is the network slug.
*
* @param Image The current object.
*/
$this->do_action( "opengraph/{$this->network}/add_additional_images", $this );
/**
* Passing a truthy value to the filter will effectively short-circuit the
* set default image process.
*
* @param bool $return Short-circuit return value. Either false or true.
*/
if ( false !== $this->do_filter( 'opengraph/pre_set_default_image', false ) ) {
return;
}
// If not, get default image.
$image_id = Helper::get_settings( 'titles.open_graph_image_id' );
if ( ! $this->has_images() ) {
if ( $image_id > 0 ) {
$this->add_image_by_id( $image_id );
return;
}
$this->add_image(); // This allows "opengraph/{$this->network}/image" filter to be used even if no image is set.
}
}
/**
* If the frontpage image exists, call `add_image`.
*
* @return void
*/
private function set_front_page_image() {
$this->set_user_defined_image();
if ( $this->has_images() ) {
return;
}
// If no frontpage image is found, don't add anything.
if ( $image_id = Helper::get_settings( 'titles.homepage_facebook_image_id' ) ) { // phpcs:ignore
$this->add_image_by_id( $image_id );
}
}
/**
* Gets the user-defined image of the post.
*
* @param null|int $post_id The post ID to get the images for.
*/
private function set_user_defined_image( $post_id = null ) {
if ( null === $post_id ) {
$post_id = get_queried_object_id();
}
$this->set_image_post_meta( $post_id );
if ( $this->has_images() ) {
return;
}
$this->set_featured_image( $post_id );
}
/**
* If opengraph-image is set, call `add_image` and return true.
*
* @param int $post_id Optional post ID to use.
*/
private function set_image_post_meta( $post_id = 0 ) {
if ( empty( $post_id ) ) {
return;
}
$image_id = Helper::get_post_meta( "{$this->opengraph->prefix}_image_id", $post_id );
$this->add_image_by_id( $image_id );
}
/**
* Retrieve the featured image.
*
* @param int $post_id The post ID.
*/
private function set_featured_image( $post_id = null ) {
/**
* Passing a truthy value to the filter will effectively short-circuit the
* set featured image process.
*
* @param bool $return Short-circuit return value. Either false or true.
* @param int $post_id Post ID for the current post.
*/
if ( false !== $this->do_filter( 'opengraph/pre_set_featured_image', false, $post_id ) ) {
return;
}
if ( $post_id && has_post_thumbnail( $post_id ) ) {
$attachment_id = get_post_thumbnail_id( $post_id );
$this->add_image_by_id( $attachment_id );
}
}
/**
* Get the images of the posts page.
*/
private function set_posts_page_image() {
$post_id = get_option( 'page_for_posts' );
$this->set_image_post_meta( $post_id );
if ( $this->has_images() ) {
return;
}
$this->set_featured_image( $post_id );
}
/**
* If this is an attachment page, call `add_image` with the attachment.
*/
private function set_attachment_page_image() {
$post_id = get_queried_object_id();
if ( wp_attachment_is_image( $post_id ) ) {
$this->add_image_by_id( $post_id );
}
}
/**
* Get the images of the singular post.
*
* @param null|int $post_id The post ID to get the images for.
*/
private function set_singular_image( $post_id = null ) {
$is_shop_page = Post::is_shop_page();
if ( $is_shop_page ) {
$post_id = Post::get_shop_page_id();
}
$post_id = is_null( $post_id ) ? get_queried_object_id() : $post_id;
$this->set_user_defined_image( $post_id );
if ( $this->has_images() ) {
return;
}
/**
* Passing a truthy value to the filter will effectively short-circuit the
* set content image process.
*
* @param bool $return Short-circuit return value. Either false or true.
* @param int $post_id Post ID for the current post.
*/
if ( false !== $this->do_filter( 'opengraph/pre_set_content_image', false, $post_id ) ) {
if ( $is_shop_page ) {
$this->set_archive_image();
}
return;
}
$this->set_content_image( get_post( $post_id ) );
if ( ! $this->has_images() && $is_shop_page ) {
$this->set_archive_image();
}
}
/**
* Adds the first usable attachment image from the post content.
*
* @param object $post The post object.
*/
private function set_content_image( $post ) {
$content = sanitize_post_field( 'post_content', $post->post_content, $post->ID );
// Early bail!
if ( '' === $content || false === Str::contains( '<img', $content ) ) {
return;
}
$do_og_content_image_cache = $this->do_filter( 'opengraph/content_image_cache', true );
if ( $do_og_content_image_cache ) {
$cache_key = 'rank_math_og_content_image';
$cache = get_post_meta( $post->ID, $cache_key, true );
$check = md5( $post->post_content );
if ( ! empty( $cache ) && isset( $cache['check'] ) && $check === $cache['check'] ) {
foreach ( $cache['images'] as $image ) {
if ( is_int( $image ) ) {
$this->add_image_by_id( $image );
} else {
$this->add_image( $image );
}
}
return;
}
$cache = [
'check' => $check,
'images' => [],
];
}
$images = [];
if ( preg_match_all( '`<img [^>]+>`', $content, $matches ) ) {
foreach ( $matches[0] as $img ) {
if ( preg_match( '`src=(["\'])(.*?)\1`', $img, $match ) ) {
if ( isset( $match[2] ) ) {
$images[] = $match[2];
}
}
}
}
$images = array_unique( $images );
if ( empty( $images ) ) {
return;
}
foreach ( $images as $image ) {
// If an image has been added, we're done.
if ( $this->has_images() ) {
break;
}
if ( Url::is_external( $image ) ) {
$this->add_image( $image );
} else {
$attachment_id = Attachment::get_by_url( $image );
if ( 0 === $attachment_id ) {
$this->add_image( $image );
if ( $do_og_content_image_cache ) {
$cache['images'][] = $image;
}
} else {
$this->add_image_by_id( $attachment_id );
if ( $do_og_content_image_cache ) {
$cache['images'][] = $attachment_id;
}
}
}
}
if ( $do_og_content_image_cache ) {
update_post_meta( $post->ID, $cache_key, $cache );
}
}
/**
* Check if Author has an image and add this image.
*/
private function set_author_image() {
$image_id = Helper::get_user_meta( "{$this->opengraph->prefix}_image_id" );
$this->add_image_by_id( $image_id );
}
/**
* Check if taxonomy has an image and add this image.
*/
private function set_taxonomy_image() {
$image_id = Helper::get_term_meta( "{$this->opengraph->prefix}_image_id" );
$this->add_image_by_id( $image_id );
}
/**
* Check if archive has an image and add this image.
*/
private function set_archive_image() {
$post_type = get_query_var( 'post_type' );
$image_id = Helper::get_settings( "titles.pt_{$post_type}_facebook_image_id" );
$this->add_image_by_id( $image_id );
}
/**
* Determines whether the passed URL is considered valid.
*
* @param string $url The URL to check.
*
* @return bool Whether or not the URL is a valid image.
*/
protected function is_valid_image_url( $url ) {
if ( ! is_string( $url ) ) {
return false;
}
$check = wp_check_filetype( $url );
if ( empty( $check['ext'] ) ) {
return false;
}
$extensions = [ 'jpeg', 'jpg', 'gif', 'png', 'webp' ];
return in_array( $check['ext'], $extensions, true );
}
/**
* Returns the different image variations for consideration.
*
* @param int $attachment_id The attachment to return the variations for.
*
* @return array The different variations possible for this attachment ID.
*/
public function get_variations( $attachment_id ) {
$variations = [];
/**
* Determines which image sizes we'll loop through to get an appropriate image.
*
* @param unsigned array - The array of image sizes to loop through.
*/
$sizes = $this->do_filter( 'opengraph/image_sizes', [ 'full', 'large', 'medium_large' ] );
foreach ( $sizes as $size ) {
if ( $variation = $this->get_attachment_image( $attachment_id, $size ) ) { // phpcs:ignore
if ( $this->has_usable_dimensions( $variation ) ) {
$variations[] = $variation;
}
}
}
return $variations;
}
/**
* Retrieve an image to represent an attachment.
*
* @param int $attachment_id Image attachment ID.
* @param string|array $size Optional. Image size. Accepts any valid image size, or an array of width
* and height values in pixels (in that order). Default 'thumbnail'.
* @return false|array
*/
private function get_attachment_image( $attachment_id, $size = 'thumbnail' ) {
$image = wp_get_attachment_image_src( $attachment_id, $size );
// Early Bail!
if ( ! $image ) {
return false;
}
list( $src, $width, $height ) = $image;
return [
'id' => $attachment_id,
'url' => $src,
'width' => $width,
'height' => $height,
'type' => get_post_mime_type( $attachment_id ),
'alt' => Attachment::get_alt_tag( $attachment_id ),
];
}
/**
* Checks whether an img sizes up to the parameters.
*
* @param array $dimensions The image values.
* @return bool True if the image has usable measurements, false if not.
*/
private function has_usable_dimensions( $dimensions ) {
foreach ( [ 'width', 'height' ] as $param ) {
$minimum = $this->usable_dimensions[ 'min_' . $param ];
$maximum = $this->usable_dimensions[ 'max_' . $param ];
$current = $dimensions[ $param ];
if ( ( $current < $minimum ) || ( $current > $maximum ) ) {
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,208 @@
<?php
/**
* Add the OpenGraph tags to the header.
*
* @since 0.9.0
* @package RankMath
* @subpackage RankMath\OpenGraph
* @author Rank Math <support@rankmath.com>
*
* @copyright Copyright (C) 2008-2019, Yoast BV
* The following code is a derivative work of the code from the Yoast(https://github.com/Yoast/wordpress-seo/), which is licensed under GPL v3.
*/
namespace RankMath\OpenGraph;
use RankMath\Post;
use RankMath\Term;
use RankMath\User;
use RankMath\Helper;
use RankMath\Paper\Paper;
use RankMath\Traits\Hooker;
use RankMath\Helpers\Str;
defined( 'ABSPATH' ) || exit;
/**
* OpenGraph class.
*/
class OpenGraph {
use Hooker;
/**
* Holds network slug.
*
* @var string
*/
public $network = '';
/**
* Hold meta_key prefix.
*
* @var string
*/
public $prefix = '';
/**
* Schema type.
*
* @var bool|string
*/
protected $schema = false;
/**
* The Constructor.
*/
public function __construct() {
$this->action( 'rank_math/head', 'output_tags', 30 );
}
/**
* Main OpenGraph output.
*/
public function output_tags() {
wp_reset_query();
/**
* Hook to add all OpenGraph metadata
*
* The dynamic part of the hook name. $this->network, is the network slug.
*
* @param OpenGraph $this The current opengraph network object.
*/
$this->do_action( "opengraph/{$this->network}", $this );
}
/**
* Get title
*
* @return bool|string
*/
public function get_title() {
$title = $this->_title();
if ( $title && Helper::get_settings( 'titles.capitalize_titles' ) ) {
$title = Str::mb_ucwords( $title );
}
return $title ? $title : Paper::get()->get_title();
}
/**
* Get title.
*
* @return string
*/
private function _title() {
$key = $this->prefix . '_title';
if ( Post::is_simple_page() ) {
return Post::get_meta( $key, Post::get_page_id() );
}
if ( is_front_page() ) {
return Helper::replace_vars( Helper::get_settings( 'titles.homepage_facebook_title' ) );
}
if ( is_category() || is_tax() || is_tag() ) {
return Term::get_meta( $key );
}
return is_author() ? User::get_meta( $key ) : false;
}
/**
* Get description.
*
* @return bool|string
*/
public function get_description() {
$desc = false;
$key = $this->prefix . '_description';
if ( Post::is_simple_page() ) {
$desc = Post::get_meta( $key, Post::get_page_id() );
$desc = '' !== $desc ? $desc : $this->fallback_description( 'get_the_excerpt' );
} elseif ( is_front_page() ) {
$desc = Helper::replace_vars( Helper::get_settings( 'titles.homepage_facebook_description' ) );
} elseif ( is_category() || is_tag() || is_tax() ) {
$desc = Term::get_meta( $key );
$desc = '' !== $desc ? $desc : $this->fallback_description( 'term_description' );
} elseif ( is_author() ) {
$desc = User::get_meta( $key );
}
return $desc ? $desc : $this->fallback_description();
}
/**
* Get a fallback description.
*
* @param string $callback Function name to call.
*
* @return string
*/
protected function fallback_description( $callback = false ) {
$desc = Paper::get()->get_description();
if ( '' === $desc && $callback ) {
$desc = $callback();
}
return $desc;
}
/**
* Internal function to output social meta tags.
*
* @param string $property Property attribute value.
* @param string $content Content attribute value.
*
* @return bool
*/
public function tag( $property, $content ) {
$og_property = str_replace( ':', '_', $property );
/**
* Allow developers to change the content of specific social meta tags.
*
* The dynamic part of the hook name. $this->network, is the network slug
* and $og_property, is the property which we are outputting.
*
* @param string $content The content of the property.
*/
$content = $this->do_filter( "opengraph/{$this->network}/$og_property", $content );
if ( empty( $content ) || ! is_scalar( $content ) ) {
return false;
}
$tag = 'facebook' === $this->network ? 'property' : 'name';
$escaped_value = esc_attr( $content );
if ( false !== filter_var( $content, FILTER_VALIDATE_URL ) ) {
$escaped_value = esc_url_raw( $content );
}
printf( '<meta %1$s="%2$s" content="%3$s" />' . "\n", $tag, esc_attr( $property ), $escaped_value );
return true;
}
/**
* Get Overlay Image URL
*
* @param string $network The social network.
*
* @return string
*/
public function get_overlay_image( $network = 'facebook' ) {
if ( is_singular() ) {
return Helper::get_post_meta( "{$network}_enable_image_overlay" ) ? Helper::get_post_meta( "{$network}_image_overlay", '', 'play' ) : '';
}
if ( is_category() || is_tag() || is_tax() ) {
return Helper::get_term_meta( "{$network}_enable_image_overlay" ) ? Helper::get_term_meta( "{$network}_image_overlay", 0, '', 'play' ) : '';
}
if ( is_author() ) {
return Helper::get_user_meta( "{$network}_enable_image_overlay" ) ? Helper::get_user_meta( "{$network}_image_overlay", 0, 'play' ) : '';
}
return '';
}
}

View File

@@ -0,0 +1,366 @@
<?php
/**
* This class handles the Slack sharing functionality.
*
* @since 1.0.76
* @package RankMath
* @subpackage RankMath\OpenGraph
* @author Rank Math <support@rankmath.com>
*
* @copyright Copyright (C) 2008-2019, Yoast BV
* The following code is a derivative work of the code from the Yoast(https://github.com/Yoast/wordpress-seo/), which is licensed under GPL v3.
*/
namespace RankMath\OpenGraph;
use RankMath\Helper;
defined( 'ABSPATH' ) || exit;
/**
* Slack class.
*/
class Slack extends OpenGraph {
/**
* Network slug.
*
* @var string
*/
public $network = 'slack';
/**
* Enhanced data tag counter.
*
* @var int
*/
private static $data_tag_count = 0;
/**
* The Constructor.
*/
public function __construct() {
$this->action( 'rank_math/opengraph/slack', 'enhanced_data', 20 );
parent::__construct();
}
/**
* Outputs the Slack enhanced data.
*/
public function enhanced_data() {
$data = $this->get_enhanced_data();
foreach ( $data as $key => $value ) {
if ( empty( $value ) ) {
continue;
}
$this->enhanced_data_tag( $key, $value );
}
}
/**
* Get Slack enhanced data tags for a key/value pair.
*
* @param string $key The key.
* @param string $value The value.
*
* @return void
*/
public function enhanced_data_tag( $key, $value ) {
self::$data_tag_count++;
$this->tag( sprintf( 'twitter:label%d', self::$data_tag_count ), $key );
$this->tag( sprintf( 'twitter:data%d', self::$data_tag_count ), $value );
}
/**
* Get Slack data for the current page.
*
* @return array
*/
private function get_enhanced_data() {
$data = [];
if ( $this->is_product() ) {
$data = $this->get_product_data();
} elseif ( $this->is_page() ) {
$data = $this->get_page_data();
} elseif ( $this->is_singular() ) {
$data = $this->get_post_data();
} elseif ( $this->is_term() ) {
$data = $this->get_term_data();
} elseif ( $this->is_author() ) {
$data = $this->get_author_data();
}
$data = $this->do_filter( 'opengraph/slack_enhanced_data', $data );
return $data;
}
/**
* Check if current page is a product.
*
* @return bool
*/
private function is_product() {
return $this->is_woo_product() || $this->is_edd_product();
}
/**
* Get product data.
*
* @return array
*/
private function get_product_data() {
if ( $this->is_woo_product() ) {
return $this->get_woo_product_data();
}
return $this->get_edd_product_data();
}
/**
* Check if current page is a WooCommerce product.
*
* @return bool
*/
private function is_woo_product() {
return Helper::get_settings( 'titles.pt_product_slack_enhanced_sharing' ) && is_singular( 'product' ) && function_exists( 'wc_get_product' );
}
/**
* Check if current page is a EDD download.
*
* @return bool
*/
private function is_edd_product() {
return Helper::get_settings( 'titles.pt_download_slack_enhanced_sharing' ) && is_singular( 'download' ) && class_exists( 'Easy_Digital_Downloads' );
}
/**
* Check if current page is a post or a CPT.
*
* @return bool
*/
private function is_singular() {
return is_singular() && Helper::get_settings( sprintf( 'titles.pt_%s_slack_enhanced_sharing', get_post_type() ) );
}
/**
* Check if current page is a page.
*
* @return bool
*/
private function is_page() {
return Helper::get_settings( 'titles.pt_page_slack_enhanced_sharing' ) && is_singular( 'page' ) && ! is_front_page();
}
/**
* Check if current page is a term archive.
*
* @return bool
*/
private function is_term() {
if ( is_category() || is_tag() || is_tax() ) {
global $wp_query;
return Helper::get_settings( sprintf( 'titles.tax_%s_slack_enhanced_sharing', $wp_query->get_queried_object()->taxonomy ) );
}
return false;
}
/**
* Check if current page is an author archive.
*
* @return bool
*/
private function is_author() {
return Helper::get_settings( 'titles.author_slack_enhanced_sharing' ) && is_author();
}
/**
* Get Slack data for WooCommerce product.
*
* @return array
*/
private function get_woo_product_data() {
global $post;
$data = [];
$product = \wc_get_product( $post );
$data[ __( 'Price', 'rank-math' ) ] = $this->get_product_price( $product );
$data[ __( 'Availability', 'rank-math' ) ] = $this->get_product_availability( $product );
return $data;
}
/**
* Get Slack data for EDD download.
*
* @return array
*/
private function get_edd_product_data() {
global $post;
$data = [];
$data[ __( 'Price', 'rank-math' ) ] = wp_strip_all_tags( \edd_price( $post->ID, false ) );
return $data;
}
/**
* Get availability of product.
*
* @param object $product Product object.
*
* @return string
*/
private function get_product_availability( $product ) {
$product_availability = $product->get_availability();
$availability_text = isset( $product_availability['availability'] ) ? $product_availability['availability'] : '';
if ( ! $availability_text ) {
return __( 'In stock', 'rank-math' );
}
return $availability_text;
}
/**
* Get price of WooCommerce product.
* Gets price range for variable products.
*
* @param object $product Product object.
*
* @return string
*/
private function get_product_price( $product ) {
$price = wp_strip_all_tags( \wc_price( $product->get_price() ) );
if ( $product->is_type( 'variable' ) ) {
$lowest = \wc_format_decimal( $product->get_variation_price( 'min', false ), \wc_get_price_decimals() );
$highest = \wc_format_decimal( $product->get_variation_price( 'max', false ), \wc_get_price_decimals() );
$price = wp_strip_all_tags( \wc_price( $lowest ) . ' - ' . \wc_price( $highest ) );
if ( $lowest === $highest ) {
$price = wp_strip_all_tags( \wc_price( $lowest ) );
}
}
return $price;
}
/**
* Get Slack data for post.
*
* @return array
*/
private function get_post_data() {
global $post;
$data = [];
$data[ __( 'Written by', 'rank-math' ) ] = get_the_author();
$data[ __( 'Time to read', 'rank-math' ) ] = $this->calculate_time_to_read( $post );
return $data;
}
/**
* Get Slack data for page.
*
* @return array
*/
private function get_page_data() {
global $post;
$data = [];
$data[ __( 'Time to read', 'rank-math' ) ] = $this->calculate_time_to_read( $post );
return $data;
}
/**
* Calculate the time to read for the post.
*
* @param object $post Post object.
*
* @return string
*/
private function calculate_time_to_read( $post ) {
/**
* Filter: 'rank_math/frontend/time_to_read_content' - Change the text to calculate the time to read.
*/
$content = $this->do_filter( 'frontend/time_to_read_content', wp_strip_all_tags( $post->post_content ) );
/**
* Filter: 'rank_math/frontend/time_to_read_wpm' - Change the words per minute to calculate the time to read.
*/
$words_per_minute = absint( $this->do_filter( 'frontend/time_to_read_wpm', 200 ) );
$words = str_word_count( $content );
$minutes = floor( $words / $words_per_minute );
if ( $minutes > 0 ) {
return sprintf(
/* translators: %d: minutes */
_n( '%d minute', '%d minutes', $minutes, 'rank-math' ),
$minutes
);
}
return __( 'Less than a minute', 'rank-math' );
}
/**
* Get Slack data for term.
*
* @return array
*/
private function get_term_data() {
global $wp_query;
$data = [];
$term = $wp_query->get_queried_object();
if ( ! $term ) {
return $data;
}
$label = __( 'Items', 'rank-math' );
$post_type_object = get_post_type_object( get_post_type() );
if ( is_object( $post_type_object ) && isset( $post_type_object->labels->name ) ) {
$label = $post_type_object->labels->name;
}
$data[ $label ] = ( ! empty( $term->category_count ) ? $term->category_count : $term->count );
return $data;
}
/**
* Get Slack data for author.
*
* @return array
*/
private function get_author_data() {
global $wp_query;
$data = [];
$author = $wp_query->get_queried_object();
if ( ! $author ) {
return $data;
}
$data[ __( 'Name', 'rank-math' ) ] = $author->display_name;
$data[ __( 'Posts', 'rank-math' ) ] = count_user_posts( $author->ID );
return $data;
}
}

View File

@@ -0,0 +1,272 @@
<?php
/**
* Twitter cards functionality.
*
* @since 0.9.0
* @package RankMath
* @subpackage RankMath\OpenGraph
* @author Rank Math <support@rankmath.com>
*
* @copyright Copyright (C) 2008-2019, Yoast BV
* The following code is a derivative work of the code from the Yoast(https://github.com/Yoast/wordpress-seo/), which is licensed under GPL v3.
*/
namespace RankMath\OpenGraph;
use RankMath\Helper;
use RankMath\Post;
use RankMath\Helpers\Str;
use RankMath\Helpers\Arr;
defined( 'ABSPATH' ) || exit;
/**
* Twitter class.
*/
class Twitter extends OpenGraph {
/**
* Network slug.
*
* @var string
*/
public $network = 'twitter';
/**
* Metakey prefix.
*
* @var string
*/
public $prefix = 'twitter';
/**
* Hold site info for twitter card.
*
* @var string
*/
private $site = null;
/**
* Will hold the Twitter card type being created
*
* @var string
*/
private $type;
/**
* The Constructor.
*/
public function __construct() {
/**
* Allow changing the Twitter Card type as output in the Twitter card.
*
* @param string $type
*/
if ( false === $this->do_filter( 'opengraph/twitter_card', true ) ) {
return;
}
$this->action( 'rank_math/opengraph/twitter', 'use_facebook', 1 );
$this->action( 'rank_math/opengraph/twitter', 'type', 5 );
$this->action( 'rank_math/opengraph/twitter', 'title', 10 );
$this->action( 'rank_math/opengraph/twitter', 'description', 11 );
$this->action( 'rank_math/opengraph/twitter', 'website', 14 );
if ( ! post_password_required() ) {
$this->action( 'rank_math/opengraph/twitter', 'image', 30 );
}
if ( is_singular() ) {
$this->action( 'rank_math/opengraph/twitter', 'article_author', 15 );
}
parent::__construct();
}
/**
* Set `use_facebook` variable.
*/
public function use_facebook() {
$use_facebook = ( is_category() || is_tag() || is_tax() ) ? Helper::get_term_meta( 'twitter_use_facebook' ) :
Helper::get_post_meta( 'twitter_use_facebook', Post::is_shop_page() ? Post::get_shop_page_id() : 0, true );
if ( $use_facebook ) {
$this->prefix = 'facebook';
}
}
/**
* Display the Twitter card type.
*
* This defaults to summary but can be filtered using the <code>rank_math_twitter_card_type</code> filter.
*/
public function type() {
$this->determine_card_type();
$this->sanitize_card_type();
$this->tag( 'twitter:card', $this->type );
$remove_tags = false;
if ( is_singular() && ! is_front_page() && in_array( $this->type, [ 'app', 'player' ], true ) ) {
$remove_tags = 'app' === $this->type;
$this->action( 'rank_math/opengraph/twitter', $this->type, 15 );
}
$remove_tags = is_date() && in_array( $this->type, [ 'summary', 'summary_large_image' ], true );
if ( $remove_tags ) {
$this->remove_tags();
}
}
/**
* Output App card.
*/
public function app() {
$this->tag( 'twitter:description', Helper::get_post_meta( 'twitter_app_description' ) );
$this->tag( 'twitter:app:country', Helper::get_post_meta( 'twitter_app_country' ) );
// iPhone.
$this->tag( 'twitter:app:name:iphone', Helper::get_post_meta( 'twitter_app_iphone_name' ) );
$this->tag( 'twitter:app:id:iphone', Helper::get_post_meta( 'twitter_app_iphone_id' ) );
$this->tag( 'twitter:app:url:iphone', Helper::get_post_meta( 'twitter_app_iphone_url' ) );
// iPad.
$this->tag( 'twitter:app:name:ipad', Helper::get_post_meta( 'twitter_app_ipad_name' ) );
$this->tag( 'twitter:app:id:ipad', Helper::get_post_meta( 'twitter_app_ipad_id' ) );
$this->tag( 'twitter:app:url:ipad', Helper::get_post_meta( 'twitter_app_ipad_url' ) );
// Google Play.
$this->tag( 'twitter:app:name:googleplay', Helper::get_post_meta( 'twitter_app_googleplay_name' ) );
$this->tag( 'twitter:app:id:googleplay', Helper::get_post_meta( 'twitter_app_googleplay_id' ) );
$this->tag( 'twitter:app:url:googleplay', Helper::get_post_meta( 'twitter_app_googleplay_url' ) );
}
/**
* Output player card.
*/
public function player() {
$this->tag( 'twitter:player', Helper::get_post_meta( 'twitter_player_url' ) );
$size = Helper::get_post_meta( 'twitter_player_size' );
if ( $size ) {
$size = Arr::from_string( $size, 'x' );
if ( isset( $size[1] ) ) {
$twitter_meta['twitter:player:width'] = (int) $size[0];
$twitter_meta['twitter:player:height'] = (int) $size[1];
}
}
$this->tag( 'twitter:player:stream', Helper::get_post_meta( 'twitter_player_stream' ) );
$this->tag( 'twitter:player:stream:content_type', Helper::get_post_meta( 'twitter_player_stream_ctype' ) );
}
/**
* Output the title.
*/
public function title() {
$this->tag( 'twitter:title', trim( $this->get_title() ) );
}
/**
* Output the description.
*/
public function description() {
$this->tag( 'twitter:description', trim( $this->get_description() ) );
}
/**
* Output the Twitter account for the site.
*/
public function website() {
$this->site = Helper::get_settings( 'titles.twitter_author_names' );
if ( Str::is_non_empty( $this->site ) ) {
$this->tag( 'twitter:site', '@' . $this->site );
}
}
/**
* Output the image for Twitter.
*
* Only used when OpenGraph is inactive or Summary Large Image card is chosen.
*/
public function image() {
$images = new Image( false, $this );
foreach ( $images->get_images() as $image_url => $image_meta ) {
$overlay = $this->get_overlay_image( $this->prefix );
if ( $overlay && ! empty( $image_meta['id'] ) ) {
$secret = $images->generate_secret( $image_meta['id'], $overlay );
$image_url = admin_url( "admin-ajax.php?action=rank_math_overlay_thumb&id={$image_meta['id']}&type={$overlay}&hash={$secret}" );
}
$this->tag( 'twitter:image', esc_url_raw( $image_url ) );
}
}
/**
* Outputs the authors twitter handle.
*/
public function article_author() {
$author = Helper::get_user_meta( 'twitter_author', $GLOBALS['post']->post_author );
$author = $author ? $author : get_user_meta( $GLOBALS['post']->post_author, 'twitter', true );
$author = $this->get_twitter_id( ltrim( trim( $author ), '@' ) );
if ( Str::is_non_empty( $author ) ) {
$this->tag( 'twitter:creator', '@' . $author );
} elseif ( Str::is_non_empty( $this->site ) ) {
$this->tag( 'twitter:creator', '@' . $this->site );
}
}
/**
* Determines the twitter card type for the current page
*/
private function determine_card_type() {
$this->type = Helper::get_post_meta( 'twitter_card_type' );
$this->type = $this->type ? $this->type : Helper::get_settings( 'titles.twitter_card_type' );
/**
* Allow changing the Twitter Card type as output in the Twitter card.
*
* @param string $this->type
*/
$this->type = $this->do_filter( 'opengraph/twitter/card_type', $this->type );
}
/**
* Determines whether the card type is of a type currently allowed by Twitter
*
* @link https://dev.twitter.com/cards/types
*/
private function sanitize_card_type() {
if ( ! in_array( $this->type, [ 'summary', 'summary_large_image', 'app', 'player' ], true ) ) {
$this->type = 'summary';
}
}
/**
* Checks if the given ID is actually an ID or a URL and if URL, distills the ID from it.
*
* Solves issues with filters returning URLs and theme's/other plugins also adding a user meta
* twitter field which expects URL rather than an ID (which is what we expect).
*
* @param string $id Twitter ID or URL.
*
* @return string|bool Twitter ID or false if it failed to get a valid Twitter ID.
*/
private function get_twitter_id( $id ) {
if ( preg_match( '`([A-Za-z0-9_]{1,25})$`', $id, $match ) ) {
return $match[1];
}
return false;
}
/**
* Remove archive tags.
*/
private function remove_tags() {
$this->remove_action( 'rank_math/opengraph/twitter', 'title', 10 );
$this->remove_action( 'rank_math/opengraph/twitter', 'description', 11 );
$this->remove_action( 'rank_math/opengraph/twitter', 'image', 30 );
}
}

View File

@@ -0,0 +1 @@
<?php // Silence is golden.