From 557b5b5a309003fd8a4d4a2143ac3a2bab00933a Mon Sep 17 00:00:00 2001 From: Jeremy Dormitzer Date: Fri, 9 Nov 2018 23:39:52 -0500 Subject: [PATCH] Include the opengraph lib if the plugin is not separately loaded --- includes/init.php | 4 + includes/lib/opengraph.php | 515 +++++++++++++++++++++++++++++++++++++ 2 files changed, 519 insertions(+) create mode 100644 includes/lib/opengraph.php diff --git a/includes/init.php b/includes/init.php index afca981..a69a1cb 100644 --- a/includes/init.php +++ b/includes/init.php @@ -14,6 +14,10 @@ require_once plugin_dir_path( __FILE__ ) . 'pgp.php'; require_once plugin_dir_path( __FILE__ ) . 'admin/admin.php'; require_once plugin_dir_path( __FILE__ ) . 'admin/settings.php'; +if ( ! function_exists( 'opengraph_metadata' ) ) { + require_once plugin_dir_path( __FILE__ ) . 'lib/opengraph.php'; +} + add_action( 'rest_api_init', function() { \pterotype\api\register_routes(); } ); diff --git a/includes/lib/opengraph.php b/includes/lib/opengraph.php new file mode 100644 index 0000000..62ba87a --- /dev/null +++ b/includes/lib/opengraph.php @@ -0,0 +1,515 @@ + element. + * + * @uses apply_filters calls 'opengraph_prefixes' filter on RDFa prefix array + */ +function opengraph_add_prefix( $output ) { + $prefixes = array( + 'og' => 'http://ogp.me/ns#', + ); + $prefixes = apply_filters( 'opengraph_prefixes', $prefixes ); + + $prefix_str = ''; + foreach ( $prefixes as $k => $v ) { + $prefix_str .= $k . ': ' . $v . ' '; + } + $prefix_str = trim( $prefix_str ); + + if ( preg_match( '/(prefix\s*=\s*[\"|\'])/i', $output ) ) { + $output = preg_replace( '/(prefix\s*=\s*[\"|\'])/i', '${1}' . $prefix_str, $output ); + } else { + $output .= ' prefix="' . $prefix_str . '"'; + } + + return $output; +} +add_filter( 'language_attributes', 'opengraph_add_prefix' ); + + +/** + * Add additional prefix namespaces that are supported by the opengraph plugin. + */ +function opengraph_additional_prefixes( $prefixes ) { + if ( is_author() ) { + $prefixes['profile'] = 'http://ogp.me/ns/profile#'; + } + if ( is_singular() ) { + $prefixes['article'] = 'http://ogp.me/ns/article#'; + } + + return $prefixes; +} + + +/** + * Get the Open Graph metadata for the current page. + * + * @uses apply_filters() Calls 'opengraph_{$name}' for each property name + * @uses apply_filters() Calls 'twitter_{$name}' for each property name + * @uses apply_filters() Calls 'opengraph_metadata' before returning metadata array + */ +function opengraph_metadata() { + $metadata = array(); + + // defualt properties defined at http://ogp.me/ + $properties = array( + // required + 'title', + 'type', + 'image', + 'url', + + // optional + 'audio', + 'description', + 'determiner', + 'locale', + 'site_name', + 'video', + ); + + foreach ( $properties as $property ) { + $filter = 'opengraph_' . $property; + $metadata[ "og:$property" ] = apply_filters( $filter, '' ); + } + + $twitter_properties = array( 'card', 'creator' ); + + foreach ( $twitter_properties as $property ) { + $filter = 'twitter_' . $property; + $metadata[ "twitter:$property" ] = apply_filters( $filter, '' ); + } + + return apply_filters( 'opengraph_metadata', $metadata ); +} + + +/** + * Register filters for default Open Graph metadata. + */ +function opengraph_default_metadata() { + // core metadata attributes + add_filter( 'opengraph_title', 'opengraph_default_title', 5 ); + add_filter( 'opengraph_type', 'opengraph_default_type', 5 ); + add_filter( 'opengraph_image', 'opengraph_default_image', 5 ); + add_filter( 'opengraph_url', 'opengraph_default_url', 5 ); + + add_filter( 'opengraph_description', 'opengraph_default_description', 5 ); + add_filter( 'opengraph_locale', 'opengraph_default_locale', 5 ); + add_filter( 'opengraph_site_name', 'opengraph_default_sitename', 5 ); + + // additional prefixes + add_filter( 'opengraph_prefixes', 'opengraph_additional_prefixes' ); + + // additional profile metadata + add_filter( 'opengraph_metadata', 'opengraph_profile_metadata' ); + + // additional article metadata + add_filter( 'opengraph_metadata', 'opengraph_article_metadata' ); + + // twitter card metadata + add_filter( 'twitter_card', 'twitter_default_card', 5 ); + add_filter( 'twitter_creator', 'twitter_default_creator', 5 ); +} +add_action( 'wp', 'opengraph_default_metadata' ); + + +/** + * Default title property, using the page title. + */ +function opengraph_default_title( $title ) { + if ( $title ) { + return $title; + } + + if ( is_singular() ) { + $title = get_the_title( get_queried_object_id() ); + } else if ( is_author() ) { + $author = get_queried_object(); + $title = $author->display_name; + } else if ( is_category() && single_cat_title( '', false ) ) { + $title = single_cat_title( '', false ); + } else if ( is_tag() && single_tag_title( '', false ) ) { + $title = single_tag_title( '', false ); + } else if ( is_archive() && get_post_format() ) { + $title = get_post_format_string( get_post_format() ); + } else if ( is_archive() && function_exists( 'get_the_archive_title' ) && get_the_archive_title() ) { // new in version 4.1 to get all other archive titles + $title = get_the_archive_title(); + } + + return $title; +} + + +/** + * Default type property. + */ +function opengraph_default_type( $type ) { + if ( empty( $type ) ) { + if ( is_singular( array( 'post', 'page' ) ) ) { + $type = 'article'; + } else if ( is_author() ) { + $type = 'profile'; + } else { + $type = 'website'; + } + } + + return $type; +} + + +/** + * Default image property, using the post-thumbnail and any attached images. + */ +function opengraph_default_image( $image ) { + if ( $image ) { + return $image; + } + + // As of July 2014, Facebook seems to only let you select from the first 3 images + $max_images = apply_filters( 'opengraph_max_images', 3 ); + + // max images can't be negative or zero + if ( $max_images <= 0 ) { + $max_images = 1; + } + + if ( is_singular() ) { + $id = get_queried_object_id(); + $image_ids = array(); + + // list post thumbnail first if this post has one + if ( function_exists( 'has_post_thumbnail' ) && has_post_thumbnail( $id ) ) { + $image_ids[] = get_post_thumbnail_id( $id ); + $max_images--; + } + + // then list any image attachments + $query = new WP_Query( + array( + 'post_parent' => $id, + 'post_status' => 'inherit', + 'post_type' => 'attachment', + 'post_mime_type' => 'image', + 'order' => 'ASC', + 'orderby' => 'menu_order ID', + 'posts_per_page' => $max_images, + ) + ); + + foreach ( $query->get_posts() as $attachment ) { + if ( ! in_array( $attachment->ID, $image_ids ) ) { + $image_ids[] = $attachment->ID; + } + } + + // get URLs for each image + $image = array(); + foreach ( $image_ids as $id ) { + $thumbnail = wp_get_attachment_image_src( $id, 'full' ); + if ( $thumbnail ) { + $image[] = $thumbnail[0]; + } + } + } elseif ( is_attachment() && wp_attachment_is_image() ) { + $id = get_queried_object_id(); + $image = array( wp_get_attachment_url( $id ) ); + } + + if ( empty( $image ) ) { + $image = array(); + + // add site icon + if ( function_exists( 'get_site_icon_url' ) && has_site_icon() ) { + $image[] = get_site_icon_url( 512 ); + } + + // add header images + if ( function_exists( 'get_uploaded_header_images' ) ) { + if ( is_random_header_image() ) { + foreach ( get_uploaded_header_images() as $header_image ) { + $image[] = $header_image['url']; + + if ( sizeof( $image ) >= $max_images ) { + break; + } + } + } elseif ( get_header_image() ) { + $image[] = get_header_image(); + } + } + } + + return $image; +} + + +/** + * Default url property, using the permalink for the page. + */ +function opengraph_default_url( $url ) { + if ( empty( $url ) ) { + if ( is_singular() ) { + $url = get_permalink(); + } else if ( is_author() ) { + $url = get_author_posts_url( get_queried_object_id() ); + } + } + + return $url; +} + + +/** + * Default site_name property, using the bloginfo name. + */ +function opengraph_default_sitename( $name ) { + if ( empty( $name ) ) { + $name = get_bloginfo( 'name' ); + } + + return $name; +} + + +/** + * Default description property, using the excerpt or content for posts, or the + * bloginfo description. + */ +function opengraph_default_description( $description ) { + if ( $description ) { + return $description; + } + + if ( is_singular() ) { + $post = get_queried_object(); + if ( ! empty( $post->post_excerpt ) ) { + $description = $post->post_excerpt; + } else { + $description = $post->post_content; + } + } else if ( is_author() ) { + $id = get_queried_object_id(); + $description = get_user_meta( $id, 'description', true ); + } else if ( is_category() && category_description() ) { + $description = category_description(); + } else if ( is_tag() && tag_description() ) { + $description = tag_description(); + } else if ( is_archive() && function_exists( 'get_the_archive_description' ) && get_the_archive_description() ) { // new in version 4.1 to get all other archive descriptions + $description = get_the_archive_description(); + } else { + $description = get_bloginfo( 'description' ); + } + + // strip description to first 55 words. + $description = strip_tags( strip_shortcodes( $description ) ); + $description = __opengraph_trim_text( $description ); + + return $description; +} + + +/** + * Default locale property, using the WordPress locale. + */ +function opengraph_default_locale( $locale ) { + if ( empty( $locale ) ) { + $locale = get_locale(); + } + + return $locale; +} + + +/** + * Default twitter-card type. + */ +function twitter_default_card( $card ) { + if ( $card ) { + return $card; + } + + $card = 'summary'; + $images = apply_filters( 'opengraph_image', null ); + + if ( is_singular() && count( $images ) >= 1 ) { + $card = 'summary_large_image'; + } + + return $card; +} + + +/** + * Default twitter-card creator. + */ +function twitter_default_creator( $creator ) { + if ( $creator || ! is_singular() ) { + return $creator; + } + + $post = get_queried_object(); + $author = $post->post_author; + $twitter = get_the_author_meta( 'twitter', $author ); + + if ( ! $twitter ) { + return $creator; + } + + // check if twitter-account matches "http://twitter.com/username" + if ( preg_match( '/^http:\/\/twitter\.com\/(#!\/)?(\w+)/i', $twitter, $matches ) ) { + $creator = '@' . $matches[2]; + } elseif ( preg_match( '/^@?(\w+)$/i', $twitter, $matches ) ) { // check if twitter-account matches "(@)username" + $creator = '@' . $matches[1]; + } + + return $creator; +} + + +/** + * Output Open Graph tags in the page header. + */ +function opengraph_meta_tags() { + $metadata = opengraph_metadata(); + foreach ( $metadata as $key => $value ) { + if ( empty( $key ) || empty( $value ) ) { + continue; + } + $value = (array) $value; + + foreach ( $value as $v ) { + // check if "strict mode" is enabled + if ( OPENGRAPH_STRICT_MODE === false ) { + // use "property" and "name" + printf('' . PHP_EOL, + esc_attr( $key ), esc_attr( $v ) ); + } else { + // use "name" attribute for Twitter Cards + if ( stripos( $key, 'twitter:' ) === 0 ) { + printf( '' . PHP_EOL, + esc_attr( $key ), esc_attr( $v ) ); + } else { // use "property" attribute for Open Graph + printf( '' . PHP_EOL, + esc_attr( $key ), esc_attr( $v ) ); + } + } + } + } +} +add_action( 'wp_head', 'opengraph_meta_tags' ); + + +/** + * Include profile metadata for author pages. + * + * @link http://ogp.me/#type_profile + */ +function opengraph_profile_metadata( $metadata ) { + if ( is_author() ) { + $id = get_queried_object_id(); + $metadata['profile:first_name'] = get_the_author_meta( 'first_name', $id ); + $metadata['profile:last_name'] = get_the_author_meta( 'last_name', $id ); + $metadata['profile:username'] = get_the_author_meta( 'nicename', $id ); + } + + return $metadata; +} + + +/** + * Include article metadata for posts and pages. + * + * @link http://ogp.me/#type_article + */ +function opengraph_article_metadata( $metadata ) { + if ( ! is_singular() ) { + return $metadata; + } + + $post = get_queried_object(); + $author = $post->post_author; + + // check if page/post has tags + $tags = wp_get_object_terms( $post->ID, 'post_tag' ); + if ( $tags && is_array( $tags ) ) { + foreach ( $tags as $tag ) { + $metadata['article:tag'][] = $tag->name; + } + } + + // check if page/post has categories + $categories = wp_get_object_terms( $post->ID, 'category' ); + if ( $categories && is_array( $categories ) ) { + $metadata['article:section'][] = current( $categories )->name; + } + + $metadata['article:published_time'] = get_the_time( 'c', $post->ID ); + $metadata['article:modified_time'] = get_the_modified_time( 'c', $post->ID ); + $metadata['article:author'][] = get_author_posts_url( $author ); + + $facebook = get_the_author_meta( 'facebook', $author ); + + if ( ! empty( $facebook ) ) { + $metadata['article:author'][] = $facebook; + } + + return $metadata; +} + + +/** + * Add "twitter" as a contact method + */ +function opengraph_user_contactmethods( $user_contactmethods ) { + $user_contactmethods['twitter'] = __( 'Twitter', 'opengraph' ); + $user_contactmethods['facebook'] = __( 'Facebook (Profile URL)', 'opengraph' ); + + return $user_contactmethods; +} +add_filter( 'user_contactmethods', 'opengraph_user_contactmethods', 1 ); + + +/** + * Add 512x512 icon size + * + * @param array $sizes sizes available for the site icon + * @return array updated list of icons + */ +function opengraph_site_icon_image_sizes( $sizes ) { + $sizes[] = 512; + + return array_unique( $sizes ); +} +add_filter( 'site_icon_image_sizes', 'opengraph_site_icon_image_sizes' ); + + +/** + * Helper function to trim text using the same default values for length and + * 'more' text as wp_trim_excerpt. + */ +function __opengraph_trim_text( $text ) { + $excerpt_length = apply_filters( 'excerpt_length', 55 ); + $excerpt_more = apply_filters( 'excerpt_more', ' [...]' ); + + return wp_trim_words( $text, $excerpt_length, $excerpt_more ); +}