<?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 ) ); } }