Last active
May 22, 2019 14:18
-
-
Save EricBusch/96dfe2ffb8fa6840793f3d2b1e1e9dbd to your computer and use it in GitHub Desktop.
Replaces any placeholder images with hotlinked image from merchant's server. [dfrpswc][datafeedr]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Class Mycode_Replace_Missing_Images_With_External_Images | |
* | |
* Replaces any placeholder images with hotlinked image from merchant's server. | |
* | |
* @since 1.0.0 | |
*/ | |
class Mycode_Replace_Missing_Images_With_External_Images { | |
private $css_class = 'dfr-external-image'; | |
private $max_width = '300px'; | |
private $max_height = '300px'; | |
private $image_fields = [ 'image', 'thumbnail' ]; | |
public function init() { | |
add_action( 'wp_head', [ $this, 'add_css' ] ); | |
add_filter( 'woocommerce_product_get_image', [ $this, 'get_image_tag_for_loop' ], 100, 2 ); | |
add_filter( 'woocommerce_placeholder_img_src', [ $this, 'replace_placeholder_img_src' ], 20, 1 ); | |
} | |
/** | |
* Add CSS to <head> element to handle clipping and sizing of external images. | |
* | |
* @link https://stackoverflow.com/a/51447865/2489248 | |
*/ | |
function add_css() { | |
echo '<style type="text/css">'; | |
echo 'ul.products .' . $this->css_class . ' {position:relative;width:100%;margin-bottom:22.652px;} '; | |
echo 'ul.products .' . $this->css_class . ':after {content:"";display:block;padding-bottom:100%;} '; | |
echo 'ul.products .' . $this->css_class . ' img {position:absolute;top:0;bottom:0;left:0;right:0;width:100%;height:100%;object-fit:cover;object-position:center;max-width:' . $this->max_width . ';}'; | |
echo '</style>'; | |
} | |
/** | |
* Replace placeholder <img> tags inside WC Loop with <img> tag with src attribute | |
* of product's external image URL. | |
* | |
* @param string $image HTML string containing the full <img> tag markup. | |
* @param WC_Product $product | |
* | |
* @return string | |
*/ | |
function get_image_tag_for_loop( $image, $product ) { | |
if ( ! preg_match( "/woocommerce-placeholder/i", $image ) ) { | |
return $image; | |
} | |
if ( empty( $dfr_product = dfrps_product( $product->get_id() ) ) ) { | |
return $image; | |
} | |
if ( ! $src = $this->get_external_image_src( $dfr_product ) ) { | |
return $image; | |
} | |
$attributes = []; | |
$attributes['width'] = absint( $this->max_width ); | |
$attributes['height'] = absint( $this->max_height ); | |
$attributes['src'] = esc_url( $src ); | |
$attributes['class'] = 'attachment-woocommerce_thumbnail size-woocommerce_thumbnail'; | |
$attributes['alt'] = esc_attr( $product->get_name() ); | |
$format = '<div class="%1$s"><img %2$s /></div>'; | |
return sprintf( $format, esc_attr( $this->css_class ), implode( ' ', array_map( function ( $k, $v ) { | |
return $k . '="' . $v . '"'; | |
}, array_keys( $attributes ), $attributes ) ) ); | |
} | |
/** | |
* Replace URL of placeholder image with the URL from the "image" field to | |
* hotlink the product image direct from merchant's server. | |
* | |
* @param string $src URL of default WooCommerce placeholder image. | |
* | |
* @return string URL The URL of the product image from the merchant's server. | |
*/ | |
function replace_placeholder_img_src( $src ) { | |
/** @var WC_Product $product */ | |
global $product; | |
if ( ! is_product() ) { | |
return $src; | |
} | |
if ( ! is_subclass_of( $product, 'WC_Product' ) ) { | |
return $src; | |
} | |
if ( empty( $dfr_product = dfrps_product( $product->get_id() ) ) ) { | |
return $src; | |
} | |
if ( $external_src = $this->get_external_image_src( $dfr_product ) ) { | |
$src = $external_src; | |
} | |
return $src; | |
} | |
/** | |
* Returns the first occurrence of an image field for the Datafeedr product | |
* or false if no image fields are found. | |
* | |
* @param array $product A full Datafeedr product array. | |
* | |
* @return bool|string | |
*/ | |
private function get_external_image_src( $product ) { | |
foreach ( $this->image_fields as $field ) { | |
if ( isset( $product[ $field ] ) && $this->starts_with( $product[ $field ], [ 'http', '//' ] ) ) { | |
return $product[ $field ]; | |
} | |
} | |
return false; | |
} | |
/** | |
* Determine if a given string starts with a given substring. | |
* | |
* @param string $haystack | |
* @param string|array $needles | |
* | |
* @return bool | |
*/ | |
private function starts_with( $haystack, $needles ) { | |
foreach ( (array) $needles as $needle ) { | |
if ( $needle !== '' && substr( $haystack, 0, strlen( $needle ) ) === (string) $needle ) { | |
return true; | |
} | |
} | |
return false; | |
} | |
} | |
( new Mycode_Replace_Missing_Images_With_External_Images() )->init(); | |
// EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment