Skip to content

Instantly share code, notes, and snippets.

@soderlind
Last active March 12, 2016 21:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save soderlind/573439391c4d18b5ffbd to your computer and use it in GitHub Desktop.
Save soderlind/573439391c4d18b5ffbd to your computer and use it in GitHub Desktop.
WordPress: Find the first image on a page in this order: Feature image, oembed image, image in post
<?php
class First_Page_Image {
private static $instance;
private static $post_ID = 0;
public static function instance() {
if ( self::$instance ) {
return self::$instance;
}
self::$instance = new self();
return self::$instance;
}
private function __construct() {
//add_image_size( 'opengraph-picture', 640, 480, true );
}
/**
* Find the first image on a page
* Priority:
* 1) Feature image
* 2) Oembed image
* 3) Image in post
*
* @param int $post_id The post ID
* @param string $post_content The Post content
* @param string $image_size Optional image size, default is 'thumbnail'
* @return array image data, array(url,width,height, bool resized), see https://codex.wordpress.org/Function_Reference/wp_get_attachment_image_src#Return_Value
*/
static function get_first_image_on_page($post_id, $post_content, $image_size = 'thumbnail') {
$image_data = array();
if (has_post_thumbnail($post_id)) {
if (false !== ($image_data = wp_get_attachment_image_src(get_post_thumbnail_id($post_id, 'thumbnail'),$image_size))) {
return $image_data;
}
} elseif (false !== ( $oembed_url = self::get_first_oembed_url($post_content)) ) {
$oembed_data = get_transient( md5($oembed_url) );
if ( empty( $oembed_data ) ) {
$oembed_url_host = parse_url($oembed_url, PHP_URL_HOST);
$oembed_content_url = sprintf("%s://%s/oembed?format=json&url=%s",
(is_ssl()) ? 'https' : 'http',
$oembed_url_host,
$oembed_url
);
$response = wp_remote_request( $oembed_content_url, array(
'method' => 'GET',
'timeout' => 5,
'sslverify' => false,
));
if ( ! is_wp_error( $response ) ) {
$oembed_data = json_decode( wp_remote_retrieve_body($response), true);
set_transient( md5($oembed_url), $oembed_data, DAY_IN_SECONDS ); // https://codex.wordpress.org/Transients_API#Using_Time_Constants
}
}
if (false !== $oembed_data) {
$image_data = array(
$oembed_data['thumbnail_url'],
$oembed_data['width'],
$oembed_data['height'],
0
);
}
} else {
/**
* search through content for images
*/
$doc = new DOMDocument();
// start libxml error managent
// modify state
$libxml_previous_state = libxml_use_internal_errors(true);
@$doc->loadHTML($post_content);
// handle errors
libxml_clear_errors();
// restore
libxml_use_internal_errors($libxml_previous_state);
// end libxml error management
$images = $doc->getElementsByTagName('img');
foreach ($images as $img) {
$url = $img->getAttribute('src');
if ( false !== ($attchment_id = self::get_attachment_id_from_url($url)) ) {
if (false !== ($image_data = wp_get_attachment_image_src($attchment_id,$image_size))) {
return $image_data;
}
}
}
}
return $image_data;
}
/**
* Find the first oembed native url in a post
* @param string $post_content The post content
* @return bool|string return false if no url is found, otherwise return the url
*/
static function get_first_oembed_url($post_content) {
require_once( ABSPATH . WPINC . '/class-oembed.php' );
$wp_oembed = _wp_oembed_get_object();
$urls = wp_extract_urls( $post_content );
foreach( (array) $urls as $url ) {
$oembed_url_host = parse_url($url, PHP_URL_HOST);
$self_url_host = parse_url(get_bloginfo( 'url') , PHP_URL_HOST);
$site_url_host = parse_url( get_site_option( 'siteurl', $self_url_host), PHP_URL_HOST);
if ( false === in_array($oembed_url_host, array( $self_url_host, $site_url_host) ) ) { // don't oembed yourself
if ( false !== ($provider_url = $wp_oembed->get_provider( $url ) ) ) {
return $url;
}
}
}
return false;
}
/**
* Find all the oembed native url in a post
* @param string $post_content The post content
* @return array An array with all the urls found
*/
static function get_all_oembed_urls($post_content) {
require_once( ABSPATH . WPINC . '/class-oembed.php' );
$wp_oembed = _wp_oembed_get_object();
$urls = wp_extract_urls( $post_content );
$oembed_urls = array();
foreach( (array) $urls as $url ) {
if( $wp_oembed->get_provider( $url ) ) {
$oembed_urls[] = $url;
}
}
return array_unique($oembed_urls);
}
// from https://philipnewcomer.net/2012/11/get-the-attachment-id-from-an-image-url-in-wordpress/
private static function get_attachment_id_from_url( $attachment_url = '' ) {
global $wpdb;
$attachment_id = false;
// If there is no url, return.
if ( '' == $attachment_url )
return;
// Get the upload directory paths
$upload_dir_paths = wp_upload_dir();
// Make sure the upload path base directory exists in the attachment URL, to verify that we're working with a media library image
if ( false !== strpos( $attachment_url, $upload_dir_paths['baseurl'] ) ) {
// If this is the URL of an auto-generated thumbnail, get the URL of the original image
$attachment_url = preg_replace( '/-\d+x\d+(?=\.(jpg|jpeg|png|gif)$)/i', '', $attachment_url );
// Remove the upload path base directory from the attachment URL
$attachment_url = str_replace( $upload_dir_paths['baseurl'] . '/', '', $attachment_url );
// Finally, run a custom database query to get the attachment ID from the modified attachment URL
$attachment_id = $wpdb->get_var( $wpdb->prepare( "SELECT wposts.ID FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta WHERE wposts.ID = wpostmeta.post_id AND wpostmeta.meta_key = '_wp_attached_file' AND wpostmeta.meta_value = '%s' AND wposts.post_type = 'attachment'", $attachment_url ) );
}
return $attachment_id;
}
} //class First_Page_Image
<?php
require_once ('class.first-page-image.php');
//initiate the class
if ( defined( 'ABSPATH' ) ) {
First_Page_Image::instance();
}
$image_data = First_Page_Image::get_first_image_on_page( $post->ID, $post->post_content );
list( $image_url, $image_width, $image_height, $image_is_resized) = $image_data;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment