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);
 | |
| 	}
 | |
| } |