Current path: home/fresvfqn/emergencywaterdamagemanhattan.com/wp-content/plugins/surerank/inc/frontend/
⬆️ Go up: inc
<?php
/**
* Image Meta Data
*
* Handles functionality to retrieve and manage image metadata for frontend requests,
* particularly for Open Graph image tags.
*
* @package surerank
* @since 0.0.1
*/
namespace SureRank\Inc\Frontend;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use SureRank\Inc\Functions\Settings;
use SureRank\Inc\Meta_Variables\Post;
use SureRank\Inc\Traits\Get_Instance;
/**
* Image Meta Data Handler
*
* Manages image metadata retrieval for frontend requests, optimized for Open Graph tags.
*
* @since 0.0.1
*/
class Image {
use Get_Instance;
/**
* Cache for image data
*
* @var array<string, string|null>
*/
private $image_cache = [];
/**
* Retrieves Open Graph image URL based on page type
*
* @return string|null OG image URL or null if none found
* @since 1.0.0
*/
public function get_og_image() {
if ( post_password_required() ) {
return null;
}
if ( ! get_queried_object_id() ) {
return null;
}
$cache_key = md5( (string) wp_json_encode( get_queried_object_id() ) );
if ( isset( $this->image_cache[ $cache_key ] ) ) {
return $this->image_cache[ $cache_key ];
}
$image_url = null;
if ( is_singular() ) {
$image_url = $this->get_singular_page_image();
} elseif ( is_tax() || is_category() || is_tag() ) {
$image_url = $this->get_taxonomy_image();
}
$this->image_cache[ $cache_key ] = $image_url;
return $image_url;
}
/**
* Get attachment ID by URL
*
* @param string $url Image URL.
* @return int Attachment ID or 0 if not found
* @since 1.0.0
*/
public function attachment_by_url( $url ) {
$attachment_id = attachment_url_to_postid( $url );
return (int) $attachment_id;
}
/**
* Prepare fallback image
*
* @param array<string, mixed> $meta_data Meta Data.
* @param string $key Meta key to populate.
* @since 1.0.0
* @return void
*/
public function get( &$meta_data, $key ) {
$fallback_image = Settings::get( 'fallback_image' );
if ( ! empty( $meta_data[ $key ] ) ) {
return;
}
if ( $this->get_og_image() ) {
$meta_data[ $key ] = $this->get_og_image();
} else {
$meta_data[ $key ] = $fallback_image;
}
}
/**
* Retrieves taxonomy page image
*
* @param int|null $term_id The term ID.
* @return string|null Taxonomy image URL or null if none found
* @since 1.0.0
*/
public function get_taxonomy_image( $term_id = null ) {
$term_description = '';
if ( ! $term_id ) {
$term_description = term_description();
} else {
$term_data = get_term( $term_id );
if ( $term_data ) {
$term_description = $term_data->description ?? '';
}
}
if ( ! $term_description ) {
return null;
}
return $this->get_first_content_image( $term_description );
}
/**
* Retrieves singular page image
*
* @param int|null $post_id The post ID.
* @return string|null Singular page image URL or null if none found
* @since 1.0.0
*/
public function get_singular_page_image( $post_id = null ) {
if ( ! $post_id ) {
$post_id = get_queried_object_id();
}
if ( ! $post_id ) {
return null;
}
$post_instance = Post::get_instance();
$post_instance->set_post( $post_id );
$content = $post_instance->get_content();
return $content ? $this->get_first_content_image( $content ) : null;
}
/**
* Extracts first valid image from content
*
* @param string $content The content to search.
* @return string|null Image URL or null if none found
* @since 1.0.0
*/
private function get_first_content_image( string $content ) {
if ( empty( $content ) || strpos( $content, '<img' ) === false ) {
return null;
}
if ( ! preg_match( '/<img\s+[^>]*?src=["\']([^"\']+)["\']/i', $content, $match ) ) {
return null;
}
$src = trim( $match[1] );
if ( empty( $src ) ) {
return null;
}
$absolute_url = $this->ensure_absolute_url( $src );
$image_data = $this->get_image_data_by_url( $absolute_url );
return $image_data && $this->is_valid_og_image( $image_data ) ? $image_data['url'] : null;
}
/**
* Gets image data by attachment ID
*
* @param int $attachment_id The attachment ID.
* @return array<string, mixed>|null Image data array or null if invalid
* @since 1.0.0
*/
private function get_image_data_by_id( int $attachment_id ) {
if ( ! wp_attachment_is_image( $attachment_id ) ) {
return null;
}
$image = wp_get_attachment_image_src( $attachment_id, 'large' );
if ( ! $image ) {
return null;
}
[$url, $width, $height] = $image;
return [
'id' => $attachment_id,
'url' => $url,
'width' => $width,
'height' => $height,
'type' => get_post_mime_type( $attachment_id ),
'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ?? '',
];
}
/**
* Gets image data by URL
*
* @param string $url Image URL.
* @return array<string, mixed>|null Image data array or null if invalid
* @since 1.0.0
*/
private function get_image_data_by_url( string $url ) {
$url = filter_var( $url, FILTER_VALIDATE_URL ) ? $url : null;
if ( ! $url ) {
return null;
}
$attachment_id = $this->attachment_by_url( $url );
if ( $attachment_id > 0 ) {
return $this->get_image_data_by_id( $attachment_id );
}
if ( ! $this->is_valid_image_extension( $url ) ) {
return null;
}
return [ 'url' => $url ];
}
/**
* Validates image for Open Graph use
*
* @param array<string, mixed> $image_data Image data to validate.
* @return bool Whether image meets OG requirements
* @since 1.0.0
*/
private function is_valid_og_image( array $image_data ) {
if ( empty( $image_data['url'] ) || ! $this->is_valid_image_extension( $image_data['url'] ) ) {
return false;
}
if ( isset( $image_data['width'] ) && isset( $image_data['height'] ) ) {
return $image_data['width'] >= apply_filters( 'surerank_og_dimensions_min_width', 200 ) &&
$image_data['height'] >= apply_filters( 'surerank_og_dimensions_min_height', 200 ) &&
$image_data['width'] <= apply_filters( 'surerank_og_dimensions_max_width', 2000 ) &&
$image_data['height'] <= apply_filters( 'surerank_og_dimensions_max_height', 2000 );
}
return true;
}
/**
* Validates image file extension
*
* @param string $url Image URL.
* @return bool Whether extension is valid
* @since 1.0.0
*/
private function is_valid_image_extension( string $url ) {
$valid_extensions = [ 'jpg', 'jpeg', 'png', 'gif', 'webp' ];
$extension = strtolower( pathinfo( $url, PATHINFO_EXTENSION ) );
return ! empty( $extension ) && in_array( $extension, $valid_extensions, true );
}
/**
* Ensures URL is absolute
*
* @param string $url Input URL.
* @return string Absolute URL
* @since 1.0.0
*/
private function ensure_absolute_url( string $url ): string {
if ( empty( $url ) ) {
return '';
}
$sanitized_url = filter_var( $url, FILTER_SANITIZE_URL );
if ( ! $sanitized_url ) {
return '';
}
return filter_var( $sanitized_url, FILTER_VALIDATE_URL ) ? $sanitized_url : home_url( $sanitized_url );
}
}