A PHP class used to generate an tag, specifically for use within WordPress sites (uploaded images, theme images, and external images) and the awesome lazysizes script (but not necessary).
<?php
// !!! ALPHA VERSION !!!
// !!! ALPHA VERSION !!!
// !!! ALPHA VERSION !!!
// !!! NOT FOR PRODUCTION USE !!!
// !!! USE LATEST STABLE v0.0.3.1:
// https://gist.github.com/crstauf/030df6bd6c436620e96cb92a44c9772f/e671037f46d8262357bbcef53581ac8235044e56
// https://gist.github.com/crstauf/030df6bd6c436620e96cb92a44c9772f
if (!defined('ABSPATH') || !function_exists('add_filter')) {
header( 'Status: 403 Forbidden' );
header( 'HTTP/1.1 403 Forbidden' );
exit();
}
class image_tag {
const VERSION = '0.0.4-alpha';
const DATAURI = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
protected $args = array();
var $attributes = array(
'id' => '',
'alt' => '',
'src' => '',
'sizes' => '',
'title' => '',
'width' => 0,
'height' => 0,
'srcset' => array(),
'class' => array(),
),
$echo = true,
$noscript = true,
$lazyload = true,
$lazypreload = false,
$noscript_sizes = array();
protected $files = array(
'__smallest' => array(
'width' => 9999999,
'height' => 9999999,
'url' => ''
),
'__largest' => array(
'width' => 0,
'height' => 0,
'url' => '',
),
);
protected $orientation = ''; // portrait|landscape
function __construct() {
if ( !is_subclass_of( $this, 'image_tag' ) ) {
$args = func_get_arg( 0 );
if ( array_key_exists( 'attachment_id', $args ) )
$source = $args['attachment_id'];
else if ( array_key_exists( 'source', $args ) )
$source = $args['source'];
else if ( array_key_exists( 'theme_image', $args ) )
$source = $args['theme_image'];
else
return false;
$args['attributes']['class']['old-generated'] = 'old-generated-image-tag';
unset(
$args['attachment_id'],
$args['source'],
$args['theme_image']
);
if (
array_key_exists( 'echo', $args )
&& false === $args['echo']
)
return image_tag( $source, $args );
else
echo image_tag( $source, $args );
}
add_filter( 'image-tag/noscript/attributes/glue', array( &$this, 'filter_image_tag_noscript_attributes_glue' ) );
if ( is_array( $this->args ) && count( $this->args ) )
foreach ( $this->args as $key => $value )
if ( isset( $this->$key ) )
$this->$key = $value;
$this->attributes['class']['generated'] = 'generated-image-tag';
$this->gather_files();
$this->determine_orientation();
$this->being_lazy();
}
function __toString() {
if ( !$this->echo )
return '';
ksort( $this->attributes );
$image_output = $this->image_output();
if ( !$this->noscript )
return implode( "\n", $image_output );
$this->noscript_prep();
return implode( "\n", array_filter( $image_output ) ) . implode( "\n", array_filter( $this->noscript_image_output() ) );
}
function image_output() {
$output = array( 'open' => "\n<img " );
foreach ( $this->attributes as $attr_name => $attr_value ) {
$attr_value = apply_filters( 'image-tag/attributes/value', $attr_value, $attr_name, $this );
$attr_value = apply_filters( 'image-tag/attributes/' . $attr_name . '/value', $attr_value, $this );
$output[$attr_name] = $this->construct_attribute( $attr_name, $attr_value );
if ( '' === trim( $output[$attr_name] ) )
unset( $output[$attr_name] );
}
$output['close'] = "/>\n";
return array_filter( $output );
}
function noscript_prep() {
$this->attributes['class']['noscript'] = 'noscript';
$this->attributes['class']['post-noscript'] = $this->attributes['class']['post'] . '-noscript';
if ( !empty( $this->attributes['id'] ) )
$this->attributes['id'] .= '-noscript';
if ( array_key_exists( 'data-sizes', $this->attributes ) )
$this->attributes['sizes'] = $this->attributes['data-sizes'];
if ( array_key_exists( 'data-src', $this->attributes ) && self::DATAURI !== $this->attributes['data-src'] )
$this->attributes['src'] = $this->attributes['data-src'];
if ( 'auto' === $this->attributes['sizes'] ) {
if ( !empty( $this->noscript_sizes ) && is_array( $this->noscript_sizes ) && count( $this->noscript_sizes ) ) {
$this->attributes['sizes'] = $this->noscript_sizes;
if ( array_key_exists( 'data-srcset', $this->attributes ) )
$this->attributes['srcset'] = $this->attributes['data-srcset'];
} else {
$this->attributes['src'] = $this->files['__largest']['url'];
unset( $this->attributes['sizes'] );
}
}
unset(
$this->attributes['class']['lazyload'],
$this->attributes['class']['lazypreload'],
$this->attribtues['data-src'],
$this->attributes['data-sizes'],
$this->attributes['data-srcset']
);
}
function noscript_image_output() {
$output = array(
'open_noscript' => '<noscript>',
'open_img' => "\t<img",
);
foreach ( $this->attributes as $attr_name => $attr_value ) {
$attr_value = apply_filters( 'image-tag/noscript/attributes/value', $attr_value, $attr_name, $this );
$attr_value = apply_filters( 'image-tag/noscript/attributes/' . $attr_name . '/value', $attr_value, $this );
$output[$attr_name] = "\t" . $this->construct_attribute( $attr_name, $attr_value, true );
if ( '' === trim( $output[$attr_name] ) )
unset( $output[$attr_name] );
}
$output['close_img'] = "\n\t/>";
$output['close_noscript'] = "</noscript>\n";
return array_filter( $output );
}
function construct_attribute( $attr_name, $attr_value, $noscript = false ) {
if ( !is_array( $attr_value ) ) {
if ( !empty( $attr_value ) && ( '' !== trim( $attr_value ) || 'alt' === $attr_name ) )
return "\t" . $attr_name . '="' . esc_attr( $attr_value ) . '" ';
return false;
}
if ( false !== strpos( $attr_name, 'srcset' ) && count( $attr_value ) )
foreach ( $attr_value as $w => $url )
$attr_value[$w] = $url . ' ' . $w;
switch ( $attr_name ) {
case 'sizes':
case 'srcset':
case 'data-srcset':
$glue = ",\n\t\t";
break;
case 'class':
default:
$glue = ' ';
break;
}
$glue = apply_filters( 'image-tag/' . ( $noscript ? 'noscript/' : '' ) . 'attributes/glue', $glue, $attr_name, $this );
$glue = apply_filters( 'image-tag/' . ( $noscript ? 'noscript/' : '' ) . 'attributes/' . $attr_name . '/glue', $glue, $this );
foreach ( $attr_value as $i => $maybe_array )
if ( is_array( $maybe_array ) )
$attr_value[$i] = implode( $glue, $maybe_array );
return "\t" . $attr_name . '="' . implode( $glue, $attr_value ) . '" ';
}
function filter_image_tag_noscript_attributes_glue( $glue ) {
if ( ' ' === $glue )
return ' ';
return $glue . "\t";
}
function determine_orientation() {
$largest = &$this->files['__largest'];
if ( $largest['width'] > $largest['height'] )
$this->orientation = 'landscape';
else if ( $largest['width'] < $largest['height'] )
$this->orientation = 'portrait';
else if ( $largest['width'] === $largest['height'] )
$this->orientation = 'square';
else
$this->orientation = false;
$this->attributes['class']['orientation'] = 'orientation-' .
( false === $this->orientation
? 'unknown'
: $this->orientation
);
}
function gather_files() {}
function being_lazy() {
if ( !$this->lazyload && !$this->lazypreload )
return false;
if ( $this->lazypreload )
$this->attributes['class']['lazypreload'] = 'lazypreload';
if ( !$this->lazyload )
return false;
$this->attributes['data-sizes'] = 'auto';
$this->attributes['class']['lazyload'] = 'lazyload';
$this->attributes['src'] = self::DATAURI;
$this->attributes['data-src' . ( count( $this->files ) > 3 ? 'set' : '' )] = $this->attributes['srcset'];
unset( $this->attributes['srcset'] );
return true;
}
}
/*
## ## ####### ######## ######## ######## ######## ######## ###### ######
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ######## ## ## ######## ######## ###### ###### ######
## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
### ### ####### ## ## ######## ## ## ## ######## ###### ######
*/
class image_tag_wp_attachment extends image_tag {
var $id = 0,
$post = null,
$image_sizes = array( 'thumbnail', 'medium', 'medium_large', 'large', 'full' );
function __construct() {
$this->args = func_get_arg( 0 );
parent::__construct();
$this->get_post();
if (
false === $this->post
|| is_wp_error( $this->post )
)
return;
$this->attributes['class']['post'] = 'post-' . $this->id;
}
function noscript_prep() {
parent::noscript_prep();
if ( !empty( $this->attributes['sizes'] ) || !empty( $this->noscript_sizes ) )
return;
$largest = $this->files['__largest'];
foreach ( $this->files as $size => $file ) {
if ( in_array( $size, array( '__largest', '__smallest' ) ) )
continue;
if ( $file['url'] === $largest['url'] ) {
$this->attributes['class']['WP-size'] = 'size-' . $size;
break;
}
}
}
function get_post() {
$this->post = get_post( $this->id );
if ( '' === $this->attributes['alt'] )
$this->attributes['alt'] = esc_attr( get_the_title( $this->post ) );
if ( '' === $this->attributes['title'] )
$this->attributes['title'] = esc_attr( get_the_title( $this->post ) );
}
function gather_files() {
foreach ( $this->image_sizes as $i => $image_size ) {
$this->attributes['class']['WP-size'][$image_size] = 'size-' . $image_size;
$img = wp_get_attachment_image_src( $this->id, $image_size );
if ( 0 === $i ) {
$this->attributes['src'] = $img[0];
$this->attributes['width'] = $img[1];
$this->attributes['height'] = $img[2];
}
$this->files[$image_size] = array(
'width' => $img[1],
'height' => $img[2],
'url' => $img[0],
);
$this->attributes['srcset'][$img[1] . 'w'] = $img[0];
if ( $this->files['__largest']['width'] < $img[1] )
$this->files['__largest'] = &$this->files[$image_size];
if ( $this->files['__smallest']['width'] > $img[1] )
$this->files['__smallest'] = &$this->files[$image_size];
}
$this->files['__largest']['ratio'] = ( $this->files['__largest']['height'] / $this->files['__largest']['width'] ) * 100;
}
}
/*
## ## ######## ##
## ## ## ## ##
## ## ## ## ##
## ## ######## ##
## ## ## ## ##
## ## ## ## ##
####### ## ## ########
*/
class image_tag_uri extends image_tag {
function __construct() {
parent::__construct();
}
function gather_files() {
}
}
function image_tag( $source, $args = false ) {
if ( false === $args )
$args = array();
if ( is_int( $source ) ) {
$args['id'] = $source;
return new image_tag_wp_attachment( $args );
} else if (
false !== stripos( 'http://', $source )
|| false !== stripos( 'https://', $source )
)
$args['source'] = $source;
else if ( apply_filters( 'image-tag/enable-theme-images', defined( 'THEME_IMAGES_URI' ) ) )
$args['source'] = apply_filters( 'image-tag/theme-images-uri', THEME_IMAGES_URI ) . $source;
return new image_tag_uri( $args );
}