__( 'Close', '3pika-gallery' ), 'prev' => __( 'Previous', '3pika-gallery' ), 'next' => __( 'Next', '3pika-gallery' ), 'zoom' => __( 'Zoom', '3pika-gallery' ), 'play' => __( 'Start slideshow', '3pika-gallery' ), 'pause' => __( 'Pause slideshow', '3pika-gallery' ), 'fullscreen' => __( 'Fullscreen', '3pika-gallery' ), 'share' => __( 'Share', '3pika-gallery' ), 'download' => __( 'Download', '3pika-gallery' ), 'copyLink' => __( 'Copy link', '3pika-gallery' ), 'copied' => __( 'Link copied', '3pika-gallery' ), 'visitLink' => __( 'Visit link', '3pika-gallery' ), 'page' => __( 'Page', '3pika-gallery' ), 'prevPage' => __( 'Previous page', '3pika-gallery' ), 'nextPage' => __( 'Next page', '3pika-gallery' ), ) ); $global = TPIKA_Settings::get(); if ( ! empty( $global['load_assets_global'] ) ) { add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue' ) ); } } public static function enqueue() { wp_enqueue_style( 'tpika-gallery' ); wp_enqueue_script( 'tpika-gallery' ); } /** * Render a gallery. * * @param int $id Gallery ID. * @param array $args Overrides (columns, layout, filter, pagination, per_page, hover, gap, aspect, ...). * @return string */ public static function render( $id, $args = array() ) { $id = absint( $id ); $g = TPIKA_Post_Type::get( $id ); if ( ! $g ) { return current_user_can( 'edit_posts' ) ? '

' . esc_html__( '3pika Gallery: gallery not found.', '3pika-gallery' ) . '

' : ''; } $s = $g['settings']; $override_keys = array( 'layout', 'columns', 'columns_tablet', 'columns_mobile', 'gap', 'radius', 'aspect', 'hover', 'hover_icon', 'caption', 'pagination', 'per_page', 'filter_style', 'filter_size', 'filter_align', 'filters_show', 'lightbox', 'order' ); foreach ( $override_keys as $k ) { if ( isset( $args[ $k ] ) && '' !== $args[ $k ] && null !== $args[ $k ] ) { $s[ $k ] = $args[ $k ]; } } if ( ! empty( $args['filter'] ) ) { $s['filter_default'] = sanitize_key( $args['filter'] ); } $s = TPIKA_Settings::sanitize( $s, $g['settings'] ); // Labels left at their English default follow the site language. if ( 'All' === $s['filter_all_label'] ) { $s['filter_all_label'] = __( 'All', '3pika-gallery' ); } if ( 'Load more' === $s['loadmore_label'] ) { $s['loadmore_label'] = __( 'Load more', '3pika-gallery' ); } $s = apply_filters( 'tpika_gallery_settings', $s, $id, $args ); $filters = $g['filters']; $images = $g['images']; $filter_ids = wp_list_pluck( $filters, 'id' ); // Default filter may be given as an ID or as the filter name (e.g. shortcode filter="Nature"). if ( '' !== $s['filter_default'] && ! in_array( $s['filter_default'], $filter_ids, true ) ) { $wanted = sanitize_title( isset( $args['filter'] ) ? $args['filter'] : $s['filter_default'] ); $s['filter_default'] = ''; foreach ( $filters as $f ) { if ( sanitize_title( $f['name'] ) === $wanted ) { $s['filter_default'] = $f['id']; break; } } } $images = self::sort_images( $images, $s['order'] ); $counts = array_fill_keys( $filter_ids, 0 ); $items = array(); foreach ( $images as $index => $img ) { $item = self::build_item( $img, $index, $s, $filter_ids ); if ( ! $item ) { continue; } foreach ( $item['filters'] as $f ) { $counts[ $f ]++; } $items[] = $item; } self::$counter++; $uid = 'tpg-' . $id . '-' . self::$counter; list( $cd, $ct, $cm ) = TPIKA_Settings::resolve_columns( $s ); $radius = (int) $s['radius'] . 'px'; if ( ! empty( $s['radius_corners'] ) && preg_match( '/^\d+ \d+ \d+ \d+$/', $s['radius_corners'] ) ) { $radius = implode( 'px ', explode( ' ', $s['radius_corners'] ) ) . 'px'; // top-left top-right bottom-right bottom-left } $style_vars = sprintf( '--tpg-cols:%d;--tpg-cols-t:%d;--tpg-cols-m:%d;--tpg-gap:%dpx;--tpg-radius:%s;--tpg-accent:%s;--tpg-accent-text:%s;', $cd, $ct, $cm, (int) $s['gap'], $radius, $s['accent'], tpika_contrast_color( $s['accent'] ) ); $classes = array( 'tpg-gallery', 'tpg-layout-' . $s['layout'], 'tpg-hover-' . $s['hover'], 'tpg-caption-' . $s['caption'], 'tpg-aspect-' . $s['aspect'], 'tpg-filters-' . $s['filter_style'], 'tpg-fsize-' . $s['filter_size'], 'tpg-fm-' . $s['filter_mobile'], 'tpg-align-' . $s['filter_align'], ); if ( ! empty( $s['filter_shadow'] ) ) { $classes[] = 'tpg-filter-shadow'; } $hover_icon_html = ''; if ( ! empty( $s['hover_icon'] ) && 'none' !== $s['hover_icon'] ) { $classes[] = 'tpg-has-hicon'; $hover_icon_html = ''; } if ( ! $s['lightbox'] ) { $classes[] = 'tpg-no-lightbox'; } $watermark_html = ''; $js = array( 'id' => $uid, 'layout' => $s['layout'], 'pagination' => $s['pagination'], 'perPage' => (int) $s['per_page'], 'loadmore' => $s['loadmore_label'], 'filterDefault' => in_array( $s['filter_default'], $filter_ids, true ) ? $s['filter_default'] : '', 'lightbox' => (bool) $s['lightbox'], 'lb' => array( 'counter' => (bool) $s['lb_counter'], 'caption' => (bool) $s['lb_caption'], ), ); self::enqueue(); $template = locate_template( array( '3pika-gallery/gallery.php' ) ); if ( ! $template ) { $template = TPIKA_PATH . 'templates/gallery.php'; } $gallery = $g; $custom_css = ''; // Kept for templates copied from an earlier version; the CSS is added below. ob_start(); include $template; $html = apply_filters( 'tpika_gallery_html', ob_get_clean(), $id, $s ); return $html; } /** * Sort images according to the "order" setting. * * @param array $images Stored images (custom order). * @param string $order Order key. * @return array */ private static function sort_images( $images, $order ) { if ( 'random' === $order ) { shuffle( $images ); return $images; } if ( ! in_array( $order, array( 'date_desc', 'date_asc', 'caption_asc', 'caption_desc', 'file_asc', 'file_desc' ), true ) ) { return $images; } $keyed = array(); foreach ( $images as $i => $img ) { $att = ! empty( $img['id'] ) ? (int) $img['id'] : 0; $key = ''; if ( 0 === strpos( $order, 'date' ) ) { $key = $att ? (string) get_post_field( 'post_date_gmt', $att ) : '9999'; } elseif ( 0 === strpos( $order, 'caption' ) ) { $key = isset( $img['caption'] ) ? $img['caption'] : ''; } else { $file = $att ? get_attached_file( $att ) : ''; $key = $file ? wp_basename( $file ) : ( isset( $img['url'] ) ? $img['url'] : '' ); } $keyed[] = array( 'k' => mb_strtolower( (string) $key ), 'i' => $i, 'img' => $img ); } $desc = '_desc' === substr( $order, -5 ); usort( $keyed, function ( $a, $b ) use ( $desc ) { $c = strnatcmp( $a['k'], $b['k'] ); if ( 0 === $c ) { $c = $a['i'] - $b['i']; } return $desc ? -$c : $c; } ); return wp_list_pluck( $keyed, 'img' ); } /** * Build a renderable item. * * @param array $img Stored image. * @param int $index Index. * @param array $s Settings. * @param array $filter_ids Allowed filters. * @return array|null */ private static function build_item( $img, $index, $s, $filter_ids ) { $item = array( 'index' => $index, 'type' => 'image', 'filters' => isset( $img['filters'] ) && is_array( $img['filters'] ) ? array_values( array_intersect( $img['filters'], $filter_ids ) ) : array(), 'caption' => isset( $img['caption'] ) ? $img['caption'] : '', 'alt' => isset( $img['alt'] ) ? $img['alt'] : '', 'link' => isset( $img['link'] ) ? $img['link'] : '', 'thumb' => '', 'srcset' => '', 'sizes' => '', 'w' => 0, 'h' => 0, 'full' => '', 'video' => null, ); $att = ! empty( $img['id'] ) ? (int) $img['id'] : 0; if ( ! $att ) { return null; } $src = wp_get_attachment_image_src( $att, $s['image_size'] ); if ( ! $src ) { return null; } $item['thumb'] = $src[0]; $item['w'] = (int) $src[1]; $item['h'] = (int) $src[2]; $item['full'] = wp_get_attachment_image_url( $att, 'full' ); $srcset = wp_get_attachment_image_srcset( $att, $s['image_size'] ); $item['srcset'] = $srcset ? $srcset : ''; $sizes = $srcset ? wp_get_attachment_image_sizes( $att, $s['image_size'] ) : ''; $item['sizes'] = $sizes ? $sizes : ''; if ( '' === $item['alt'] ) { $item['alt'] = (string) get_post_meta( $att, '_wp_attachment_image_alt', true ); } if ( '' === $item['alt'] ) { $item['alt'] = $item['caption']; } return $item; } }