Your IP : 216.73.216.248


Current Path : /home/digilove/www/41423/
Upload File :
Current File : /home/digilove/www/41423/Slider.tar

FeatureManager.php000064400000014364152356644430010167 0ustar00<?php


namespace Nextend\SmartSlider3\Slider;


use Nextend\Framework\Asset\Predefined;
use Nextend\SmartSlider3\Renderable\AbstractRenderable;
use Nextend\SmartSlider3\Slider\Feature\Align;
use Nextend\SmartSlider3\Slider\Feature\Autoplay;
use Nextend\SmartSlider3\Slider\Feature\BlockRightClick;
use Nextend\SmartSlider3\Slider\Feature\Controls;
use Nextend\SmartSlider3\Slider\Feature\Focus;
use Nextend\SmartSlider3\Slider\Feature\LayerMode;
use Nextend\SmartSlider3\Slider\Feature\LazyLoad;
use Nextend\SmartSlider3\Slider\Feature\MaintainSession;
use Nextend\SmartSlider3\Slider\Feature\Margin;
use Nextend\SmartSlider3\Slider\Feature\Optimize;
use Nextend\SmartSlider3\Slider\Feature\PostBackgroundAnimation;
use Nextend\SmartSlider3\Slider\Feature\Responsive;
use Nextend\SmartSlider3\Slider\Feature\SlideBackground;
use Nextend\SmartSlider3\Slider\Feature\TranslateUrl;

class FeatureManager {

    /**
     * @var AbstractRenderable
     */
    private $slider;

    /**
     * @var Responsive
     */
    public $responsive;

    /**
     * @var Controls
     */
    public $controls;

    /**
     * @var LazyLoad
     */
    public $lazyLoad;

    /**
     * @var Align
     */
    public $align;

    /**
     * @var BlockRightClick
     */
    public $blockRightClick;
    /**
     * @var Autoplay
     */
    public $autoplay;

    /**
     * @var TranslateUrl
     */
    public $translateUrl;

    /**
     * @var LayerMode
     */
    public $layerMode;

    /**
     * @var SlideBackground
     */
    public $slideBackground;

    /**
     * @var PostBackgroundAnimation
     */
    public $postBackgroundAnimation;

    /**
     * @var Focus
     */
    public $focus;

    /**
     * @var MaintainSession
     */
    public $maintainSession;

    /**
     * @var Margin
     */
    public $margin;

    public $optimize;

    /**
     * FeatureManager constructor.
     *
     * @param $slider AbstractRenderable
     */
    public function __construct($slider) {
        $this->slider = $slider;

        $this->optimize        = new Optimize($slider);
        $this->align           = new Align($slider);
        $this->responsive      = new Responsive($slider, $this);
        $this->controls        = new Controls($slider);
        $this->lazyLoad        = new LazyLoad($slider);
        $this->margin          = new Margin($slider);
        $this->blockRightClick = new BlockRightClick($slider);
        $this->maintainSession = new MaintainSession($slider);
        $this->autoplay        = new Autoplay($slider);
        $this->translateUrl    = new TranslateUrl($slider);
        $this->layerMode       = new LayerMode($slider);
        $this->slideBackground = new SlideBackground($slider);
        $this->focus           = new Focus($slider);
        $this->postBackgroundAnimation = new PostBackgroundAnimation($slider);
    
    }

    public function generateJSProperties() {

        $return         = array(
            'admin'                   => $this->slider->isAdmin,
            'background.video.mobile' => intval($this->slider->params->get('slides-background-video-mobile', 1)),
            'loadingTime'             => intval($this->slider->params->get('loading-time', 2000))
        );
        $randomizeCache = $this->slider->params->get('randomize-cache', 0);
        if (!$this->slider->isAdmin && $randomizeCache) {
            $return['randomize'] = array(
                'randomize'      => intval($this->slider->params->get('randomize', 0)),
                'randomizeFirst' => intval($this->slider->params->get('randomizeFirst', 0))
            );
        }
        $enabled = $this->slider->params->get('global-lightbox', 0);
        if ($enabled) {
            Predefined::loadLiteBox();

            $this->slider->exposeSlideData['lightboxImage'] = true;

            $label                         = $this->slider->params->get('global-lightbox-label', 0);
            $return['plugins']['lightbox'] = array(
                'label' => $label
            );
            switch ($label) {
                case 'namemore':
                    $this->slider->exposeSlideData['description'] = true;
                    break;
            }
        }
    
        $return['callbacks'] = $this->slider->params->get('callbacks', '');
    

        $return['alias'] = array(
            'id'           => intval($this->slider->params->get('alias-id', 0)),
            'smoothScroll' => intval($this->slider->params->get('alias-smoothscroll', 0)),
            'slideSwitch'  => intval($this->slider->params->get('alias-slideswitch', 0)),
            'scroll'       => intval($this->slider->params->get('alias-slideswitch-scroll', 1))
        );

        $this->makeJavaScriptProperties($return);

        return $return;
    }

    protected function makeJavaScriptProperties(&$properties) {
        $this->align->makeJavaScriptProperties($properties);
        $this->responsive->makeJavaScriptProperties($properties);
        $this->controls->makeJavaScriptProperties($properties);
        $this->optimize->makeJavaScriptProperties($properties);
        $this->lazyLoad->makeJavaScriptProperties($properties);
        $this->blockRightClick->makeJavaScriptProperties($properties);
        $this->maintainSession->makeJavaScriptProperties($properties);
        $this->autoplay->makeJavaScriptProperties($properties);
        $this->layerMode->makeJavaScriptProperties($properties);
        $this->slideBackground->makeJavaScriptProperties($properties);
        $this->focus->makeJavaScriptProperties($properties);
        $this->postBackgroundAnimation->makeJavaScriptProperties($properties);
    
        $properties['initCallbacks'] = &$this->slider->initCallbacks;
    }

    /**
     * @param $slide Slide
     */
    public function makeSlide($slide) {
        $this->postBackgroundAnimation->makeSlide($slide);
    
    }

    /**
     * @param $slide Slide
     *
     * @return string
     */
    public function makeBackground($slide) {

        return $this->slideBackground->make($slide);
    }

    public function addInitCallback($callback, $name = false) {
        $this->slider->addScript($callback, $name);
    }
}Slide.php000064400000110006152356644430006327 0ustar00<?php


namespace Nextend\SmartSlider3\Slider;


use Joomla\CMS\Router\Route;
use Nextend\Framework\Cast;
use Nextend\Framework\Data\Data;
use Nextend\Framework\FastImageSize\FastImageSize;
use Nextend\Framework\Image\Image;
use Nextend\Framework\Image\ImageEdit;
use Nextend\Framework\Misc\Str;
use Nextend\Framework\Parser\Common;
use Nextend\Framework\Parser\Link;
use Nextend\Framework\Platform\Platform;
use Nextend\Framework\Plugin;
use Nextend\Framework\Request\Request;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\Sanitize;
use Nextend\Framework\Translation\Translation;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Generator\Generator;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\Component\AbstractComponent;
use Nextend\SmartSlider3\Renderable\Component\ComponentSlide;

class Slide extends AbstractRenderableOwner {

    /**
     * @var Slider
     */
    protected $sliderObject;
    public $id = 0, $slider = 0, $publish_up = '1970-01-01 00:00:00', $publish_down = '1970-01-01 00:00:00', $published = 1, $first = 0, $slide = '', $ordering = 0, $generator_id = 0;

    protected $frontendFirst = false;

    protected $title = '', $description = '', $thumbnail = '';

    public $parameters;

    /**
     * @var string contains escaped html data
     */
    public $background = '';

    protected $html = '';

    protected $visible = 1;

    public $hasLink = false;

    /**
     * @var bool|Generator
     */
    protected $generator = false;
    protected $variables = array();

    public $index = -1;

    public $publicID = 0;

    public $attributes = array(), $linkAttributes = array(), $showOnAttributes = array();

    public $containerAttributes = array(
        'class' => 'n2-ss-layers-container n2-ss-slide-limiter n2-ow'
    );

    public $classes = '', $style = '';

    public $nextCacheRefresh = 2145916800; // 2038

    /**
     * Slide constructor.
     *
     * @param $slider Slider
     * @param $data   array
     */
    public function __construct($slider, $data) {
        $this->parameters = new Data($data['params'], true);

        $version = $this->parameters->getIfEmpty('version', '0.0.0');
        if (version_compare($version, '3.3.9999', '<')) {
            $this->parameters->set('desktopportraitpadding', '0|*|0|*|0|*|0');
        }

        unset($data['params']);
        foreach ($data as $key => $value) {
            $this->$key = $value;
        }

        $this->slide = array(
                'type'         => 'slide',
                'layers'       => json_decode($this->slide, true),
                'title'        => $this->title,
                'publish_up'   => $this->publish_up,
                'publish_down' => $this->publish_down,
                'published'    => $this->published,
                'description'  => $this->description,
                'thumbnail'    => $this->thumbnail,
            ) + $this->parameters->toArray();

        if ($version == '0.0.0') {
            /**
             * Required for sample slider city!!!
             */
            $this->fixOldZIndexes($this->slide['layers']);
        }

        $this->sliderObject = $slider;
        $this->renderable   = $slider;
        $this->onCreate();
    }

    private function fixOldZIndexes(&$layers) {
        /**
         * If we do not have version info for the slide, we should do the check for the old zIndexed storage and sort the layers to the new structure.
         */
        if (is_array($layers)) {
            for ($i = 0; $i < count($layers); $i++) {
                if (!isset($layers[$i]['zIndex'])) {
                    if (isset($layers[$i]['style']) && preg_match('/z\-index:[ ]*([0-9]+);/', $layers[$i]['style'], $matches)) {
                        $layers[$i]['zIndex'] = intval($matches[1]);
                    } else {
                        $layers[$i]['zIndex'] = 0;
                    }
                }

                if (isset($layers[$i]['type']) && $layers[$i]['type'] == 'group') {
                    $this->fixOldZIndexes($layers[$i]['layers']);
                }
            }

            if (isset($layers[0]['zIndex'])) {
                usort($layers, array(
                    $this,
                    "sortOldZIndex"
                ));
            }
        }
    }

    private function sortOldZIndex($a, $b) {
        if ($a['zIndex'] == $b['zIndex']) {
            return 0;
        }

        return ($a['zIndex'] < $b['zIndex']) ? 1 : -1;
    }

    public function __clone() {
        $this->parameters = clone $this->parameters;
    }

    protected function onCreate() {
        Plugin::doAction('ssSlide', array($this));
    }

    public function initGenerator($extend = array()) {
        if ($this->generator_id > 0) {
            $this->generator = new Generator($this, $this->sliderObject, $extend);
        }
    }

    public function hasGenerator() {
        return !!$this->generator;
    }

    public function isComponentVisible($generatorVisibleVariable) {
        return !empty($generatorVisibleVariable) && $this->hasGenerator();
    }

    /**
     * @return Slide[]
     */
    public function expandSlide() {
        return $this->generator->getSlides();
    }

    public function expandSlideAdmin() {
        return $this->generator->getSlidesAdmin();
    }

    public function fillSample() {
        if ($this->hasGenerator()) {
            $this->generator->fillSample();
        }
    }

    public function setVariables($variables) {
        $this->variables = array_merge($this->variables, (array)$variables);
    }

    public function isFirst() {
        return !!$this->first;
    }

    public function isCurrentlyEdited() {
        return Request::$REQUEST->getInt('slideid') == $this->id;
    }

    public function setIndex($index) {
        $this->index = $index;
    }

    public function setPublicID($publicID) {
        $this->publicID = $publicID;
    }

    /**
     * @return int
     */
    public function getPublicID(): int {
        return $this->publicID;
    }

    public function setFirst() {

        $this->frontendFirst = true;

        $this->attributes['data-first'] = '1';
    }

    public function getFrontendFirst() {
        return $this->frontendFirst;
    }

    public function prepare() {
        $this->variables['slide'] = array(
            'name'        => $this->getTitle(),
            'description' => $this->getDescription()
        );
    }

    public function setSlidesParams() {

        $this->background = $this->sliderObject->features->makeBackground($this);

        $this->addSlideLink();

        $this->attributes['data-slide-duration']  = Cast::floatToString(max(0, $this->parameters->get('slide-duration', 0)) / 1000);
        $this->attributes['data-id']              = $this->id;
        $this->attributes['data-slide-public-id'] = $this->publicID;

        $this->classes .= ' n2-ss-slide-' . $this->id;

        $this->sliderObject->features->makeSlide($this);

        $this->renderHtml();
    }

    protected function addSlideLink() {

        $linkV1 = $this->parameters->getIfEmpty('link', '');
        if (!empty($linkV1)) {
            list($link, $target) = array_pad((array)Common::parse($linkV1), 2, '');
            $this->parameters->un_set('link');
            $this->parameters->set('href', $link);
            $this->parameters->set('href-target', $target);
        }

        $url    = $this->parameters->get('href');
        $target = $this->parameters->get('href-target');

        if (!empty($url) && $url != '#') {
            $url = $this->fill($url);
        }

        if (!empty($url) && $url != '#') {

            if (empty($target)) {
                $target = '_self';
            }

            $url = ResourceTranslator::toUrl($url);


            $url = Link::parse($url, $this->linkAttributes);
            $this->linkAttributes['data-href'] = Route::_($url, false);
            $this->linkAttributes['tabindex'] = 0;
            $this->linkAttributes['role']     = 'button';

            $ariaLabel = $this->parameters->get('aria-label');
            if (!empty($ariaLabel)) {
                $this->linkAttributes['aria-label'] = $this->fill($ariaLabel);
            }

            if (!isset($this->linkAttributes['onclick']) && !isset($this->linkAttributes['data-n2-lightbox'])) {
                if (!empty($target) && $target != '_self') {
                    $this->linkAttributes['data-target'] = $target;
                }
                $this->linkAttributes['data-n2click'] = "url";
            }

            if (!isset($this->linkAttributes['style'])) {
                $this->linkAttributes['style'] = '';
            }
            $this->linkAttributes['data-force-pointer'] = "";

            $this->hasLink = true;
        }
    }

    public function getRawLink() {
        $linkV1 = $this->parameters->getIfEmpty('link', '');
        if (!empty($linkV1)) {
            list($link, $target) = array_pad((array)Common::parse($linkV1), 2, '');

            return $link;
        }

        return $this->parameters->getIfEmpty('href', '');
    }

    public function getRawLinkHref() {
        $linkV1 = $this->parameters->getIfEmpty('link', '');
        if (!empty($linkV1)) {
            list($link, $target) = array_pad((array)Common::parse($linkV1), 2, '');

            return $target;
        }

        return $this->parameters->getIfEmpty('href-target', '_self');
    }

    public function getSlider() {
        return $this->sliderObject;
    }

    public function getAvailableDevices() {
        return array_diff(array_keys($this->sliderObject->features->responsive->mediaQueries), array('all'));
    }

    protected function renderHtml() {
        if (empty($this->html)) {

            AbstractComponent::$isAdmin = $this->sliderObject->isAdmin;

            $mainContainer = new ComponentSlide($this, $this->slide);

            $attributes = array(
                'role'  => 'note',
                'class' => 'n2-ss-slide--focus'
            );

            if (!isset($this->linkAttributes['role']) || $this->linkAttributes['role'] != 'button') {
                $attributes['tabindex'] = '-1';
            }

            $this->html = Html::tag('div', $attributes, Sanitize::remove_all_html($this->getTitle()));
            $this->html .= Html::tag('div', $this->containerAttributes, $mainContainer->render($this->sliderObject->isAdmin));
        }
    }

    public function finalize() {

        if ($this->sliderObject->exposeSlideData['title']) {
            $title = $this->getTitle();
            if (!empty($title)) {
                $this->attributes['data-title'] = Translation::_($title);
            }
        }

        if ($this->sliderObject->exposeSlideData['description']) {
            $description = $this->getDescription();
            if (!empty($description)) {
                $this->attributes['data-description'] = Translation::_($description);
            }
        }

        if ($this->sliderObject->exposeSlideData['thumbnail']) {
            $thumbnail = $this->getThumbnailDynamic();
            if (!empty($thumbnail)) {

                $attributes = Html::addExcludeLazyLoadAttributes(array(
                    'loading' => 'lazy',
                    'style'   => '',
                    'class'   => 'n2-ss-slide-thumbnail'
                ));

                $this->html .= Html::image($this->sliderObject->features->optimize->optimizeThumbnail($thumbnail), esc_attr($this->getThumbnailAltDynamic()), $attributes);
            }
        }
        if ($this->sliderObject->exposeSlideData['lightboxImage']) {
            $lightboxImage = $this->getLightboxImage();
            if (!empty($lightboxImage)) {
                $this->attributes['data-lightbox-image'] = $lightboxImage;
            }
        }
    

        if ($this->hasLink) {
            $this->attributes['data-haslink'] = 1;
        }

        if (!$this->sliderObject->isAdmin || !$this->underEdit) {
            if (!$this->isVisibleDesktopPortrait()) {
                $this->showOnAttributes['data-hide-desktopportrait'] = 1;
            }
            if (!$this->isVisibleDesktopLandscape()) {
                $this->showOnAttributes['data-hide-desktoplandscape'] = 1;
            }
        
            if (!$this->isVisibleTabletPortrait()) {
                $this->showOnAttributes['data-hide-tabletportrait'] = 1;
            }
            if (!$this->isVisibleTabletLandscape()) {
                $this->showOnAttributes['data-hide-tabletlandscape'] = 1;
            }
        
            if (!$this->isVisibleMobilePortrait()) {
                $this->showOnAttributes['data-hide-mobileportrait'] = 1;
            }
            if (!$this->isVisibleMobileLandscape()) {
                $this->showOnAttributes['data-hide-mobilelandscape'] = 1;
            }
        
        }

        $this->attributes += $this->showOnAttributes;
    }

    public function isVisibleDesktopPortrait() {
        return $this->parameters->get('desktopportrait', 1);
    }

    public function isVisibleDesktopLandscape() {
        return $this->parameters->get('desktoplandscape', 1);
    }

    public function isVisibleTabletPortrait() {
        return $this->parameters->get('tabletportrait', 1);
    }

    public function isVisibleTabletLandscape() {
        return $this->parameters->get('tabletlandscape', 1);
    }

    public function isVisibleMobilePortrait() {
        return $this->parameters->get('mobileportrait', 1);
    }

    public function isVisibleMobileLandscape() {
        return $this->parameters->get('mobilelandscape', 1);
    }

    /**
     * @return string contains escaped html data
     */
    public function getHTML() {
        return $this->html;
    }

    public function getAsStatic() {

        $mainContainer = new ComponentSlide($this, $this->slide);

        $attributes = array(
            'class' => 'n2-ss-static-slide n2-ow' . $this->classes
        );

        if (!$this->sliderObject->isAdmin || !$this->underEdit) {
            if (!$this->isVisibleDesktopPortrait()) {
                $attributes['data-hide-desktopportrait'] = 1;
            }
            if (!$this->isVisibleDesktopLandscape()) {
                $attributes['data-hide-desktoplandscape'] = 1;
            }
            if (!$this->isVisibleTabletPortrait()) {
                $attributes['data-hide-tabletportrait'] = 1;
            }
            if (!$this->isVisibleTabletLandscape()) {
                $attributes['data-hide-tabletlandscape'] = 1;
            }
            if (!$this->isVisibleMobilePortrait()) {
                $attributes['data-hide-mobileportrait'] = 1;
            }
            if (!$this->isVisibleMobileLandscape()) {
                $attributes['data-hide-mobilelandscape'] = 1;
            }
        }

        return Html::tag('div', $attributes, $mainContainer->render($this->sliderObject->isAdmin));
    }

    public function forceNonStatic() {
        $this->parameters->set('static-slide', 0);
    }

    public function isStatic() {
        if ($this->parameters->get('static-slide', 0)) {
            return true;
        }

        return false;
    }

    private static function splitTokens($input) {
        $tokens       = array();
        $currentToken = "";
        $nestingLevel = 0;
        for ($i = 0; $i < strlen($input); $i++) {
            $currentChar = $input[$i];
            if ($currentChar === "," && $nestingLevel === 0) {
                $tokens[]     = $currentToken;
                $currentToken = "";
            } else {
                $currentToken .= $currentChar;
                if ($currentChar === "(") {
                    $nestingLevel++;
                } else if ($currentChar === ")") {
                    $nestingLevel--;
                }
            }
        }
        if (strlen($currentToken)) {
            $tokens[] = $currentToken;
        }

        return $tokens;
    }

    public function fill($value) {
        if (!empty($this->variables) && !empty($value)) {
            return preg_replace_callback('/{((([a-z]+)\(([^}]+)\))|([a-zA-Z0-9][a-zA-Z0-9_\/]*))}/', array(
                $this,
                'parseFunction'
            ), $value);
        }

        return $value;
    }

    private function parseFunction($match) {
        if (!isset($match[5])) {
            $args = self::splitTokens($match[4]);
            for ($i = 0; $i < count($args); $i++) {
                $args[$i] = $this->parseVariable($args[$i]);
            }

            if (method_exists($this, '_' . $match[3])) {
                return call_user_func_array(array(
                    $this,
                    '_' . $match[3]
                ), $args);
            }

            return $match[0];
        } else {
            return $this->parseVariable($match[5]);
        }
    }

    private function parseVariable($variable) {
        preg_match('/^("|\')(.*)("|\')$/', $variable, $match);
        if (!empty($match)) {
            return $match[2];
        }

        preg_match('/((([a-z]+)\(([^}]+)\)))/', $variable, $match);
        if (!empty($match)) {
            return call_user_func(array(
                $this,
                'parseFunction'
            ), $match);
        } else {
            preg_match('/([a-zA-Z][0-9a-zA-Z_]*)(\/([0-9a-z]+))?/', $variable, $match);
            if ($match) {
                $index = empty($match[3]) ? 0 : $match[3];
                if (is_numeric($index)) {
                    $index = max(1, intval($index)) - 1;
                }

                if (isset($this->variables[$index]) && isset($this->variables[$index][$match[1]])) {
                    return $this->variables[$index][$match[1]];
                } else {
                    return '';
                }
            }

            return $variable;
        }
    }

    private function _fallback($s, $def) {
        if (empty($s)) {
            return $def;
        }

        return $s;
    }

    private function _cleanhtml($s) {
        return strip_tags($s, '<p><a><b><br><i>');
    }

    private function _removehtml($s) {
        return strip_tags($s);
    }

    private function _splitbychars($s, $start = 0, $length = null) {

        return Str::substr($s, $start, $length);
    }

    private function _splitbywords($s, $start, $length) {

        $len = intval(Str::strlen($s));
        if ($len > $start) {
            $posStart = max(0, $start == 0 ? 0 : Str::strpos($s, ' ', $start));
            $posEnd   = max(0, $length > $len ? $len : Str::strpos($s, ' ', $length));
            if ($posEnd == 0 && $length <= $len) $posEnd = $len;

            return Str::substr($s, $posStart, $posEnd);
        } else {
            return '';
        }
    }

    private function _findimage($s, $index) {
        $index = isset($index) ? intval($index) - 1 : 0;
        preg_match_all('/(<img.*?src=[\'"](.*?)[\'"][^>]*>)|(background(-image)??\s*?:.*?url\((["|\']?)?(.+?)(["|\']?)?\))/i', $s, $r);
        if (isset($r[2]) && !empty($r[2][$index])) {
            $s = $r[2][$index];
        } else if (isset($r[6]) && !empty($r[6][$index])) {
            $s = trim($r[6][$index], "'\" \t\n\r\0\x0B");
        } else {
            $s = '';
        }

        return $s;
    }

    private function _findlink($s, $index) {
        $index = isset($index) ? intval($index) - 1 : 0;
        preg_match_all('/href=["\']?([^"\'>]+)["\']?/i', $s, $r);
        if (isset($r[1]) && !empty($r[1][$index])) {
            $s = $r[1][$index];
        } else {
            $s = '';
        }

        return $s;
    }

    private function _removevarlink($s) {
        return preg_replace('/<a href=\"(.*?)\">(.*?)<\/a>/', '', $s);
    }

    private function _removelinebreaks($s) {
        return preg_replace('/\r?\n|\r/', '', $s);
    }

    public function getTitle($isAdmin = false) {

        return $this->fill($this->title);
    }

    public function getDescription() {
        return $this->fill($this->description);
    }

    public function getRawTitle() {
        return $this->title;
    }

    public function getRawDescription() {
        return $this->description;
    }

    public function getBackgroundImage() {
        return $this->fill($this->parameters->get('backgroundImage'));
    }

    public function getThumbnail() {

        return ResourceTranslator::toUrl($this->getThumbnailRaw());
    }

    public function getThumbnailRaw() {
        $image = $this->thumbnail;
        if (empty($image)) {
            return $this->getBackgroundImage();
        }

        return $this->fill($image);
    }

    public function getThumbnailDynamic() {
        $image = $this->thumbnail;
        if (empty($image)) {
            $image = $this->parameters->get('backgroundImage');
        }

        return $this->fill($image);
    }

    public function getThumbnailAltDynamic() {
        $alt = $this->fill($this->parameters->get('thumbnailAlt'));
        if (empty($alt)) {
            $alt = $this->getTitle();
        }

        return $alt;
    }

    public function getLightboxImage() {
        $image = $this->fill($this->parameters->get('ligthboxImage'));
        if (empty($image)) {
            $image = $this->getBackgroundImage();
        }

        return ResourceTranslator::toUrl($image);
    }

    public function getRow() {
        $this->fillParameters();

        return array(
            'title'        => $this->getTitle(),
            'slide'        => $this->getFilledLayers(),
            'description'  => $this->getDescription(),
            'thumbnail'    => ResourceTranslator::urlToResource($this->getThumbnail()),
            'published'    => $this->published,
            'publish_up'   => $this->publish_up,
            'publish_down' => $this->publish_down,
            'first'        => $this->first,
            'params'       => $this->parameters->toJSON(),
            'slider'       => $this->slider,
            'ordering'     => $this->ordering,
            'generator_id' => 0
        );
    }

    public function fillParameters() {
        $this->parameters->set('backgroundImage', $this->fill($this->parameters->get('backgroundImage')));
        $this->parameters->set('backgroundAlt', $this->fill($this->parameters->get('backgroundAlt')));
        $this->parameters->set('backgroundTitle', $this->fill($this->parameters->get('backgroundTitle')));
        $this->parameters->set('backgroundVideoMp4', $this->fill($this->parameters->get('backgroundVideoMp4')));
        $this->parameters->set('backgroundColor', $this->fill($this->parameters->get('backgroundColor')));
        $this->parameters->set('href', $this->fill($this->parameters->get('href')));
    }

    private function getFilledLayers() {
        $layers = $this->slide['layers'];
        if (!$this->underEdit) {
            $layers = AbstractComponent::translateUniqueIdentifier($layers);
        }

        $this->fillLayers($layers);

        return json_encode($layers);
    }

    public function setNextCacheRefresh($time) {
        $this->nextCacheRefresh = min($this->nextCacheRefresh, $time);
    }

    public function setVisibility($visibility) {
        $this->visible = $visibility;
    }

    public function isVisible() {

        if (!$this->visible) {
            return false;
        }

        if ($this->publish_down != '1970-01-01 00:00:00') {
            $publish_down = strtotime($this->publish_down);

            if ($publish_down) {
                if ($publish_down > Platform::getTimestamp()) {
                    $this->setNextCacheRefresh($publish_down);
                } else {
                    return false;
                }
            }
        }

        if ($this->publish_up != '1970-01-01 00:00:00') {
            $publish_up = strtotime($this->publish_up);

            if ($publish_up) {
                if ($publish_up > Platform::getTimestamp()) {
                    $this->setNextCacheRefresh($publish_up);

                    return false;
                }
            }
        }

        return true;
    }

    public function getSlideStat() {
        if ($this->hasGenerator()) {
            return $this->generator->getSlideStat();
        }

        return '1/1';
    }

    public function getGeneratorLabel() {
        $source = $this->generator->getSource();
        if (!$source) {
            return n2_('Not found');
        }

        return $source->getLabel();

    }

    public function getElementID() {
        return $this->getSlider()->elementId;
    }

    public function addScript($script, $name = false) {
        $this->sliderObject->addScript($script, $name);
    }

    public function isScriptAdded($name) {
        return $this->sliderObject->isScriptAdded($name);
    }

    public function addLess($file, $context) {
        $this->sliderObject->addLess($file, $context);
    }

    public function addCSS($css) {
        $this->sliderObject->addCSS($css);
    }

    public function addDeviceCSS($device, $css) {
        $this->sliderObject->addDeviceCSS($device, $css);
    }

    public function addFont($font, $mode, $pre = null) {
        return $this->sliderObject->addFont($font, $mode, $pre);
    }

    public function addStyle($style, $mode, $pre = null) {
        return $this->sliderObject->addStyle($style, $mode, $pre);
    }

    public function addImage($imageUrl) {
        $this->sliderObject->addImage($imageUrl);
    }

    public function isAdmin() {
        return $this->sliderObject->isAdmin;
    }

    public function isLazyLoadingEnabled() {
        return $this->sliderObject->features->lazyLoad->isEnabled;
    }

    public function optimizeImageWebP($src) {
        if ($this->sliderObject->params->get('layer-image-webp', 0)) {

            $imagePath = ResourceTranslator::toPath($src);
            if (isset($imagePath[0])) {
                $extension = pathinfo($imagePath, PATHINFO_EXTENSION);
                if ($extension != 'svg') {

                    $lazyLoad = $this->sliderObject->features->lazyLoad;

                    return $this->sliderObject->features->optimize->optimizeImageWebP($src, array(
                        'optimize'     => true,
                        'quality'      => intval($this->sliderObject->params->get('layer-image-optimize-quality', 70)),
                        'resize'       => $this->sliderObject->params->get('layer-image-optimize', 0),
                        'defaultWidth' => $lazyLoad->layerImageWidthNormal,
                        'mediumWidth'  => $lazyLoad->layerImageWidthTablet,
                        'smallWidth'   => $lazyLoad->layerImageWidthMobile
                    ));
                }
            }
        }
    

        return array();
    }

    public function renderImage($item, $src, $attributes = array(), $pictureAttributes = array()) {

        /**
         * @see https://bugs.chromium.org/p/chromium/issues/detail?id=1181291
         */
        if (!$this->frontendFirst) {
            $attributes['loading'] = 'lazy';
        }

        $imageUrl = ResourceTranslator::toUrl($src);

        FastImageSize::initAttributes($src, $attributes);

        $attributes = Html::addExcludeLazyLoadAttributes($attributes);

        $lazyLoad = $this->sliderObject->features->lazyLoad;

        $imagePath = ResourceTranslator::toPath($src);
        if (isset($imagePath[0])) {
            $extension = pathinfo($imagePath, PATHINFO_EXTENSION);

            $isRemote = false;
            if (preg_match('/(https?:)?\/\//', $imagePath)) {
                //this is a remote image
                $isRemote = true;
            }

            if (!$isRemote && $lazyLoad->layerImageSizeBase64 && $lazyLoad->layerImageSizeBase64Size && filesize($imagePath) < $lazyLoad->layerImageSizeBase64Size) {

                if ($extension != 'svg') {
                    $attributes['src'] = ImageEdit::base64($imagePath, $imageUrl);

                } else {
                    $attributes['src'] = Image::SVGToBase64($src);
                }

                return Html::tag('img', $attributes, false);
            }

            if ($extension != 'svg' && $item->data->get('image-optimize', 1)) {

                $optimizeScale = $this->sliderObject->params->get('layer-image-optimize', 0);
                $optimizedData = $this->sliderObject->features->optimize->optimizeImageWebP($src, array(
                    'optimize'     => $this->sliderObject->params->get('layer-image-webp', 0),
                    'quality'      => intval($this->sliderObject->params->get('layer-image-optimize-quality', 70)),
                    'resize'       => $optimizeScale,
                    'defaultWidth' => $lazyLoad->layerImageWidthNormal,
                    'mediumWidth'  => $lazyLoad->layerImageWidthTablet,
                    'smallWidth'   => $lazyLoad->layerImageWidthMobile
                ));

                $retinaSupport = !!$this->sliderObject->params->get('layer-image-width-retina', 0);

                $sources = array();

                if ($optimizeScale && $retinaSupport) {

                    $webPSrcSet = array();
                    if (isset($optimizedData['small'])) {
                        $this->addImage($optimizedData['small']['src']);

                        $webPSrcSet[] = $optimizedData['small']['src'] . ' ' . $optimizedData['small']['width'] . 'w';
                    }

                    if (isset($optimizedData['medium'])) {
                        $this->addImage($optimizedData['medium']['src']);

                        $webPSrcSet[] = $optimizedData['medium']['src'] . ' ' . $optimizedData['medium']['width'] . 'w';
                    }

                    if (isset($optimizedData['normal'])) {
                        $this->addImage($optimizedData['normal']['src']);
                        $webPSrcSet[] = $optimizedData['normal']['src'] . ' ' . $optimizedData['normal']['width'] . 'w';
                    }

                    if (!empty($webPSrcSet)) {
                        $sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
                            'srcset' => implode(',', $webPSrcSet),
                            'type'   => 'image/webp'
                        )), false, false);
                    }
                } else {

                    if (isset($optimizedData['small'])) {
                        $this->addImage($optimizedData['small']['src']);

                        $sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
                            'srcset' => $optimizedData['small']['src'],
                            'type'   => 'image/webp',
                            'media'  => '(max-width: ' . $optimizedData['small']['width'] . 'px)'
                        )), false, false);
                    }

                    if (isset($optimizedData['medium'])) {
                        $this->addImage($optimizedData['medium']['src']);

                        $sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
                            'srcset' => $optimizedData['medium']['src'],
                            'type'   => 'image/webp',
                            'media'  => '(max-width: ' . $optimizedData['medium']['width'] . 'px)'
                        )), false, false);
                    }

                    if (isset($optimizedData['normal'])) {
                        $this->addImage($optimizedData['normal']['src']);

                        $sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
                            'srcset' => $optimizedData['normal']['src'],
                            'type'   => 'image/webp'
                        )), false, false);
                    }
                }

                $attributes['src'] = $imageUrl;
                $this->addImage($imageUrl);

                $sources[] = Html::tag('img', $attributes, false);

                return HTML::tag('picture', Html::addExcludeLazyLoadAttributes($pictureAttributes), implode('', $sources));
            }
        }
    

        $attributes['src'] = $imageUrl;
        $this->addImage($imageUrl);

        return Html::tag('img', $attributes, false);
    }

    public function getThumbnailType() {
        return $this->parameters->get('thumbnailType', 'default');
    }

    public function renderThumbnailImage($width, $height, $attributes = array()) {

        $src = $this->getThumbnailRaw();

        if (empty($src)) {
            return '<img src="data:," alt style="visibility:hidden;">';
        }

        $attributes['src']     = ResourceTranslator::toUrl($src);
        $originalThumbnailSize = FastImageSize::getSize($src);
        if ($originalThumbnailSize) {
            $attributes['width']  = $originalThumbnailSize['width'];
            $attributes['height'] = $originalThumbnailSize['height'];
        }
        $attributes['loading'] = 'lazy';

        $attributes = Html::addExcludeLazyLoadAttributes($attributes);

        $sources = array();

        $imagePath = ResourceTranslator::toPath($src);
        if (isset($imagePath[0])) {
            $optimizeThumbnail = $this->sliderObject->params->get('optimize-thumbnail-scale', 0);
            $extension = pathinfo($imagePath, PATHINFO_EXTENSION);
            if ($extension && $this->sliderObject->params->get('optimize-webp', 0) && function_exists('imagewebp')) {

                $isRemote = false;
                if (preg_match('/(https?:)?\/\//', $imagePath)) {
                    //this is a remote image
                    $isRemote = true;
                }

                $quality = intval($this->sliderObject->params->get('optimize-thumbnail-quality', 70));

                $options = array(
                    'quality' => $quality,
                    'remote'  => $isRemote
                );

                if ($optimizeThumbnail) {
                    $options['mode']   = 'resize';
                    $options['width']  = intval($this->sliderObject->params->get('optimizeThumbnailWidth', 100));
                    $options['height'] = intval($this->sliderObject->params->get('optimizeThumbnailHeight', 60));
                } else {
                    $options['mode']  = 'scale';
                    $options['scale'] = 1;
                }

                $imageWebpUrl = ImageEdit::scaleImageWebp('slider/cache', $src, $options);

                if ($imageWebpUrl) {
                    $imageWebpUrl = ResourceTranslator::toUrl($imageWebpUrl);
                    $this->addImage($imageWebpUrl);

                    $sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
                        'srcset' => $imageWebpUrl,
                        'type'   => 'image/webp'
                    )), false, false);
                }
            }
        

            if ($optimizeThumbnail) {
                $optimizedThumbnailUrl  = $this->sliderObject->features->optimize->optimizeThumbnail($attributes['src']);
                $attributes['src']      = $optimizedThumbnailUrl;
                $optimizedThumbnailSize = FastImageSize::getSize(ResourceTranslator::urlToResource($optimizedThumbnailUrl));
                if ($optimizedThumbnailSize) {
                    $attributes['width']  = $optimizedThumbnailSize['width'];
                    $attributes['height'] = $optimizedThumbnailSize['height'];
                }
            }

        }


        $sources[] = Html::tag('img', $attributes, false);

        return HTML::tag('picture', Html::addExcludeLazyLoadAttributes(), implode('', $sources));
    }
}Slider.php000064400000036222152356644430006520 0ustar00<?php


namespace Nextend\SmartSlider3\Slider;


use Exception;
use Nextend\Framework\Asset\AssetManager;
use Nextend\Framework\Asset\Css\Css;
use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Data\Data;
use Nextend\Framework\Pattern\MVCHelperTrait;
use Nextend\Framework\Settings;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Application\Model\ModelSliders;
use Nextend\SmartSlider3\Renderable\AbstractRenderable;
use Nextend\SmartSlider3\Slider\Base\PlatformSliderTrait;
use Nextend\SmartSlider3\Slider\SliderType\AbstractSliderTypeCss;
use Nextend\SmartSlider3\Slider\SliderType\AbstractSliderTypeFrontend;
use Nextend\SmartSlider3\Slider\SliderType\SliderTypeFactory;


class Slider extends AbstractRenderable {

    use PlatformSliderTrait, MVCHelperTrait;

    const LOAD_STATE_NONE = 0;
    const LOAD_STATE_SLIDER = 1;
    const LOAD_STATE_SLIDES = 2;
    const LOAD_STATE_ALL = 3;

    protected $loadState;

    protected $isAdminArea = false;

    public $manifestData = array(
        'generator' => array()
    );

    protected $isGroup = false;

    public $hasError = false;

    public $sliderId = 0;

    public $cacheId = '';

    public $isFrame = false;

    /** @var  Data */
    public $data;

    public $disableResponsive = false;

    protected $parameters = array(
        'disableResponsive' => false,
        'sliderData'        => array(),
        'slidesData'        => array(),
        'generatorData'     => array()
    );

    public $fontSize = 16;

    /**
     * @var Slides
     */
    protected $slidesBuilder;

    protected $cache = false;

    public static $_identifier = 'n2-ss';

    /** @var Slide[] */
    public $staticSlides = array();

    /** @var  AbstractSliderTypeFrontend */
    public $sliderType;

    /**
     * @var AbstractSliderTypeCss
     */
    public $assets;

    /**
     * @var string contains already escaped data
     */
    public $staticHtml = '';

    private $sliderRow;

    private $fallbackId;

    public $exposeSlideData = array(
        'title'         => true,
        'description'   => false,
        'thumbnail'     => false,
        'lightboxImage' => false
    );

    /**
     * @var Data
     */
    public $params;

    /**
     * @var Slide
     */
    protected $activeSlide;

    /**
     * Slider constructor.
     *
     * @param MVCHelperTrait $MVCHelper
     * @param                $sliderId
     * @param                $parameters
     * @param                $isAdminArea
     */
    public function __construct($MVCHelper, $sliderId, $parameters, $isAdminArea = false) {
        $this->loadState = self::LOAD_STATE_NONE;

        $this->isAdminArea = $isAdminArea;

        $this->setMVCHelper($MVCHelper);

        $this->initPlatformSlider();

        $this->sliderId = $sliderId;

        $this->setElementId();

        $this->cacheId = static::getCacheId($this->sliderId);

        $this->parameters = array_merge($this->parameters, $parameters);

        $this->disableResponsive = $this->parameters['disableResponsive'];
    }


    public function setElementId() {
        $this->elementId = self::$_identifier . '-' . $this->sliderId;
    }

    public static function getCacheId($sliderId) {
        return self::$_identifier . '-' . $sliderId;
    }

    public function getAlias() {
        return $this->data->get('alias', '');
    }

    /**
     * @throws Exception
     */
    public function initSlider() {
        if ($this->loadState < self::LOAD_STATE_SLIDER) {

            $slidersModel = new ModelSliders($this->MVCHelper);
            $sliderRow    = $slidersModel->get($this->sliderId);

            if (empty($sliderRow)) {
                $this->hasError = true;
                throw new Exception('Slider does not exists!');
            } else {
                if (!$this->isAdminArea && $sliderRow['slider_status'] != 'published') {
                    $this->hasError = true;
                    throw new Exception('Slider is not published!');
                }

                if (!empty($this->parameters['sliderData'])) {
                    $sliderData         = $this->parameters['sliderData'];
                    $sliderRow['title'] = $sliderData['title'];
                    unset($sliderData['title']);
                    $sliderRow['type'] = $sliderData['type'];
                    unset($sliderData['type']);

                    $this->data   = new Data($sliderRow);
                    $this->params = new SliderParams($this->sliderId, $sliderRow['type'], $sliderData);
                } else {
                    $this->data   = new Data($sliderRow);
                    $this->params = new SliderParams($this->sliderId, $sliderRow['type'], $sliderRow['params'], true);
                }

                switch ($sliderRow['type']) {
                    case 'group':
                        $this->isGroup = true;
                        break;
                }
            }

            $this->loadState = self::LOAD_STATE_SLIDER;
        }
    }

    /**
     * @throws Exception
     */
    public function initSlides() {
        if ($this->loadState < self::LOAD_STATE_SLIDES) {

            $this->initSlider();

            if (!$this->isGroup) {
                $this->slidesBuilder = new Slides($this);

                $this->slidesBuilder->initSlides($this->parameters['slidesData'], $this->parameters['generatorData']);
            }

            $this->loadState = self::LOAD_STATE_SLIDES;
        }
    }

    /**
     * @throws Exception
     */
    public function initAll() {
        if ($this->loadState < self::LOAD_STATE_ALL) {

            $this->initSlides();
            if (!$this->hasSlides() && !$this->fallbackId) {
                $fallback = $this->params->get('fallback-slider');
                if (!empty($fallback)) {
                    $this->fallbackId = $this->sliderId;
                    $this->sliderId   = $this->setSliderIDFromAlias($fallback);
                    $this->setElementId();
                    $this->loadState = self::LOAD_STATE_NONE;
                    $this->initSlides();
                }
            }
        
            $this->loadState = self::LOAD_STATE_ALL;
        }
    }


    private function setSliderIDFromAlias($slider) {
        if (is_numeric($slider)) {
            return $slider;
        } else {
            $slidersModel = new ModelSliders($this->MVCHelper);
            $slider       = $slidersModel->getByAlias($slider);

            return $slider['id'];
        }

    }

    private function loadSlider() {

        $this->sliderType = SliderTypeFactory::createFrontend($this->data->get('type', 'simple'), $this);
        $defaults         = $this->sliderType->getDefaults();

        $this->params->fillDefault($defaults);
        $this->sliderType->limitParams($this->params);

        if (!$this->isGroup) {
            $this->features = new FeatureManager($this);
        }

        return true;
    }

    public function getNextCacheRefresh() {
        if ($this->isGroup) {
            return $this->sliderType->getNextCacheRefresh();
        }

        return $this->slidesBuilder->getNextCacheRefresh();
    }

    /**
     * @return string
     * @throws Exception
     */
    public function render() {
        if ($this->loadState < self::LOAD_STATE_ALL) {
            throw new Exception('Load state not reached all!');
        }

        if (!$this->loadSlider()) {
            return false;
        }

        if (!$this->isGroup) {
            if (!$this->hasSlides()) {
                $this->slidesBuilder->addDummySlides();
            }

            if (!$this->getActiveSlide()) {
                $slides = $this->getSlides();
                $this->setActiveSlide($slides[0]);
            }

            $this->getActiveSlide()
                 ->setFirst();
        }

        $this->assets = SliderTypeFactory::createCss($this->data->get('type', 'simple'), $this);

        if (!$this->isGroup) {

            $this->slidesBuilder->prepareRender();

            $this->renderStaticSlide();
        }
        $slider = $this->sliderType->render($this->assets);

        $slider = str_replace('n2-ss-0', $this->elementId, $slider);

        $rockedLoader = false;
        if (!$this->isAdmin) {
            $rocketAttributes = '';

            $loadingType = $this->params->get('loading-type');
            if ($loadingType == 'afterOnLoad') {
                $rocketAttributes .= ' data-loading-type="' . $loadingType . '"';
            } else if ($loadingType == 'afterDelay') {

                $delay = max(0, intval($this->params->get('delay'), 0));
                if ($delay > 0) {
                    $rocketAttributes .= ' data-loading-type="' . $loadingType . '"';
                    $rocketAttributes .= ' data-loading-delay="' . $delay . '"';
                }
            }

            if (!empty($rocketAttributes)) {
                $slider       = '<template id="' . $this->elementId . '_t"' . $rocketAttributes . '>' . $slider . '</template>';
                $rockedLoader = true;
            }
        }
        if (!$this->isGroup) {
            $slider = $this->features->translateUrl->replaceUrl($slider) . HTML::tag('ss3-loader', array(), '');

            $slider = $this->features->align->renderSlider($slider, $this->assets->sizes['width']);
            $slider = $this->features->margin->renderSlider($slider);


            Css::addInline($this->features->translateUrl->replaceUrl($this->sliderType->getStyle()), $this->elementId);
            $jsInlineMode = Settings::get('javascript-inline', 'head');
            switch ($jsInlineMode) {
                case 'body':
                    $slider .= Html::script($this->sliderType->getScript());
                    break;
                case 'head':
                default:
                    Js::addInline($this->sliderType->getScript());
                    break;
            }
        
        }

        $html = '';

        $classes = array(
            'n2-section-smartslider',
            'fitvidsignore',
            $this->params->get('classes', '')
        );

        if (intval($this->params->get('clear-both', 1))) {
            $classes[] = 'n2_clear';
        }


        $sliderAttributes = array(
            'class'     => implode(' ', $classes),
            'data-ssid' => $this->sliderId
        );

        if ($this->fallbackId) {
            $sliderAttributes['data-fallback-for'] = $this->fallbackId;
        }

        $ariaLabel = $this->params->get('aria-label', 'Slider');
        if (!empty($ariaLabel)) {
            $sliderAttributes['tabindex']   = '0';
            $sliderAttributes['role']       = 'region';
            $sliderAttributes['aria-label'] = $ariaLabel;
        }

        $alias = $this->getAlias();
        if (!empty($alias)) {
            $sliderAttributes['data-alias'] = $alias;

            if (intval($this->params->get('alias-id', 0))) {
                $sliderAttributes['id'] = $alias;

                if (intval($this->params->get('alias-slideswitch-scroll', 1))) {
                    $slideAnchorHTML = '';
                    $slideCount      = $this->getSlidesCount();
                    for ($i = 1; $i <= $slideCount; $i++) {
                        $slideAnchorHTML .= Html::tag('div', array(
                            'id' => $alias . '-' . $i
                        ));
                    }

                    $slider = $slideAnchorHTML . $slider;
                }
            }
        }

        $sizes = $this->assets->sizes;

        if ($rockedLoader && !empty($sizes['width']) && !empty($sizes['height'])) {
            $sliderAttributes['style'] = 'height:' . $sizes['height'] . 'px;';
        }

        $html .= Html::tag("div", $sliderAttributes, $slider);

        AssetManager::$image->add($this->images);

        $needDivWrap = false;
        if (!$this->isGroup && $this->features->responsive->type === 'fullpage') {
            $attrs = array(
                'data-based-on' => $this->features->responsive->sliderHeightBasedOn,
            );

            if (!$this->isAdminArea) {
                $attrs['data-threshold'] = 150;
            }

            $subtract = $this->features->responsive->responsiveDecreaseSliderHeight;
            if ($subtract) {
                $attrs['style'] = '--subtract:' . $this->features->responsive->responsiveDecreaseSliderHeight . 'px';
            }
            $html        = Html::tag("ss3-fullpage", $attrs, $html);
            $needDivWrap = true;
        }
    

        if (!$this->isGroup && !$this->isAdmin && $this->features->responsive->forceFull) {
            $html        = Html::tag("ss3-force-full-width", array(
                'data-overflow-x'          => $this->features->responsive->forceFullOverflowX,
                'data-horizontal-selector' => $this->features->responsive->forceFullHorizontalSelector
            ), $html);
            $needDivWrap = true;
        }

        if ($needDivWrap) {
            $attr = array();
            if ($this->params->get('clear-both', 1)) {
                $attr['class'] = 'n2_clear';
            }

            return Html::tag("div", $attr, $html);
        }

        return $html;
    }

    public function addStaticSlide($slide) {
        $this->staticSlides[] = $slide;
    }

    public function renderStaticSlide() {
        $this->staticHtml = '';
        if (count($this->staticSlides)) {
            for ($i = 0; $i < count($this->staticSlides); $i++) {
                $this->staticHtml .= $this->staticSlides[$i]->getAsStatic();
            }
        }
    }

    public static function removeShortcode($content) {
        $content = preg_replace('/smartslider3\[([0-9]+)\]/', '', $content);
        $content = preg_replace('/\[smartslider3 slider="([0-9]+)"\]/', '', $content);
        $content = preg_replace('/\[smartslider3 slider=([0-9]+)\]/', '', $content);

        return $content;
    }

    /**
     * @return Slide
     */
    public function getActiveSlide() {
        return $this->activeSlide;
    }

    /**
     * @param Slide $activeSlide
     */
    public function setActiveSlide($activeSlide) {
        $this->activeSlide = $activeSlide;
    }

    /**
     * @return Slide[]
     */
    public function getSlides() {
        return $this->slidesBuilder->getSlides();
    }

    /**
     * @return bool
     */
    public function hasSlides() {
        if ($this->isGroup) {
            return true;
        }

        return $this->slidesBuilder->hasSlides();
    }

    /**
     * @return int
     */
    public function getSlidesCount() {
        if ($this->isGroup) {
            return 0;
        }

        return $this->slidesBuilder->getSlidesCount();
    }

    public function isGroup() {
        $this->initSlider();

        return $this->isGroup;
    }

    public function isLegacyFontScale() {
        return !!$this->params->get('legacy-font-scale', 0);
    }
}SliderParams.php000064400000042756152356644430007675 0ustar00<?php


namespace Nextend\SmartSlider3\Slider;


use Nextend\Framework\Data\Data;
use Nextend\SmartSlider3\Application\ApplicationSmartSlider3;
use Nextend\SmartSlider3\Application\Model\ModelSlides;

class SliderParams extends Data {

    protected $sliderID;

    /**
     * @var string
     */
    protected $sliderType;

    public function __construct($sliderID, $sliderType, $data = null, $json = false) {

        $this->sliderID   = $sliderID;
        $this->sliderType = $sliderType;

        parent::__construct($data, $json);

        $this->upgradeData();
    }

    private function upgradeData() {

        $this->upgradeSliderTypeResponsive();

        $this->upgradeMaxSliderHeight();

        $this->upgradeLimitSlideWidth();

        $this->upgradeShowOn();

        $this->upgradeShowOn('widget-arrow-display-');

        $this->upgradeShowOn('widget-autoplay-display-');

        $this->upgradeShowOn('widget-bar-display-');

        $this->upgradeShowOn('widget-bullet-display-');

        $this->upgradeShowOn('widget-shadow-display-');

        $this->upgradeShowOn('widget-thumbnail-display-');

        $this->upgradeShowOn('widget-fullscreen-display-');

        $this->upgradeShowOn('widget-html-display-');

        $this->upgradeShowOn('widget-indicator-display-');

        $this->upgradeAdaptiveResponsiveMode();

        $this->upgradeCustomSliderSize();


        $this->upgradeLoadingType();

        $this->upgradeSlideBackgroundOptimize();

        $this->upgradeThumbnailsControlSize();

        $this->upgradeCarouselSideSpacing();

        $this->upgradeShowcaseSideSpacing();

        $this->upgradeShowcaseCarouselSideSpacingWithCustomSize();

        if ($this->has('optimize-background-image-width')) {
            /**
             * This setting was available only before version 3.5 so, if we end up here then it is an old slider.
             * If there are root absolute layers with disabled adaptive sizing, we enable the legacy font scale.
             */

            $slidesModel = new ModelSlides(ApplicationSmartSlider3::getInstance()
                                                                  ->getApplicationTypeFrontend());
            $hasAbsolute = false;
            $slides      = $slidesModel->getAll($this->sliderID);
            foreach ($slides as $slide) {
                $layers = json_decode($slide['slide'], true);
                foreach ($layers as $layer) {
                    if (isset($layer['type']) && $layer['type'] != 'content') {
                        if (isset($layer['adaptivefont']) && $layer['adaptivefont'] == 0 && isset($layer['item']) && in_array($layer['item']['type'], array(
                                'button',
                                'heading',
                                'text',
                                'animatedHeading',
                                'caption',
                                'highlightedHeading',
                                'html',
                                'list',
                                'imagebox',
                                'input'
                            ))) {
                            $hasAbsolute = true;
                            break;
                        }
                    }
                }
                if ($hasAbsolute) {
                    break;
                }
            }
            if ($hasAbsolute) {
                $this->set('legacy-font-scale', '1');
            }
        }
    }

    private function upgradeSliderTypeResponsive() {
        if ($this->sliderType == 'carousel' || $this->sliderType == 'showcase') {
            if ($this->get('responsive-mode') == 'fullpage') {
                $this->set('responsive-mode', 'fullwidth');
            }
        }
    }

    private function upgradeMaxSliderHeight() {
        if ($this->has('responsiveSliderHeightMax')) {
            $maxSliderHeight = intval($this->get('responsiveSliderHeightMax', 3000));
            if ($maxSliderHeight < 1) {
                $maxSliderHeight = 3000;
            }

            $sliderWidth  = intval($this->get('width'));
            $sliderHeight = intval($this->get('height'));

            $maxSliderWidth = round($sliderWidth * ($maxSliderHeight / $sliderHeight));

            $maxSlideWidth = intval($this->get('responsiveSlideWidthMax', 3000));
            if ($this->has('responsiveSlideWidth')) {
                if ($this->get('responsiveSlideWidth', 1)) {
                    if ($maxSliderWidth < $maxSlideWidth) {
                        $this->set('responsiveSlideWidthMax', $maxSliderWidth);
                    }
                } else {
                    if ($maxSliderWidth > 100) {
                        $this->set('responsiveSlideWidth', 1);
                        $this->set('responsiveSlideWidthMax', $maxSliderWidth);
                    }
                }
            } else {
                $maxWidth = INF;
                if ($maxSlideWidth > 0) {
                    $maxWidth = min($maxWidth, $maxSlideWidth);
                }
                if ($maxSliderWidth > 0) {
                    $maxWidth = min($maxWidth, $maxSliderWidth);
                }
                if ($maxWidth != INF) {
                    $this->set('responsiveSlideWidth', 1);
                    $this->set('responsiveSlideWidthMax', $maxWidth);
                }
            }
            $this->un_set('responsiveSliderHeightMax');
        }

    }

    private function upgradeLimitSlideWidth() {
        if (!$this->has('responsiveLimitSlideWidth')) {
            if (!$this->has('responsiveSlideWidth')) {
                /**
                 * Layout: Auto, fullpage
                 */
                if ($this->get('responsiveSlideWidthMax') > 0) {
                    $this->set('responsiveLimitSlideWidth', 1);
                    $this->set('responsiveSlideWidth', 1);
                } else {
                    $this->set('responsiveLimitSlideWidth', 0);
                    $this->set('responsiveSlideWidth', 0);
                }
            } else {
                /**
                 * Layout: full width
                 */
                if (!$this->get('responsiveSlideWidth') && !$this->get('responsiveSlideWidthDesktopLandscape') && !$this->get('responsiveSlideWidthTablet') && !$this->get('responsiveSlideWidthTabletLandscape') && !$this->get('responsiveSlideWidthMobile') && !$this->get('responsiveSlideWidthMobileLandscape')) {
                    $this->set('responsiveLimitSlideWidth', 0);
                } else {
                    $this->set('responsiveLimitSlideWidth', 1);
                }
            }

        }
    }

    private function upgradeShowOn($pre = '') {

        $this->upgradeShowOnDevice($pre . 'desktop');
        $this->upgradeShowOnDevice($pre . 'tablet');
        $this->upgradeShowOnDevice($pre . 'mobile');
    }

    private function upgradeShowOnDevice($device, $pre = '') {
        if ($this->has($pre . $device)) {
            $value = $this->get($pre . $device);
            $this->un_set($pre . $device);

            $this->set($device . 'portrait', $value);
            $this->set($device . 'landscape', $value);
        }
    }

    private function upgradeAdaptiveResponsiveMode() {
        $responsiveMode = $this->get('responsive-mode');
        if ($responsiveMode === 'adaptive') {
            $this->set('responsiveScaleUp', 0);
        }
    }

    private function upgradeCustomSliderSize() {
        $deviceModes = array(
            'desktop-landscape',
            'tablet-portrait',
            'tablet-landscape',
            'mobile-portrait',
            'mobile-landscape'
        );

        foreach ($deviceModes as $deviceMode) {
            if (intval($this->get($deviceMode)) === 1) {

                if (intval($this->get('slider-size-override')) === 0) {
                    $this->set('slider-size-override', 1);
                }

                $this->set('slider-size-override-' . $deviceMode, 1);
                $this->set('responsive-breakpoint-' . $deviceMode . '-enabled', 1);
            }
        }

    }

    private function upgradeLoadingType() {
        if (!empty($this->get('dependency'))) {
            $this->set('loading-type', 'afterOnLoad');
        } else {
            if (!$this->has('loading-type') && $this->get('delay') > 0) {
                $this->set('loading-type', 'afterDelay');
            }
        }
    }

    private function upgradeSlideBackgroundOptimize() {
        $optimize = $this->get('optimize');
        //Allow "Convert To Webp" if "Optimize" was enabled earlier.
        if (!empty($optimize) && $optimize) {
            $this->set('optimize-webp', 1);
        }
    

        //Slide Background Resize
        $isResizeBackgroundEnabled = $this->get('optimize-background-image-custom');
        $resizeBackgroundWidth     = $this->get('optimize-background-image-width');
        if (!empty($optimize) && $optimize) {
            $this->set('optimize-thumbnail-scale', 1);
            $this->set('optimize-thumbnail-quality', intval($this->get('optimize-quality', 70)));

            if (!empty($isResizeBackgroundEnabled) && $isResizeBackgroundEnabled && !empty($resizeBackgroundWidth)) {
                $this->set('optimize-scale', 1);

                $this->set('optimize-slide-width-normal', (int)$resizeBackgroundWidth);
            }
        }
    }

    private function upgradeThumbnailsControlSize() {
        $isThumbnailEnabled = $this->get('widget-thumbnail-enabled');

        if ($isThumbnailEnabled) {

            if (!$this->has('widget-thumbnail-tablet-width') && !$this->has('widget-thumbnail-mobile-width')) {
                $defaultThumbnailWidth = intval($this->get('widget-thumbnail-width', 100));
                $this->set('widget-thumbnail-tablet-width', $defaultThumbnailWidth);
                $this->set('widget-thumbnail-mobile-width', $defaultThumbnailWidth);
            }
            if (!$this->has('widget-thumbnail-tablet-height') && !$this->has('widget-thumbnail-mobile-height')) {
                $defaultThumbnailHeight = intval($this->get('widget-thumbnail-height', 60));
                $this->set('widget-thumbnail-tablet-height', $defaultThumbnailHeight);
                $this->set('widget-thumbnail-mobile-height', $defaultThumbnailHeight);
            }

        }
    }

    private function upgradeCarouselSideSpacing() {
        if ($this->sliderType == 'carousel') {
            if ($this->has('optimize-background-image-width')) {
                /**
                 * This setting was available only before version 3.5 so, if we end up here then it is an old slider.
                 * Earlier we automatically created top and bottom side spacing: (Slider Height - Slide Height) / 2
                 * so for old sliders we need to set those values for Side Spacing top and bottom.
                 */
                $sliderHeight = intval($this->get('height'));
                $slideHeight  = intval($this->get('slide-height'));
                if ($sliderHeight > $slideHeight) {
                    $heightDifference = $sliderHeight - $slideHeight;
                    $spacingValue     = intval($heightDifference / 2);

                    if (!$this->get('side-spacing-desktop-enable')) {
                        $this->set('side-spacing-desktop-enable', 1);
                        $this->set('side-spacing-desktop', $spacingValue . '|*|0|*|' . $spacingValue . '|*|0');
                        $this->set('height', ($sliderHeight - $heightDifference));
                    }
                }
            }
        }
    }

    private function upgradeShowcaseSideSpacing() {
        if ($this->sliderType == 'showcase') {
            if ($this->has('optimize-background-image-width')) {
                /**
                 * This setting was available only before version 3.5 so, if we end up here then it is an old slider.
                 * Earlier we automatically created top and bottom side spacing: (Slider Height - Slide Height) / 2
                 * so for old sliders we need to set those values for Side Spacing top and bottom.
                 */
                $sliderHeight = intval($this->get('height'));
                $slideHeight  = intval($this->get('slide-height'));
                if ($sliderHeight > $slideHeight) {
                    $heightDifference = $sliderHeight - $slideHeight;
                    $spacingValue     = intval($heightDifference / 2);
                    $this->set('side-spacing-desktop-enable', 1);
                    $this->set('side-spacing-desktop', $spacingValue . '|*|20|*|' . $spacingValue . '|*|20');
                    $this->set('height', ($sliderHeight - $heightDifference));
                }
            }
        }
    }

    private function upgradeShowcaseCarouselSideSpacingWithCustomSize() {
        if ($this->sliderType == 'showcase' || $this->sliderType == 'carousel') {
            /**
             * Showcase and Carousel slider types no longer have Custom size option.
             * If earlier there was a custom slider size set, then we need to add top and bottom side spacings
             */
            $customSliderSizeEnabled = intval($this->get('slider-size-override'));
            if ($customSliderSizeEnabled) {
                $sliderHeight = intval($this->get('height'));
                $slideHeight  = intval($this->get('slide-height'));

                $customTabletSizeEnabled = intval($this->get('slider-size-override-tablet-portrait'));
                if ($customTabletSizeEnabled) {
                    $customTabletSliderHeight    = intval($this->get('tablet-portrait-height'));
                    $tabletSideSpacingDifference = 0;
                    if ($customTabletSliderHeight > 0) {
                        if (($slideHeight >= $sliderHeight && $slideHeight < $customTabletSliderHeight) || ($slideHeight < $sliderHeight && $sliderHeight >= $customTabletSliderHeight)) {
                            $tabletSideSpacingDifference = round(($customTabletSliderHeight - $slideHeight) / 2);
                        }
                        if ($slideHeight < $sliderHeight && $sliderHeight < $customTabletSliderHeight) {
                            $tabletSideSpacingDifference = round((($customTabletSliderHeight - $sliderHeight) / 2) + (($sliderHeight - $slideHeight) / 2));
                        }

                        if ($slideHeight >= $customTabletSliderHeight) {
                            $tabletSideSpacingDifference = 0;
                        }
                    }

                    if ($tabletSideSpacingDifference > 0) {
                        if ($this->get('side-spacing-tablet-enable', 0)) {
                            $tabletSideSpacing = array_pad(array_map('intval', explode('|*|', $this->get('side-spacing-tablet'))), 4, 0);
                            $this->set('side-spacing-tablet', ($tabletSideSpacing[0] + $tabletSideSpacingDifference) . '|*|' . $tabletSideSpacing[1] . '|*|' . ($tabletSideSpacing[2] + $tabletSideSpacingDifference) . '|*|' . $tabletSideSpacing[3]);
                        } else {
                            $this->set('side-spacing-tablet-enable', 1);
                            $this->set('side-spacing-tablet', $tabletSideSpacingDifference . '|*|0|*|' . $tabletSideSpacingDifference . '|*|0');
                        }
                    }
                }

                $customMobileSizeEnabled = intval($this->get('slider-size-override-mobile-portrait'));
                if ($customMobileSizeEnabled) {
                    $customMobileSliderHeight    = intval($this->get('mobile-portrait-height'));
                    $mobileSideSpacingDifference = 0;
                    if ($customMobileSliderHeight > 0) {
                        if (($slideHeight >= $sliderHeight && $slideHeight < $customMobileSliderHeight) || ($slideHeight < $sliderHeight && $sliderHeight >= $customMobileSliderHeight)) {
                            $mobileSideSpacingDifference = round(($customMobileSliderHeight - $slideHeight) / 2);
                        }
                        if ($slideHeight < $sliderHeight && $sliderHeight < $customMobileSliderHeight) {
                            $mobileSideSpacingDifference = round((($customMobileSliderHeight - $sliderHeight) / 2) + (($sliderHeight - $slideHeight) / 2));
                        }

                        if ($slideHeight >= $customMobileSliderHeight) {
                            $mobileSideSpacingDifference = 0;
                        }
                    }

                    if ($mobileSideSpacingDifference > 0) {
                        if ($this->get('side-spacing-mobile-enable', 0)) {
                            $mobileSideSpacing = array_pad(array_map('intval', explode('|*|', $this->get('side-spacing-mobile'))), 4, 0);
                            $this->set('side-spacing-mobile', ($mobileSideSpacing[0] + $mobileSideSpacingDifference) . '|*|' . $mobileSideSpacing[1] . '|*|' . ($mobileSideSpacing[2] + $mobileSideSpacingDifference) . '|*|' . $mobileSideSpacing[3]);
                        } else {
                            $this->set('side-spacing-mobile-enable', 1);
                            $this->set('side-spacing-mobile', $mobileSideSpacingDifference . '|*|0|*|' . $mobileSideSpacingDifference . '|*|0');
                        }
                    }
                }
            }
        }
    }

}Slides.php000064400000017340152356644430006521 0ustar00<?php


namespace Nextend\SmartSlider3\Slider;


use Nextend\SmartSlider3\Application\Model\ModelSlides;

class Slides {

    /**
     * @var Slider
     */
    protected $slider;

    /**
     * @var Slide[]
     */
    protected $slides = array();

    /**
     * @var Slide[]
     */
    protected $allEnabledSlides = array();

    protected $maximumSlideCount = 10000;

    /**
     * Slides constructor.
     *
     * @param Slider $slider
     */
    public function __construct($slider) {
        $this->slider = $slider;

        $this->maximumSlideCount = intval($slider->params->get('maximumslidecount', 10000));
    }


    public function initSlides($slidesData = array(), $generatorData = array()) {

        $this->loadSlides($slidesData);

        $this->makeSlides($slidesData, $generatorData);

        return $this->slides;
    }

    /**
     * @param Slide[] $slides
     */
    protected function legacyFixOnlyStaticOverlays(&$slides) {

        if (count($slides)) {
            $hasNonStaticSlide = false;
            foreach ($slides as $slide) {
                if (!$slide->isStatic()) {
                    $hasNonStaticSlide = true;
                }
            }

            if (!$hasNonStaticSlide) {
                foreach ($slides as $slide) {
                    $slide->forceNonStatic();
                }
            }
        }
    }

    protected function makeSlides($slidesData, $extendGenerator = array()) {

        $slides = &$this->slides;

        if (count($slides)) {
            for ($i = 0; $i < count($slides); $i++) {
                $slides[$i]->initGenerator($extendGenerator);
            }

            for ($i = count($slides) - 1; $i >= 0; $i--) {
                if ($slides[$i]->hasGenerator()) {
                    array_splice($slides, $i, 1, $slides[$i]->expandSlide());
                }
            }

            $this->legacyFixOnlyStaticOverlays($slides);

            $staticSlides = array();
            for ($j = count($slides) - 1; $j >= 0; $j--) {
                $slide = $slides[$j];
                if ($slide->isStatic()) {
                    $staticSlides[] = $slide;
                    $this->slider->addStaticSlide($slide);
                    array_splice($slides, $j, 1);
                }
            }

            $randomize      = intval($this->slider->params->get('randomize', 0));
            $randomizeFirst = intval($this->slider->params->get('randomizeFirst', 0));
            $randomizeCache = intval($this->slider->params->get('randomize-cache', 0));
            if (!$randomizeCache && $randomize) {
                shuffle($slides);
            }

            $reverse = intval($this->slider->params->get('reverse-slides', 0));
            if ($reverse) {
                $slides = array_reverse($slides);
            }

            if ($this->maximumSlideCount > 0) {
                $mustShowSlides = array();
                if (!empty($slidesData)) {
                    for ($i = count($slides) - 1; $i >= 0; $i--) {
                        if (isset($slidesData[$slides[$i]->id])) {
                            $mustShowSlides[] = $slides[$i];
                        }
                    }
                }
                array_splice($slides, $this->maximumSlideCount);

                if (!empty($mustShowSlides)) {
                    for ($i = count($mustShowSlides) - 1; $i >= 0; $i--) {
                        if (!in_array($mustShowSlides[$i], $slides)) {
                            array_pop($slides);
                        } else {
                            array_splice($mustShowSlides, $i, 1);
                        }
                    }
                    $slides = array_merge($slides, $mustShowSlides);
                }

            }

            if (count($slides)) {
                if (!$randomizeCache && $randomizeFirst) {
                    $this->slider->setActiveSlide($slides[mt_rand(0, count($slides) - 1)]);
                } else {
                    for ($i = 0; $i < count($slides); $i++) {
                        if ($slides[$i]->isFirst()) {
                            $this->slider->setActiveSlide($slides[$i]);
                            break;
                        }
                    }
                }

                if (count($slides) == 1 && $this->slider->params->get('autoplay', 0) && $this->slider->data->get('type') === 'simple' && !$slides[0]->hasGenerator()) {
                    $slides[1] = clone $slides[0];
                }

                for ($i = 0; $i < count($slides); $i++) {
                    $slides[$i]->setPublicID($i + 1);
                }
            }
        }
    }


    public function addDummySlides() {
        /**
         * When the currently edited slide is static and there is not other slide, we create a temporary empty slide
         */
        $slidesModel = new ModelSlides($this->slider);

        $images = array(
            '$ss3-frontend$/images/placeholder/placeholder1.png',
            '$ss3-frontend$/images/placeholder/placeholder2.png'
        );
        for ($i = 0; $i < count($images); $i++) {

            $this->slides[] = $this->createSlide($slidesModel->convertSlideDataToDatabaseRow(array(
                'id'                    => $i,
                'title'                 => 'Slide #' . $i,
                'layers'                => '[]',
                'description'           => '',
                'thumbnail'             => $images[$i],
                'published'             => 1,
                'publish_up'            => '0000-00-00 00:00:00',
                'publish_down'          => '0000-00-00 00:00:00',
                'backgroundImage'       => $images[$i],
                "backgroundFocusX"      => 50,
                "backgroundFocusY"      => 100,
                'slide-background-type' => 'image'
            )));
        }

        $this->makeSlides(array());
    }

    protected function loadSlides($extend) {

        $where = $this->slidesWhereQuery();

        $slidesModel = new ModelSlides($this->slider);
        $slideRows   = $slidesModel->getAll($this->slider->sliderId, $where);

        for ($i = 0; $i < count($slideRows); $i++) {
            if (isset($extend[$slideRows[$i]['id']])) {
                $slideRows[$i] = array_merge($slideRows[$i], $extend[$slideRows[$i]['id']]);
            }
            $slide = $this->createSlide($slideRows[$i]);
            if ($slide->isVisible()) {
                $this->slides[] = $slide;
            }
            $this->allEnabledSlides[$i] = $slide;
        }
    }

    protected function createSlide($slideRow) {
        return new Slide($this->slider, $slideRow);
    }

    protected function slidesWhereQuery() {
        return " AND published = 1 ";
    }

    public function getNextCacheRefresh() {
        $earlier = 2145916800;
        for ($i = 0; $i < count($this->allEnabledSlides); $i++) {
            $earlier = min($this->allEnabledSlides[$i]->nextCacheRefresh, $earlier);
        }

        return $earlier;
    }

    /**
     * @return Slide[]
     */
    public function getSlides() {
        return $this->slides;
    }

    /**
     * @return int
     */
    public function getSlidesCount() {
        return count($this->slides);
    }

    /**
     * @return bool
     */
    public function hasSlides() {
        return !empty($this->slides);
    }

    public function prepareRender() {

        for ($i = 0; $i < count($this->slides); $i++) {
            $this->slides[$i]->setIndex($i);
            $this->slides[$i]->prepare();
            $this->slides[$i]->setSlidesParams();
        }
    }
}SliderType/AbstractSliderType.php000064400000002214152356644430013124 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\SliderType;


use Nextend\Framework\Pattern\GetAssetsPathTrait;
use Nextend\SmartSlider3\BackupSlider\ExportSlider;
use Nextend\SmartSlider3\BackupSlider\ImportSlider;
use Nextend\SmartSlider3\Slider\Slider;

abstract class AbstractSliderType {

    use GetAssetsPathTrait;

    public abstract function getName();

    /**
     * @param Slider $slider
     *
     * @return AbstractSliderTypeFrontend
     */
    public abstract function createFrontend($slider);

    /**
     * @param Slider $slider
     *
     * @return AbstractSliderTypeCss
     */
    public abstract function createCss($slider);

    /**
     *
     * @return AbstractSliderTypeAdmin
     */
    public abstract function createAdmin();

    /**
     * @param ExportSlider $export
     * @param              $slider
     */
    public function export($export, $slider) {
    }

    /**
     * @param ImportSlider $import
     * @param              $slider
     */
    public function import($import, $slider) {
    }

    public function getItemDefaults() {

        return array();
    }
}SliderType/AbstractSliderTypeAdmin.php000064400000002521152356644430014076 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\SliderType;


use Nextend\Framework\Form\Container\LayerWindow\ContainerSettings;
use Nextend\Framework\Form\Form;
use Nextend\Framework\Pattern\GetPathTrait;
use Nextend\Framework\Pattern\OrderableTrait;
use Nextend\SmartSlider3\Renderable\Component\ComponentSlide;

abstract class AbstractSliderTypeAdmin {

    use GetPathTrait;
    use OrderableTrait;

    /** @var AbstractSliderType */
    protected $type;

    public function __construct($type) {
        $this->type = $type;
    }

    public function getName() {
        return $this->type->getName();
    }

    /**
     * @return string
     */
    public abstract function getIcon();

    /**
     * @return string
     */
    public abstract function getLabel();

    /**
     * @return string
     */
    public function getLabelFull() {
        return $this->getLabel();
    }

    /**
     * @param Form $form
     */
    abstract public function prepareForm($form);

    /**
     * @param ContainerSettings $container
     */
    public function renderSlideFields($container) {

    }

    /**
     * @param ComponentSlide $component
     */
    public function registerSlideAdminProperties($component) {

    }

    public function isDepreciated() {
        return false;
    }
}SliderType/AbstractSliderTypeCss.php000064400000011321152356644430013574 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\SliderType;


use Nextend\Framework\Asset\Builder\BuilderCss;
use Nextend\Framework\Asset\Css\Css;
use Nextend\Framework\Asset\Css\Less\LessCompiler;
use Nextend\Framework\Notification\Notification;
use Nextend\Framework\Platform\Platform;
use Nextend\Framework\Sanitize;
use Nextend\SmartSlider3\Application\Frontend\ApplicationTypeFrontend;
use Nextend\SmartSlider3\Slider\Feature\Responsive;
use Nextend\SmartSlider3\Slider\Slider;

abstract class AbstractSliderTypeCss {

    /**
     * @var Slider
     */
    protected $slider;

    public $sizes = array();

    protected $context = array();

    public $base = array();

    /**
     * AbstractSliderTypeCss constructor.
     *
     * @param Slider $slider
     */
    public function __construct($slider) {
        $this->slider = $slider;


        $params = $slider->params;

        if (!Platform::needStrongerCSS()) {
            Css::addStaticGroupPreload(ApplicationTypeFrontend::getAssetsPath() . '/dist/smartslider.min.css', 'smartslider');
        }

        $width  = intval($params->get('width', 900));
        $height = intval($params->get('height', 500));
        if ($width < 10 || $height < 10) {
            Notification::error(n2_('Slider size is too small!'));
        }
        $this->context = array_merge($this->context, array(
            'sliderid'       => "~'#{$slider->elementId}'",
            'width'          => $width . 'px',
            'height'         => $height . 'px',
            'canvas'         => 0,
            'count'          => $slider->getSlidesCount(),
            'margin'         => '0px 0px 0px 0px',
            'hasPerspective' => 0
        ));

        $perspective = intval($params->get('perspective', 1500));
        if ($perspective > 0) {
            $this->context['hasPerspective'] = 1;
            $this->context['perspective']    = $perspective . 'px';
        }
    }

    public function getCSS() {
        $css = '';
        if (Platform::needStrongerCSS()) {
            $cssPath = ApplicationTypeFrontend::getAssetsPath() . '/dist/smartslider.min.css';
            if (file_exists($cssPath)) {
                $css = file_get_contents($cssPath);
            }
        }

        foreach ($this->slider->less as $file => $context) {
            $compiler = new LessCompiler();
            $compiler->setVariables($context);
            $css .= $compiler->compileFile($file);
        }
        $css .= implode('', $this->slider->css);

        $mediaQueries = $this->slider->features->responsive->mediaQueries;

        foreach ($this->slider->cssDevice as $device => $styles) {
            if (!empty($styles) && isset($mediaQueries[$device])) {
                if (empty($mediaQueries[$device])) {
                    $css .= implode('', $styles);
                } else {
                    if (!$this->slider->isAdmin) {
                        $css .= '@media ' . implode(',', $mediaQueries[$device]) . '{' . implode('', $styles) . '}';
                    } else {
                        $css .= str_replace('div#' . $this->slider->elementId, 'body[data-device="' . Responsive::$translation[$device] . '"] div#' . $this->slider->elementId, implode('', $styles));
                    }
                }
            }
        }

        if (Platform::needStrongerCSS()) {
            $css = preg_replace(array(
                '/' . preg_quote('#' . $this->slider->elementId) . '([\#\. \{,\[])/',
                '/' . preg_quote('#' . $this->slider->elementId) . '\.n2-ss-slider([\#\. \{,\[])/',
                '/\.n2-ss-align([\#\. \{,\[])/',
                '/\.n2-ss-slider([\#\. \{,\[])/'
            ), array(
                '#' . $this->slider->elementId . '#' . $this->slider->elementId . '#' . $this->slider->elementId . '$1',
                '#' . $this->slider->elementId . '#' . $this->slider->elementId . '$1',
                '#' . $this->slider->elementId . '-align#' . $this->slider->elementId . '-align$1',
                '#' . $this->slider->elementId . '#' . $this->slider->elementId . '$1'
            ), $css);
        }

        $css .= Sanitize::remove_closing_style_tag($this->slider->params->get('custom-css-codes', ''));

        return $css;
    }

    public function initSizes() {

        $this->sizes['marginVertical']   = 0;
        $this->sizes['marginHorizontal'] = 0;

        $this->sizes['width']        = intval($this->context['width']);
        $this->sizes['height']       = intval($this->context['height']);
        $this->sizes['canvasWidth']  = intval($this->context['canvaswidth']);
        $this->sizes['canvasHeight'] = intval($this->context['canvasheight']);
    }
}SliderType/AbstractSliderTypeFrontend.php000064400000044353152356644430014636 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\SliderType;


use Nextend\Framework\Asset\Builder\BuilderJs;
use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Data\Data;
use Nextend\Framework\Filesystem\Filesystem;
use Nextend\Framework\Parser\Color;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Application\Frontend\ApplicationTypeFrontend;
use Nextend\SmartSlider3\Slider\Slider;
use Nextend\SmartSlider3\Widget\SliderWidget;

abstract class AbstractSliderTypeFrontend {

    /**
     * @var Slider
     */
    protected $slider;

    protected $jsDependency = array(
        'documentReady',
        'smartslider-frontend'
    );

    protected $javaScriptProperties;

    /** @var  SliderWidget */
    protected $widgets;

    protected $shapeDividerAdded = false;

    protected $style = '';

    public function __construct($slider) {
        $this->slider = $slider;

        $this->enqueueAssets();
    }

    public function addJSDependency($dependency) {
        $this->jsDependency[] = $dependency;
    }

    protected $classes = array();

    public function addClass($className) {
        $this->classes[] = $className;
    }

    /**
     * @param AbstractSliderTypeCss $css
     *
     * @return string
     */
    public function render($css) {

        $this->javaScriptProperties = $this->slider->features->generateJSProperties();

        $this->widgets = new SliderWidget($this->slider);

        ob_start();
        $this->renderType($css);

        return ob_get_clean();
    }

    /**
     * @param AbstractSliderTypeCss $css
     *
     * @return string
     */
    protected abstract function renderType($css);

    protected function getSliderClasses() {

        return $this->slider->getAlias() . ' ' . implode(' ', $this->classes);
    }

    protected function openSliderElement() {

        $attributes = array(
            'id'              => $this->slider->elementId,
            'data-creator'    => 'Smart Slider 3',
            'data-responsive' => $this->slider->features->responsive->type,
            'class'           => 'n2-ss-slider n2-ow n2-has-hover n2notransition ' . $this->getSliderClasses(),
        );

        if ($this->slider->isLegacyFontScale()) {
            $attributes['data-ss-legacy-font-scale'] = 1;
        }

        return Html::openTag('div', $attributes);
    }

    protected function closeSliderElement() {

        return '</div>';
    }

    public function getDefaults() {
        return array();
    }

    /**
     * @param $params Data
     */
    public function limitParams($params) {

    }

    protected function encodeJavaScriptProperties() {

        $initCallback = implode($this->javaScriptProperties['initCallbacks']);
        unset($this->javaScriptProperties['initCallbacks']);

        $encoded = array();
        foreach ($this->javaScriptProperties as $k => $v) {
            $encoded[] = '"' . $k . '":' . json_encode($v);
        }
        $encoded[] = '"initCallbacks":function(){' . $initCallback . '}';

        return '{' . implode(',', $encoded) . '}';
    }


    protected function initParticleJS() {
        $particle = $this->slider->params->get('particle');
        if ($this->slider->isAdmin || empty($particle)) {
            return;
        }
        $particle = new Data($particle, true);
        $preset   = $particle->get('preset', '0');
        if ($preset != '0') {

            Js::addStaticGroup(ResourceTranslator::toPath('$ss3-pro-frontend$/dist/particle.min.js'), 'particles');

            $custom = $particle->get('custom', '');
            if ($preset == 'custom' && is_array($custom)) {
                $jsProp = $custom;
            } else {
                $jsProp = json_decode(Filesystem::readFile(ResourceTranslator::toPath('$ss3-pro-frontend$/js/particle/presets/' . $particle->get('preset') . '.json')), true);

                $color                                   = Color::colorToSVG($particle->get('color'));
                $jsProp['particles']["color"]["value"]   = '#' . $color[0];
                $jsProp['particles']["opacity"]["value"] = $color[1];

                $lineColor                                     = Color::colorToSVG($particle->get('line-color'));
                $jsProp['particles']["line_linked"]["color"]   = '#' . $lineColor[0];
                $jsProp['particles']["line_linked"]["opacity"] = $lineColor[1];

                $hover = $particle->get('hover', 0);
                if ($hover == '0') {
                    $jsProp['interactivity']["events"]["onhover"]['enable'] = 0;
                } else {
                    $jsProp['interactivity']["events"]["onhover"]['enable'] = 1;
                    $jsProp['interactivity']["events"]["onhover"]['mode']   = $hover;
                }

                $click = $particle->get('click', 0);
                if ($click == '0') {
                    $jsProp['interactivity']["events"]["onclick"]['enable'] = 0;
                } else {
                    $jsProp['interactivity']["events"]["onclick"]['enable'] = 1;
                    $jsProp['interactivity']["events"]["onclick"]['mode']   = $click;
                }

                $jsProp['particles']["number"]["value"] = max(10, min(200, $particle->get('number')));

                $jsProp['particles']["move"]["speed"] = max(1, min(60, $particle->get('speed')));
            }

            $jsProp['mobile'] = intval($particle->get('mobile', 0));

            $this->javaScriptProperties['particlejs'] = $jsProp;
        }
    
    }

    protected function renderShapeDividers() {
        $shapeDividers = $this->slider->params->get('shape-divider');
        if (!empty($shapeDividers)) {
            $shapeDividers = json_decode($shapeDividers, true);
            if ($shapeDividers) {
                $this->renderShapeDivider('top', $shapeDividers['top']);
                $this->renderShapeDivider('bottom', $shapeDividers['bottom']);
            }
        }
    
    }

    private function renderShapeDivider($side, $params) {
        $data = new Data($params);
        $type = $data->get('type', "0");
        if ($type != "0") {
            preg_match('/([a-z]+)\-(.*)/', $type, $matches);

            $type = $matches[2];
            switch ($matches[1]) {
                case 'bi':
                    $type = 'bicolor/' . $type;
                    break;
            }

            $file = ResourceTranslator::toPath('$ss3-pro-frontend$/shapedivider/' . $type . '.svg');
            if (Filesystem::existsFile($file)) {

                $animate = $data->get('animate') == '1';

                $id       = $this->slider->elementId . '-shape-divider-' . $side;
                $selector = 'div#' . $id;

                $height = max(0, $data->get('desktopportraitheight'));

                if ($height > 0) {
                    $this->slider->addDeviceCSS('all', $selector . '{' . 'height:' . $height . 'px}');
                } else {
                    $this->slider->addDeviceCSS('all', $selector . '{' . 'display:none}');
                }

                $width = $data->get('desktopportraitwidth');
                if ($width != 100) {
                    $this->slider->addDeviceCSS('all', $selector . ' .n2-ss-shape-divider-inner{' . 'width:' . $width . '%;margin: 0 ' . (($width - 100) / -2) . '%;}');

                }

                foreach ($this->slider->features->responsive->sizes as $device => $size) {
                    if ($device === 'desktopPortrait') continue;

                    $device = strtolower($device);

                    $deviceHeight = max(0, $data->get($device . 'height'));

                    if ($height != $deviceHeight) {
                        if ($height > 0) {
                            $this->slider->addDeviceCSS($device, $selector . '{' . 'height:' . $deviceHeight . 'px}');
                        } else {
                            $this->slider->addDeviceCSS($device, $selector . '{' . 'display:none}');
                        }
                    }

                    $deviceWidth = $data->get($device . 'width');
                    if ($width != $deviceWidth) {
                        $this->slider->addDeviceCSS($device, $selector . ' .n2-ss-shape-divider-inner{' . 'width:' . $deviceWidth . '%;margin: 0 ' . (($deviceWidth - 100) / -2) . '%;}');
                    }
                }

                $scroll = $data->get('scroll', null);

                $outer = array(
                    'id'                 => $id,
                    'class'              => 'n2-ss-shape-divider n2-ss-shape-divider-' . $side,
                    'data-ss-sd-animate' => ($animate ? 1 : 0),
                    'data-ss-sd-scroll'  => $scroll,
                    'data-ss-sd-speed'   => $data->get('speed', 100),
                    'data-ss-sd-side'    => $side
                );

                $inner = array(
                    'class' => 'n2-ss-shape-divider-inner',
                );
                switch ($scroll) {
                    case 'shrink':
                    case 'grow':
                        $inner['style'] = 'transform:scaleY(0)';
                        break;
                }

                $svg = Filesystem::readFile($file);

                if (!$animate) {
                    /**
                     * when not animated, we do not need the start state of the svg
                     */
                    $svg = preg_replace_callback('/((to-)?d)(=".*?")/', function ($match) {
                        if ($match[1] === 'd') {
                            return '';
                        }

                        return 'd' . $match[3];
                    }, $svg);
                }

                /**
                 * compress svg
                 */
                $svg = preg_replace('/\s\s+/', ' ', preg_replace('/[\n\r\t]/', '', $svg));

                if ($side == 'bottom') {
                    if ($data->get('flip') == '1') {
                        $svg = SVGFlip::mirror($svg, true, true);
                    } else {
                        $svg = SVGFlip::mirror($svg, false, true);
                    }
                } else {
                    if ($data->get('flip') == '1') {
                        $svg = SVGFlip::mirror($svg, true, false);
                    }
                }

                $output = Html::tag('div', $outer, Html::tag('div', $inner, str_replace(array(
                    '#000000',
                    '#000010'
                ), array(
                    Color::colorToRGBA($data->get('color')),
                    Color::colorToRGBA($data->get('color2'))
                ), $svg)));
                // PHPCS - Content already escaped
                echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

                if (!$this->shapeDividerAdded) {

                    $path = ResourceTranslator::toPath('$ss3-pro-frontend$/dist/shapedivider.min.js');
                    if (file_exists($path)) {
                        $this->javaScriptProperties['initCallbacks'][] = file_get_contents($path);
                    } else {
                    }

                    $this->shapeDividerAdded = true;
                }
            }
        }
    
    }

    /**
     * @return string
     */
    public function getScript() {
        return '';
    }

    public function getStyle() {
        return $this->style;
    }

    public function setJavaScriptProperty($key, $value) {
        $this->javaScriptProperties[$key] = $value;
    }

    public function enqueueAssets() {

        Js::addStaticGroup(ApplicationTypeFrontend::getAssetsPath() . '/dist/smartslider-frontend.min.js', 'smartslider-frontend');
    }

    public function handleSliderMinHeight($minHeight) {

        $this->slider->addDeviceCSS('all', 'div#' . $this->slider->elementId . ' .n2-ss-slider-1{min-height:' . $minHeight . 'px;}');
    }

    public function displaySizeSVGs($css, $hasMaxWidth = false) {
        if (!$this->slider->isAdmin && $this->slider->features->responsive->type == 'fullpage' && !intval($this->slider->params->get('responsiveConstrainRatio', 0))) {

            /**
             * Full page responsive type with constrain ratio off does not use the initial slider size to prevent too large heights.
             */
            return;
        }
    

        $attrs = array(
            'xmlns'               => "http://www.w3.org/2000/svg",
            'viewBox'             => '0 0 ' . $css->base['sliderWidth'] . ' ' . $css->base['sliderHeight'],
            'data-related-device' => "desktopPortrait",
            'class'               => "n2-ow n2-ss-preserve-size n2-ss-preserve-size--slider n2-ss-slide-limiter"
        );
        if ($hasMaxWidth) {
            $attrs['style'] = 'max-width:' . $css->base['sliderWidth'] . 'px';
        }

        $svgs = array(
            Html::tag('svg', $attrs, '')
        );

        foreach ($this->slider->features->responsive->sizes as $device => $size) {
            if ($device === 'desktopPortrait') continue;

            if ($size['customHeight'] && $size['width'] > 0 && $size['height'] > 0) {

                $attrs['viewBox']             = '0 0 ' . $size['width'] . ' ' . $size['height'];
                $attrs['data-related-device'] = $device;
                if ($hasMaxWidth) {
                    $attrs['style'] = 'max-width:' . $size['width'] . 'px';
                }

                $svgs[] = Html::tag('svg', $attrs, '');

                $styles = array(
                    'div#' . $this->slider->elementId . ' .n2-ss-preserve-size[data-related-device="desktopPortrait"] {display:none}',
                    'div#' . $this->slider->elementId . ' .n2-ss-preserve-size[data-related-device="' . $device . '"] {display:block}'
                );
                $this->slider->addDeviceCSS(strtolower($device), implode('', $styles));
            }

        }

        // PHPCS - Content already escaped
        echo implode('', $svgs);  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }

    protected function initSliderBackground($selector) {

        $params = $this->slider->params;

        $backgroundImage = $params->get('background');
        $backgroundColor = $params->get('background-color', '');

        $sliderCSS2 = '';

        if (!empty($backgroundImage)) {
            $sliderCSS2 .= 'background-image: url(' . ResourceTranslator::toUrl($backgroundImage) . ');';
        }
        if (!empty($backgroundColor)) {
            $rgba = Color::hex2rgba($backgroundColor);
            if ($rgba[3] != 0) {
                $sliderCSS2 .= 'background-color:RGBA(' . $rgba[0] . ',' . $rgba[1] . ',' . $rgba[2] . ',' . round($rgba[3] / 127, 2) . ');';
            }
        }

        if (!empty($sliderCSS2)) {

            $this->slider->addCSS('div#' . $this->slider->elementId . ' ' . $selector . '{' . $sliderCSS2 . '}');
            if (!empty($backgroundImage)) {

                $optimizedData = $this->slider->features->optimize->optimizeImageWebP($backgroundImage, array(
                    'optimize'     => $this->slider->params->get('optimize-slider-webp', 0),
                    'quality'      => intval($this->slider->params->get('optimize-slider-quality', 70)),
                    'resize'       => $this->slider->params->get('optimize-slider-scale', 0),
                    'defaultWidth' => intval($this->slider->params->get('optimize-slider-width-normal', 1920)),
                    'mediumWidth'  => intval($this->slider->params->get('optimize-slider-width-tablet', 1200)),
                    'mediumHeight' => intval($this->slider->params->get('optimize-slider-height-tablet', 0)),
                    'smallWidth'   => intval($this->slider->params->get('optimize-slider-width-mobile', 500)),
                    'smallHeight'  => intval($this->slider->params->get('optimize-slider-height-mobile', 0)),
                ));


                if (isset($optimizedData['normal'])) {
                    $this->slider->addImage($optimizedData['normal']['src']);

                    $this->slider->addCSS('.n2webp div#' . $this->slider->elementId . ' ' . $selector . '{background-image: url(' . $optimizedData['normal']['src'] . ')}');
                }

                if (isset($optimizedData['medium'])) {
                    $this->slider->addImage($optimizedData['medium']['src']);

                    $this->slider->addCSS('@media (max-width: ' . $optimizedData['medium']['width'] . 'px) {.n2webp div#' . $this->slider->elementId . ' ' . $selector . '{background-image: url(' . $optimizedData['medium']['src'] . ')}}');
                }

                if (isset($optimizedData['small'])) {
                    $this->slider->addImage($optimizedData['small']['src']);

                    $this->slider->addCSS('@media (max-width: ' . $optimizedData['small']['width'] . 'px) {.n2webp div#' . $this->slider->elementId . ' ' . $selector . '{background-image: url(' . $optimizedData['small']['src'] . ')}}');

                }

            }
        
        }
    }

    protected function getBackgroundVideo($params) {
        $mp4 = ResourceTranslator::toUrl($params->get('backgroundVideoMp4', ''));

        if (empty($mp4)) {
            return '';
        }

        $attributes = array();

        if ($params->get('backgroundVideoLoop', 1)) {
            $attributes['loop'] = 'loop';
        }

        $objectFit = 'cover';
        if ($params->get('backgroundVideoMode', 'fill') == 'fit') {

            $objectFit = 'contain';
        }

        return Html::tag('video', $attributes + array(
                'class'              => 'n2-ss-slider-background-video n2-ow n2-' . $objectFit,
                'playsinline'        => 1,
                'webkit-playsinline' => 1,
                'data-keepplaying'   => 1,
                'preload'            => 'none',
                'muted'              => 'muted'
            ), Html::tag("source", array(
            "src"  => $mp4,
            "type" => "video/mp4"
        ), '', false));
    }
}SliderType/SliderTypeFactory.php000064400000004567152356644430013005 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\SliderType;


use Nextend\Framework\Pattern\OrderableTrait;
use Nextend\Framework\Pattern\PluggableTrait;
use Nextend\Framework\Pattern\SingletonTrait;
use Nextend\SmartSlider3\Slider\Slider;

class SliderTypeFactory {

    use SingletonTrait, PluggableTrait, OrderableTrait;

    /**
     * @var AbstractSliderType[]
     */
    private static $types = array();

    /**
     * @param AbstractSliderType $sliderType
     */
    public static function addType($sliderType) {
        self::$types[$sliderType->getName()] = $sliderType;
    }

    /**
     * @param $name
     *
     * @return AbstractSliderType|null
     */
    public static function getType($name) {

        if (isset(self::$types[$name])) {
            return self::$types[$name];
        }

        if ($name == 'simple') {
            /**
             * There is no fallback if simple type missing
             */
            return null;
        }

        return self::getType('simple');
    }

    /**
     * @return AbstractSliderType[]
     */
    public static function getTypes() {

        return self::$types;
    }

    /**
     * @return AbstractSliderTypeAdmin[]
     */
    public static function getAdminTypes() {
        $adminTypes = array();

        foreach (self::$types as $name => $type) {
            $admin = $type->createAdmin();
            if ($admin) {
                $adminTypes[$name] = $admin;
            }
        }

        self::uasort($adminTypes);

        return $adminTypes;
    }

    protected function init() {

        $this->makePluggable('SliderType');
    }

    /**
     * @param        $name
     * @param Slider $slider
     *
     * @return AbstractSliderTypeFrontend|null
     */
    public static function createFrontend($name, $slider) {
        $type = self::getType($name);
        if ($type) {
            return $type->createFrontend($slider);
        }

        return null;
    }

    /**
     * @param        $name
     * @param Slider $slider
     *
     * @return AbstractSliderTypeCss|null
     */
    public static function createCss($name, $slider) {
        $type = self::getType($name);
        if ($type) {
            return $type->createCss($slider);
        }

        return null;
    }
}

SliderTypeFactory::getInstance();SliderType/SVGFlip.php000064400000015763152356644430010643 0ustar00<?php

namespace Nextend\SmartSlider3\Slider\SliderType;

class SVGFlip {

    private static $viewBoxX;
    private static $viewBoxY;

    /**
     * @param string $svg
     * @param bool   $x
     * @param bool   $y
     *
     * @return string
     */
    public static function mirror($svg, $x, $y) {
        /* @var callable $callable */

        if ($x && $y) {
            $callable = array(
                self::class,
                'xy'
            );
        } else if ($x) {
            $callable = array(
                self::class,
                'x'
            );
        } else if ($y) {
            $callable = array(
                self::class,
                'y'
            );
        } else {
            return $svg;
        }

        preg_match('/(viewBox)=[\'"](.*?)[\'"]/i', $svg, $viewBoxResult);
        $viewBox        = explode(' ', end($viewBoxResult));
        self::$viewBoxX = $viewBox[2];
        self::$viewBoxY = $viewBox[3];

        $pattern = '/d=[\'"](.*?)[\'"]/i';

        return preg_replace_callback($pattern, $callable, $svg);
    }

    private static function x($matches) {
        $path = $matches[1];

        $path    = substr($path, 0, -1);
        $values  = explode(' ', $path);
        $newPath = '';
        for ($i = 0; $i < count($values); $i++) {
            $pathCommand = substr($values[$i], 0, 1);
            $pathPart    = substr($values[$i], 1);
            $points      = explode(',', $pathPart);
            if ($pathCommand === 'A') {
                $points[2] = -$points[2];
                $points[4] = ($points[4]) ? 1 : 0;
                $points[5] = self::$viewBoxX - $points[5];
            } else if ($pathCommand == 'a') {
                $points[2] = -$points[2];
                $points[4] = ($points[4]) ? 1 : 0;
                $points[5] = -$points[5];
            } else {
                for ($j = 0; $j < count($points); $j = $j + 2) {
                    switch ($pathCommand) {
                        case 'l':
                        case 'm':
                        case 'h':
                        case 'c':
                        case 's':
                        case 'q':
                        case 't':
                            $points[$j] = -$points[$j];
                            break;
                        case 'L':
                        case 'M':
                        case 'H':
                        case 'C':
                        case 'S':
                        case 'Q':
                        case 'T':
                            $points[$j] = self::$viewBoxX - $points[$j];
                            break;
                    }
                }
            }
            $newPath .= $pathCommand . implode(',', $points);
        }

        return 'd="' . $newPath . 'z"';
    }

    private static function y($matches) {
        $path = $matches[1];

        $path    = substr($path, 0, -1);
        $values  = explode(' ', $path);
        $newPath = '';
        for ($i = 0; $i < count($values); $i++) {
            $pathCommand = substr($values[$i], 0, 1);
            $pathPart    = substr($values[$i], 1);
            $points      = explode(',', $pathPart);
            if ($pathCommand === 'A') {
                $points[2] = -$points[2];
                $points[4] = ($points[4]) ? 1 : 0;
                $points[6] = self::$viewBoxY - $points[6];
            } else if ($pathCommand === 'a') {
                $points[2] = -$points[2];
                $points[4] = ($points[4]) ? 1 : 0;
                $points[6] = -$points[6];
            } else {
                for ($j = 0; $j < count($points); $j = $j + 2) {
                    switch ($pathCommand) {
                        case 'v':
                            $points[$j] = -$points[$j];
                            break;
                        case 'V':
                            $points[$j] = self::$viewBoxY - $points[$j];
                            break;
                        case 'l':
                        case 'm':
                        case 'c':
                        case 's':
                        case 'q':
                        case 't':
                            $points[$j + 1] = -$points[$j + 1];
                            break;
                        case 'L':
                        case 'M':
                        case 'C':
                        case 'S':
                        case 'Q':
                        case 'T':
                            $points[$j + 1] = self::$viewBoxY - $points[$j + 1];
                            break;
                    }
                }
            }
            $newPath .= $pathCommand . implode(',', $points);
        }

        return 'd="' . $newPath . 'z"';
    }

    private static function xy($matches) {
        $path = $matches[1];

        $path    = substr($path, 0, -1);
        $values  = explode(' ', $path);
        $newPath = '';
        for ($i = 0; $i < count($values); $i++) {
            $pathCommand = substr($values[$i], 0, 1);
            $pathPart    = substr($values[$i], 1);
            $points      = explode(',', $pathPart);
            if ($pathCommand === 'A') {
                $points[5] = self::$viewBoxX - $points[5];
                $points[6] = self::$viewBoxY - $points[6];
            } else if ($pathCommand == 'a') {
                $points[5] = -$points[5];
                $points[6] = -$points[6];
            } else {
                for ($j = 0; $j < count($points); $j = $j + 2) {
                    switch ($pathCommand) {
                        case 'h':
                        case 'v':
                            $points[$j] = -$points[$j];
                            break;
                        case 'H':
                            $points[$j] = self::$viewBoxX - $points[$j];
                            break;
                        case 'V':
                            $points[$j] = self::$viewBoxY - $points[$j];
                            break;
                        case 'l':
                        case 'm':
                        case 'c':
                        case 's':
                        case 'q':
                        case 't':
                            $points[$j]     = -$points[$j];
                            $points[$j + 1] = -$points[$j + 1];
                            break;
                        case 'L':
                        case 'M':
                        case 'C':
                        case 'S':
                        case 'Q':
                        case 'T':
                            $points[$j]     = self::$viewBoxX - $points[$j];
                            $points[$j + 1] = self::$viewBoxY - $points[$j + 1];
                            break;
                    }
                }
            }
            $newPath .= $pathCommand . implode(',', $points);
        }

        return 'd="' . $newPath . 'z"';
    }
}SliderType/Block/SliderTypeBlock.php000064400000002041152356644430013443 0ustar00<?php

namespace Nextend\SmartSlider3\Slider\SliderType\Block;

use Nextend\SmartSlider3\Slider\SliderType\AbstractSliderType;

class SliderTypeBlock extends AbstractSliderType {

    public function getName() {
        return 'block';
    }

    public function createFrontend($slider) {
        return new SliderTypeBlockFrontend($slider);
    }

    public function createCss($slider) {
        return new SliderTypeBlockCss($slider);
    }


    public function createAdmin() {
        return new SliderTypeBlockAdmin($this);
    }

    public function export($export, $slider) {
        $export->addImage($slider['params']->get('background', ''));
        $export->addImage($slider['params']->get('backgroundVideoMp4', ''));
    }

    public function import($import, $slider) {

        $slider['params']->set('background', $import->fixImage($slider['params']->get('background', '')));
        $slider['params']->set('backgroundVideoMp4', $import->fixImage($slider['params']->get('backgroundVideoMp4', '')));
    }
}SliderType/Block/SliderTypeBlockAdmin.php000064400000016601152356644430014423 0ustar00<?php

namespace Nextend\SmartSlider3\Slider\SliderType\Block;

use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Container\ContainerRowGroup;
use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Grouping;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Element\Textarea;
use Nextend\Framework\Form\Fieldset\FieldsetRow;
use Nextend\Framework\Form\Fieldset\LayerWindow\FieldsetLayerWindow;
use Nextend\Framework\Form\Insert\InsertAfter;
use Nextend\Framework\Form\Insert\InsertBefore;
use Nextend\SmartSlider3\Slider\SliderType\AbstractSliderTypeAdmin;
use Nextend\SmartSlider3Pro\Form\Element\PostBackgroundAnimation;
use Nextend\SmartSlider3Pro\PostBackgroundAnimation\PostBackgroundAnimationManager;

class SliderTypeBlockAdmin extends AbstractSliderTypeAdmin {

    protected $ordering = 2;

    public function getLabel() {
        return n2_('Block');
    }

    public function getIcon() {
        return 'ssi_64 ssi_64--block';
    }

    public function prepareForm($form) {


        $form->getElement('/autoplay')
             ->remove();
        $tableBackground = new ContainerTable(new InsertBefore($form->getElement('/animations/effects')), 'slider-type-block-background', n2_('Background animation'));

        $rowKenBurns = new FieldsetRow($tableBackground, 'slider-type-block-kenburns');

        new PostBackgroundAnimation($rowKenBurns, 'kenburns-animation', n2_('Ken Burns effect'), '50|*|50|*|', array(
            'relatedFields' => array(
                'sliderkenburns-animation-speed',
                'sliderkenburns-animation-strength'
            )
        ));

        new Select($rowKenBurns, 'kenburns-animation-speed', n2_('Speed'), 'default', array(
            'options' => array(
                'default'   => n2_('Default'),
                'superSlow' => n2_('Super slow') . ' 0.25x',
                'slow'      => n2_('Slow') . ' 0.5x',
                'normal'    => n2_('Normal') . ' 1x',
                'fast'      => n2_('Fast') . ' 2x',
                'superFast' => n2_('Super fast') . ' 4x'
            )
        ));

        new Select($rowKenBurns, 'kenburns-animation-strength', n2_('Strength'), 'default', array(
            'options' => array(
                'default'     => n2_('Default'),
                'superSoft'   => n2_('Super soft') . ' 0.3x',
                'soft'        => n2_('Soft') . ' 0.6x',
                'normal'      => n2_('Normal') . ' 1x',
                'strong'      => n2_('Strong') . ' 1.5x',
                'superStrong' => n2_('Super strong') . ' 2x'
            )
        ));

        $rowGroup = new ContainerRowGroup(new InsertAfter($form->getElement('/general/design/design-1')), 'slider-type-block-group-general', false);

        $rowStyle = new FieldsetRow($rowGroup, 'slider-type-simple-settings-style');

        new Number($rowStyle, 'border-width', n2_('Border width'), 0, array(
            'unit'          => 'px',
            'wide'          => 3,
            'relatedFields' => array('sliderborder-color')
        ));
        new Color($rowStyle, 'border-color', n2_('Border color'), '3E3E3Eff', array(
            'alpha' => true
        ));
        new Number($rowStyle, 'border-radius', n2_('Border radius'), 0, array(
            'unit' => 'px',
            'wide' => 3
        ));

        $rowOther = new FieldsetRow($rowGroup, 'slider-type-block-other');
        new Textarea($rowOther, 'slider-css', n2_('Slider') . ' CSS', '', array(
            'height' => 26
        ));
    

        /**
         * Removing slider settings which are unnecessary for Block slider type.
         */
        $form->getElement('/controls/general')
             ->remove();
        $form->getElement('/general/alias/alias-1/alias-slideswitch')
             ->remove();
        $form->getElement('/controls/widget-arrow')
             ->remove();
        $form->getElement('/controls/widget-bullet')
             ->remove();
        $form->getElement('/controls/widget-bar')
             ->remove();
        $form->getElement('/controls/widget-thumbnail')
             ->remove();
        $form->getElement('/developer/developer/developer-1/controlsBlockCarouselInteraction')
             ->remove();
        $form->getElement('/animations/layer-animations')
             ->remove();
        $form->getElement('/optimize/optimize-slide/optimize-slide-loading-mode')
             ->remove();
        $form->getElement('/slides/slides-randomize')
             ->remove();
        $form->getElement('/slides/other')
             ->remove();
        $form->getElement('/controls/widget-fullscreen')
             ->remove();
    

    }

    public function renderSlideFields($container) {
        $dataToFields = array();

        $tableAnimation = new FieldsetLayerWindow($container, 'fields-slide-animation', n2_('Animation'));

        PostBackgroundAnimationManager::enqueue($container->getForm());

        $rowKenBurns = new Grouping($tableAnimation, 'slide-settings-animation-ken-burns');
        new PostBackgroundAnimation($rowKenBurns, 'kenburns-animation', n2_('Ken Burns effect'), '', array(
            'relatedFields' => array(
                'layerkenburns-animation-speed',
                'layerkenburns-animation-strength'
            )
        ));
        $dataToFields[] = [
            'name' => 'kenburns-animation',
            'id'   => 'layerkenburns-animation',
            'def'  => '50|*|50|*'
        ];

        new Select($rowKenBurns, 'kenburns-animation-speed', n2_('Speed'), '', array(
            'options' => array(
                'default'   => n2_('Default'),
                'superSlow' => n2_('Super slow') . ' 0.25x',
                'slow'      => n2_('Slow') . ' 0.5x',
                'normal'    => n2_('Normal') . ' 1x',
                'fast'      => n2_('Fast') . ' 2x',
                'superFast' => n2_('Super fast' . ' 4x')
            )
        ));
        $dataToFields[] = [
            'name' => 'kenburns-animation-speed',
            'id'   => 'layerkenburns-animation-speed',
            'def'  => 'default'
        ];

        new Select($rowKenBurns, 'kenburns-animation-strength', n2_('Strength'), '', array(
            'options' => array(
                'default'     => n2_('Default'),
                'superSoft'   => n2_('Super soft') . ' 0.3x',
                'soft'        => n2_('Soft') . ' 0.6x',
                'normal'      => n2_('Normal') . ' 1x',
                'strong'      => n2_('Strong') . ' 1.5x',
                'superStrong' => n2_('Super strong') . ' 2x'
            )
        ));
        $dataToFields[] = [
            'name' => 'kenburns-animation-strength',
            'id'   => 'layerkenburns-animation-strength',
            'def'  => 'default'
        ];

        Js::addInline("_N2.r('SectionSlide', function(){ _N2.SectionSlide.addExternalDataToField(" . json_encode($dataToFields) . ");});");
    

    }

    public function registerSlideAdminProperties($component) {
        $component->createProperty('kenburns-animation', '50|*|50|*|');
        $component->createProperty('kenburns-animation-speed', 'default');
        $component->createProperty('kenburns-animation-strength', 'default');
    
    }
}SliderType/Block/SliderTypeBlockCss.php000064400000003310152356644430014114 0ustar00<?php

namespace Nextend\SmartSlider3\Slider\SliderType\Block;

use Nextend\Framework\Parser\Color;
use Nextend\SmartSlider3\Slider\SliderType\AbstractSliderTypeCss;

class SliderTypeBlockCss extends AbstractSliderTypeCss {

    public function __construct($slider) {
        parent::__construct($slider);
        $params = $this->slider->params;

        $width  = intval($this->context['width']);
        $height = intval($this->context['height']);

        $borderWidth                 = $params->getIfEmpty('border-width', 0);
        $borderColor                 = $params->get('border-color');
        $this->context['border']     = $borderWidth . 'px';
        $rgba                        = Color::hex2rgba($borderColor);
        $this->context['borderrgba'] = 'RGBA(' . $rgba[0] . ',' . $rgba[1] . ',' . $rgba[2] . ',' . round($rgba[3] / 127, 2) . ')';

        $this->context['borderRadius'] = $params->get('border-radius') . 'px';

        $this->context['backgroundSize']       = $params->getIfEmpty('background-size', 'inherit');
        $this->context['backgroundAttachment'] = $params->get('background-fixed') ? 'fixed' : 'scroll';

        $this->context['canvaswidth']  = $width . "px";
        $this->context['canvasheight'] = $height . "px";

        $this->base = array(
            'slideOuterWidth'  => $width,
            'slideOuterHeight' => $height,
            'sliderWidth'      => $width,
            'sliderHeight'     => $height,
            'slideWidth'       => $width,
            'slideHeight'      => $height
        );

        $this->initSizes();

        $this->slider->addLess(SliderTypeBlock::getAssetsPath() . '/style.n2less', $this->context);
    }
}SliderType/Block/SliderTypeBlockFrontend.php000064400000011100152356644430015137 0ustar00<?php

namespace Nextend\SmartSlider3\Slider\SliderType\Block;

use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Data\Data;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Slider\SliderType\AbstractSliderTypeFrontend;

class SliderTypeBlockFrontend extends AbstractSliderTypeFrontend {

    public function getDefaults() {
        return array(
            'background'       => '',
            'background-size'  => 'cover',
            'background-fixed' => 0,
            'slider-css'       => '',
            'border-width'     => 0,
            'border-color'     => '3E3E3Eff',
            'border-radius'    => 0,

            'kenburns-animation' => ''
        );
    }

    protected function renderType($css) {

        $params = $this->slider->params;

        Js::addStaticGroup(SliderTypeBlock::getAssetsPath() . '/dist/ss-block.min.js', 'ss-block');

        $this->jsDependency[] = 'ss-block';

        $sliderCSS = $params->get('slider-css');

        $this->initSliderBackground('.n2-ss-slider-1');

        $this->initParticleJS();

        echo wp_kses($this->openSliderElement(), Sanitize::$basicTags);
        ob_start();

        $slide = $this->slider->getActiveSlide();
        $slide->finalize();
        ?>

        <div class="n2-ss-slider-1 n2-ow"<?php echo empty($sliderCSS) ? '' : ' style="' . esc_attr($sliderCSS) . '"'; ?>>
            <div class="n2-ss-slider-2 n2-ow">
                <?php
                echo wp_kses($this->getBackgroundVideo($params), Sanitize::$videoTags);

                // PHPCS - Content already escaped
                echo Html::tag('div', array('class' => 'n2-ss-slide-backgrounds n2-ow-all'), $slide->background); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
                ?>
                <div class="n2-ss-slider-3 n2-ow">
                    <?php
                    $this->displaySizeSVGs($css);

                    // PHPCS - Content already escaped
                    echo $this->slider->staticHtml; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

                    // PHPCS - Content already escaped
                    echo Html::tag('div', Html::mergeAttributes($slide->attributes, $slide->linkAttributes, array( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
                                                                                                                   'class' => 'n2-ss-slide n2-ow ' . $slide->classes,
                                                                                                                   'style' => $slide->style
                    )), $slide->getHTML());
                    ?>
                </div>
                <?php

                $this->renderShapeDividers();
                ?>
            </div>
        </div>
        <?php

        // PHPCS - Content already escaped
        echo $this->widgets->wrapSlider(ob_get_clean()); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        echo wp_kses($this->closeSliderElement(), Sanitize::$basicTags);

        $this->style .= $css->getCSS();
    }

    public function getScript() {
        return "_N2.r(" . json_encode(array_unique($this->jsDependency)) . ",function(){new _N2.SmartSliderBlock('{$this->slider->elementId}', " . $this->encodeJavaScriptProperties() . ");});";
    }

    /**
     * @param $params Data
     */
    public function limitParams($params) {

        $params->loadArray(array(
            'controlsScroll'            => 0,
            'controlsDrag'              => 0,
            'controlsTouch'             => 0,
            'controlsKeyboard'          => 0,
            'blockCarouselInteraction'  => 1,
            'autoplay'                  => 0,
            'autoplayStart'             => 0,
            'widget-arrow-enabled'      => 0,
            'widget-bullet-enabled'     => 0,
            'widget-autoplay-enabled'   => 0,
            'widget-indicator-enabled'  => 0,
            'widget-bar-enabled'        => 0,
            'widget-thumbnail-enabled'  => 0,
            'widget-fullscreen-enabled' => 0,
            'randomize'                 => 0,
            'randomizeFirst'            => 0,
            'randomize-cache'           => 0,
            'maximumslidecount'         => 1,
            'imageload'                 => 0,
            'imageloadNeighborSlides'   => 0,
            'maintain-session'          => 0,
            'global-lightbox'           => 0
        ));
    }
}SliderType/Simple/SliderTypeSimple.php000064400000002051152356644430014042 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\SliderType\Simple;

use Nextend\SmartSlider3\Slider\SliderType\AbstractSliderType;

class SliderTypeSimple extends AbstractSliderType {

    public function getName() {
        return 'simple';
    }

    public function createFrontend($slider) {
        return new SliderTypeSimpleFrontend($slider);
    }

    public function createCss($slider) {
        return new SliderTypeSimpleCss($slider);
    }


    public function createAdmin() {
        return new SliderTypeSimpleAdmin($this);
    }

    public function export($export, $slider) {
        $export->addImage($slider['params']->get('background', ''));
        $export->addImage($slider['params']->get('backgroundVideoMp4', ''));
    }

    public function import($import, $slider) {

        $slider['params']->set('background', $import->fixImage($slider['params']->get('background', '')));
        $slider['params']->set('backgroundVideoMp4', $import->fixImage($slider['params']->get('backgroundVideoMp4', '')));
    }
}SliderType/Simple/SliderTypeSimpleAdmin.php000064400000037274152356644430015032 0ustar00<?php

namespace Nextend\SmartSlider3\Slider\SliderType\Simple;

use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Container\ContainerRowGroup;
use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Grouping;
use Nextend\Framework\Form\Element\Hidden;
use Nextend\Framework\Form\Element\MarginPadding;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Radio;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\Easing;
use Nextend\Framework\Form\Element\Select\Skin;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;
use Nextend\Framework\Form\Element\Textarea;
use Nextend\Framework\Form\Fieldset\FieldsetRow;
use Nextend\Framework\Form\Fieldset\LayerWindow\FieldsetLayerWindow;
use Nextend\Framework\Form\Insert\InsertAfter;
use Nextend\Framework\Form\Insert\InsertBefore;
use Nextend\SmartSlider3\BackgroundAnimation\BackgroundAnimationManager;
use Nextend\SmartSlider3\Form\Element\BackgroundAnimation;
use Nextend\SmartSlider3\Slider\SliderType\AbstractSliderTypeAdmin;
use Nextend\SmartSlider3Pro\Form\Element\PostBackgroundAnimation;
use Nextend\SmartSlider3Pro\PostBackgroundAnimation\PostBackgroundAnimationManager;

class SliderTypeSimpleAdmin extends AbstractSliderTypeAdmin {

    protected $ordering = 1;

    public function getLabel() {
        return n2_('Simple');
    }

    public function getLabelFull() {
        return n2_x('Simple slider', 'Slider type');
    }

    public function getIcon() {
        return 'ssi_64 ssi_64--slider';
    }

    public function prepareForm($form) {

        $tableMainAnimation = new ContainerTable(new InsertBefore($form->getElement('/animations/effects')), 'slider-type-simple-main-animation', n2_('Main animation'));

        $rowMainAnimation = new FieldsetRow($tableMainAnimation, 'slider-type-simple-main-animation-1');

        new Select($rowMainAnimation, 'animation', n2_('Main animation'), 'horizontal', array(
            'options'            => array(
                'no'                  => n2_('No animation'),
                'fade'                => n2_('Fade'),
                'crossfade'           => n2_('Crossfade'),
                'horizontal'          => n2_('Horizontal'),
                'vertical'            => n2_('Vertical'),
                'horizontal-reversed' => n2_('Horizontal - reversed'),
                'vertical-reversed'   => n2_('Vertical - reversed')
            ),
            'relatedValueFields' => array(
                array(
                    'values' => array(
                        'fade',
                        'crossfade',
                        'horizontal',
                        'vertical',
                        'horizontal-reversed',
                        'vertical-reversed'
                    ),
                    'field'  => array(
                        'slideranimation-duration',
                        'slideranimation-delay',
                        'slideranimation-easing'
                    )
                )
            )
        ));


        new NumberAutoComplete($rowMainAnimation, 'animation-duration', n2_('Duration'), 800, array(
            'min'    => 0,
            'values' => array(
                800,
                1500,
                2000
            ),
            'unit'   => 'ms',
            'wide'   => 5
        ));
        new Number($rowMainAnimation, 'animation-delay', n2_('Delay'), 0, array(
            'min'  => 0,
            'unit' => 'ms',
            'wide' => 5
        ));
        new Easing($rowMainAnimation, 'animation-easing', n2_('Easing'), 'easeOutQuad');

        new OnOff($rowMainAnimation, 'carousel', n2_x('Carousel', 'Feature'), 1, array(
            'tipLabel'         => n2_x('Carousel', 'Feature'),
            'tipDescription'   => n2_('If you turn off this option, you can\'t switch to the first slide from the last one.'),
            'tipLink'          => 'https://smartslider.helpscoutdocs.com/article/1780-simple-slider-type#carousel',
            'relatedFieldsOn'  => array(
                'slidercontrolsBlockCarouselInteraction'
            ),
            'relatedFieldsOff' => array(
                'sliderdisabled-carousel-notice'
            )
        ));
    

        $tableBackground = new ContainerTable(new InsertBefore($form->getElement('/animations/effects')), 'slider-type-simple-background', n2_('Background animation'));

        $rowBackgroundAnimation = new FieldsetRow($tableBackground, 'slider-type-simple-background-animation');

        new BackgroundAnimation($rowBackgroundAnimation, 'background-animation', n2_('Background animation'), '', array(
            'relatedFields'  => array(
                'sliderbackground-animation-speed',
                'slideranimation-shifted-background-animation'
            ),
            'tipLabel'       => n2_('Background animation'),
            'tipDescription' => n2_('Background animations only work on the slide background images, which have Fill selected at their Fill mode. They don\'t affect any images if the background parallax is enabled.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1780-simple-slider-type#background-animation',
        ));
        new Hidden($rowBackgroundAnimation, 'background-animation-color', '333333ff');

        new Select($rowBackgroundAnimation, 'background-animation-speed', n2_('Speed'), 'normal', array(
            'options' => array(
                'superSlow10' => n2_('Super slow') . ' 10x',
                'superSlow'   => n2_('Super slow') . ' 3x',
                'slow'        => n2_('Slow') . ' 1.5x',
                'normal'      => n2_('Normal') . ' 1x',
                'fast'        => n2_('Fast') . ' 0.75x',
                'superFast'   => n2_('Super fast') . ' 0.5x'
            )
        ));
        new Radio($rowBackgroundAnimation, 'animation-shifted-background-animation', n2_('Shifted'), 'auto', array(
            'tipLabel'       => n2_('Shifted'),
            'tipDescription' => n2_('The background and the main animation plays simultaneously or shifted.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1780-simple-slider-type#shifted',
            'options'        => array(
                'auto' => n2_('Auto'),
                '0'    => n2_('Off'),
                '1'    => n2_('On')
            )
        ));
    
        $rowKenBurns = new FieldsetRow($tableBackground, 'slider-type-simple-kenburns-animation');

        new PostBackgroundAnimation($rowKenBurns, 'kenburns-animation', n2_('Ken Burns effect'), '50|*|50|*|', array(
            'relatedFields' => array(
                'sliderkenburns-animation-speed',
                'sliderkenburns-animation-strength'
            )
        ));

        new Select($rowKenBurns, 'kenburns-animation-speed', n2_('Speed'), 'default', array(
            'options' => array(
                'default'   => n2_('Default'),
                'superSlow' => n2_('Super slow') . ' 0.25x',
                'slow'      => n2_('Slow') . ' 0.5x',
                'normal'    => n2_('Normal') . ' 1x',
                'fast'      => n2_('Fast') . ' 2x',
                'superFast' => n2_('Super fast') . ' 4x'
            )
        ));

        new Select($rowKenBurns, 'kenburns-animation-strength', n2_('Strength'), 'default', array(
            'options' => array(
                'default'     => n2_('Default'),
                'superSoft'   => n2_('Super soft') . ' 0.3x',
                'soft'        => n2_('Soft') . ' 0.6x',
                'normal'      => n2_('Normal') . ' 1x',
                'strong'      => n2_('Strong') . ' 1.5x',
                'superStrong' => n2_('Super strong') . ' 2x'
            )
        ));

    

        $margin = new MarginPadding(new InsertAfter($form->getElement('/general/design/design-1/margin')), 'padding', n2_('Padding'), '0|*|0|*|0|*|0', array(
            'unit' => 'px'
        ));

        for ($i = 1; $i < 5; $i++) {
            new Number($margin, 'padding-' . $i, false, '', array(
                'wide' => 3
            ));
        }

        $rowGroup = new ContainerRowGroup(new InsertAfter($form->getElement('/general/design/design-1')), 'slider-type-simple-group-general', false);

        $rowStyle = new FieldsetRow($rowGroup, 'slider-type-simple-settings-style');

        new Number($rowStyle, 'border-width', n2_('Border width'), 0, array(
            'unit'          => 'px',
            'wide'          => 3,
            'relatedFields' => array('sliderborder-color')
        ));
        new Color($rowStyle, 'border-color', n2_('Border color'), '3E3E3Eff', array(
            'alpha' => true
        ));
        new Number($rowStyle, 'border-radius', n2_('Border radius'), 0, array(
            'unit' => 'px',
            'wide' => 3
        ));

        $rowSliderCSS = new FieldsetRow($rowGroup, 'slider-type-simple-settings-slidercss');

        new Skin($rowSliderCSS, 'slider-preset', n2_('Slider CSS Preset'), '', array(
            'post'    => 'break',
            'options' => array(
                'shadow'       => array(
                    'label'    => n2_('Light shadow'),
                    'settings' => array(
                        'slider-css' => 'box-shadow: 1px 0 5px RGBA(0, 0, 0, 0.2), -1px 0 5px RGBA(0, 0, 0, 0.2);'
                    )
                ),
                'shadow2'      => array(
                    'label'    => n2_('Dark shadow'),
                    'settings' => array(
                        'slider-css' => 'box-shadow: 0 2px 4px 1px rgba(0, 0, 0, 0.6);'
                    )
                ),
                'photo'        => array(
                    'label'    => n2_('Photo'),
                    'settings' => array(
                        'slider-css'   => 'box-shadow: 1px 0 5px RGBA(0, 0, 0, 0.2), -1px 0 5px RGBA(0, 0, 0, 0.2);',
                        'border-width' => '8',
                        'border-color' => 'FFFFFFFF'
                    )
                ),
                'roundedphoto' => array(
                    'label'    => n2_('Photo rounded'),
                    'settings' => array(
                        'slider-css'    => 'box-shadow: 1px 0 5px RGBA(0, 0, 0, 0.2), -1px 0 5px RGBA(0, 0, 0, 0.2);',
                        'border-width'  => '5',
                        'border-color'  => 'FFFFFFFF',
                        'border-radius' => '12'
                    )
                )
            )
        ));

        new Textarea($rowSliderCSS, 'slider-css', n2_('Slider') . ' CSS', '', array(
            'height' => 26
        ));

        $rowSlideCSS = new FieldsetRow(new InsertAfter($form->getElement('/slides/slides-design/slides-design-1')), 'slider-type-simple-settings-slidecss');

        new Textarea($rowSlideCSS, 'slide-css', n2_('Slide') . ' CSS', '', array(
            'height' => 26
        ));
    }

    public function renderSlideFields($container) {

        $dataToFields = array();

        $tableAnimation = new FieldsetLayerWindow($container, 'fields-slide-animation', n2_('Animation'));

        // Background animations are required for simple type. We need to load the lightbox, because it is not working over AJAX slider type change.
        BackgroundAnimationManager::enqueue($container->getForm());

        $rowBackgroundAnimation = new Grouping($tableAnimation, 'slide-settings-animation-background-animation');

        new BackgroundAnimation($rowBackgroundAnimation, 'slide-background-animation', n2_('Background animation'), '', array(
            'relatedFields' => array(
                'layerslide-background-animation-speed'
            )
        ));
        $dataToFields[] = [
            'name' => 'background-animation',
            'id'   => 'layerslide-background-animation',
            'def'  => ''
        ];

        new Hidden($rowBackgroundAnimation, 'slide-background-animation-color', '');
        $dataToFields[] = [
            'name' => 'background-animation-color',
            'id'   => 'layerslide-background-animation-color',
            'def'  => '333333ff'
        ];

        new Select($rowBackgroundAnimation, 'slide-background-animation-speed', n2_('Speed'), '', array(
            'options' => array(
                'default'     => n2_('Default'),
                'superSlow10' => n2_('Super slow') . ' 10x',
                'superSlow'   => n2_('Super slow') . ' 3x',
                'slow'        => n2_('Slow') . ' 1.5x',
                'normal'      => n2_('Normal') . ' 1x',
                'fast'        => n2_('Fast') . ' 0.75x',
                'superFast'   => n2_('Super fast') . ' 0.5x'
            )
        ));
        $dataToFields[] = [
            'name' => 'background-animation-speed',
            'id'   => 'layerslide-background-animation-speed',
            'def'  => 'default'
        ];

        PostBackgroundAnimationManager::enqueue($container->getForm());

        $rowKenBurns = new Grouping($tableAnimation, 'slide-settings-animation-ken-burns');

        new PostBackgroundAnimation($rowKenBurns, 'slide-kenburns-animation', n2_('Ken Burns effect'), '', array(
            'relatedFields' => array(
                'layerslide-kenburns-animation-speed',
                'layerslide-kenburns-animation-strength'
            )
        ));
        $dataToFields[] = [
            'name' => 'kenburns-animation',
            'id'   => 'layerslide-kenburns-animation',
            'def'  => '50|*|50|*'
        ];

        new Select($rowKenBurns, 'slide-kenburns-animation-speed', n2_('Speed'), '', array(
            'options' => array(
                'default'   => n2_('Default'),
                'superSlow' => n2_('Super slow') . ' 0.25x',
                'slow'      => n2_('Slow') . ' 0.5x',
                'normal'    => n2_('Normal') . ' 1x',
                'fast'      => n2_('Fast') . ' 2x',
                'superFast' => n2_('Super fast' . ' 4x')
            )
        ));
        $dataToFields[] = [
            'name' => 'kenburns-animation-speed',
            'id'   => 'layerslide-kenburns-animation-speed',
            'def'  => 'default'
        ];

        new Select($rowKenBurns, 'slide-kenburns-animation-strength', n2_('Strength'), '', array(
            'options' => array(
                'default'     => n2_('Default'),
                'superSoft'   => n2_('Super soft') . ' 0.3x',
                'soft'        => n2_('Soft') . ' 0.6x',
                'normal'      => n2_('Normal') . ' 1x',
                'strong'      => n2_('Strong') . ' 1.5x',
                'superStrong' => n2_('Super strong') . ' 2x'
            )
        ));
        $dataToFields[] = [
            'name' => 'kenburns-animation-strength',
            'id'   => 'layerslide-kenburns-animation-strength',
            'def'  => 'default'
        ];
    

        Js::addInline("_N2.r('SectionSlide', function(){ _N2.SectionSlide.addExternalDataToField(" . json_encode($dataToFields) . ");});");
    }

    public function registerSlideAdminProperties($component) {

        $component->createProperty('background-animation', '');
        $component->createProperty('background-animation-color', '333333ff');
        $component->createProperty('background-animation-speed', 'default');
        $component->createProperty('kenburns-animation', '50|*|50|*|');
        $component->createProperty('kenburns-animation-speed', 'default');
        $component->createProperty('kenburns-animation-strength', 'default');
    
    }
}SliderType/Simple/SliderTypeSimpleCss.php000064400000005311152356644430014515 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\SliderType\Simple;


use Nextend\Framework\Parser\Color;
use Nextend\Framework\Parser\Common;
use Nextend\SmartSlider3\Slider\SliderType\AbstractSliderTypeCss;

class SliderTypeSimpleCss extends AbstractSliderTypeCss {

    public function __construct($slider) {
        parent::__construct($slider);

        $params = $this->slider->params;

        $width  = intval($this->context['width']);
        $height = intval($this->context['height']);

        $this->base = array(
            'slideOuterWidth'  => $width,
            'slideOuterHeight' => $height,
            'sliderWidth'      => $width,
            'sliderHeight'     => $height,
            'slideWidth'       => $width,
            'slideHeight'      => $height
        );

        $this->context['backgroundSize']       = $params->getIfEmpty('background-size', 'inherit');
        $this->context['backgroundAttachment'] = $params->get('background-fixed') ? 'fixed' : 'scroll';

        $borderWidth                   = $params->getIfEmpty('border-width', 0);
        $borderColor                   = $params->get('border-color');
        $this->context['borderRadius'] = $params->get('border-radius') . 'px';

        $padding                   = Common::parse($params->get('padding'));
        $this->context['paddingt'] = max(0, $padding[0]) . 'px';
        $this->context['paddingr'] = max(0, $padding[1]) . 'px';
        $this->context['paddingb'] = max(0, $padding[2]) . 'px';
        $this->context['paddingl'] = max(0, $padding[3]) . 'px';

        if ($this->context['canvas']) {
            $width  += 2 * $borderWidth + max(0, $padding[1]) + max(0, $padding[3]);
            $height += 2 * $borderWidth + max(0, $padding[0]) + max(0, $padding[2]);

            $this->context['width']  = $width . "px";
            $this->context['height'] = $height . "px";
        }


        $this->context['border'] = $borderWidth . 'px';

        $rgba                        = Color::hex2rgba($borderColor);
        $this->context['borderrgba'] = 'RGBA(' . $rgba[0] . ',' . $rgba[1] . ',' . $rgba[2] . ',' . round($rgba[3] / 127, 2) . ')';

        $width                         = $width - (max(0, $padding[1]) + max(0, $padding[3])) - $borderWidth * 2;
        $height                        = $height - (max(0, $padding[0]) + max(0, $padding[2])) - $borderWidth * 2;
        $this->context['inner1height'] = $height . 'px';

        $this->context['canvaswidth']  = $width . "px";
        $this->context['canvasheight'] = $height . "px";

        $this->initSizes();

        $this->slider->addLess(SliderTypeSimple::getAssetsPath() . '/style.n2less', $this->context);
    }
}SliderType/Simple/SliderTypeSimpleFrontend.php000064400000022427152356644430015553 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\SliderType\Simple;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Model\Section;
use Nextend\Framework\Parser\Color;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\BackgroundAnimation\BackgroundAnimationStorage;
use Nextend\SmartSlider3\Slider\SliderType\AbstractSliderTypeFrontend;

class SliderTypeSimpleFrontend extends AbstractSliderTypeFrontend {

    private $backgroundAnimation = false;

    public function getDefaults() {
        return array(
            'background'                             => '',
            'background-size'                        => 'cover',
            'background-fixed'                       => 0,
            'padding'                                => '0|*|0|*|0|*|0',
            'border-width'                           => 0,
            'border-color'                           => '3E3E3Eff',
            'border-radius'                          => 0,
            'slider-css'                             => '',
            'slide-css'                              => '',
            'animation'                              => 'horizontal',
            'animation-duration'                     => 800,
            'animation-delay'                        => 0,
            'animation-easing'                       => 'easeOutQuad',
            'animation-shifted-background-animation' => 'auto',
            'carousel'                               => 1,

            'background-animation' => '',
            'kenburns-animation'   => ''
        );
    }

    protected function renderType($css) {

        $params = $this->slider->params;

        $this->loadResources();

        $sliderCSS = $params->get('slider-css');

        $this->initSliderBackground('.n2-ss-slider-2');

        $slideCSS = $params->get('slide-css');

        $this->initBackgroundAnimation();
        $this->initParticleJS();
    

        echo wp_kses($this->openSliderElement(), Sanitize::$basicTags);

        ob_start();

        $slides = $this->slider->getSlides();
        ?>

        <div class="n2-ss-slider-1 n2_ss__touch_element n2-ow"<?php echo empty($sliderCSS) ? '' : ' style="' . esc_attr($sliderCSS) . '"'; ?>>
            <div class="n2-ss-slider-2 n2-ow">
                <?php
                echo wp_kses($this->getBackgroundVideo($params), Sanitize::$videoTags);
                ?>
                <?php if ($this->backgroundAnimation): ?>
                    <div class="n2-ss-background-animation n2-ow"></div>
                <?php endif; ?>
                <div class="n2-ss-slider-3 n2-ow"<?php echo empty($slideCSS) ? '' : ' style="' . esc_attr($slideCSS) . '"'; ?>>

                    <?php

                    // PHPCS - Content already escaped
                    echo $this->slider->staticHtml; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

                    echo wp_kses(Html::openTag('div', array('class' => 'n2-ss-slide-backgrounds n2-ow-all')), Sanitize::$basicTags);
                    foreach ($slides as $slide) {

                        // PHPCS - Content already escaped
                        echo $slide->background; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
                    }
                    echo wp_kses(Html::closeTag('div'), Sanitize::$basicTags);
                    ?>
                    <div class="n2-ss-slider-4 n2-ow">
                        <?php
                        $this->displaySizeSVGs($css);

                        foreach ($slides as $slide) {
                            $slide->finalize();

                            // PHPCS - Content already escaped
                            echo Html::tag('div', Html::mergeAttributes($slide->attributes, $slide->linkAttributes, array( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
                                                                                                                           'class' => 'n2-ss-slide n2-ow ' . $slide->classes,
                                                                                                                           'style' => $slide->style
                            )), $slide->getHTML());
                        }
                        ?>
                    </div>

                    <?php
                    $this->renderShapeDividers();
                
                    ?>
                </div>
            </div>
        </div>
        <?php

        // PHPCS - Content already escaped
        echo $this->widgets->wrapSlider(ob_get_clean()); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

        echo wp_kses($this->closeSliderElement(), Sanitize::$basicTags);

        $this->javaScriptProperties['mainanimation'] = array(
            'type'                       => $params->get('animation'),
            'duration'                   => intval($params->get('animation-duration')),
            'delay'                      => intval($params->get('animation-delay')),
            'ease'                       => $params->get('animation-easing'),
            'shiftedBackgroundAnimation' => $params->get('animation-shifted-background-animation')
        );

        $this->javaScriptProperties['carousel'] = intval($params->get('carousel'));

        $this->style .= $css->getCSS();

        $this->jsDependency[] = 'ss-simple';
    }

    public function getScript() {
        return "_N2.r(" . json_encode(array_unique($this->jsDependency)) . ",function(){new _N2.SmartSliderSimple('{$this->slider->elementId}', " . $this->encodeJavaScriptProperties() . ");});";
    }

    public function loadResources() {

        Js::addStaticGroup(SliderTypeSimple::getAssetsPath() . '/dist/ss-simple.min.js', 'ss-simple');
    }

    private function initBackgroundAnimation() {
        $speed = $this->slider->params->get('background-animation-speed', 'normal');
        $color = Color::colorToRGBA($this->slider->params->get('background-animation-color', '333333ff'));

        $this->javaScriptProperties['bgAnimations'] = array(
            'global' => $this->parseBackgroundAnimations($this->slider->params->get('background-animation', '')),
            'color'  => $color,
            'speed'  => $speed
        );

        $slides    = array();
        $hasCustom = false;

        foreach ($this->slider->getSlides() as $i => $slide) {
            $animation = $this->parseBackgroundAnimations($slide->parameters->get('background-animation'));
            if ($animation) {
                $slideSpeed = $slide->parameters->get('background-animation-speed', 'default');
                if ($slideSpeed == 'default') {
                    $slideSpeed = $speed;
                }
                $slides[$i] = array(
                    'animation' => $this->parseBackgroundAnimations($slide->parameters->get('background-animation')),
                    'speed'     => $slideSpeed
                );

                $localColor = $slide->parameters->get('background-animation-color', '');
                if (!empty($localColor)) {
                    $slides[$i]['color'] = Color::colorToRGBA($localColor);
                }

                if ($slides[$i]) {
                    $hasCustom = true;
                }
            }
        }
        if ($hasCustom) {
            $this->javaScriptProperties['bgAnimations']['slides'] = $slides;
        } else if (!$this->javaScriptProperties['bgAnimations']['global']) {
            $this->javaScriptProperties['bgAnimations'] = 0;
        }

        if ($this->javaScriptProperties['bgAnimations'] != 0) {

            $this->jsDependency[] = "smartslider-backgroundanimation";
            // We have background animation so load the required JS files

            Js::addStaticGroup(SliderTypeSimple::getAssetsPath() . '/dist/smartslider-backgroundanimation.min.js', 'smartslider-backgroundanimation');

            $this->slider->addLess(SliderTypeSimple::getAssetsPath() . '/BackgroundAnimation/style.n2less', array(
                'sliderid' => "~'#{$this->slider->elementId}'",
                "color"    => $color
            ));
        }

    }

    private function parseBackgroundAnimations($backgroundAnimation) {
        $backgroundAnimations = array_unique(array_map('intval', explode('||', $backgroundAnimation)));

        $jsProps = array();

        if (count($backgroundAnimations)) {
            BackgroundAnimationStorage::getInstance();

            foreach ($backgroundAnimations as $animationId) {
                $animation = Section::getById($animationId, 'backgroundanimation');
                if (isset($animation)) {
                    $data = $animation['value']['data'];
                    if (isset($data['displacementImage'])) {
                        $data['displacementImage'] = ResourceTranslator::toUrl($data['displacementImage']);
                    }
                    $jsProps[] = $data;
                }

            }

            if (count($jsProps)) {
                $this->backgroundAnimation = true;

                return $jsProps;
            }
        }

        return 0;
    }
}ResponsiveType/AbstractResponsiveType.php000064400000000765152356644430014763 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\ResponsiveType;


use Nextend\SmartSlider3\Slider\Feature\Responsive;

abstract class AbstractResponsiveType {

    public abstract function getName();

    /**
     * @param Responsive $responsive
     *
     * @return AbstractResponsiveTypeFrontend
     */
    public abstract function createFrontend($responsive);

    /**
     *
     * @return AbstractResponsiveTypeAdmin
     */
    public abstract function createAdmin();

}ResponsiveType/AbstractResponsiveTypeAdmin.php000064400000001422152356644430015723 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\ResponsiveType;

use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\Pattern\GetPathTrait;
use Nextend\Framework\Pattern\OrderableTrait;

abstract class AbstractResponsiveTypeAdmin {

    use GetPathTrait;
    use OrderableTrait;

    /** @var AbstractResponsiveType */
    protected $type;

    public function __construct($type) {
        $this->type = $type;
    }

    public function getName() {
        return $this->type->getName();
    }

    /**
     * @return string
     */
    public abstract function getIcon();

    public abstract function getLabel();

    /**
     * @param ContainerInterface $container
     */
    public function renderFields($container) {

    }

}ResponsiveType/AbstractResponsiveTypeFrontend.php000064400000001140152356644430016447 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\ResponsiveType;


use Nextend\SmartSlider3\Slider\Feature\Responsive;

abstract class AbstractResponsiveTypeFrontend {

    /** @var AbstractResponsiveType */
    protected $type;
    /**
     * @var Responsive
     */
    protected $responsive;

    public function __construct($type, $responsive) {
        $this->type       = $type;
        $this->responsive = $responsive;
    }

    public function getType() {
        return $this->type->getName();
    }

    public function parse($params, $responsive, $features) {

    }

}ResponsiveType/ResponsiveTypeFactory.php000064400000004064152356644430014623 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\ResponsiveType;


use Nextend\Framework\Pattern\OrderableTrait;
use Nextend\Framework\Pattern\PluggableTrait;
use Nextend\Framework\Pattern\SingletonTrait;
use Nextend\SmartSlider3\Slider\Feature\Responsive;

class ResponsiveTypeFactory {

    use SingletonTrait, PluggableTrait, OrderableTrait;

    /**
     * @var AbstractResponsiveType[]
     */
    private static $types = array();

    /**
     * @param AbstractResponsiveType $responsiveType
     */
    public static function addType($responsiveType) {
        self::$types[$responsiveType->getName()] = $responsiveType;
    }

    /**
     * @param $name
     *
     * @return AbstractResponsiveType|null
     */
    public static function getType($name) {

        if (isset(self::$types[$name])) {
            return self::$types[$name];
        }

        if ($name == 'auto') {
            /**
             * There is no fallback if auto type missing
             */
            return null;
        }

        return self::getType('auto');
    }

    /**
     * @return AbstractResponsiveType[]
     */
    public static function getTypes() {

        return self::$types;
    }

    /**
     * @return AbstractResponsiveTypeAdmin[]
     */
    public static function getAdminTypes() {
        $adminTypes = array();

        foreach (self::$types as $name => $type) {
            $adminTypes[$name] = $type->createAdmin();
        }

        self::uasort($adminTypes);

        return $adminTypes;
    }

    protected function init() {

        $this->makePluggable('SliderResponsiveType');
    }

    /**
     * @param            $name
     * @param Responsive $responsive
     *
     * @return AbstractResponsiveTypeFrontend|null
     */
    public static function createFrontend($name, $responsive) {
        $type = self::getType($name);
        if ($type) {
            return $type->createFrontend($responsive);
        }

        return null;
    }
}

ResponsiveTypeFactory::getInstance();ResponsiveType/FullWidth/ResponsiveTypeFullWidth.php000064400000001020152356644430017005 0ustar00<?php

namespace Nextend\SmartSlider3\Slider\ResponsiveType\FullWidth;

use Nextend\SmartSlider3\Slider\ResponsiveType\AbstractResponsiveType;

class ResponsiveTypeFullWidth extends AbstractResponsiveType {


    public function getName() {
        return 'fullwidth';
    }

    public function createFrontend($responsive) {

        return new ResponsiveTypeFullWidthFrontend($this, $responsive);
    }

    public function createAdmin() {

        return new ResponsiveTypeFullWidthAdmin($this);
    }
}ResponsiveType/FullWidth/ResponsiveTypeFullWidthAdmin.php000064400000004521152356644430017767 0ustar00<?php

namespace Nextend\SmartSlider3\Slider\ResponsiveType\FullWidth;

use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Fieldset\FieldsetRow;
use Nextend\SmartSlider3\Slider\ResponsiveType\AbstractResponsiveTypeAdmin;

class ResponsiveTypeFullWidthAdmin extends AbstractResponsiveTypeAdmin {

    protected $ordering = 2;

    public function getLabel() {
        return n2_('Full width');
    }

    public function getIcon() {
        return 'ssi_64 ssi_64--fit';
    }

    public function renderFields($container) {
        $row1 = new FieldsetRow($container, 'responsive-fullwidth-1');

        new Number($row1, 'responsiveSliderHeightMin', n2_('Min height'), 0, array(
            'unit'           => 'px',
            'wide'           => 5,
            'tipLabel'       => n2_('Min height'),
            'tipDescription' => n2_('Prevents the slider from getting smaller than the set value.')
        ));

        new OnOff($row1, 'responsiveForceFull', n2_('Force full width'), 1, array(
            'tipLabel'       => n2_('Force full width'),
            'tipDescription' => n2_('The slider tries to fill the full width of the browser.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1776-fullwidth-layout#force-full-width'
        ));

        new Select($row1, 'responsiveForceFullOverflowX', n2_('Overflow-X'), 'body', array(
            'options'        => array(
                'body' => 'body',
                'html' => 'html',
                'none' => n2_('None')
            ),
            'tipLabel'       => n2_('Overflow-X'),
            'tipDescription' => n2_('Prevents the vertical scrollbar from appear during certain slide background animations.')
        ));


        new Text($row1, 'responsiveForceFullHorizontalSelector', n2_('Adjust slider width to'), 'body', array(
            'tipLabel'       => n2_('Adjust slider width to'),
            'tipDescription' => n2_('You can make the slider fill up a selected parent element instead of the full browser width.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1776-fullwidth-layout#adjust-slider-width-to'
        ));
    }
}ResponsiveType/FullWidth/ResponsiveTypeFullWidthFrontend.php000064400000001357152356644430020522 0ustar00<?php

namespace Nextend\SmartSlider3\Slider\ResponsiveType\FullWidth;

use Nextend\SmartSlider3\Slider\ResponsiveType\AbstractResponsiveTypeFrontend;

class ResponsiveTypeFullWidthFrontend extends AbstractResponsiveTypeFrontend {


    public function parse($params, $responsive, $features) {
        $features->align->align = 'normal';

        $responsive->minimumHeight = intval($params->get('responsiveSliderHeightMin', 0));

        $responsive->forceFull = intval($params->get('responsiveForceFull', 1));

        $responsive->forceFullOverflowX = $params->get('responsiveForceFullOverflowX', 'body');

        $responsive->forceFullHorizontalSelector = $params->get('responsiveForceFullHorizontalSelector', 'body');
    }
}ResponsiveType/Auto/ResponsiveTypeAutoAdmin.php000064400000002673152356644430016011 0ustar00<?php

namespace Nextend\SmartSlider3\Slider\ResponsiveType\Auto;

use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Fieldset\FieldsetRow;
use Nextend\SmartSlider3\Slider\ResponsiveType\AbstractResponsiveTypeAdmin;

class ResponsiveTypeAutoAdmin extends AbstractResponsiveTypeAdmin {

    protected $ordering = 1;

    public function getLabel() {
        return n2_('Boxed');
    }

    public function getIcon() {
        return 'ssi_64 ssi_64--auto';
    }

    public function renderFields($container) {

        $row1 = new FieldsetRow($container, 'responsive-auto-1');

        new OnOff($row1, 'responsiveScaleDown', n2_('Downscale'), 1, array(
            'tipLabel'       => n2_('Downscale'),
            'tipDescription' => n2_('Allows the slider to scale down for smaller screens.')
        ));
        new OnOff($row1, 'responsiveScaleUp', n2_('Upscale'), 1, array(
            'tipLabel'       => n2_('Upscale'),
            'tipDescription' => n2_('Allows the slider to scale up for larger screens.')
        ));


        new Number($row1, 'responsiveSliderHeightMin', n2_('Min height'), 0, array(
            'wide'           => 5,
            'unit'           => 'px',
            'tipLabel'       => n2_('Min height'),
            'tipDescription' => n2_('Prevents the slider from getting smaller than the set value.')
        ));

    }
}ResponsiveType/Auto/ResponsiveTypeAuto.php000064400000000773152356644430015037 0ustar00<?php

namespace Nextend\SmartSlider3\Slider\ResponsiveType\Auto;

use Nextend\SmartSlider3\Slider\ResponsiveType\AbstractResponsiveType;

class ResponsiveTypeAuto extends AbstractResponsiveType {


    public function getName() {
        return 'auto';
    }

    public function createFrontend($responsive) {

        return new ResponsiveTypeAutoFrontend($this, $responsive);
    }

    public function createAdmin() {

        return new ResponsiveTypeAutoAdmin($this);
    }


}ResponsiveType/Auto/ResponsiveTypeAutoFrontend.php000064400000001215152356644430016527 0ustar00<?php

namespace Nextend\SmartSlider3\Slider\ResponsiveType\Auto;

use Nextend\SmartSlider3\Slider\ResponsiveType\AbstractResponsiveTypeFrontend;

class ResponsiveTypeAutoFrontend extends AbstractResponsiveTypeFrontend {

    public function parse($params, $responsive, $features) {
        $responsive->scaleDown = intval($params->get('responsiveScaleDown', 1));
        $responsive->scaleUp   = intval($params->get('responsiveScaleUp', 1));
        if ($responsive->scaleUp) {
            $features->align->align = 'normal';
        }

        $responsive->minimumHeight = intval($params->get('responsiveSliderHeightMin', 0));
    }
}Joomla/PlatformSlider.php000064400000001251152356644430011440 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Joomla;


use Nextend\SmartSlider3\Platform\Joomla\JoomlaShim;
use Nextend\SmartSlider3\Slider\Base\PlatformSliderBase;
use stdClass;

class PlatformSlider extends PlatformSliderBase {

    public $_module;

    public function addCMSFunctions($text) {

        $params        = new stdclass();
        $article       = new stdClass;
        $article->text = '<div>' . $text . '</div>';

        $data = array(
            'mod_smartslider',
            &$article,
            &$params,
            0
        );

        JoomlaShim::triggerOnContentPrepare($data);

        return $article->text;
    }
}Cache/CacheGenerator.php000064400000003113152356644430011144 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Cache;


use Nextend\Framework\Cache\Manifest;
use Nextend\Framework\Platform\Platform;
use Nextend\SmartSlider3\Generator\Generator;
use Nextend\SmartSlider3\Slider\Slider;

class CacheGenerator extends Manifest {

    /**
     * @var Slider
     */
    private $slider;

    private $generator;

    protected $_storageEngine = 'database';

    /**
     * @param Slider    $slider
     * @param Generator $generator
     */
    public function __construct($slider, $generator) {
        parent::__construct($slider->cacheId, false);
        $this->slider    = $slider;
        $this->generator = $generator;
    }

    protected function decode($data) {
        return json_decode($data, true);
    }

    protected function isCacheValid(&$manifestData) {
        $nextRefresh = $manifestData['cacheTime'] + max(0, floatval($this->generator->currentGenerator['params']->get('cache-expiration', 1))) * 60 * 60;
        if ($manifestData['cacheTime'] + max(0, floatval($this->generator->currentGenerator['params']->get('cache-expiration', 1))) * 60 * 60 < Platform::getTimestamp()) {
            return false;
        }
        $this->generator->setNextCacheRefresh($nextRefresh);

        return true;
    }

    protected function addManifestData(&$manifestData) {
        $manifestData['cacheTime'] = Platform::getTimestamp();
        $this->generator->setNextCacheRefresh($manifestData['cacheTime'] + max(0, floatval($this->generator->currentGenerator['params']->get('cache-expiration', 1))) * 60 * 60);
    }
}Cache/CacheSlider.php000064400000011424152356644430010444 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Cache;


use Nextend\Framework\Cache\Manifest;
use Nextend\Framework\Platform\Platform;
use Nextend\Framework\Plugin;
use Nextend\SmartSlider3\Application\Helper\HelperSliderChanged;
use Nextend\SmartSlider3\Application\Model\ModelGenerator;
use Nextend\SmartSlider3\SmartSlider3Info;

class CacheSlider extends Manifest {

    private $parameters = array();

    protected $_storageEngine = 'database';

    private $isExtended = false;

    public function __construct($cacheId, $parameters = array()) {
        parent::__construct($cacheId, false);
        $this->parameters = $parameters;

    }

    protected function decode($data) {
        return json_decode($data, true);
    }

    /**
     * @param          $fileName
     * @param          $hash
     * @param callback $callable
     *
     * @return bool
     */
    public function makeCache($fileName, $hash, $callable) {

        $variations = 1;
        if ($this->exists($this->getManifestKey('variations'))) {
            $variations = intval($this->get($this->getManifestKey('variations')));
        }
        $fileName = $fileName . mt_rand(1, $variations);

        if ($this->exists($this->getManifestKey('data'))) {
            $data     = json_decode($this->get($this->getManifestKey('data')), true);
            $fileName = $this->extendFileName($fileName, $data);
        } else {
            $this->clearCurrentGroup();
        }

        $output = parent::makeCache($fileName, $hash, $callable);

        return $output;
    }

    protected function createCacheFile($fileName, $hash, $content) {

        $this->set($this->getManifestKey('data'), json_encode($this->parameters['slider']->manifestData));

        $fileName = $this->extendFileName($fileName, $this->parameters['slider']->manifestData);

        return parent::createCacheFile($fileName, $hash, $content);
    }

    private function extendFileName($fileName, $manifestData) {

        if ($this->isExtended) {
            return $fileName;
        }

        $this->isExtended = true;

        $generators = $manifestData['generator'];

        if (count($generators)) {
            $generatorModel = new ModelGenerator($this->parameters['slider']);

            foreach ($generators as $generator) {
                list($group, $type, $params) = $generator;

                $generatorGroup = $generatorModel->getGeneratorGroup($group);
                if (!$generatorGroup) {
                    echo esc_html(n2_('Slider error! Generator group not found: ') . $group);
                } else {

                    $generatorSource = $generatorGroup->getSource($type);
                    if (!$generatorSource) {
                        echo esc_html(n2_('Slider error! Generator source not found: ') . $type);
                    } else {

                        $fileName .= call_user_func(array(
                            $generatorSource,
                            'cacheKey'
                        ), $params);
                    }
                }
            }
        }

        return $fileName;
    }

    protected function isCacheValid(&$manifestData) {

        if (!isset($manifestData['version']) || $manifestData['version'] != SmartSlider3Info::$version) {
            return false;
        }

        $helper = new HelperSliderChanged($this->parameters['slider']);

        if ($helper->isSliderChanged($this->parameters['slider']->sliderId)) {
            $this->clearCurrentGroup();
            $helper->setSliderChanged($this->parameters['slider']->sliderId, 0);

            return false;
        }

        $time = Platform::getTimestamp();

        if ($manifestData['nextCacheRefresh'] < $time) {
            return false;
        }

        if (!isset($manifestData['currentPath']) || $manifestData['currentPath'] != md5(__FILE__)) {
            return false;
        }

        return true;
    }

    protected function addManifestData(&$manifestData) {

        $manifestData['nextCacheRefresh'] = Plugin::applyFilters('SSNextCacheRefresh', $this->parameters['slider']->getNextCacheRefresh(), array($this->parameters['slider']));
        $manifestData['currentPath']      = md5(__FILE__);
        $manifestData['version']          = SmartSlider3Info::$version;

        $variations = 1;

        $params = $this->parameters['slider']->params;
        if (!$params->get('randomize-cache', 0) && ($params->get('randomize', 0) || $params->get('randomizeFirst', 0))) {
            $variations = intval($params->get('variations', 5));
            if ($variations < 1) {
                $variations = 1;
            }
        }

        $this->set($this->getManifestKey('variations'), $variations);
    }
}Feature/Align.php000064400000003335152356644430007722 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Feature;


use Nextend\Framework\View\Html;

class Align {

    private $slider;

    public $align = 'normal';

    public function __construct($slider) {

        $this->slider = $slider;

        $this->align = $slider->params->get('align', 'normal');
    }

    public function renderSlider($sliderHTML, $maxWidth) {

        $htmlOptions = array(
            "id"     => $this->slider->elementId . '-align',
            "class"  => "n2-ss-align",
            "encode" => false
        );

        $htmlOptionsPadding = array(
            "class" => 'n2-padding'
        );

        if (!$this->slider->features->responsive->scaleUp && $this->align != 'normal') {
            switch ($this->align) {
                case 'left':
                case 'right':
                    $width                = $this->slider->assets->sizes['width'];
                    $htmlOptions["style"] = "float: {$this->align}; width: {$width}px; max-width:100%;";
                    break;
                case 'center':
                    $htmlOptions["style"] = "margin: 0 auto; max-width: {$maxWidth}px;";
                    break;
            }
        }

        $sliderHTML = Html::tag("div", $htmlOptions, Html::tag("div", $htmlOptionsPadding, $sliderHTML));

        if ($this->slider->params->get('clear-both-after', 1)) {
            $sliderHTML .= Html::tag("div", array("class" => "n2_clear"), "");
        }

        return $sliderHTML;
    }

    public function makeJavaScriptProperties(&$properties) {
        $properties['align']     = $this->align;
        $properties['isDelayed'] = intval($this->slider->params->get('is-delayed', 0));
    }
}Feature/Autoplay.php000064400000011364152356644430010467 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Feature;


use Nextend\Framework\Data\Data;
use Nextend\Framework\Parser\Common;
use Nextend\SmartSlider3\Slider\Slider;

#[\AllowDynamicProperties]
class Autoplay {

    /**
     * @var Slider
     */
    private $slider;

    public $isEnabled = 0, $isStart = 0, $duration = 8000;
    public $isLoop = 1, $interval = 1, $intervalModifier = 'loop', $intervalSlide = 'current', $allowReStart = 0;
    public $stopOnClick = 1, $stopOnMediaStarted = 1;
    public $resumeOnMediaEnded = 1, $resumeOnSlideChanged = 0;


    public function __construct($slider) {

        $this->slider = $slider;
        $params       = $slider->params;
        $this->upgradeData($params);
    

        $this->isEnabled = intval($params->get('autoplay', 0));
        $this->isStart   = intval($params->get('autoplayStart', 1));
        $this->duration  = intval($params->get('autoplayDuration', 8000));

        if ($this->duration < 1) {
            $this->duration = 1500;
        }

        list($this->interval, $this->intervalModifier, $this->intervalSlide) = (array)Common::parse($slider->params->get('autoplayfinish', '1|*|loop|*|current'));

        $this->allowReStart = intval($params->get('autoplayAllowReStart', 0));

        $this->isLoop = intval($params->get('autoplayLoop', 1));

        $this->interval = intval($this->interval);

        $this->stopOnClick        = intval($params->get('autoplayStopClick', 1));
        $this->stopOnMouse        = $params->get('autoplayStopMouse', 'enter');
        $this->stopOnMediaStarted = intval($params->get('autoplayStopMedia', 1));


        $this->resumeOnClick      = intval($params->get('autoplayResumeClick', 0));
        $this->resumeOnMouse      = $params->get('autoplayResumeMouse', 0);
        $this->resumeOnMediaEnded = intval($params->get('autoplayResumeMedia', 1));


    }

    public function makeJavaScriptProperties(&$properties) {
        $properties['autoplay'] = array(
            'enabled'          => $this->isEnabled,
            'start'            => $this->isStart,
            'duration'         => $this->duration,
            'autoplayLoop'     => $this->isLoop,
            'allowReStart'     => $this->allowReStart,
            'pause'            => array(
                'click'        => $this->stopOnClick,
                'mouse'        => $this->stopOnMouse,
                'mediaStarted' => $this->stopOnMediaStarted
            ),
            'resume'           => array(
                'click'        => $this->resumeOnClick,
                'mouse'        => $this->resumeOnMouse,
                'mediaEnded'   => $this->resumeOnMediaEnded,
                'slidechanged' => $this->resumeOnSlideChanged
            ),
            'interval'         => $this->interval,
            'intervalModifier' => $this->intervalModifier,
            'intervalSlide'    => $this->intervalSlide
        );
    }

    /**
     * For compatibility with legacy autoplay values.
     *
     * @param Data $params
     */
    protected function upgradeData($params) {
        list($interval, $intervalModifier, $intervalSlide) = (array)Common::parse($params->get('autoplayfinish', '1|*|loop|*|current'));

        if ($interval <= 0 || $params->get('autoplayLoop') === '') {
            // 0|*|loop|*|current -> In old versions it brought to the Next slide.
            if ($intervalModifier === 'slide' && $intervalSlide === 'next') {
                $params->set('autoplayfinish', '1|*|slide|*|current');
                $params->set('autoplayLoop', '0');
            }

            // 0|*|loop/slide/slideindex|*|current -> Infinite loop
            // 0|*|loop|*|next -> Infinite loop
            if ($intervalSlide === 'current' || ($intervalModifier === 'loop' && $intervalSlide === 'next')) {
                $params->set('autoplayfinish', '1|*|loop|*|current');
                $params->set('autoplayLoop', '1');
            }

            // 0|*|slideindex|*|next -> In old versions it always brought to the 2nd slide.
            if ($intervalModifier === 'slideindex' && $intervalSlide === 'next') {
                $params->set('autoplayfinish', '2|*|slideindex|*|current');
                $params->set('autoplayLoop', '0');
            } else {
                //next is not allowed for "slide" and "slideindex" modifiers
                if ($intervalModifier === 'slide' || $intervalModifier === 'slideindex') {
                    $params->set('autoplayfinish', $interval . '|*|' . $intervalModifier . '|*|current');
                    // turn off Loop, and work with the original settings
                    $params->set('autoplayLoop', '0');
                }
            }

        }
    
    }
}Feature/BlockRightClick.php000064400000000677152356644430011674 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Feature;


class BlockRightClick {

    private $slider;

    public $isEnabled = 0;

    public function __construct($slider) {

        $this->slider = $slider;

        $this->isEnabled = intval($slider->params->get('blockrightclick', 0));
    }

    public function makeJavaScriptProperties(&$properties) {

        $properties['blockrightclick'] = $this->isEnabled;
    }
}Feature/Controls.php000064400000002303152356644430010465 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Feature;


class Controls {

    private $slider;

    private $mousewheel = 0;

    public $drag = 0;

    public $touch = 1;

    public $keyboard = 0;

    public $blockCarouselInteraction = 1;

    public function __construct($slider) {

        $this->slider = $slider;

        $this->mousewheel               = intval($slider->params->get('controlsScroll', 0));
        $this->keyboard                 = intval($slider->params->get('controlsKeyboard', 1));
        $this->blockCarouselInteraction = intval($slider->params->get('controlsBlockCarouselInteraction', 1));
        $this->touch                    = $slider->params->get('controlsTouch', 'horizontal');
        if ($slider->getSlidesCount() < 2) {
            $this->touch = 0;
        }
    }

    public function makeJavaScriptProperties(&$properties) {
        $properties['controls'] = array(
            'mousewheel'               => $this->mousewheel,
            'touch'                    => $this->touch,
            'keyboard'                 => $this->keyboard,
            'blockCarouselInteraction' => $this->blockCarouselInteraction
        );
    }
}Feature/Focus.php000064400000003257152356644430007752 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Feature;


use Nextend\SmartSlider3\Settings;
use Nextend\SmartSlider3\Slider\Slider;

class Focus {

    /**
     * @var Slider
     */
    private $slider;

    private $focusOffsetTop = '';

    private $focusOffsetBottom = '';


    public function __construct($slider) {

        $this->slider = $slider;
        $responsiveHeightOffsetValue = '';
    

        $this->focusOffsetTop    = Settings::get('responsive-focus-top', $responsiveHeightOffsetValue);
        $this->focusOffsetBottom = Settings::get('responsive-focus-bottom', '');
    }

    public function makeJavaScriptProperties(&$properties) {
        $properties['responsive']['focus'] = array(
            'offsetTop'    => $this->focusOffsetTop,
            'offsetBottom' => $this->focusOffsetBottom
        );

        $params = $this->slider->params;

        if ($params->get('responsive-mode') == 'fullpage') {
            if (!$params->has('responsive-focus') && $params->has('responsiveHeightOffset')) {
                $old = $params->get('responsiveHeightOffset');

                $oldDefault = '';

                if ($old !== $oldDefault) {
                    $params->set('responsive-focus', 1);
                    $params->set('responsive-focus-top', $old);
                }
            }

            if ($params->get('responsive-focus', 0)) {
                $properties['responsive']['focus'] = array(
                    'offsetTop'    => $params->get('responsive-focus-top', ''),
                    'offsetBottom' => $params->get('responsive-focus-bottom', '')
                );
            }
        }
    }
}Feature/LayerMode.php000064400000004153152356644430010550 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Feature;


class LayerMode {

    private $slider;

    public $playOnce = 0;

    public $playFirstLayer = 1;

    public $mode = 'skippable';

    public $inAnimation = 'mainInEnd';

    public function __construct($slider) {

        $this->slider = $slider;

        $this->playOnce = intval($slider->params->get('playonce', 0));

        $this->playFirstLayer = intval($slider->params->get('playfirstlayer', 1));

        switch ($slider->params->get('layer-animation-play-mode', 'skippable')) {
            case 'forced':
                $this->mode = 'forced';
                break;
            default:
                $this->mode = 'skippable';
        }

        switch ($slider->params->get('layer-animation-play-in', 'end')) {
            case 'end':
                $this->inAnimation = 'mainInEnd';
                break;
            default:
                $this->inAnimation = 'mainInStart';
        }
    }

    public function makeJavaScriptProperties(&$properties) {
        $params                    = $this->slider->params;
        $properties['perspective'] = max(0, intval($params->get('perspective', 1500)));

        $properties['layerMode'] = array(
            'playOnce'       => $this->playOnce,
            'playFirstLayer' => $this->playFirstLayer,
            'mode'           => $this->mode,
            'inAnimation'    => $this->inAnimation
        );
        $properties['parallax'] = array(
            'enabled'    => intval($params->get('parallax-enabled', 1)),
            'mobile'     => intval($params->get('parallax-enabled-mobile', 0)),
            'is3D'       => intval($params->get('parallax-3d', 0)),
            'animate'    => intval($params->get('parallax-animate', 1)),
            'horizontal' => $params->get('parallax-horizontal', 'mouse'),
            'vertical'   => $params->get('parallax-vertical', 'mouse'),
            'origin'     => $params->get('parallax-mouse-origin', 'slider'),
            'scrollmove' => $params->get('parallax-scroll-move', 'both')
        );
    
    }
}Feature/LazyLoad.php000064400000002675152356644430010415 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Feature;


#[\AllowDynamicProperties]
class LazyLoad {

    private $slider;

    public $isEnabled = 0, $neighborCount = 0, $layerImageOptimize = 0, $layerImageWidthNormal = 1400, $layerImageWidthTablet = 800, $layerImageWidthMobile = 425;

    public function __construct($slider) {

        $this->slider = $slider;

        $this->isEnabled     = intval($slider->params->get('imageload', 0));
        $this->neighborCount = intval($slider->params->get('imageloadNeighborSlides', 0));

        $this->layerImageOptimize = intval($slider->params->get('layer-image-optimize', 0)) && !$slider->isAdmin;
        if ($this->layerImageOptimize) {
            $this->layerImageWidthNormal = $slider->params->get('layer-image-width-normal', 1400);
            $this->layerImageWidthTablet = $slider->params->get('layer-image-width-tablet', 800);
            $this->layerImageWidthMobile = $slider->params->get('layer-image-width-mobile', 425);
        }

        $this->layerImageSizeBase64     = intval($slider->params->get('layer-image-base64', 0)) && !$slider->isAdmin;
        $this->layerImageSizeBase64Size = max(0, intval($slider->params->get('layer-image-base64-size', 5))) * 1024;

    }

    public function makeJavaScriptProperties(&$properties) {

        $properties['lazyLoad']         = $this->isEnabled;
        $properties['lazyLoadNeighbor'] = $this->neighborCount;
    }
}Feature/MaintainSession.php000064400000000674152356644430011777 0ustar00<?php

namespace Nextend\SmartSlider3\Slider\Feature;

class MaintainSession {

    private $slider;

    public $isEnabled = 0;

    public function __construct($slider) {

        $this->slider = $slider;

        $this->isEnabled = intval($slider->params->get('maintain-session', 0));
    }

    public function makeJavaScriptProperties(&$properties) {

        $properties['maintainSession'] = $this->isEnabled;
    }
}Feature/Margin.php000064400000001740152356644430010103 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Feature;


use Nextend\Framework\Platform\Platform;
use Nextend\Framework\View\Html;

class Margin {

    private $slider;

    private $margin;

    public function __construct($slider) {

        $this->slider = $slider;

        $this->margin = explode('|*|', $slider->params->get('margin', '0|*|0|*|0|*|0'));
    }

    public function renderSlider($sliderHTML) {
        if (!Platform::isAdmin() && count($this->margin) >= 4) {
            array_splice($this->margin, 4);
            if ($this->margin[0] != 0 || $this->margin[1] != 0 || $this->margin[2] != 0 || $this->margin[3] != 0) {
                $sliderHTML = Html::tag("div", array(
                    "class"  => "n2-ss-margin",
                    "encode" => false,
                    "style"  => "margin: " . implode('px ', $this->margin) . "px;"
                ), $sliderHTML);
            }
        }

        return $sliderHTML;
    }
}Feature/Optimize.php000064400000026451152356644430010474 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Feature;


use Exception;
use Nextend\Framework\FastImageSize\FastImageSize;
use Nextend\Framework\Image\ImageEdit;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;

class Optimize {

    private $slider;

    private $playWhenVisible = 1;

    private $playWhenVisibleAt = 0.5;

    private $backgroundImageWidthNormal = 1920, $quality = 70, $thumbnailWidth = 100, $thumbnailHeight = 60, $thumbnailQuality = 70;

    public function __construct($slider) {

        $this->slider = $slider;

        $this->playWhenVisible   = intval($slider->params->get('playWhenVisible', 1));
        $this->playWhenVisibleAt = max(0, min(100, intval($slider->params->get('playWhenVisibleAt', 50)))) / 100;

        $this->backgroundImageWidthNormal = intval($slider->params->get('optimize-slide-width-normal', 1920));
        $this->quality                    = intval($slider->params->get('optimize-quality', 70));

        $this->thumbnailWidth   = $slider->params->get('optimizeThumbnailWidth', 100);
        $this->thumbnailHeight  = $slider->params->get('optimizeThumbnailHeight', 60);
        $this->thumbnailQuality = $slider->params->get('optimize-thumbnail-quality', 70);


    }

    public function makeJavaScriptProperties(&$properties) {
        $properties['playWhenVisible']   = $this->playWhenVisible;
        $properties['playWhenVisibleAt'] = $this->playWhenVisibleAt;
    }

    public function optimizeBackground($image, $x = 50, $y = 50) {
        try {
            $imageSize = FastImageSize::getSize($image);
            if ($imageSize) {
                $optimizeScale = $this->slider->params->get('optimize-scale', 0);

                $targetWidth  = $imageSize['width'];
                $targetHeight = $imageSize['height'];
                if ($optimizeScale && $targetWidth > $this->backgroundImageWidthNormal) {
                    $targetHeight = ceil($this->backgroundImageWidthNormal / $targetWidth * $targetHeight);
                    $targetWidth  = $this->backgroundImageWidthNormal;
                }

                return ImageEdit::resizeImage('slider/cache', ResourceTranslator::toPath($image), $targetWidth, $targetHeight, false, 'normal', 'ffffff', true, $this->quality, true, $x, $y);
            }

            return $image;

        } catch (Exception $e) {
            return $image;
        }
    }

    public function optimizeThumbnail($image) {
        if ($this->slider->params->get('optimize-thumbnail-scale', 0)) {
            try {
                return ImageEdit::resizeImage('slider/cache', ResourceTranslator::toPath($image), $this->thumbnailWidth, $this->thumbnailHeight, false, 'normal', 'ffffff', true, $this->thumbnailQuality, true);
            } catch (Exception $e) {

                return ResourceTranslator::toUrl($image);
            }
        }

        return ResourceTranslator::toUrl($image);
    }

    public function adminOptimizeThumbnail($image) {
        if ($this->slider->params->get('optimize-thumbnail-scale', 0)) {
            try {
                return ImageEdit::resizeImage('slider/cache', ResourceTranslator::toPath($image), $this->thumbnailWidth, $this->thumbnailHeight, true, 'normal', 'ffffff', true, $this->thumbnailQuality, true);
            } catch (Exception $e) {

                return ResourceTranslator::toUrl($image);
            }
        }

        return ResourceTranslator::toUrl($image);
    }


    public function optimizeImageWebP($src, $options) {

        $options = array_merge(array(
            'optimize'         => false,
            'quality'          => 70,
            'resize'           => false,
            'defaultWidth'     => 1920,
            'mediumWidth'      => 1200,
            'mediumHeight'     => 0,
            'smallWidth'       => 500,
            'smallHeight'      => 0,
            'focusX'           => 50,
            'focusY'           => 50,
            'compressOriginal' => false
        ), $options);
        $data = array();

        if ($options['optimize'] && function_exists('imagewebp')) {

            $resourceSrc = ResourceTranslator::urlToResource($src);
            $imagePath   = ResourceTranslator::toPath($resourceSrc);

            if (isset($imagePath)) {
                $isRemote = false;
                if ($resourceSrc == $imagePath) {
                    //this is a remote image
                    $isRemote  = true;
                    $imagePath = $src;
                } else {
                    $src = $resourceSrc;
                }

                $extension = pathinfo($imagePath, PATHINFO_EXTENSION);

                $originalImageWidth = FastImageSize::getWidth($src);

                if ($extension && $originalImageWidth) {

                    $normalScale = 1;
                    if ($options['resize']) {
                        if ($originalImageWidth > $options['defaultWidth']) {
                            $normalScale = $options['defaultWidth'] / $originalImageWidth;
                        }
                    }

                    $imageWebpUrl = ImageEdit::scaleImageWebp('slider/cache', $src, array(
                        'mode'    => 'scale',
                        'scale'   => $normalScale,
                        'quality' => $options['quality'],
                        'remote'  => $isRemote
                    ));

                    if ($imageWebpUrl) {

                        $width        = FastImageSize::getWidth($imageWebpUrl);
                        $imageWebpUrl = ResourceTranslator::toUrl($imageWebpUrl);

                        $data['normal'] = array(
                            'src'   => $imageWebpUrl,
                            'width' => $width
                        );

                        if ($options['resize']) {

                            if ($options['compressOriginal'] && $normalScale < 1) {

                                $imageWebpUrlOriginal = ImageEdit::scaleImageWebp('slider/cache', $src, array(
                                    'mode'    => 'scale',
                                    'quality' => $options['quality'],
                                    'remote'  => $isRemote
                                ));

                                if ($imageWebpUrlOriginal) {
                                    $width = FastImageSize::getWidth($imageWebpUrlOriginal);
                                    if ($width) {
                                        $imageWebpUrlOriginal = ResourceTranslator::toUrl($imageWebpUrlOriginal);

                                        $data['original'] = array(
                                            'src'   => $imageWebpUrlOriginal,
                                            'width' => $width
                                        );
                                    }
                                }
                            }

                            if ($originalImageWidth > $options['smallWidth'] && $options['defaultWidth'] > $options['smallWidth'] && $options['mediumWidth'] > $options['smallWidth']) {

                                if ($options['smallHeight'] > 0) {

                                    $imageWebpUrlSmall = ImageEdit::scaleImageWebp('slider/cache', $src, array(
                                        'mode'    => 'resize',
                                        'width'   => $options['smallWidth'],
                                        'height'  => $options['smallHeight'],
                                        'focusX'  => $options['focusX'],
                                        'focusY'  => $options['focusY'],
                                        'quality' => $options['quality'],
                                        'remote'  => $isRemote
                                    ));
                                } else {
                                    $mobileScale = $options['smallWidth'] / $originalImageWidth;

                                    $imageWebpUrlSmall = ImageEdit::scaleImageWebp('slider/cache', $src, array(
                                        'mode'    => 'scale',
                                        'scale'   => $mobileScale,
                                        'quality' => $options['quality'],
                                        'remote'  => $isRemote
                                    ));
                                }

                                if ($imageWebpUrlSmall) {
                                    $width = FastImageSize::getWidth($imageWebpUrlSmall);
                                    if ($width) {
                                        $imageWebpUrlSmall = ResourceTranslator::toUrl($imageWebpUrlSmall);

                                        $data['small'] = array(
                                            'src'   => $imageWebpUrlSmall,
                                            'width' => $width
                                        );
                                    }
                                }
                            }

                            if ($originalImageWidth > $options['mediumWidth'] && $options['defaultWidth'] > $options['mediumWidth']) {

                                if ($options['mediumHeight'] > 0) {

                                    $imageWebpUrlMedium = ImageEdit::scaleImageWebp('slider/cache', $src, array(
                                        'mode'    => 'resize',
                                        'width'   => $options['mediumWidth'],
                                        'height'  => $options['mediumHeight'],
                                        'focusX'  => $options['focusX'],
                                        'focusY'  => $options['focusY'],
                                        'quality' => $options['quality'],
                                        'remote'  => $isRemote
                                    ));
                                } else {
                                    $tabletScale = $options['mediumWidth'] / $originalImageWidth;

                                    $imageWebpUrlMedium = ImageEdit::scaleImageWebp('slider/cache', $src, array(
                                        'mode'    => 'scale',
                                        'scale'   => $tabletScale,
                                        'quality' => $options['quality'],
                                        'remote'  => $isRemote
                                    ));
                                }

                                if ($imageWebpUrlMedium) {
                                    $width = FastImageSize::getWidth($imageWebpUrlMedium);
                                    if ($width) {
                                        $imageWebpUrlMedium = ResourceTranslator::toUrl($imageWebpUrlMedium);

                                        $data['medium'] = array(
                                            'src'   => $imageWebpUrlMedium,
                                            'width' => $width
                                        );
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        return $data;
    
    }
}Feature/PostBackgroundAnimation.php000064400000005656152356644430013465 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Feature;


use Nextend\Framework\Model\Section;
use Nextend\Framework\Parser\Common;
use Nextend\SmartSlider3\Slider\Slide;
use Nextend\SmartSlider3Pro\PostBackgroundAnimation\PostBackgroundAnimationStorage;
class PostBackgroundAnimation {

    private $slider;

    private $hasSlideData = false;

    private $slideData = array();

    public function __construct($slider) {

        $this->slider = $slider;
    }

    /**
     * @param Slide $slide
     */
    public function makeSlide($slide) {
        $animations = $this->parseKenBurns($slide->parameters->get('kenburns-animation', '50|*|50|*|'));
        if ($animations) {
            $this->slideData[$slide->index] = array(
                'data'     => $animations,
                'speed'    => $slide->parameters->get('kenburns-animation-speed', 'default'),
                'strength' => $slide->parameters->get('kenburns-animation-strength', 'default')
            );
            $this->hasSlideData             = true;
        }
    }

    public function makeJavaScriptProperties(&$properties) {
        $properties['postBackgroundAnimations'] = array(
            'data'     => $this->parseKenBurns($this->slider->params->get('kenburns-animation', '50|*|50|*|')),
            'speed'    => $this->slider->params->get('kenburns-animation-speed', 'default'),
            'strength' => $this->slider->params->get('kenburns-animation-strength', 'default')
        );

        if ($this->hasSlideData) {
            $properties['postBackgroundAnimations']['slides'] = $this->slideData;
        } else if (!$properties['postBackgroundAnimations']['data']) {
            $properties['postBackgroundAnimations'] = 0;
        }

        if ($properties['postBackgroundAnimations'] && !$this->slider->isAdmin) {
            $this->slider->sliderType->addClass('n2-ss-feature-post-bg-loader');
        }
    }

    private function parseKenBurns($kenBurnsRaw) {

        $kenBurns   = Common::parse($kenBurnsRaw);
        $animations = array();
        if (is_array($kenBurns)) {
            if (count($kenBurns) >= 2) {
                $animations = array_unique(array_map('intval', (array)$kenBurns[2]));
            }
        }

        $jsProps = array();

        if (count($animations)) {
            PostBackgroundAnimationStorage::getInstance();

            foreach ($animations as $animationId) {
                $animation = Section::getById($animationId, 'postbackgroundanimation');
                if (isset($animation)) {
                    $jsProps[] = $animation['value']['data'];
                }
            }
            if (count($jsProps)) {
                return array(
                    'transformOrigin' => $kenBurns[0] . '% ' . $kenBurns[1] . '%',
                    'animations'      => $jsProps
                );
            }
        }

        return 0;
    }
}
Feature/Responsive.php000064400000103742152356644430011030 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Feature;


use Nextend\Framework\Data\Data;
use Nextend\SmartSlider3\Application\Admin\Settings\ViewSettingsGeneral;
use Nextend\SmartSlider3\Settings;
use Nextend\SmartSlider3\Slider\ResponsiveType\AbstractResponsiveTypeFrontend;
use Nextend\SmartSlider3\Slider\ResponsiveType\ResponsiveTypeFactory;
use Nextend\SmartSlider3\Slider\Slider;
use Nextend\SmartSlider3\SmartSlider3Info;

class Responsive {

    /** @var  Slider */
    public $slider;

    /**
     * @var AbstractResponsiveTypeFrontend
     */
    protected $responsivePlugin;

    protected $hideOnDesktopLandscape = 1;
    protected $hideOnDesktopPortrait = 1;

    protected $hideOnTabletLandscape = 1;
    protected $hideOnTabletPortrait = 1;

    protected $hideOnMobileLandscape = 1;
    protected $hideOnMobilePortrait = 1;

    public $onResizeEnabled = 1;

    public $type = 'auto';

    public $scaleDown = 1;

    public $scaleUp = 1;

    public $forceFull = 0;

    public $forceFullOverflowX = 'body';

    public $forceFullHorizontalSelector = '';

    public $minimumHeight = -1;

    public $maximumSlideWidthLandscape = -1;
    public $maximumSlideWidth = 10000;
    public $maximumSlideWidthTabletLandscape = -1;
    public $maximumSlideWidthTablet = -1;
    public $maximumSlideWidthMobileLandscape = -1;
    public $maximumSlideWidthMobile = -1;

    public $sliderHeightBasedOn = 'real';
    public $responsiveDecreaseSliderHeight = 0;

    public $focusUser = 1;

    public $focusEdge = 'auto';

    protected $enabledDevices = array(
        'desktopLandscape' => 0,
        'desktopPortrait'  => 1,
        'tabletLandscape'  => 0,
        'tabletPortrait'   => 1,
        'mobileLandscape'  => 0,
        'mobilePortrait'   => 1
    );

    protected $breakpoints = array();

    /**
     * @var array[]
     */
    public $mediaQueries = array(
        'all' => false
    );

    public $sizes = array(
        'desktopPortrait' => array(
            'width'  => 800,
            'height' => 600
        ),
    );

    public static $translation = array(
        'desktoplandscape' => 'desktopLandscape',
        'desktopportrait'  => 'desktopPortrait',
        'tabletlandscape'  => 'tabletLandscape',
        'tabletportrait'   => 'tabletPortrait',
        'mobilelandscape'  => 'mobileLandscape',
        'mobileportrait'   => 'mobilePortrait'
    );

    public function __construct($slider, $features) {

        $this->slider = $slider;

        $this->hideOnDesktopLandscape = !intval($slider->params->get('desktoplandscape', 1));
        $this->hideOnDesktopPortrait  = !intval($slider->params->get('desktopportrait', 1));

        $this->hideOnTabletLandscape = !intval($slider->params->get('tabletlandscape', 1));
        $this->hideOnTabletPortrait  = !intval($slider->params->get('tabletportrait', 1));

        $this->hideOnMobileLandscape = !intval($slider->params->get('mobilelandscape', 1));
        $this->hideOnMobilePortrait  = !intval($slider->params->get('mobileportrait', 1));


        $this->focusUser = intval($slider->params->get('responsiveFocusUser', 1));

        $this->focusEdge = $slider->params->get('responsiveFocusEdge', 'auto');

        $this->responsivePlugin = ResponsiveTypeFactory::createFrontend($slider->params->get('responsive-mode', 'auto'), $this);
        $this->type             = $this->responsivePlugin->getType();
        $this->responsivePlugin->parse($slider->params, $this, $features);

        $this->onResizeEnabled = !$slider->disableResponsive;

        if (!$this->scaleDown && !$this->scaleUp) {
            $this->onResizeEnabled = 0;
        }

        $overrideSizeEnabled = !!$slider->params->get('slider-size-override', 0);

        $this->sizes['desktopPortrait']['width']  = max(10, intval($slider->params->get('width', 1200)));
        $this->sizes['desktopPortrait']['height'] = max(10, intval($slider->params->get('height', 600)));

        $heightHelperRatio = $this->sizes['desktopPortrait']['height'] / $this->sizes['desktopPortrait']['width'];

        $this->enabledDevices['desktopLandscape'] = intval($slider->params->get('responsive-breakpoint-desktop-landscape-enabled', 0));
        $this->enabledDevices['tabletLandscape']  = intval($slider->params->get('responsive-breakpoint-tablet-landscape-enabled', 0));
        $this->enabledDevices['tabletPortrait']   = intval($slider->params->get('responsive-breakpoint-tablet-portrait-enabled', 1));
        $this->enabledDevices['mobileLandscape']  = intval($slider->params->get('responsive-breakpoint-mobile-landscape-enabled', 0));
        $this->enabledDevices['mobilePortrait']   = intval($slider->params->get('responsive-breakpoint-mobile-portrait-enabled', 1));

        $useLocalBreakpoints = !$slider->params->get('responsive-breakpoint-global', 0);

        $landscapePortraitWidth = $breakpointWidthLandscape = 3001;
        $previousSize           = false;

        if ($this->enabledDevices['desktopLandscape']) {

            $landscapePortraitWidth   = $breakpointWidthPortrait = intval($useLocalBreakpoints ? $slider->params->get('responsive-breakpoint-desktop-portrait', ViewSettingsGeneral::defaults['desktop-large-portrait']) : Settings::get('responsive-screen-width-desktop-portrait', ViewSettingsGeneral::defaults['desktop-large-portrait']));
            $breakpointWidthLandscape = max($landscapePortraitWidth, intval($useLocalBreakpoints ? $slider->params->get('responsive-breakpoint-desktop-portrait-landscape', ViewSettingsGeneral::defaults['desktop-large-landscape']) : Settings::get('responsive-screen-width-desktop-portrait-landscape', ViewSettingsGeneral::defaults['desktop-large-landscape'])));

            $this->breakpoints[] = array(
                'device'         => 'desktopLandscape',
                'type'           => 'min-screen-width',
                'portraitWidth'  => $breakpointWidthPortrait,
                'landscapeWidth' => $breakpointWidthLandscape
            );

            $editorWidth = intval($slider->params->get('desktop-landscape-width', 1440));

            if ($overrideSizeEnabled && $slider->params->get('slider-size-override-desktop-landscape', 0) && $editorWidth > 10) {

                $customHeight = false;
                $editorHeight = intval($slider->params->get('desktop-landscape-height', 900));

                if ($editorWidth < $breakpointWidthPortrait) {
                    if ($editorHeight > 0) {
                        $editorHeight = $breakpointWidthPortrait / $editorWidth * $editorHeight;
                    }

                    $editorWidth = $breakpointWidthPortrait;
                }

                if ($editorHeight <= 0) {
                    switch ($this->slider->data->get('type', 'simple')) {
                        case 'carousel':
                        case 'showcase':
                            $editorHeight = 0;
                            break;
                        default:
                            $editorHeight = $editorWidth * $heightHelperRatio;
                    }
                } else {
                    $customHeight = true;
                }

                $this->sizes['desktopLandscape'] = array(
                    'width'        => $editorWidth,
                    'height'       => floor($editorHeight),
                    'customHeight' => $customHeight
                );
            } else {

                $this->sizes['desktopLandscape'] = array(
                    'width'        => $this->sizes['desktopPortrait']['width'],
                    'height'       => $this->sizes['desktopPortrait']['height'],
                    'customHeight' => false
                );
            }

            $this->sizes['desktopLandscape']['max'] = 3000;
            $this->sizes['desktopLandscape']['min'] = $breakpointWidthPortrait;

            $previousSize = &$this->sizes['desktopLandscape'];

        }

        $this->sizes['desktopPortrait']['max'] = max($this->sizes['desktopPortrait']['width'], $landscapePortraitWidth - 1, $breakpointWidthLandscape - 1);

        $previousSize = &$this->sizes['desktopPortrait'];

        /**
         * Keep a copy of the current smallest width to be able to disable smaller devices
         */
        $smallestWidth = $this->sizes['desktopPortrait']['width'];

        if ($this->enabledDevices['tabletLandscape']) {

            $breakpointWidthPortrait  = intval($useLocalBreakpoints ? $slider->params->get('responsive-breakpoint-tablet-landscape', ViewSettingsGeneral::defaults['tablet-large-portrait']) : Settings::get('responsive-screen-width-tablet-landscape', ViewSettingsGeneral::defaults['tablet-large-portrait']));
            $breakpointWidthLandscape = max($breakpointWidthPortrait, intval($useLocalBreakpoints ? $slider->params->get('responsive-breakpoint-tablet-landscape-landscape', ViewSettingsGeneral::defaults['tablet-large-landscape']) : Settings::get('responsive-screen-width-tablet-landscape-landscape', ViewSettingsGeneral::defaults['tablet-large-landscape'])));

            $this->breakpoints[] = array(
                'device'         => 'tabletLandscape',
                'type'           => 'max-screen-width',
                'portraitWidth'  => $breakpointWidthPortrait,
                'landscapeWidth' => $breakpointWidthLandscape
            );

            $editorWidth = intval($slider->params->get('tablet-landscape-width', 1024));

            if ($overrideSizeEnabled && $slider->params->get('slider-size-override-tablet-landscape', 0) && $editorWidth > 10) {

                $customHeight = false;
                $editorHeight = intval($slider->params->get('tablet-landscape-height', 768));

                if ($editorWidth > $breakpointWidthPortrait) {
                    if ($editorHeight > 0) {
                        $editorHeight = $breakpointWidthPortrait / $editorWidth * $editorHeight;
                    }

                    $editorWidth = $breakpointWidthPortrait;
                }

                if ($editorHeight <= 0) {
                    $editorHeight = $editorWidth * $heightHelperRatio;
                } else {
                    $customHeight = true;
                }

                $this->sizes['tabletLandscape'] = array(
                    'width'        => $editorWidth,
                    'height'       => floor($editorHeight),
                    'customHeight' => $customHeight
                );

                $smallestWidth = min($smallestWidth, $editorWidth);
            } else {
                $width = min($smallestWidth, $breakpointWidthPortrait);

                $this->sizes['tabletLandscape'] = array(
                    'width'        => $width,
                    'height'       => floor($width * $heightHelperRatio),
                    'auto'         => true,
                    'customHeight' => false
                );

                $smallestWidth = min($smallestWidth, $breakpointWidthPortrait);
            }

            $this->sizes['tabletLandscape']['max'] = max($this->sizes['tabletLandscape']['width'], $breakpointWidthPortrait, $breakpointWidthLandscape);

            $previousSize['min'] = min($previousSize['width'], $breakpointWidthPortrait + 1);

            $previousSize = &$this->sizes['tabletLandscape'];

        }

        if ($this->enabledDevices['tabletPortrait']) {

            $breakpointWidthPortrait  = intval($useLocalBreakpoints ? $slider->params->get('responsive-breakpoint-tablet-portrait', ViewSettingsGeneral::defaults['tablet-portrait']) : Settings::get('responsive-screen-width-tablet-portrait', ViewSettingsGeneral::defaults['tablet-portrait']));
            $breakpointWidthLandscape = max($breakpointWidthPortrait, intval($useLocalBreakpoints ? $slider->params->get('responsive-breakpoint-tablet-portrait-landscape', ViewSettingsGeneral::defaults['tablet-landscape']) : Settings::get('responsive-screen-width-tablet-portrait-landscape', ViewSettingsGeneral::defaults['tablet-landscape'])));

            $this->breakpoints[] = array(
                'device'         => 'tabletPortrait',
                'type'           => 'max-screen-width',
                'portraitWidth'  => $breakpointWidthPortrait,
                'landscapeWidth' => $breakpointWidthLandscape
            );

            $editorWidth = intval($slider->params->get('tablet-portrait-width', 768));

            if ($overrideSizeEnabled && $slider->params->get('slider-size-override-tablet-portrait', 0) && $editorWidth > 10) {

                $customHeight = false;
                $editorHeight = intval($slider->params->get('tablet-portrait-height', 1024));

                if ($editorWidth > $breakpointWidthPortrait) {
                    if ($editorHeight > 0) {
                        $editorHeight = $breakpointWidthPortrait / $editorWidth * $editorHeight;
                    }

                    $editorWidth = $breakpointWidthPortrait;
                }

                if ($editorHeight <= 0) {
                    $editorHeight = $editorWidth * $heightHelperRatio;
                } else {
                    $customHeight = true;
                }

                $this->sizes['tabletPortrait'] = array(
                    'width'        => $editorWidth,
                    'height'       => floor($editorHeight),
                    'customHeight' => $customHeight
                );

                $smallestWidth = min($smallestWidth, $editorWidth);
            } else {
                $width = min($smallestWidth, $breakpointWidthPortrait);

                $this->sizes['tabletPortrait'] = array(
                    'width'        => $width,
                    'height'       => floor($width * $heightHelperRatio),
                    'auto'         => true,
                    'customHeight' => false
                );

                $smallestWidth = min($smallestWidth, $breakpointWidthPortrait);
            }

            $this->sizes['tabletPortrait']['max'] = max($this->sizes['tabletPortrait']['width'], $breakpointWidthPortrait, $breakpointWidthLandscape);

            $previousSize['min'] = min($previousSize['width'], $breakpointWidthPortrait + 1);

            $previousSize = &$this->sizes['tabletPortrait'];
        }

        if ($this->enabledDevices['mobileLandscape']) {

            $breakpointWidthPortrait  = intval($useLocalBreakpoints ? $slider->params->get('responsive-breakpoint-mobile-landscape', ViewSettingsGeneral::defaults['mobile-large-portrait']) : Settings::get('responsive-screen-width-mobile-landscape', ViewSettingsGeneral::defaults['mobile-large-portrait']));
            $breakpointWidthLandscape = max($breakpointWidthPortrait, intval($useLocalBreakpoints ? $slider->params->get('responsive-breakpoint-mobile-landscape-landscape', ViewSettingsGeneral::defaults['mobile-large-landscape']) : Settings::get('responsive-screen-width-mobile-landscape-landscape', ViewSettingsGeneral::defaults['mobile-large-landscape'])));

            $this->breakpoints[] = array(
                'device'         => 'mobileLandscape',
                'type'           => 'max-screen-width',
                'portraitWidth'  => $breakpointWidthPortrait,
                'landscapeWidth' => $breakpointWidthLandscape
            );


            $editorWidth = intval($slider->params->get('mobile-landscape-width', 568));

            if ($overrideSizeEnabled && $slider->params->get('slider-size-override-mobile-landscape', 0) && $editorWidth > 10) {

                $customHeight = false;
                $editorHeight = intval($slider->params->get('mobile-landscape-height', 320));

                if ($editorWidth > $breakpointWidthPortrait) {
                    if ($editorHeight > 0) {
                        $editorHeight = $breakpointWidthPortrait / $editorWidth * $editorHeight;
                    }

                    $editorWidth = $breakpointWidthPortrait;
                }

                if ($editorHeight <= 0) {
                    $editorHeight = $editorWidth * $heightHelperRatio;
                } else {
                    $customHeight = true;
                }

                $this->sizes['mobileLandscape'] = array(
                    'width'        => $editorWidth,
                    'height'       => floor($editorHeight),
                    'customHeight' => $customHeight
                );

                $smallestWidth = min($smallestWidth, $editorWidth);
            } else {

                $width = min($smallestWidth, $breakpointWidthPortrait);

                $this->sizes['mobileLandscape'] = array(
                    'width'        => $width,
                    'height'       => floor($width * $heightHelperRatio),
                    'auto'         => true,
                    'customHeight' => false
                );

                $smallestWidth = min($smallestWidth, $breakpointWidthPortrait);
            }

            $this->sizes['mobileLandscape']['max'] = max($this->sizes['mobileLandscape']['width'], $breakpointWidthPortrait, $breakpointWidthLandscape);

            $previousSize['min'] = min($previousSize['width'], $breakpointWidthPortrait + 1);

            $previousSize = &$this->sizes['mobileLandscape'];
        }

        if ($this->enabledDevices['mobilePortrait']) {

            $breakpointWidthPortrait  = intval($useLocalBreakpoints ? $slider->params->get('responsive-breakpoint-mobile-portrait', ViewSettingsGeneral::defaults['mobile-portrait']) : Settings::get('responsive-screen-width-mobile-portrait', ViewSettingsGeneral::defaults['mobile-portrait']));
            $breakpointWidthLandscape = max($breakpointWidthPortrait, intval($useLocalBreakpoints ? $slider->params->get('responsive-breakpoint-mobile-portrait-landscape', ViewSettingsGeneral::defaults['mobile-landscape']) : Settings::get('responsive-screen-width-mobile-portrait-landscape', ViewSettingsGeneral::defaults['mobile-landscape'])));

            $this->breakpoints[] = array(
                'device'         => 'mobilePortrait',
                'type'           => 'max-screen-width',
                'portraitWidth'  => $breakpointWidthPortrait,
                'landscapeWidth' => $breakpointWidthLandscape
            );


            $editorWidth = intval($slider->params->get('mobile-portrait-width', 320));

            if ($overrideSizeEnabled && $slider->params->get('slider-size-override-mobile-portrait', 0) && $editorWidth > 10) {

                $customHeight = false;
                $editorHeight = intval($slider->params->get('mobile-portrait-height', 568));

                if ($editorWidth > $breakpointWidthPortrait) {
                    if ($editorHeight > 0) {
                        $editorHeight = $breakpointWidthPortrait / $editorWidth * $editorHeight;
                    }

                    $editorWidth = $breakpointWidthPortrait;
                }

                if ($editorHeight <= 0) {
                    $editorHeight = $editorWidth * $heightHelperRatio;
                } else {
                    $customHeight = true;
                }

                $this->sizes['mobilePortrait'] = array(
                    'width'        => $editorWidth,
                    'height'       => floor($editorHeight),
                    'customHeight' => $customHeight
                );
            } else {
                $width = min(320, $smallestWidth, $breakpointWidthPortrait);

                $this->sizes['mobilePortrait'] = array(
                    'width'        => $width,
                    'height'       => floor($width * $heightHelperRatio),
                    'customHeight' => false
                );
            }

            $this->sizes['mobilePortrait']['max'] = max($this->sizes['mobilePortrait']['width'], $breakpointWidthPortrait, $breakpointWidthLandscape);

            $previousSize['min'] = min($previousSize['width'], $breakpointWidthPortrait + 1);

            $previousSize = &$this->sizes['mobilePortrait'];
        }

        $previousSize['min'] = min(320, $previousSize['width']);

        if (isset($this->sizes['mobileLandscape']['auto'])) {
            unset($this->sizes['mobileLandscape']['auto']);

            $this->sizes['mobileLandscape']['width']  = $this->sizes['mobileLandscape']['min'];
            $this->sizes['mobileLandscape']['height'] = floor($this->sizes['mobileLandscape']['width'] * $heightHelperRatio);
        }

        if (isset($this->sizes['tabletPortrait']['auto'])) {
            unset($this->sizes['tabletPortrait']['auto']);

            $this->sizes['tabletPortrait']['width']  = $this->sizes['tabletPortrait']['min'];
            $this->sizes['tabletPortrait']['height'] = floor($this->sizes['tabletPortrait']['width'] * $heightHelperRatio);
        }

        if (isset($this->sizes['tabletLandscape']['auto'])) {
            unset($this->sizes['tabletLandscape']['auto']);

            $this->sizes['tabletLandscape']['width']  = $this->sizes['tabletLandscape']['min'];
            $this->sizes['tabletLandscape']['height'] = floor($this->sizes['tabletLandscape']['width'] * $heightHelperRatio);
        }

        $this->parseLimitSlideWidth($slider->params);

        $breakpointData = array();
        foreach ($this->breakpoints as $breakpoint) {
            $breakpointData[$breakpoint['device']] = $breakpoint;
        }

        if (isset($breakpointData['desktopLandscape'])) {

            $portraitMinWidth  = $breakpointData['desktopLandscape']['portraitWidth'];
            $landscapeMinWidth = $breakpointData['desktopLandscape']['landscapeWidth'];

            if ($portraitMinWidth == $landscapeMinWidth || $this->slider->isFrame) {
                $this->mediaQueries['desktoplandscape'] = array('(min-width: ' . $portraitMinWidth . 'px)');

            } else {
                $this->mediaQueries['desktoplandscape'] = array(
                    '(orientation: landscape) and (min-width: ' . $landscapeMinWidth . 'px)',
                    '(orientation: portrait) and (min-width: ' . $portraitMinWidth . 'px)'
                );
            }
        }

        $nextSize = null;
        foreach (array(
                     'tabletLandscape',
                     'tabletPortrait',
                     'mobileLandscape',
                     'mobilePortrait'
                 ) as $nextDevice) {
            if (isset($breakpointData[$nextDevice])) {
                $nextSize = $breakpointData[$nextDevice];
                break;
            }
        }

        $portraitMaxWidth  = 0;
        $landscapeMaxWidth = 0;
        if (isset($breakpointData['desktopLandscape'])) {
            $portraitMaxWidth  = $breakpointData['desktopLandscape']['portraitWidth'] - 1;
            $landscapeMaxWidth = $breakpointData['desktopLandscape']['landscapeWidth'] - 1;
        }
        $portraitMinWidth  = $nextSize['portraitWidth'] + 1;
        $landscapeMinWidth = $nextSize['landscapeWidth'] + 1;

        if ($portraitMaxWidth == 0 || $landscapeMaxWidth == 0) {
            if ($portraitMinWidth == $landscapeMinWidth || $this->slider->isFrame) {
                $this->mediaQueries['desktopportrait'] = array('(min-width: ' . $portraitMinWidth . 'px)');

            } else {
                $this->mediaQueries['desktopportrait'] = array(
                    '(orientation: landscape) and (min-width: ' . $landscapeMinWidth . 'px)',
                    '(orientation: portrait) and (min-width: ' . $portraitMinWidth . 'px)'
                );
            }
        } else {
            if (($portraitMinWidth == $landscapeMinWidth && $portraitMaxWidth == $landscapeMaxWidth) || $this->slider->isFrame) {
                $this->mediaQueries['desktopportrait'] = array('(min-width: ' . $portraitMinWidth . 'px) and (max-width: ' . $portraitMaxWidth . 'px)');

            } else {
                $this->mediaQueries['desktopportrait'] = array(
                    '(orientation: landscape) and (min-width: ' . $landscapeMinWidth . 'px) and (max-width: ' . $landscapeMaxWidth . 'px)',
                    '(orientation: portrait) and (min-width: ' . $portraitMinWidth . 'px) and (max-width: ' . $portraitMaxWidth . 'px)'
                );
            }
        }


        $this->initMediaQuery($breakpointData, 'tabletLandscape', array(
            'tabletPortrait',
            'mobileLandscape',
            'mobilePortrait'
        ));

        $this->initMediaQuery($breakpointData, 'tabletPortrait', array(
            'mobileLandscape',
            'mobilePortrait'
        ));

        $this->initMediaQuery($breakpointData, 'mobileLandscape', array(
            'mobilePortrait'
        ));

        $this->initMediaQuery($breakpointData, 'mobilePortrait', array());
    }

    private function initMediaQuery(&$breakpointData, $deviceName, $nextDevices) {
        if (isset($breakpointData[$deviceName])) {

            $deviceNameLower = strtolower($deviceName);

            $nextSize = null;
            foreach ($nextDevices as $nextDevice) {
                if (isset($breakpointData[$nextDevice])) {
                    $nextSize = $breakpointData[$nextDevice];
                    break;
                }
            }

            $portraitMaxWidth  = $breakpointData[$deviceName]['portraitWidth'];
            $landscapeMaxWidth = $breakpointData[$deviceName]['landscapeWidth'];

            if ($nextSize) {
                if (($nextSize['portraitWidth'] == $nextSize['landscapeWidth'] && $portraitMaxWidth == $landscapeMaxWidth) || $this->slider->isFrame) {
                    $this->mediaQueries[$deviceNameLower] = array('(max-width: ' . $portraitMaxWidth . 'px) and (min-width: ' . ($nextSize['portraitWidth'] + 1) . 'px)');

                } else {
                    $this->mediaQueries[$deviceNameLower] = array(
                        '(orientation: landscape) and (max-width: ' . $landscapeMaxWidth . 'px) and (min-width: ' . ($nextSize['landscapeWidth'] + 1) . 'px)',
                        '(orientation: portrait) and (max-width: ' . $portraitMaxWidth . 'px) and (min-width: ' . ($nextSize['portraitWidth'] + 1) . 'px)'
                    );
                }
            } else {
                if (($portraitMaxWidth == $landscapeMaxWidth) || $this->slider->isFrame) {
                    $this->mediaQueries[$deviceNameLower] = array('(max-width: ' . $portraitMaxWidth . 'px)');

                } else {
                    $this->mediaQueries[$deviceNameLower] = array(
                        '(orientation: landscape) and (max-width: ' . $landscapeMaxWidth . 'px)',
                        '(orientation: portrait) and (max-width: ' . $portraitMaxWidth . 'px)'
                    );
                }
            }
        }

    }

    public function makeJavaScriptProperties(&$properties) {

        if ($this->maximumSlideWidthLandscape <= 0) {
            $this->maximumSlideWidthLandscape = $this->maximumSlideWidth;
        }

        if ($this->maximumSlideWidthTablet <= 0) {
            $this->maximumSlideWidthTablet = $this->maximumSlideWidth;
        }

        if ($this->maximumSlideWidthTabletLandscape <= 0) {
            $this->maximumSlideWidthTabletLandscape = $this->maximumSlideWidthTablet;
        }

        if ($this->maximumSlideWidthMobile <= 0) {
            $this->maximumSlideWidthMobile = $this->maximumSlideWidth;
        }

        if ($this->maximumSlideWidthMobileLandscape <= 0) {
            $this->maximumSlideWidthMobileLandscape = $this->maximumSlideWidthMobile;
        }

        if (!$this->scaleDown) {
            $this->slider->addDeviceCSS('all', 'div#' . $this->slider->elementId . '-align{min-width:' . $this->sizes['desktopPortrait']['width'] . 'px;}');
        }

        if (!$this->scaleUp) {
            $this->slider->addDeviceCSS('all', 'div#' . $this->slider->elementId . '-align{max-width:' . $this->sizes['desktopPortrait']['width'] . 'px;}');
        }


        if ($this->minimumHeight > 0) {
            $this->slider->sliderType->handleSliderMinHeight($this->minimumHeight);
        }

        foreach ($this->mediaQueries as $device => $mediaQuery) {
            if ($mediaQuery) {
                $this->slider->addDeviceCSS($device, 'div#' . $this->slider->elementId . ' [data-hide-' . $device . '="1"]{display: none !important;}');
            }
        }

        if (!$this->slider->isAdmin) {
            if ($this->hideOnDesktopLandscape) {
                $this->slider->addDeviceCSS('desktoplandscape', '.n2-section-smartslider[data-ssid="' . $this->slider->sliderId . '"]{display: none;}');
            }
            if (!SmartSlider3Info::$forceDesktop && $this->hideOnDesktopPortrait) {
                $this->slider->addDeviceCSS('desktopportrait', '.n2-section-smartslider[data-ssid="' . $this->slider->sliderId . '"]{display: none;}');
            }

            if ($this->hideOnTabletLandscape) {
                $this->slider->addDeviceCSS('tabletlandscape', '.n2-section-smartslider[data-ssid="' . $this->slider->sliderId . '"]{display: none;}');
            }
            if ($this->hideOnTabletPortrait) {
                $this->slider->addDeviceCSS('tabletportrait', '.n2-section-smartslider[data-ssid="' . $this->slider->sliderId . '"]{display: none;}');
            }

            if ($this->hideOnMobileLandscape) {
                $this->slider->addDeviceCSS('mobilelandscape', '.n2-section-smartslider[data-ssid="' . $this->slider->sliderId . '"]{display: none;}');
            }
            if ($this->hideOnMobilePortrait) {
                $this->slider->addDeviceCSS('mobileportrait', '.n2-section-smartslider[data-ssid="' . $this->slider->sliderId . '"]{display: none;}');
            }
        }


        $properties['responsive'] = array(
            'mediaQueries' => $this->mediaQueries,
            'base'         => $this->slider->assets->base,
            'hideOn'       => array(
                'desktopLandscape' => SmartSlider3Info::$forceAllDevices ? false : $this->hideOnDesktopLandscape,
                'desktopPortrait'  => SmartSlider3Info::$forceDesktop ? false : $this->hideOnDesktopPortrait,
                'tabletLandscape'  => SmartSlider3Info::$forceAllDevices ? false : $this->hideOnTabletLandscape,
                'tabletPortrait'   => SmartSlider3Info::$forceAllDevices ? false : $this->hideOnTabletPortrait,
                'mobileLandscape'  => SmartSlider3Info::$forceAllDevices ? false : $this->hideOnMobileLandscape,
                'mobilePortrait'   => SmartSlider3Info::$forceAllDevices ? false : $this->hideOnMobilePortrait,
            ),

            'onResizeEnabled'     => $this->onResizeEnabled,
            'type'                => $this->type,
            'sliderHeightBasedOn' => $this->sliderHeightBasedOn,

            'focusUser' => $this->focusUser,
            'focusEdge' => $this->focusEdge,

            'breakpoints'    => $this->breakpoints,
            'enabledDevices' => $this->enabledDevices,
            'sizes'          => $this->sizes,

            'overflowHiddenPage' => intval($this->slider->params->get('overflow-hidden-page', 0))
        );
    }

    /**
     * @param Data $params
     */
    private function parseLimitSlideWidth($params) {
        if ($params->get('responsiveLimitSlideWidth', 1)) {

            if ($this->enabledDevices['desktopLandscape']) {
                if ($params->get('responsiveSlideWidthDesktopLandscape', 0)) {
                    $this->maximumSlideWidthLandscape = intval($params->get('responsiveSlideWidthMaxDesktopLandscape', 1600));

                    $this->slider->addDeviceCSS('desktoplandscape', 'div#' . $this->slider->elementId . ' .n2-ss-slide-limiter{max-width:' . $this->maximumSlideWidthLandscape . 'px;}');
                }
            }

            if ($params->get('responsiveSlideWidth', 0)) {
                $this->maximumSlideWidth = intval($params->get('responsiveSlideWidthMax', 3000));
            } else {
                $this->maximumSlideWidth = $this->sizes['desktopPortrait']['width'];
            }

            if ($this->maximumSlideWidth < 1) {
                $this->maximumSlideWidth = 10000;
            }

            $this->slider->addDeviceCSS('all', 'div#' . $this->slider->elementId . ' .n2-ss-slide-limiter{max-width:' . $this->maximumSlideWidth . 'px;}');


            if ($this->enabledDevices['tabletLandscape']) {
                if ($params->get('responsiveSlideWidthTabletLandscape', 0)) {
                    $this->maximumSlideWidthTabletLandscape = intval($params->get('responsiveSlideWidthMaxTabletLandscape', 1200));

                    $this->slider->addDeviceCSS('tabletlandscape', 'div#' . $this->slider->elementId . ' .n2-ss-slide-limiter{max-width:' . $this->maximumSlideWidthTabletLandscape . 'px;}');
                }
            }

            if ($params->get('responsiveSlideWidthTablet', 0)) {
                $this->maximumSlideWidthTablet = intval($params->get('responsiveSlideWidthMaxTablet', 980));

                $this->slider->addDeviceCSS('tabletportrait', 'div#' . $this->slider->elementId . ' .n2-ss-slide-limiter{max-width:' . $this->maximumSlideWidthTablet . 'px;}');
            }


            if ($this->enabledDevices['mobileLandscape']) {
                if ($params->get('responsiveSlideWidthMobileLandscape', 0)) {
                    $this->maximumSlideWidthMobileLandscape = intval($params->get('responsiveSlideWidthMaxMobileLandscape', 780));

                    $this->slider->addDeviceCSS('mobilelandscape', 'div#' . $this->slider->elementId . ' .n2-ss-slide-limiter{max-width:' . $this->maximumSlideWidthMobileLandscape . 'px;}');
                }
            }

            if ($params->get('responsiveSlideWidthMobile', 0)) {
                $this->maximumSlideWidthMobile = intval($params->get('responsiveSlideWidthMaxMobile', 480));

                $this->slider->addDeviceCSS('mobileportrait', 'div#' . $this->slider->elementId . ' .n2-ss-slide-limiter{max-width:' . $this->maximumSlideWidthMobile . 'px;}');
            }
        }
    }
}Feature/SlideBackground.php000064400000051442152356644430011732 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Feature;


use Nextend\Framework\Image\ImageEdit;
use Nextend\Framework\Image\ImageManager;
use Nextend\Framework\Parser\Color;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Slider\Slide;
use Nextend\SmartSlider3\Slider\Slider;

class SlideBackground {

    /**
     * @var Slider
     */
    private $slider;

    public function __construct($slider) {

        $this->slider = $slider;
    }

    public function makeJavaScriptProperties(&$properties) {
        $enabled = intval($this->slider->params->get('slide-background-parallax', 0));
        if ($enabled) {
            $properties['backgroundParallax'] = array(
                'strength' => intval($this->slider->params->get('slide-background-parallax-strength', 50)) / 100,
                'tablet'   => intval($this->slider->params->get('bg-parallax-tablet', 0)),
                'mobile'   => intval($this->slider->params->get('bg-parallax-mobile', 0))
            );
        }
    }

    /**
     * @param $slide Slide
     *
     * @return string
     */

    public function make($slide) {

        if ($slide->parameters->get('background-type') == '') {
            $slide->parameters->set('background-type', 'color');
            if ($slide->parameters->get('backgroundVideoMp4')) {
                $slide->parameters->set('background-type', 'video');
            } else if ($slide->parameters->get('backgroundImage')) {
                $slide->parameters->set('background-type', 'image');
            }
        }

        return $this->makeBackground($slide);
    }

    private function getBackgroundStyle($slide) {

        $attributes = array();

        $style = '';
        $color = $slide->fill($slide->parameters->get('backgroundColor', ''));
        if (empty($color)) {
            $color = 'ffffff00';
        }
        if (strlen($color) > 0 && $color[0] == '#') {
            $color = substr($color, 1);
            if (strlen($color) == 6) {
                $color .= 'ff';
            }
        }
        $gradient = $slide->parameters->get('backgroundGradient', 'off');

        if ($gradient != 'off') {
            $colorEnd = $slide->fill($slide->parameters->get('backgroundColorEnd', 'ffffff00'));
            if (empty($colorEnd)) {
                $colorEnd = 'ffffff00';
            }

            if ($colorEnd[0] == '#') {
                $colorEnd = substr($colorEnd, 1);
                if (strlen($colorEnd) == 6) {
                    $colorEnd .= 'ff';
                }
            }

            $startColor = Color::colorToRGBA($color);
            $endColor   = Color::colorToRGBA($colorEnd);

            $attributes['data-gradient']    = $gradient;
            $attributes['data-color-start'] = $startColor;
            $attributes['data-color-end']   = $endColor;

            switch ($gradient) {
                case 'horizontal':
                    $style .= 'background:linear-gradient(to right, ' . $startColor . ' 0%,' . $endColor . ' 100%);';
                    break;
                case 'vertical':
                    $style .= 'background:linear-gradient(to bottom, ' . $startColor . ' 0%,' . $endColor . ' 100%);';
                    break;
                case 'diagonal1':
                    $style .= 'background:linear-gradient(45deg, ' . $startColor . ' 0%,' . $endColor . ' 100%);';
                    break;
                case 'diagonal2':
                    $style .= 'background:linear-gradient(135deg, ' . $startColor . ' 0%,' . $endColor . ' 100%);';
                    break;
            }
        } else {
            if (strlen($color) == 8) {

                $colorRGBA = Color::colorToRGBA($color);
                $style     .= "background-color: " . Color::colorToRGBA($color) . ";";

                $attributes['data-color'] = $colorRGBA;


            }
        }

        $attributes['style'] = $style;

        return $attributes;
    }

    private function makeBackground($slide) {

        $backgroundType = $slide->parameters->get('background-type');

        if (empty($backgroundType)) {
            $backgroundVideoMp4 = $slide->parameters->get('backgroundVideoMp4', '');
            $backgroundImage    = $slide->parameters->get('backgroundImage', '');
            if (!empty($backgroundVideoMp4)) {
                $backgroundType = 'video';
            } else if (!empty($backgroundImage)) {
                $backgroundType = 'image';
            } else {
                $backgroundType = 'color';
            }
        }

        $fillMode = $slide->parameters->get('backgroundMode', 'default');

        if ($fillMode == 'default') {
            $fillMode = $this->slider->params->get('backgroundMode', 'fill');

        }

        $backgroundElements = array();

        if ($backgroundType == 'color') {
            $backgroundElements[] = $this->renderColor($slide);

        } else if ($backgroundType == 'video') {


            $backgroundElements[] = $this->renderBackgroundVideo($slide);
            $backgroundElements[] = $this->renderImage($slide, $fillMode);

            $backgroundElements[] = $this->renderColor($slide);

        } else if ($backgroundType == 'image') {


            $backgroundElements[] = $this->renderImage($slide, $fillMode);

            $backgroundElements[] = $this->renderColor($slide);
        }

        $html = implode('', $backgroundElements);

        /* @see https://bugs.chromium.org/p/chromium/issues/detail?id=1181291
         * if (!$slide->getFrontendFirst()) {
         * $html = '<template>' . $html . '</template>';
         * }
         */

        return Html::tag('div', array(
            'class'          => "n2-ss-slide-background",
            'data-public-id' => $slide->publicID,
            'data-mode'      => $fillMode
        ), $html);
    }

    private function renderColor($slide) {
        $backgroundAttributes = $this->getBackgroundStyle($slide);

        if (!empty($backgroundAttributes['style'])) {

            $backgroundAttributes['class'] = 'n2-ss-slide-background-color';

            if ($slide->parameters->get('backgroundColorOverlay', 0)) {
                $backgroundAttributes['data-overlay'] = 1;
            }

            return Html::tag('div', $backgroundAttributes, '');
        }

        return '';
    }

    /**
     * @param $slide Slide
     * @param $fillMode
     *
     * @return string
     */
    private function renderImage($slide, $fillMode) {

        $rawBackgroundImage = $slide->parameters->get('backgroundImage', '');

        if (empty($rawBackgroundImage)) {
            return '';
        }

        $backgroundImageBlur = max(0, $slide->parameters->get('backgroundImageBlur', 0));

        $focusX = max(0, min(100, $slide->fill($slide->parameters->get('backgroundFocusX', 50))));
        $focusY = max(0, min(100, $slide->fill($slide->parameters->get('backgroundFocusY', 50))));

        $backgroundImageMobile        = '';
        $backgroundImageTablet        = '';
        $backgroundImageDesktopRetina = '';
        $backgroundImage              = $slide->fill($rawBackgroundImage);

        if (!$slide->hasGenerator()) {
            $imageData                    = ImageManager::getImageData($backgroundImage);
            $backgroundImageDesktopRetina = $imageData['desktop-retina']['image'];
            $backgroundImageMobile        = $imageData['mobile']['image'];
            $backgroundImageTablet        = $imageData['tablet']['image'];
        }

        $alt   = $slide->fill($slide->parameters->get('backgroundAlt', ''));
        $title = $slide->fill($slide->parameters->get('backgroundTitle', ''));


        $opacity = min(100, max(0, $slide->parameters->get('backgroundImageOpacity', 100)));

        $style = array();
        if ($opacity < 100) {
            $style[] = 'opacity:' . ($opacity / 100);
        }

        if ($focusX != '50') {
            $style[] = '--ss-o-pos-x:' . $focusX . '%';
        }

        if ($focusY != '50') {
            $style[] = '--ss-o-pos-y:' . $focusY . '%';
        }

        $attributes = array(
            "class"        => 'n2-ss-slide-background-image',
            "data-blur"    => $backgroundImageBlur,
            "data-opacity" => $opacity,
            "data-x"       => $focusX,
            "data-y"       => $focusY,
            "data-alt"     => $alt,
            "data-title"   => $title
        );

        if (!empty($style)) {
            $attributes['style'] = implode(';', $style);
        }

        $sources = array();

        if ($this->slider->isAdmin) {
            $src = $backgroundImage;

            $attributes['data-hash']               = md5($src);
            $attributes['data-src-desktop']        = $src;
            $attributes['data-src-desktop-retina'] = $backgroundImageDesktopRetina;
            $attributes['data-src-tablet']         = $backgroundImageTablet;
            $attributes['data-src-mobile']         = $backgroundImageMobile;
        } else {

            if (empty($backgroundImage)) {
                /**
                 * @todo Does it really work as expected?
                 */
                $src = ImageEdit::base64Transparent();
            } else {
                /**
                 * @todo this resize might have a better place
                 */
                $src = $backgroundImage;
                if ($this->slider->params->get('optimize-webp', 0)) {
                    $src = ResourceTranslator::urlToResource($this->slider->features->optimize->optimizeBackground($backgroundImage, $focusX, $focusY));
                }

                $slide->addImage(ResourceTranslator::toUrl($src));
            }

            $hasDeviceSpecificImage = false;

            $mediaQueries = $this->slider->features->responsive->mediaQueries;

            if (!empty($backgroundImageDesktopRetina)) {

                $hasDeviceSpecificImage = true;

                $backgroundImageDesktopRetina = ResourceTranslator::toUrl($backgroundImageDesktopRetina);

                $mediaQueryMinPixelRatio = ' and (-webkit-min-device-pixel-ratio: 1.5)';

                if (!empty($mediaQueries['desktopportrait'])) {
                    $sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
                        'srcset' => $backgroundImageDesktopRetina,
                        'media'  => implode($mediaQueryMinPixelRatio . ',', $mediaQueries['desktopportrait']) . $mediaQueryMinPixelRatio
                    )), false, false);
                }
                if (!empty($mediaQueries['desktoplandscape'])) {
                    $sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
                        'srcset' => $backgroundImageDesktopRetina,
                        'media'  => implode($mediaQueryMinPixelRatio . ',', $mediaQueries['desktoplandscape']) . $mediaQueryMinPixelRatio
                    )), false, false);
                }

            }

            if (!empty($backgroundImageMobile)) {

                $hasDeviceSpecificImage = true;

                $backgroundImageMobileUrl = ResourceTranslator::toUrl($backgroundImageMobile);

                if (!empty($mediaQueries['mobileportrait'])) {
                    $sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
                        'srcset' => $backgroundImageMobileUrl,
                        'media'  => implode(',', $mediaQueries['mobileportrait'])
                    )), false, false);
                }
                if (!empty($mediaQueries['mobilelandscape'])) {
                    $sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
                        'srcset' => $backgroundImageMobileUrl,
                        'media'  => implode(',', $mediaQueries['mobilelandscape'])
                    )), false, false);
                }
            }

            if (!empty($backgroundImageTablet)) {

                $hasDeviceSpecificImage = true;

                $backgroundImageTabletUrl = ResourceTranslator::toUrl($backgroundImageTablet);

                if (!empty($mediaQueries['tabletportrait'])) {
                    $sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
                        'srcset' => $backgroundImageTabletUrl,
                        'media'  => implode(',', $mediaQueries['tabletportrait'])
                    )), false, false);
                }
                if (!empty($mediaQueries['tabletlandscape'])) {
                    $sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
                        'srcset' => $backgroundImageTabletUrl,
                        'media'  => implode(',', $mediaQueries['tabletlandscape'])
                    )), false, false);
                }
            }
            if (!$hasDeviceSpecificImage) {

                $retinaSupport = !!$this->slider->params->get('optimize-slide-width-retina', 0);
                $optimizeScale = $this->slider->params->get('optimize-scale', 0);
                $optimizedData = $this->slider->features->optimize->optimizeImageWebP($backgroundImage, array(
                    'optimize'         => $this->slider->params->get('optimize-webp', 0),
                    'quality'          => intval($this->slider->params->get('optimize-quality', 70)),
                    'resize'           => $optimizeScale,
                    'defaultWidth'     => intval($this->slider->params->get('optimize-slide-width-normal', 1920)),
                    'mediumWidth'      => intval($this->slider->params->get('optimize-slide-width-tablet', 1200)),
                    'mediumHeight'     => intval($this->slider->params->get('optimize-slide-height-tablet', 0)),
                    'smallWidth'       => intval($this->slider->params->get('optimize-slide-width-mobile', 500)),
                    'smallHeight'      => intval($this->slider->params->get('optimize-slide-height-mobile', 0)),
                    'focusX'           => $focusX,
                    'focusY'           => $focusY,
                    'compressOriginal' => $retinaSupport
                ));


                if ($optimizeScale && $retinaSupport) {

                    $webPSrcSet = array();
                    if (isset($optimizedData['small'])) {
                        $slide->addImage($optimizedData['small']['src']);

                        $webPSrcSet[] = $optimizedData['small']['src'] . ' ' . $optimizedData['small']['width'] . 'w';
                    }

                    if (isset($optimizedData['medium'])) {
                        $slide->addImage($optimizedData['medium']['src']);

                        $webPSrcSet[] = $optimizedData['medium']['src'] . ' ' . $optimizedData['medium']['width'] . 'w';
                    }

                    if (isset($optimizedData['normal'])) {
                        $slide->addImage($optimizedData['normal']['src']);
                        $webPSrcSet[] = $optimizedData['normal']['src'] . ' ' . $optimizedData['normal']['width'] . 'w';
                    }

                    if (isset($optimizedData['original'])) {
                        $slide->addImage($optimizedData['original']['src']);
                        $webPSrcSet[] = $optimizedData['original']['src'] . ' ' . $optimizedData['original']['width'] . 'w';
                    }

                    if (!empty($webPSrcSet)) {
                        $sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
                            'srcset' => implode(',', $webPSrcSet),
                            'type'   => 'image/webp'
                        )), false, false);
                    }
                } else {

                    if (isset($optimizedData['small'])) {
                        $slide->addImage($optimizedData['small']['src']);

                        $sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
                            'srcset' => $optimizedData['small']['src'],
                            'type'   => 'image/webp',
                            'media'  => '(max-width: ' . $optimizedData['small']['width'] . 'px)'
                        )), false, false);
                    }

                    if (isset($optimizedData['medium'])) {
                        $slide->addImage($optimizedData['medium']['src']);

                        $sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
                            'srcset' => $optimizedData['medium']['src'],
                            'type'   => 'image/webp',
                            'media'  => '(max-width: ' . $optimizedData['medium']['width'] . 'px)'
                        )), false, false);
                    }

                    if (isset($optimizedData['normal'])) {
                        $slide->addImage($optimizedData['normal']['src']);

                        $sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
                            'srcset' => $optimizedData['normal']['src'],
                            'type'   => 'image/webp'
                        )), false, false);
                    }
                }
            }
        
        }

        $imageAttributes = array(
            'src'     => ResourceTranslator::toUrl($src),
            'alt'     => $alt,
            'title'   => $title,
            'loading' => 'lazy',
            'style'   => ''
        );

        $imageAttributes = Html::addExcludeLazyLoadAttributes($imageAttributes);

        $sources[] = Html::tag('img', $imageAttributes, '', false);

        $picture = HTML::tag('picture', Html::addExcludeLazyLoadAttributes(), implode('', $sources));

        $originalImage = Html::tag('div', $attributes, $picture);

        if ($fillMode === 'blurfit') {
            $slideOption = $slide->parameters->get('backgroundMode', 'default');

            if ($slideOption === 'blurfit') {
                $blurFit = $slide->parameters->get('backgroundBlurFit', 7);
            } else {
                $blurFit                        = $this->slider->params->get('backgroundBlurFit', 7);
                $attributes['data-blurfitmode'] = 'default';
            }
            $picture      = HTML::tag('picture', Html::addExcludeLazyLoadAttributes(array(
                'style' => 'filter:blur(' . $blurFit . 'px)'
            )), implode('', $sources));
            $blurFitStyle = array(
                'margin:-' . ($blurFit * 2) . 'px',
                'padding:' . ($blurFit * 2) . 'px'
            );
            if (!isset($attributes['style'])) {
                $attributes['style'] = '';
            }

            $attributes['data-globalblur'] = $this->slider->params->get('backgroundBlurFit', 7);
            $attributes['data-bgblur']     = $slide->parameters->get('backgroundBlurFit', 7);
            $attributes['style']           = implode(';', $blurFitStyle);
            $ret                           = Html::tag('div', $attributes, $picture) . $originalImage;
        } else {
            $ret = $originalImage;
        }

        return $ret;
    }

    /**
     * @param Slide $slide
     *
     * @return string
     */
    private function renderBackgroundVideo($slide) {
        $mp4 = ResourceTranslator::toUrl($slide->fill($slide->parameters->get('backgroundVideoMp4', '')));

        if (empty($mp4)) {
            return '';
        }

        $sources = '';

        if ($mp4) {
            $sources .= Html::tag("source", array(
                "src"  => $mp4,
                "type" => "video/mp4"
            ), '', false);
        }

        $opacity = min(100, max(0, $slide->parameters->get('backgroundVideoOpacity', 100)));

        $attributes = array(
            'class'              => 'n2-ss-slide-background-video intrinsic-ignore data-tf-not-load',
            'style'              => 'opacity:' . ($opacity / 100) . ';',
            'data-mode'          => $slide->parameters->get('backgroundVideoMode', 'fill'),
            'playsinline'        => 1,
            'webkit-playsinline' => 1,
            'onloadstart'        => 'this.n2LoadStarted=1;',
            'data-keepplaying'   => 1,
            'preload'            => 'none',
            'muted'              => 'muted'
        );

        if ($slide->parameters->get('backgroundVideoLoop', 1)) {
            $attributes['loop'] = 'loop';
        }

        if ($slide->parameters->get('backgroundVideoReset', 1)) {
            $attributes['data-reset-slide-change'] = 1;
        }

        return Html::tag('video', $attributes, $sources);
    

        return '';
    }
}Feature/TranslateUrl.php000064400000001306152356644430011304 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Feature;


use Nextend\Framework\Parser\Common;
use Nextend\Framework\Sanitize;
use Nextend\SmartSlider3\Settings;

class TranslateUrl {

    private $slider;

    public $from = '';

    public $to = '';

    public function __construct($slider) {

        $this->slider = $slider;
        list($this->from, $this->to) = (array)Common::parse(esc_attr(Settings::get('translate-url', '||')));
    }

    public function replaceUrl($string) {

        if (!$this->slider->isAdmin && !empty($this->from) && !empty($this->to)) {
            return str_replace($this->from, $this->to, $string);
        }

        return $string;
    }
}Base/PlatformSliderBase.php000064400000000251152356644430011663 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Base;


class PlatformSliderBase {

    public function addCMSFunctions($text) {

        return $text;
    }
}Base/PlatformSliderTrait.php000064400000000706152356644430012101 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Base;

use Nextend\SmartSlider3\Slider;

trait PlatformSliderTrait {

    /**
     * @var PlatformSliderBase
     */
    private $platformSlider;

    public function initPlatformSlider() {
        $this->platformSlider = new Slider\Joomla\PlatformSlider();
    
    }

    public function addCMSFunctions($text) {

        return $this->platformSlider->addCMSFunctions($text);
    }
}Admin/AdminSlide.php000064400000001147152356644430010335 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Admin;


use Nextend\SmartSlider3\Slider\Slide;

class AdminSlide extends Slide {

    public function setSlidesParams() {
        $this->attributes['data-variables'] = json_encode($this->variables);
        parent::setSlidesParams();
    }

    protected function addSlideLink() {

    }

    public function isVisible() {
        return true;
    }

    protected function onCreate() {
    }

    public function setCurrentlyEdited() {
        $this->underEdit = true;
        $this->classes   .= ' n2-ss-currently-edited-slide';
    }
}Admin/AdminSlider.php000064400000003065152356644430010520 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Admin;


use Nextend\SmartSlider3\Slider\Slide;
use Nextend\SmartSlider3\Slider\Slider;

class AdminSlider extends Slider {

    public $isAdmin = true;

    protected $editedSlideID;

    /**
     * @var AdminSlides
     */
    protected $slidesBuilder;

    public function __construct($MVCHelper, $sliderId, $parameters) {
        parent::__construct($MVCHelper, $sliderId, $parameters, true);
    }

    public static function getCacheId($sliderId) {
        return self::$_identifier . '-admin-' . $sliderId;
    }

    public function setElementId() {
        $this->elementId = self::$_identifier . '-' . 0;
    }

    public function initSlides() {
        if ($this->loadState < self::LOAD_STATE_SLIDES) {

            $this->initSlider();

            if (!$this->isGroup) {
                $this->slidesBuilder = new AdminSlides($this);

                $this->slidesBuilder->initSlides($this->parameters['slidesData'], $this->parameters['generatorData']);
            }

            $this->loadState = self::LOAD_STATE_SLIDES;
        }
    }

    /**
     * @return Slide
     */
    public function getEditedSlide() {
        return $this->slidesBuilder->getEditedSlide();
    }

    /**
     * @return int
     */
    public function getEditedSlideID() {
        return $this->editedSlideID;
    }

    /**
     * @param int $editedSlideID
     */
    public function setEditedSlideID($editedSlideID) {
        $this->editedSlideID = $editedSlideID;
    }


}Admin/AdminSlides.php000064400000010153152356644430010515 0ustar00<?php


namespace Nextend\SmartSlider3\Slider\Admin;


use Nextend\Framework\Platform\Platform;
use Nextend\Framework\Request\Request;
use Nextend\SmartSlider3\Application\Model\ModelSlides;
use Nextend\SmartSlider3\Slider\Slide;
use Nextend\SmartSlider3\Slider\Slides;

class AdminSlides extends Slides {

    /**
     * @var Slide
     */
    protected $editedSlide;

    protected function slidesWhereQuery() {
        $date = Platform::getMysqlDate();

        return "   AND ((published = 1 AND (publish_up = '1970-01-01 00:00:00' OR publish_up < '{$date}')
                   AND (publish_down = '1970-01-01 00:00:00' OR publish_down > '{$date}'))
                   OR id = " . Request::$REQUEST->getInt('slideid') . ") ";
    }

    protected function createSlide($slideRow) {
        return new AdminSlide($this->slider, $slideRow);
    }

    protected function makeSlides($slidesData, $extendGenerator = array()) {

        $slides = &$this->slides;

        $editedSlideID = $this->slider->getEditedSlideID();

        $this->legacyFixOnlyStaticOverlays($slides);

        $staticSlides = array();
        for ($j = count($slides) - 1; $j >= 0; $j--) {
            $slide = $slides[$j];
            if ($slide->isStatic()) {
                if ($slide->id == $editedSlideID) {
                    $this->editedSlide = $slide;
                }
                $staticSlides[] = $slide;
                $this->slider->addStaticSlide($slide);
                array_splice($slides, $j, 1);
            }
        }

        for ($i = 0; $i < count($slides); $i++) {
            $slides[$i]->initGenerator($extendGenerator);
        }

        for ($i = count($slides) - 1; $i >= 0; $i--) {
            if ($slides[$i]->hasGenerator()) {
                array_splice($slides, $i, 1, $slides[$i]->expandSlideAdmin());
            }
        }

        if (!$this->editedSlide) {
            for ($i = 0; $i < count($slides); $i++) {
                if ($slides[$i]->id == $editedSlideID) {
                    $this->editedSlide = $slides[$i];
                    $this->slider->setActiveSlide($this->editedSlide);
                    break;
                }
            }
        }

        // If we edit a static slide -> remove other static slides from the canvas.
        if ($this->editedSlide->isStatic()) {
            for ($i = 0; $i < count($this->slider->staticSlides); $i++) {
                if ($this->slider->staticSlides[$i]->id != $editedSlideID) {
                    array_splice($this->slider->staticSlides, $i, 1);
                    $i--;
                }
            }

            if (empty($slides)) {
                /**
                 * When the currently edited slide is static and there is not other slide, we create a temporary empty slide
                 */
                $slidesModel = new ModelSlides($this->slider);

                $slides[] = $this->createSlide($slidesModel->convertSlideDataToDatabaseRow(array(
                    'id'              => 0,
                    'title'           => 'Slide #' . 1,
                    'layers'          => '[]',
                    'description'     => '',
                    'thumbnail'       => '',
                    'published'       => 1,
                    'publish_up'      => '0000-00-00 00:00:00',
                    'publish_down'    => '0000-00-00 00:00:00',
                    'backgroundImage' => ''
                )));
            }

            $this->slider->setActiveSlide($slides[0]);
        } else {

            if ($this->maximumSlideCount > 0) {
                array_splice($slides, $this->maximumSlideCount);

                if (!in_array($this->editedSlide, $slides)) {
                    $slides[] = $this->editedSlide;
                }
            }
        }


        $this->editedSlide->setCurrentlyEdited();

        for ($i = 0; $i < count($slides); $i++) {
            $slides[$i]->setPublicID($i + 1);
        }
    }

    /**
     * @return Slide
     */
    public function getEditedSlide() {
        return $this->editedSlide;
    }
}