diff --git a/Demo.php b/Demo.php index c43c8b2..1d944da 100644 --- a/Demo.php +++ b/Demo.php @@ -75,6 +75,7 @@ public function action__template_redirect() : void { $this->picsum(); $this->unsplash(); $this->placeholder(); + $this->placehold(); $this->url(); $this->fallback(); @@ -297,8 +298,32 @@ protected function placeholder() : void { $this->output( $image, ob_get_clean() ); } + protected function placehold() : void { + $image = \Image_Tag::create( 'placehold', array( + 'width' => 1000, + 'height' => 350, + ), array( + 'text' => 'Placehold.co \n FTW', + 'retina' => 2, + ) ); + + ob_start(); + ?> + +\Image_Tag::create( 'placehold', array( + 'width' => 1000, + 'height' => 350, +), array( + 'text' => 'Placehold.co \n FTW', + 'retina' => 2, +) ); + + output( $image, ob_get_clean() ); + } + protected function url() { - $url = get_theme_file_uri( 'assets/images/playing-in-the-sand.jpg' ); + $url = 'https://placehold.co/982x1424@2x.png'; $image = \Image_Tag::create( $url, array( 'width' => 982, @@ -327,7 +352,7 @@ protected function fallback() { 'image-sizes' => 'full', 'fallback' => array( 'joeschmoe' => ! empty( $_GET['person'] ), - 'placeholder' => current_user_can( 'edit_post', get_queried_object_id() ), + 'placehold' => current_user_can( 'edit_post', get_queried_object_id() ), 'picsum' => true ), ) ); diff --git a/includes/abstracts/Base.php b/includes/abstracts/Base.php index cb6c44b..6164c71 100644 --- a/includes/abstracts/Base.php +++ b/includes/abstracts/Base.php @@ -559,6 +559,32 @@ public function placeholder( $attributes = null, $settings = null ) : \Image_Tag return $created; } + /** + * Convert to Placehold.co image. + * + * @param null|mixed[]|Attributes $attributes + * @param null|mixed[]|Settings $settings + * @uses $this->is_type() + * @return \Image_Tag\Types\Placehold + */ + public function placehold( $attributes = null, $settings = null ) : \Image_Tag\Types\Placehold { + if ( is_a( $this, \Image_Tag\Types\Placehold::class ) ) { + trigger_error( sprintf( 'Image is already type %s', $this->get_type() ) ); + return $this; + } + + $attributes = wp_parse_args( ( array ) $attributes, $this->attributes->store ); + $settings = wp_parse_args( ( array ) $settings, $this->settings->store ); + + $created = Image_Tag::create( 'placehold', $attributes, $settings ); + + if ( ! is_a( $created, \Image_Tag\Types\Placehold::class ) ) { + return new \Image_Tag\Types\Placehold; + } + + return $created; + } + /** * Convert to Unsplash Source photo. * diff --git a/includes/types/Image_Tag.php b/includes/types/Image_Tag.php index b5c846b..3488c64 100644 --- a/includes/types/Image_Tag.php +++ b/includes/types/Image_Tag.php @@ -58,6 +58,11 @@ public static function create( $source, $attributes = null, $settings = null ) : return new Image_Tag\Types\Picsum( $attributes, $settings ); } + if ( 'placehold' === $_source ) { + require_once Plugin::inc() . 'types/Placehold.php'; + return new Image_Tag\Types\Placehold( $attributes, $settings ); + } + if ( 'placeholder' === $_source ) { require_once Plugin::inc() . 'types/Placeholder.php'; return new Image_Tag\Types\Placeholder( $attributes, $settings ); diff --git a/includes/types/Placehold.php b/includes/types/Placehold.php new file mode 100644 index 0000000..89c4d9d --- /dev/null +++ b/includes/types/Placehold.php @@ -0,0 +1,240 @@ +construct() + */ + public function __construct( $attributes = null, $settings = null ) { + $this->construct( $attributes, $settings ); + } + + /** + * Create Attributes object to use for output. + * + * @uses Base::output_attributes() + * @uses $this->generate_source() + * @return Attributes + */ + protected function output_attributes() : Attributes { + $attributes = parent::output_attributes(); + $dimensions = array(); + + $attributes->update( 'src', $this->generate_source() ); + + # Width + if ( $this->settings->has( 'width' ) ) { + $dimensions[] = $this->settings->get( 'width' ); + } else if ( $this->attributes->has( 'width' ) ) { + $dimensions[] = $this->attributes->get( 'width' ); + } + + # Height + if ( $this->settings->has( 'height' ) ) { + $dimensions[] = $this->settings->get( 'height' ); + } else if ( $this->attributes->has( 'height' ) ) { + $dimensions[] = $this->attributes->get( 'height' ); + } + + if ( 1 === count( $dimensions ) ) { + $dimensions[] = $dimensions[0]; + } + + if ( ! $attributes->has( 'width' ) && ! empty( $dimensions[0] ) ) { + $attributes->set( 'width', $dimensions[0] ); + } + + if ( ! $attributes->has( 'height' ) && ! empty( $dimensions[1] ) ) { + $attributes->set( 'height', $dimensions[1] ); + } + + return $attributes; + } + + /** + * Generate image source. + * + * @uses Settings::has() + * @uses Settings::get() + * @uses Attributes::has() + * @uses Attributes::get() + * @return string + */ + public function generate_source() : string { + if ( array_key_exists( __FUNCTION__, $this->cache ) ) { + return $this->cache[ __FUNCTION__ ]; + } + + $dimensions = array(); + $src = array( static::BASE_URL ); + + # Width + if ( $this->settings->has( 'width' ) ) { + $dimensions[] = $this->settings->get( 'width' ); + } else if ( $this->attributes->has( 'width' ) ) { + $dimensions[] = $this->attributes->get( 'width' ); + } + + # Height + if ( $this->settings->has( 'height' ) ) { + $dimensions[] = $this->settings->get( 'height' ); + } else if ( $this->attributes->has( 'height' ) ) { + $dimensions[] = $this->attributes->get( 'height' ); + } + + if ( 1 === count( $dimensions ) ) { + $dimensions[] = $dimensions[0]; + } + + $dimensions = implode( 'x', $dimensions ); + + # Retina + if ( $this->settings->has( 'retina' ) ) { + $retina = absint( $this->settings->get( 'retina' ) ); + $dimensions .= sprintf( '@%sx', $retina ); + } + + $src[] = $dimensions; + + # Colors + if ( $this->settings->has( 'bg_color' ) && $this->settings->has( 'text_color' ) ) { + $src[] = $this->settings->get( 'bg_color' ); + $src[] = $this->settings->get( 'text_color' ); + } + + # Format + if ( $this->settings->has( 'format' ) ) { + $src[] = $this->settings->get( 'format' ); + } + + # Convert to string + $src = implode( '/', $src ); + + # Custom text + if ( $this->settings->has( 'text' ) ) { + $src = add_query_arg( 'text', urlencode( $this->settings->get( 'text' ) ), $src ); + } + + $this->cache[ __FUNCTION__ ] = $src; + + return $src; + } + + /** + * Get ratio of image dimensions: width divided by height. + * + * @return float + */ + public function ratio() : float { + $width = 0; + $height = 0; + + if ( $this->settings->has( 'width', false ) ) { + $width = $this->settings->get( 'width' ); + } else if ( $this->attributes->has( 'width', false ) ) { + $width = $this->attributes->get( 'width' ); + } + + if ( $this->settings->has( 'height', false ) ) { + $height = $this->settings->get( 'height' ); + } else if ( $this->attributes->has( 'height', false ) ) { + $height = $this->attributes->get( 'height' ); + } + + if ( empty( $height ) ) { + $height = $width; + } + + if ( empty( $width ) ) { + $width = $height; + } + + if ( empty( $height ) ) { + return 0; + } + + return absint( $width ) / absint( $height ); + } + + /** + * Perform validation checks. + * + * @uses $this->validate_dimensions() + * @return \WP_Error + */ + protected function perform_validation_checks() : \WP_Error { + $errors = new \WP_Error; + + try { + $this->validate_dimensions(); + } catch ( \Exception $e ) { + $errors->add( 'placehold', $e->getMessage() ); + } + + return $errors; + } + + /** + * Check that at least one dimension is set. + * + * @uses Settings::has() + * @uses Attributes::has() + * @return void + */ + protected function validate_dimensions() : void { + if ( + $this->settings->has( 'width', false ) + || $this->settings->has( 'height', false ) + || $this->attributes->has( 'width', false ) + || $this->attributes->has( 'height', false ) + ) { + return; + } + + throw new \Exception( 'Placehold requires at least one dimension.' ); + } + + /** + * Prevent conversion to same type. + * + * @param null|mixed[]|Attributes $attributes + * @param null|mixed[]|Settings $settings + * @return self + */ + public function placehold( $attributes = null, $settings = null ) : self { + trigger_error( sprintf( 'Image is already type %s', $this->get_type() ) ); + return $this; + } + +}