@@ -0,0 +1,405 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This class renders the html for the event avatar.
|
||||
*
|
||||
* @author Time.ly Network Inc.
|
||||
* @since 2.0
|
||||
*
|
||||
* @package AI1EC
|
||||
* @subpackage AI1EC.View.Event
|
||||
*/
|
||||
class Ai1ec_View_Event_Avatar extends Ai1ec_Base {
|
||||
|
||||
/**
|
||||
* Get HTML markup for the post's "avatar" image according conditional
|
||||
* fallback model.
|
||||
*
|
||||
* Accepts an ordered array of named avatar $fallbacks. Also accepts a string
|
||||
* of space-separated classes to add to the default classes.
|
||||
* @param Ai1ec_Event $event The event to get the avatar for
|
||||
* @param array|null $fallback_order Order of fallback in searching for
|
||||
* images, or null to use default
|
||||
* @param string $classes A space-separated list of CSS classes
|
||||
* to apply to the outer <div> element.
|
||||
* @param boolean $wrap_permalink Whether to wrap the element in a link
|
||||
* to the event details page.
|
||||
*
|
||||
* @return string String of HTML if image is found
|
||||
*/
|
||||
public function get_event_avatar(
|
||||
Ai1ec_Event $event,
|
||||
$fallback_order = null,
|
||||
$classes = '',
|
||||
$wrap_permalink = true
|
||||
) {
|
||||
$source = $size = null;
|
||||
$url = $this->get_event_avatar_url(
|
||||
$event,
|
||||
$fallback_order,
|
||||
$source,
|
||||
$size
|
||||
);
|
||||
|
||||
if ( empty( $url ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$url = esc_attr( $url );
|
||||
$classes = esc_attr( $classes );
|
||||
|
||||
// Set the alt tag (helpful for SEO).
|
||||
$alt = $event->get( 'post' )->post_title;
|
||||
$location = $this->_registry->get( 'view.event.location' )->get_short_location( $event );
|
||||
if ( ! empty( $location ) ) {
|
||||
$alt .= ' @ ' . $location;
|
||||
}
|
||||
|
||||
$alt = esc_attr( $alt );
|
||||
$size_attr = $size[0] ? "width=\"$size[0]\" height=\"$size[1]\"" : "";
|
||||
$html = '<img src="' . $url . '" alt="' . $alt . '" ' .
|
||||
$size_attr . ' />';
|
||||
|
||||
if ( $wrap_permalink ) {
|
||||
$permalink = add_query_arg(
|
||||
'instance_id',
|
||||
$event->get( 'instance_id' ),
|
||||
get_permalink( $event->get( 'post_id' ) )
|
||||
);
|
||||
$html = '<a href="' . $permalink . '">' . $html . '</a>';
|
||||
}
|
||||
|
||||
$classes .= ' ai1ec-' . $source;
|
||||
$classes .= ( $size[0] > $size[1] )
|
||||
? ' ai1ec-landscape'
|
||||
: ' ai1ec-portrait';
|
||||
$html = '<div class="ai1ec-event-avatar timely ' . $classes . '">' .
|
||||
$html . '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post's "avatar" image url according conditional fallback model.
|
||||
*
|
||||
* Accepts an ordered array of named methods for $fallback order. Returns
|
||||
* image URL or null if no image found. Also returns matching fallback in the
|
||||
* $source reference.
|
||||
*
|
||||
* @param array|null $fallback_order Order of fallbacks in search for images
|
||||
* @param null $source Fallback that returned matching image,
|
||||
* returned format is string
|
||||
* @param null $size (width, height) array of returned image
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_event_avatar_url(
|
||||
Ai1ec_Event $event,
|
||||
$fallback_order = null,
|
||||
&$source = null,
|
||||
&$size = null
|
||||
) {
|
||||
if ( empty( $fallback_order ) ) {
|
||||
$fallback_order = array(
|
||||
'post_thumbnail',
|
||||
'content_img',
|
||||
'category_avatar',
|
||||
'default_avatar',
|
||||
);
|
||||
}
|
||||
|
||||
$valid_fallbacks = $this->_get_valid_fallbacks();
|
||||
|
||||
foreach ( $fallback_order as $fallback ) {
|
||||
if ( ! isset( $valid_fallbacks[$fallback] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$function = $valid_fallbacks[$fallback];
|
||||
$url = null;
|
||||
if (
|
||||
! is_array( $function ) &&
|
||||
method_exists( $this, $function )
|
||||
) {
|
||||
$url = $this->$function( $event, $size );
|
||||
} else if ( is_callable( $function ) ) {
|
||||
$url = call_user_func_array( $function, array( $event, &$size ) );
|
||||
}
|
||||
if ( null !== $url ) {
|
||||
$source = $fallback;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $url ) ) {
|
||||
return null;
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read post meta for post-thumbnail and return its URL as a string.
|
||||
*
|
||||
* @param Ai1ec_Event $event Event object.
|
||||
* @param null $size (width, height) array of returned image.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_post_thumbnail_url( Ai1ec_Event $event, &$size = null ) {
|
||||
return $this->_get_post_attachment_url(
|
||||
$event,
|
||||
array(
|
||||
'medium',
|
||||
'large',
|
||||
'full',
|
||||
),
|
||||
$size
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read post meta for post-image and return its URL as a string.
|
||||
*
|
||||
* @param Ai1ec_Event $event Event object.
|
||||
* @param null $size (width, height) array of returned image.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_post_image_url( Ai1ec_Event $event, &$size = null ) {
|
||||
return $this->_get_post_attachment_url(
|
||||
$event,
|
||||
array(
|
||||
'full',
|
||||
'large',
|
||||
'medium'
|
||||
),
|
||||
$size
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read post meta for featured image and return its URL as a string.
|
||||
*
|
||||
* @param Ai1ec_Event $event Event object.
|
||||
* @param null $size (width, height) array of returned image.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_featured_image_url( Ai1ec_Event $event, &$size = null ) {
|
||||
$featured_image = get_post_meta( $event->get( 'post_id' ) , '_featured_image', true );
|
||||
if ( empty( $featured_image ) ) {
|
||||
return $this->_get_post_attachment_url(
|
||||
$event,
|
||||
array(
|
||||
'full',
|
||||
'large',
|
||||
'medium'
|
||||
),
|
||||
$size
|
||||
);
|
||||
} else {
|
||||
$priority_order = array( 'large', 'full', 'medium', 'thumbnail' );
|
||||
$url = null;
|
||||
foreach ( $priority_order as $priority ) {
|
||||
foreach ( $featured_image as $values_arr ) {
|
||||
if ( $values_arr[0] === $priority ) {
|
||||
$url = $values_arr[1];
|
||||
$size = array( $values_arr[2], $values_arr[3] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( null !== $url ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the avatar url from the event content
|
||||
*/
|
||||
public function remove_avatar_url( $content ) {
|
||||
return preg_replace( '/<div[^<>]+class=[\'"]?ai1ec-event-avatar[^<>]*[\'"]?[^<>]+>.+<\/div>[.\s]*/'
|
||||
, ''
|
||||
, $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple regex-parse of post_content for matches of <img src="foo" />; if
|
||||
* one is found, return its URL.
|
||||
*
|
||||
* @param Ai1ec_Event $event
|
||||
* @param null $size (width, height) array of returned image
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_content_img_url( Ai1ec_Event $event, &$size = null ) {
|
||||
$matches = $this->get_image_from_content(
|
||||
$event->get( 'post' )->post_content
|
||||
);
|
||||
// Check if we have a result, otherwise a notice is issued.
|
||||
if ( empty( $matches ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$url = $matches[2];
|
||||
$size = array( 0, 0 );
|
||||
|
||||
// Try to detect width and height.
|
||||
$attrs = $matches[1] . $matches[3];
|
||||
$matches = null;
|
||||
preg_match_all(
|
||||
'/(width|height)=["\']?(\d+)/i',
|
||||
$attrs,
|
||||
$matches,
|
||||
PREG_SET_ORDER
|
||||
);
|
||||
// Check if we have a result, otherwise a notice is issued.
|
||||
if ( ! empty( $matches ) ) {
|
||||
foreach ( $matches as $match ) {
|
||||
$size[ $match[1] === 'width' ? 0 : 1 ] = $match[2];
|
||||
}
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an image tag from an html string
|
||||
*
|
||||
* @param string $content
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_image_from_content( $content ) {
|
||||
preg_match(
|
||||
'/<img([^>]+)src=["\']?([^"\'\ >]+)([^>]*)>/i',
|
||||
$content,
|
||||
$matches
|
||||
);
|
||||
return $matches;
|
||||
}
|
||||
/**
|
||||
* Returns default avatar image (normally when no other ones are available).
|
||||
*
|
||||
* @param null $size (width, height) array of returned image
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_default_avatar_url( &$size = null ) {
|
||||
$loader = $this->_registry->get( 'theme.loader' );
|
||||
$file = $loader->get_file( 'default-event-avatar.png', array(), false );
|
||||
$size = array( 256, 256 );
|
||||
return $file->get_url();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns avatar image for event's deepest category, if any.
|
||||
*
|
||||
* @param Ai1ec_Event $event Avatar requester.
|
||||
* @param void $size Unused argument.
|
||||
*
|
||||
* @return string|null Avatar's HTML or null if none.
|
||||
*/
|
||||
public function get_category_avatar_url( Ai1ec_Event $event, &$size = null ) {
|
||||
$db = $this->_registry->get( 'dbi.dbi' );
|
||||
|
||||
$terms = $this->_registry->get( 'model.taxonomy' )->get_post_categories(
|
||||
$event->get( 'post_id' )
|
||||
);
|
||||
if ( empty( $terms ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$terms_by_id = array();
|
||||
// Key $terms by term_id rather than arbitrary int.
|
||||
foreach ( $terms as $term ) {
|
||||
$terms_by_id[$term->term_id] = $term;
|
||||
}
|
||||
|
||||
// Array to store term depths, sorted later.
|
||||
$term_depths = array();
|
||||
foreach ( $terms_by_id as $term ) {
|
||||
$depth = 0;
|
||||
$ancestor = $term;
|
||||
while ( ! empty( $ancestor->parent ) ) {
|
||||
$depth++;
|
||||
if ( ! isset( $terms_by_id[$ancestor->parent] ) ) {
|
||||
break;
|
||||
}
|
||||
$ancestor = $terms_by_id[$ancestor->parent];
|
||||
}
|
||||
// Store negative depths for asort() to order from deepest to shallowest.
|
||||
$term_depths[$term->term_id] = -$depth;
|
||||
}
|
||||
// Order term IDs by depth.
|
||||
asort( $term_depths );
|
||||
|
||||
$url = '';
|
||||
$model = $this->_registry->get( 'model.taxonomy' );
|
||||
// Starting at deepest depth, find the first category that has an avatar.
|
||||
foreach ( $term_depths as $term_id => $depth ) {
|
||||
$term_image = $model->get_category_image( $term_id );
|
||||
if ( $term_image ) {
|
||||
$url = $term_image;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return empty( $url ) ? null : $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read post meta for post-attachment and return its URL as a string.
|
||||
*
|
||||
* @param Ai1ec_Event $event Event object.
|
||||
* @param array $ordered_img_sizes Image sizes order.
|
||||
* @param null $size (width, height) array of returned
|
||||
* image.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function _get_post_attachment_url(
|
||||
Ai1ec_Event $event,
|
||||
array $ordered_img_sizes,
|
||||
&$size = null
|
||||
) {
|
||||
// Since WP does will return null if the wrong size is targeted,
|
||||
// we iterate over an array of sizes, breaking if a URL is found.
|
||||
foreach ( $ordered_img_sizes as $size ) {
|
||||
$attributes = wp_get_attachment_image_src(
|
||||
get_post_thumbnail_id( $event->get( 'post_id' ) ), $size
|
||||
);
|
||||
if ( $attributes ) {
|
||||
$url = array_shift( $attributes );
|
||||
$size = $attributes;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return empty( $url ) ? null : $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of valid fallbacks.
|
||||
*
|
||||
* @return array List of valid fallbacks.
|
||||
*/
|
||||
protected function _get_valid_fallbacks() {
|
||||
static $fallbacks;
|
||||
if ( null === $fallbacks ) {
|
||||
$fallbacks = apply_filters(
|
||||
'ai1ec_avatar_valid_callbacks',
|
||||
array(
|
||||
'post_image' => 'get_post_image_url',
|
||||
'post_thumbnail' => 'get_post_thumbnail_url',
|
||||
'content_img' => 'get_content_img_url',
|
||||
'category_avatar' => 'get_category_avatar_url',
|
||||
'default_avatar' => 'get_default_avatar_url',
|
||||
'featured_image' => 'get_featured_image_url'
|
||||
)
|
||||
);
|
||||
}
|
||||
return $fallbacks;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user