292 lines
6.4 KiB
PHP
292 lines
6.4 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @author Tassos Marinos <info@tassos.gr>
|
|
* @link https://www.tassos.gr
|
|
* @copyright Copyright © 2024 Tassos All Rights Reserved
|
|
* @license GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later
|
|
*/
|
|
|
|
namespace NRFramework\Widgets;
|
|
|
|
defined('_JEXEC') or die;
|
|
|
|
use \NRFramework\Helpers\Widgets\Gallery as GalleryHelper;
|
|
use NRFramework\Mimes;
|
|
use NRFramework\File;
|
|
use NRFramework\Image;
|
|
use Joomla\CMS\Factory;
|
|
|
|
class Slideshow extends Widget
|
|
{
|
|
/**
|
|
* Widget default options
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $widget_options = [
|
|
// Slides per view
|
|
'slides_per_view' => [
|
|
'desktop' => 1
|
|
],
|
|
|
|
// Space between slides in px
|
|
'space_between_slides' => [
|
|
'desktop' => 10
|
|
],
|
|
|
|
// Enable Infinite Loop
|
|
'infinite_loop' => false,
|
|
|
|
// Enable Keyboard Control
|
|
'keyboard_control' => false,
|
|
|
|
/**
|
|
* Set the ordering.
|
|
*
|
|
* Available values:
|
|
* - default
|
|
* - alphabetical
|
|
* - reverse_alphabetical
|
|
* - random
|
|
*/
|
|
'ordering' => 'default',
|
|
|
|
/**
|
|
* The transition effect.
|
|
*
|
|
* Available values:
|
|
* - slide
|
|
* - fade
|
|
* - cube
|
|
* - coverflow
|
|
* - flip
|
|
*/
|
|
'transition_effect' => 'slide',
|
|
|
|
// Enable Autoplay
|
|
'autoplay' => false,
|
|
|
|
// Autoplay delay
|
|
'autoplay_delay' => 3000,
|
|
|
|
// Enable autoplay circular progress
|
|
'autoplay_progress' => false,
|
|
|
|
// Show thumbnails below the slideshow
|
|
'show_thumbnails' => false,
|
|
|
|
// Set whether to show arrows in the thumbnails slider
|
|
'show_thumbnails_arrows' => false,
|
|
|
|
/**
|
|
* Navigation controls.
|
|
*
|
|
* Accepted values:
|
|
* - arrows
|
|
* - dots
|
|
* - arrows_dots
|
|
*/
|
|
'nav_controls' => false,
|
|
|
|
// Theme color
|
|
'theme_color' => '#007aff',
|
|
|
|
// Set whether to display a lightbox
|
|
'lightbox' => false,
|
|
|
|
// Set the module key to display whenever we are viewing a single item's lightbox, appearing after the image
|
|
'module' => '',
|
|
|
|
// Options
|
|
'options' => []
|
|
];
|
|
|
|
public function __construct($options = [])
|
|
{
|
|
parent::__construct($options);
|
|
|
|
$this->prepare();
|
|
|
|
$this->prepareItems();
|
|
|
|
$this->setOrdering();
|
|
|
|
$this->setCSSVars();
|
|
}
|
|
|
|
private function prepare()
|
|
{
|
|
if ($this->options['lightbox'])
|
|
{
|
|
$this->options['css_class'] .= ' lightbox';
|
|
}
|
|
|
|
$options = [
|
|
'transition_effect' => $this->options['transition_effect'],
|
|
'infinite_loop' => $this->options['infinite_loop'],
|
|
'keyboard_control' => $this->options['keyboard_control'],
|
|
'autoplay' => $this->options['autoplay'],
|
|
'autoplay_delay' => $this->options['autoplay_delay'],
|
|
'autoplay_progress' => $this->options['autoplay_progress'],
|
|
'show_thumbnails' => $this->options['show_thumbnails'],
|
|
'show_thumbnails_arrows' => $this->options['show_thumbnails_arrows'],
|
|
'lightbox' => $this->options['lightbox'],
|
|
'breakpoints' => \NRFramework\Helpers\Responsive::getBreakpointsSettings(),
|
|
'slides_per_view' => $this->options['slides_per_view'],
|
|
'space_between_slides' => $this->getSpaceBetweenSlides(),
|
|
'nav_controls' => $this->options['nav_controls']
|
|
];
|
|
|
|
$this->options['options'] = $options;
|
|
}
|
|
|
|
private function getSpaceBetweenSlides()
|
|
{
|
|
$space_between_slides = $this->options['space_between_slides'];
|
|
|
|
if (is_array($space_between_slides))
|
|
{
|
|
foreach ($space_between_slides as $key => &$value)
|
|
{
|
|
$value = \NRFramework\Helpers\Controls\Control::getCSSValue($value['value']);
|
|
}
|
|
}
|
|
|
|
return $space_between_slides;
|
|
}
|
|
|
|
/**
|
|
* Prepares the items.
|
|
*
|
|
* - Sets the thumbnails image dimensions.
|
|
* - Assures caption property exist.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
private function prepareItems()
|
|
{
|
|
if (!is_array($this->options['items']) || !count($this->options['items']))
|
|
{
|
|
return;
|
|
}
|
|
|
|
$smartTagsInstance = \NRFramework\SmartTags::getInstance();
|
|
|
|
foreach ($this->options['items'] as $key => &$item)
|
|
{
|
|
// Initialize image atts
|
|
$item['img_atts'] = '';
|
|
|
|
// Initializes caption if none given
|
|
if (!isset($item['caption']))
|
|
{
|
|
$item['caption'] = '';
|
|
}
|
|
|
|
if (!isset($item['alt']) || empty($item['alt']))
|
|
{
|
|
$item['alt'] = !empty($item['caption']) ? mb_substr($item['caption'], 0, 100) : pathinfo($item['url'], PATHINFO_FILENAME);
|
|
}
|
|
|
|
// Replace Smart Tags in alt
|
|
$item['alt'] = $smartTagsInstance->replace($item['alt']);
|
|
|
|
// Ensure a thumbnail is given
|
|
if (!isset($item['thumbnail_url']))
|
|
{
|
|
// If no thumbnail is given, set it to the full image
|
|
$item['thumbnail_url'] = $item['url'];
|
|
continue;
|
|
}
|
|
|
|
// If the thumbnail size for this item is given, set the image attributes
|
|
if (isset($item['thumbnail_size']))
|
|
{
|
|
$item['img_atts'] = 'width="' . $item['thumbnail_size']['width'] . '" height="' . $item['thumbnail_size']['height'] . '"';
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the ordering of the gallery.
|
|
*
|
|
* @return void
|
|
*/
|
|
private function setOrdering()
|
|
{
|
|
switch ($this->options['ordering']) {
|
|
case 'random':
|
|
shuffle($this->options['items']);
|
|
break;
|
|
case 'alphabetical':
|
|
usort($this->options['items'], [$this, 'compareByThumbnailASC']);
|
|
break;
|
|
case 'reverse_alphabetical':
|
|
usort($this->options['items'], [$this, 'compareByThumbnailDESC']);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Compares thumbnail file names in ASC order
|
|
*
|
|
* @param array $a
|
|
* @param array $b
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function compareByThumbnailASC($a, $b)
|
|
{
|
|
return strcmp(basename($a['thumbnail']), basename($b['thumbnail']));
|
|
}
|
|
|
|
/**
|
|
* Compares thumbnail file names in DESC order
|
|
*
|
|
* @param array $a
|
|
* @param array $b
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function compareByThumbnailDESC($a, $b)
|
|
{
|
|
return strcmp(basename($b['thumbnail']), basename($a['thumbnail']));
|
|
}
|
|
|
|
/**
|
|
* Sets the CSS variables.
|
|
*
|
|
* @return void
|
|
*/
|
|
private function setCSSVars()
|
|
{
|
|
if (!$this->options['load_css_vars'])
|
|
{
|
|
return;
|
|
}
|
|
|
|
$controls = [
|
|
[
|
|
'property' => '--slideshow-slides-per-view',
|
|
'value' => $this->options['slides_per_view']
|
|
],
|
|
[
|
|
'property' => '--slideshow-space-between-slides',
|
|
'value' => $this->options['space_between_slides']
|
|
]
|
|
];
|
|
|
|
$selector = '.nrf-widget.tf-slideshow-wrapper.' . $this->options['id'];
|
|
|
|
$controlsInstance = new \NRFramework\Controls\Controls(null, $selector);
|
|
|
|
if (!$controlsCSS = $controlsInstance->generateCSS($controls))
|
|
{
|
|
return;
|
|
}
|
|
|
|
Factory::getDocument()->addStyleDeclaration($controlsCSS);
|
|
}
|
|
} |