<?php
/**
* Genesis Framework.
*
* WARNING: This file is part of the core Genesis Framework. DO NOT edit this file under any circumstances.
* Please do all modifications in the form of a child theme.
*
* @package StudioPress\Genesis
* @author StudioPress
* @license GPL-2.0-or-later
* @link https://my.studiopress.com/themes/genesis/
*/
namespace StudioPress\Genesis\SEO;
/**
* Genesis Open Graph support.
*
* @since 3.2.0
*/
class Open_Graph {
/**
* Icon size for author and site icon square images.
*
* @since 3.2.0
*
* @var int
*/
protected $icon_size;
/**
* Constructs the Open_Graph object.
*
* @since 3.2.0
*
* @param array $config Open Graph configuration.
*/
public function __construct( $config ) {
$this->icon_size = $config['icon_size'];
}
/**
* Adds WordPress hooks.
*
* @since 3.2.0
*/
public function add_hooks() {
add_action( 'wp_head', [ $this, 'output_open_graph_tags' ], 5 );
add_action( 'customize_register', [ $this, 'add_default_image_control' ] );
}
/**
* Adds default Open Graph image control to the Customizer.
*
* Can be moved to `config/customizer-seo-settings.php` when it
* supports image controls. (Genesis issue #1885.)
*
* @since 3.2.0
*
* @param WP_Customize_Manager $wp_customize Customizer instance.
*/
public function add_default_image_control( $wp_customize ) {
$wp_customize->add_setting(
'genesis-seo-settings[open_graph_default_image]',
[
'default' => '',
'sanitize_callback' => 'esc_attr',
'type' => 'option',
]
);
$wp_customize->add_control(
new \WP_Customize_Media_Control(
$wp_customize,
'open_graph_default_image',
[
'label' => __( 'Default Image', 'genesis' ),
'description' => __( 'Select an image to use on social sites if no featured image is set.', 'genesis' ),
'section' => 'genesis_seo_open_graph',
'settings' => 'genesis-seo-settings[open_graph_default_image]',
'mime_type' => 'image',
]
)
);
}
/**
* Outputs Open Graph meta elements if Open Graph support is enabled.
*
* @since 3.2.0
*/
public function output_open_graph_tags() {
$open_graph_enabled = genesis_get_seo_option( 'open_graph' ) ?: false;
if ( ! $open_graph_enabled ) {
return;
}
echo "<!-- Genesis Open Graph -->\n"; // For support teams.
$this->tag( 'title', wp_get_document_title() );
$this->tag( 'type', $this->get_type() );
$this->tag( 'description', genesis_get_seo_meta_description() );
$this->tag( 'url', $this->get_url() );
$image = $this->get_image();
if ( isset( $image['url'] ) ) {
$this->tag( 'image', $image['url'] );
if ( isset( $image['width'] ) && isset( $image['height'] ) ) {
$this->tag( 'image:width', $image['width'] );
$this->tag( 'image:height', $image['height'] );
}
if ( isset( $image['alt'] ) ) {
$this->tag( 'image:alt', $image['alt'] );
}
}
}
/**
* Gets the current Open Graph object type.
*
* Filterable via `genesis_open_graph_type`.
*
* @since 3.2.0
*
* @see https://ogp.me/#types Open Graph object types.
* @return string The Open Graph type.
*/
protected function get_type() {
$type = 'website';
if ( is_singular() && ! is_front_page() ) {
$type = 'article';
} elseif ( is_author() ) {
$type = 'profile';
}
return $type;
}
/**
* Gets the current page URL.
*
* Filterable via `genesis_open_graph_url`.
*
* @since 3.2.0
*
* @return string The current page URL.
*/
protected function get_url() {
global $wp;
return trailingslashit( home_url( $wp->request ) );
}
/**
* Gets the image URL.
*
* Featured image if present, falling back to the first image attached to
* the post, then the default set in Customizer Open Graph SEO settings,
* then the site icon if set.
*
* Filterable via `genesis_open_graph_image`.
*
* @since 3.2.0
*
* @return array The featured or fallback image with 'url', 'height', and 'width' keys.
*/
protected function get_image() {
$image = [];
if ( is_author() ) {
$image = $this->get_author_image();
} else {
$image = $this->get_genesis_image();
}
if ( ! $image || ( is_archive() && ! is_author() ) ) {
$image = $this->get_open_graph_default_image();
}
if ( ! $image && function_exists( 'get_site_icon_url' ) && has_site_icon() ) {
$image = $this->get_site_icon_image();
}
return $image;
}
/**
* Gets the author profile image information.
*
* @since 3.2.0
*
* @return array Image info with 'url', 'height', 'width', and 'alt' keys or empty array.
*/
protected function get_author_image() {
$avatar_url = get_avatar_url(
get_the_author_meta( 'ID' ),
[ 'size' => $this->icon_size ]
);
return $this->get_image_info( $avatar_url, true );
}
/**
* Gets the default Genesis image featured image or first attachment.
*
* @since 3.2.0
*
* @return array Image info with 'url', 'height', 'width', and 'alt' keys or empty array.
*/
protected function get_genesis_image() {
$genesis_image = genesis_get_image( [ 'format' => 'url' ] );
return $this->get_image_info( attachment_url_to_postid( $genesis_image ) );
}
/**
* Gets the default Open Graph image if set in the Customizer.
*
* @since 3.2.0
*
* @return array Image info with 'url', 'height', 'width', and 'alt' keys or empty array.
*/
protected function get_open_graph_default_image() {
$default_image_id = genesis_get_seo_option( 'open_graph_default_image' ) ?: false;
return $this->get_image_info( $default_image_id );
}
/**
* Gets the site icon image info if set.
*
* @since 3.2.0
*
* @return array Image info with 'url', 'height', 'width', and 'alt' keys or empty array.
*/
protected function get_site_icon_image() {
$site_icon = get_site_icon_url( $this->icon_size );
return $this->get_image_info( $site_icon, true );
}
/**
* Gets image info given a URL or attachment ID.
*
* @since 3.2.0
*
* @param string|int $image URL or attachment ID. Icons assume use of URL.
* @param bool $icon If true, gives square value from `icon_size` class property.
* @return array Image info with 'url', 'height', 'width', and 'alt' keys or empty array.
*/
protected function get_image_info( $image, $icon = false ) {
if ( $icon && $image ) {
return [
'url' => $image,
'height' => $this->icon_size,
'width' => $this->icon_size,
];
}
if ( is_numeric( $image ) ) {
$url = wp_get_attachment_url( $image );
$info = wp_get_attachment_metadata( $image );
$alt_text = get_post_meta( $image, '_wp_attachment_image_alt', true );
$image = [];
if ( $url ) {
$image['url'] = $url;
if ( isset( $info['height'] ) && isset( $info['width'] ) ) {
$image['height'] = $info['height'];
$image['width'] = $info['width'];
}
if ( $alt_text ) {
$image['alt'] = $alt_text;
}
}
return $image;
}
return [];
}
/**
* Outputs a single Open Graph meta tag.
*
* @since 3.2.0
*
* @param string $property The Open Graph property without the `og:` prefix.
* @param string $content The value of the content attribute.
*/
protected function tag( $property, $content ) {
/**
* Override the content attribute of any Genesis Open Graph property.
*
* ```php
* add_filter( 'genesis_open_graph_title', 'custom_open_graph_title' );
*
* function custom_open_graph_title( $content ) {
* if ( is_front_page() ) {
* $content = $content . ' — Some custom text';
* }
*
* return $content;
* }
* ```
*
* @since 3.2.0
*
* @param $content The content to return for the given property.
*/
$content = apply_filters( "genesis_open_graph_{$property}", $content );
$content = trim( $content );
if ( ! $content ) {
return;
}
printf(
'<meta property="og:%1$s" content="%2$s" />' . "\n",
esc_attr( $property ),
esc_attr( $content )
);
}
}