pics/templates/PhotosIndex.php

357 lines
7.8 KiB
PHP

<?php
/*****************************************************************************
* PhotosIndex.php
* Contains the project index template.
*
* Kabuki CMS (C) 2013-2015, Aaron van Geffen
*****************************************************************************/
class PhotosIndex extends Template
{
protected $mosaic;
protected $show_edit_buttons;
protected $show_headers;
protected $show_labels;
protected $previous_header = '';
protected $edit_menu_items = [];
protected $photo_url_suffix;
const PANORAMA_WIDTH = 1256;
const PANORAMA_HEIGHT = null;
const PORTRAIT_WIDTH = 387;
const PORTRAIT_HEIGHT = 628;
const LANDSCAPE_WIDTH = 822;
const LANDSCAPE_HEIGHT = 628;
const DUO_WIDTH = 604;
const DUO_HEIGHT = 403;
const SINGLE_WIDTH = 618;
const SINGLE_HEIGHT = 412;
const TILE_WIDTH = 387;
const TILE_HEIGHT = 290;
public function __construct(PhotoMosaic $mosaic, $show_edit_buttons = false, $show_labels = false, $show_headers = true)
{
$this->mosaic = $mosaic;
$this->show_edit_buttons = $show_edit_buttons;
$this->show_headers = $show_headers;
$this->show_labels = $show_labels;
}
public function html_main()
{
echo '
<div class="container photo-index">';
$i = 0;
while ($row = $this->mosaic->getRow())
{
[$photos, $what] = $row;
$this->header($photos);
$this->$what($photos, ($i++) % 2);
}
echo '
</div>
<script type="text/javascript" src="', BASEURL, '/js/albumnav.js"></script>';
}
protected function header($photos)
{
if (!$this->show_headers)
return;
$date = $photos[0]->getDateCaptured();
if (!$date)
return;
$header = $date->format('F Y');
if ($header === $this->previous_header)
return;
$name = str_replace(' ', '', strtolower($header));
echo '
<h4 class="tiled-header" id="', $name, '">
<a href="#', $name, '">', $header, '</a>
</h4>';
$this->previous_header = $header;
}
protected function editMenu(Image $image)
{
if (empty($this->edit_menu_items))
return;
echo '
<div class="edit dropdown">
<button class="btn btn-primary btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
</button>
<ul class="dropdown-menu">';
foreach ($this->edit_menu_items as $item)
{
echo '
<li><a class="dropdown-item" href="', $item['uri']($image), '"',
isset($item['onclick']) ? ' onclick="' . $item['onclick'] . '"' : '',
'>', $item['label'], '</a></li>';
}
echo '
</ul>
</div>';
}
protected function photo(Image $image, $className, $width, $height, $crop = true, $fit = true)
{
// Prefer thumbnail aspect ratio if available, otherwise use image aspect ratio.
$aspectRatio = isset($width, $height) ? $width / $height : $image->ratio();
echo '
<div class="polaroid ', $className, '" style="aspect-ratio: ', $aspectRatio, '">';
if ($this->show_edit_buttons && $image->canBeEditedBy(Registry::get('user')))
$this->editMenu($image);
echo '
<a href="', $image->getPageUrl(), $this->photo_url_suffix, '#photo_frame">';
foreach (['normal-photo', 'blur-photo'] as $className)
{
echo '
<img src="', $image->getThumbnailUrl($width, $height, $crop, $fit), '"';
// Can we offer double-density thumbs?
if ($image->width() >= $width * 2 && $image->height() >= $height * 2)
echo ' srcset="', $image->getThumbnailUrl($width * 2, $height * 2, $crop, $fit), ' 2x"';
else
echo ' srcset="', $image->getThumbnailUrl($image->width(), $image->height(), true), ' 2x"';
echo ' alt="" title="', $image->getTitle(), '" class="', $className, '" style="aspect-ratio: ', $aspectRatio, '">';
}
if ($this->show_labels)
echo '
<h4>', $image->getTitle(), '</h4>';
echo '
</a>
</div>';
}
protected function panorama(array $photos, $altLayout)
{
foreach ($photos as $image)
{
echo '
<div class="row mb-5 tile-panorama">
<div class="col">';
$this->photo($image, 'panorama', static::PANORAMA_WIDTH, static::PANORAMA_HEIGHT, false, false);
echo '
</div>
</div>';
}
}
protected function sixLandscapes(array $photos, $altLayout)
{
$chunks = array_chunk($photos, 3);
$this->sideLandscape($chunks[0], $altLayout);
$this->threeLandscapes($chunks[1], $altLayout);
}
protected function sidePortrait(array $photos, $altLayout)
{
$image = array_shift($photos);
echo '
<div class="row g-5 mb-5 tile-feat-portrait',
$altLayout ? ' flex-row-reverse' : '', '">
<div class="col-md-4">';
$this->photo($image, 'portrait', static::PORTRAIT_WIDTH, static::PORTRAIT_HEIGHT, 'centre');
echo '
</div>
<div class="col-md-8">
<div class="row g-5">';
foreach ($photos as $image)
{
echo '
<div class="col-md-6">';
$this->photo($image, 'landscape', static::TILE_WIDTH, static::TILE_HEIGHT, 'top');
echo '
</div>';
}
echo '
</div>
</div>
</div>';
}
protected function sideLandscape(array $photos, $altLayout)
{
$image = array_shift($photos);
echo '
<div class="row g-5 mb-5 tile-feat-landscape',
$altLayout ? ' flex-row-reverse' : '', '">
<div class="col-md-8">';
$this->photo($image, 'landscape', static::LANDSCAPE_WIDTH, static::LANDSCAPE_HEIGHT, 'top');
echo '
</div>
<div class="col-md-4">
<div class="row g-5">';
foreach ($photos as $image)
{
echo '
<div>';
$this->photo($image, 'landscape', static::TILE_WIDTH, static::TILE_HEIGHT, 'top');
echo '
</div>';
}
echo '
</div>
</div>
</div>';
}
protected function threeLandscapes(array $photos, $altLayout)
{
echo '
<div class="row g-5 mb-5 tile-row-landscapes">';
foreach ($photos as $image)
{
echo '
<div class="col-md-4">';
$this->photo($image, 'landscape', static::TILE_WIDTH, static::TILE_HEIGHT, true);
echo '
</div>';
}
echo '
</div>';
}
protected function threePortraits(array $photos, $altLayout)
{
echo '
<div class="row g-5 mb-5 tile-row-portraits">';
foreach ($photos as $image)
{
echo '
<div class="col-md-4">';
$this->photo($image, 'portrait', static::PORTRAIT_WIDTH, static::PORTRAIT_HEIGHT, true);
echo '
</div>';
}
echo '
</div>';
}
protected function dualLandscapes(array $photos, $altLayout)
{
echo '
<div class="row g-5 mb-5 tile-duo">';
foreach ($photos as $image)
{
echo '
<div class="col-md-6">';
$this->photo($image, 'duo', static::DUO_WIDTH, static::DUO_HEIGHT, true);
echo '
</div>';
}
echo '
</div>';
}
protected function dualMixed(array $photos, $altLayout)
{
echo '
<div class="row g-5 mb-5 tile-feat-landscape',
$altLayout ? ' flex-row-reverse' : '', '">
<div class="col-md-8">';
$image = array_shift($photos);
$this->photo($image, 'landscape', static::LANDSCAPE_WIDTH, static::LANDSCAPE_HEIGHT, 'top');
echo '
</div>
<div class="col-md-4">';
$image = array_shift($photos);
$this->photo($image, 'portrait', static::PORTRAIT_WIDTH, static::PORTRAIT_HEIGHT, true);
echo '
</div>
</div>
</div>';
}
protected function dualPortraits(array $photos, $altLayout)
{
// Recycle the row layout so portraits don't appear too large
$this->threePortraits($photos, $altLayout);
}
protected function singleLandscape(array $photos, $altLayout)
{
echo '
<div class="row g-5 mb-5 tile-single">
<div class="col-md-6">';
$image = array_shift($photos);
$this->photo($image, 'single', static::SINGLE_WIDTH, static::SINGLE_HEIGHT, 'top');
echo '
</div>
</div>';
}
protected function singlePortrait(array $photos, $altLayout)
{
// Recycle the row layout so portraits don't appear too large
$this->threePortraits($photos, $altLayout);
}
public function setEditMenuItems(array $items)
{
$this->edit_menu_items = $items;
}
public function setUrlSuffix($suffix)
{
$this->photo_url_suffix = $suffix;
}
}