Your IP : 216.73.216.248


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

AdministratorApplication.php000064400000031406152344706220012272 0ustar00<?php
/**
 * Joomla! Content Management System
 *
 * @copyright  (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace Joomla\CMS\Application;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Input\Input;
use Joomla\Registry\Registry;

/**
 * Joomla! Administrator Application class
 *
 * @since  3.2
 */
class AdministratorApplication extends CMSApplication
{
	/**
	 * Class constructor.
	 *
	 * @param   Input                   $input   An optional argument to provide dependency injection for the application's
	 *                                           input object.  If the argument is a \JInput object that object will become
	 *                                           the application's input object, otherwise a default input object is created.
	 * @param   Registry                $config  An optional argument to provide dependency injection for the application's
	 *                                           config object.  If the argument is a Registry object that object will become
	 *                                           the application's config object, otherwise a default config object is created.
	 * @param   \JApplicationWebClient  $client  An optional argument to provide dependency injection for the application's
	 *                                           client object.  If the argument is a \JApplicationWebClient object that object will become
	 *                                           the application's client object, otherwise a default client object is created.
	 *
	 * @since   3.2
	 */
	public function __construct(Input $input = null, Registry $config = null, \JApplicationWebClient $client = null)
	{
		// Register the application name
		$this->_name = 'administrator';

		// Register the client ID
		$this->_clientId = 1;

		// Execute the parent constructor
		parent::__construct($input, $config, $client);

		// Set the root in the URI based on the application name
		\JUri::root(null, rtrim(dirname(\JUri::base(true)), '/\\'));
	}

	/**
	 * Dispatch the application
	 *
	 * @param   string  $component  The component which is being rendered.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	public function dispatch($component = null)
	{
		if ($component === null)
		{
			$component = \JAdministratorHelper::findOption();
		}

		// Load the document to the API
		$this->loadDocument();

		// Set up the params
		$document = \JFactory::getDocument();

		// Register the document object with \JFactory
		\JFactory::$document = $document;

		switch ($document->getType())
		{
			case 'html':
				$document->setMetaData('keywords', $this->get('MetaKeys'));

				// Get the template
				$template = $this->getTemplate(true);

				// Store the template and its params to the config
				$this->set('theme', $template->template);
				$this->set('themeParams', $template->params);

				break;

			default:
				break;
		}

		$document->setTitle($this->get('sitename') . ' - ' . \JText::_('JADMINISTRATION'));
		$document->setDescription($this->get('MetaDesc'));
		$document->setGenerator('Joomla! - Open Source Content Management');

		$contents = ComponentHelper::renderComponent($component);
		$document->setBuffer($contents, 'component');

		// Trigger the onAfterDispatch event.
		\JPluginHelper::importPlugin('system');
		$this->triggerEvent('onAfterDispatch');
	}

	/**
	 * Method to run the Web application routines.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	protected function doExecute()
	{
		// Get the language from the (login) form or user state
		$login_lang = ($this->input->get('option') == 'com_login') ? $this->input->get('lang') : '';
		$options    = array('language' => $login_lang ?: $this->getUserState('application.lang'));

		// Initialise the application
		$this->initialiseApp($options);

		// Test for magic quotes
		if (PHP_VERSION_ID < 50400 && get_magic_quotes_gpc())
		{
			$lang = $this->getLanguage();

			if ($lang->hasKey('JERROR_MAGIC_QUOTES'))
			{
				$this->enqueueMessage(\JText::_('JERROR_MAGIC_QUOTES'), 'error');
			}
			else
			{
				$this->enqueueMessage('Your host needs to disable magic_quotes_gpc to run this version of Joomla!', 'error');
			}
		}

		// Mark afterInitialise in the profiler.
		JDEBUG ? $this->profiler->mark('afterInitialise') : null;

		// Route the application
		$this->route();

		// Mark afterRoute in the profiler.
		JDEBUG ? $this->profiler->mark('afterRoute') : null;

		/*
		 * Check if the user is required to reset their password
		 *
		 * Before $this->route(); "option" and "view" can't be safely read using:
		 * $this->input->getCmd('option'); or $this->input->getCmd('view');
		 * ex: due of the sef urls
		 */
		$this->checkUserRequireReset('com_admin', 'profile', 'edit', 'com_admin/profile.save,com_admin/profile.apply,com_login/logout');

		// Dispatch the application
		$this->dispatch();

		// Mark afterDispatch in the profiler.
		JDEBUG ? $this->profiler->mark('afterDispatch') : null;
	}

	/**
	 * Return a reference to the \JRouter object.
	 *
	 * @param   string  $name     The name of the application.
	 * @param   array   $options  An optional associative array of configuration settings.
	 *
	 * @return  \JRouter
	 *
	 * @since	3.2
	 */
	public static function getRouter($name = 'administrator', array $options = array())
	{
		return parent::getRouter($name, $options);
	}

	/**
	 * Gets the name of the current template.
	 *
	 * @param   boolean  $params  True to return the template parameters
	 *
	 * @return  string  The name of the template.
	 *
	 * @since   3.2
	 * @throws  \InvalidArgumentException
	 */
	public function getTemplate($params = false)
	{
		if (is_object($this->template))
		{
			if ($params)
			{
				return $this->template;
			}

			return $this->template->template;
		}

		$admin_style = \JFactory::getUser()->getParam('admin_style');

		// Load the template name from the database
		$db = \JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('template, s.params')
			->from('#__template_styles as s')
			->join('LEFT', '#__extensions as e ON e.type=' . $db->quote('template') . ' AND e.element=s.template AND e.client_id=s.client_id');

		if ($admin_style)
		{
			$query->where('s.client_id = 1 AND id = ' . (int) $admin_style . ' AND e.enabled = 1', 'OR');
		}

		$query->where('s.client_id = 1 AND home = ' . $db->quote('1'), 'OR')
			->order('home');
		$db->setQuery($query);
		$template = $db->loadObject();

		$template->template = \JFilterInput::getInstance()->clean($template->template, 'cmd');
		$template->params = new Registry($template->params);

		if (!file_exists(JPATH_THEMES . '/' . $template->template . '/index.php'))
		{
			$this->enqueueMessage(\JText::_('JERROR_ALERTNOTEMPLATE'), 'error');
			$template->params = new Registry;
			$template->template = 'isis';
		}

		// Cache the result
		$this->template = $template;

		if (!file_exists(JPATH_THEMES . '/' . $template->template . '/index.php'))
		{
			throw new \InvalidArgumentException(\JText::sprintf('JERROR_COULD_NOT_FIND_TEMPLATE', $template->template));
		}

		if ($params)
		{
			return $template;
		}

		return $template->template;
	}

	/**
	 * Initialise the application.
	 *
	 * @param   array  $options  An optional associative array of configuration settings.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	protected function initialiseApp($options = array())
	{
		$user = \JFactory::getUser();

		// If the user is a guest we populate it with the guest user group.
		if ($user->guest)
		{
			$guestUsergroup = ComponentHelper::getParams('com_users')->get('guest_usergroup', 1);
			$user->groups = array($guestUsergroup);
		}

		// If a language was specified it has priority, otherwise use user or default language settings
		if (empty($options['language']))
		{
			$lang = $user->getParam('admin_language');

			// Make sure that the user's language exists
			if ($lang && \JLanguageHelper::exists($lang))
			{
				$options['language'] = $lang;
			}
			else
			{
				$params = ComponentHelper::getParams('com_languages');
				$options['language'] = $params->get('administrator', $this->get('language', 'en-GB'));
			}
		}

		// One last check to make sure we have something
		if (!\JLanguageHelper::exists($options['language']))
		{
			$lang = $this->get('language', 'en-GB');

			if (\JLanguageHelper::exists($lang))
			{
				$options['language'] = $lang;
			}
			else
			{
				// As a last ditch fail to english
				$options['language'] = 'en-GB';
			}
		}

		// Finish initialisation
		parent::initialiseApp($options);
	}

	/**
	 * Login authentication function
	 *
	 * @param   array  $credentials  Array('username' => string, 'password' => string)
	 * @param   array  $options      Array('remember' => boolean)
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   3.2
	 */
	public function login($credentials, $options = array())
	{
		// The minimum group
		$options['group'] = 'Public Backend';

		// Make sure users are not auto-registered
		$options['autoregister'] = false;

		// Set the application login entry point
		if (!array_key_exists('entry_url', $options))
		{
			$options['entry_url'] = \JUri::base() . 'index.php?option=com_users&task=login';
		}

		// Set the access control action to check.
		$options['action'] = 'core.login.admin';

		$result = parent::login($credentials, $options);

		if (!($result instanceof \Exception))
		{
			$lang = $this->input->getCmd('lang');
			$lang = preg_replace('/[^A-Z-]/i', '', $lang);

			if ($lang)
			{
				$this->setUserState('application.lang', $lang);
			}

			static::purgeMessages();
		}

		return $result;
	}

	/**
	 * Purge the jos_messages table of old messages
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	public static function purgeMessages()
	{
		$user = \JFactory::getUser();
		$userid = $user->get('id');

		$db = \JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('*')
			->from($db->quoteName('#__messages_cfg'))
			->where($db->quoteName('user_id') . ' = ' . (int) $userid, 'AND')
			->where($db->quoteName('cfg_name') . ' = ' . $db->quote('auto_purge'), 'AND');
		$db->setQuery($query);
		$config = $db->loadObject();

		// Check if auto_purge value set
		if (is_object($config) && $config->cfg_name === 'auto_purge')
		{
			$purge = $config->cfg_value;
		}
		else
		{
			// If no value set, default is 7 days
			$purge = 7;
		}

		// If purge value is not 0, then allow purging of old messages
		if ($purge > 0)
		{
			// Purge old messages at day set in message configuration
			$past = \JFactory::getDate(time() - $purge * 86400);
			$pastStamp = $past->toSql();

			$query->clear()
				->delete($db->quoteName('#__messages'))
				->where($db->quoteName('date_time') . ' < ' . $db->quote($pastStamp), 'AND')
				->where($db->quoteName('user_id_to') . ' = ' . (int) $userid, 'AND');
			$db->setQuery($query);
			$db->execute();
		}
	}

	/**
	 * Rendering is the process of pushing the document buffers into the template
	 * placeholders, retrieving data from the document and pushing it into
	 * the application response buffer.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	protected function render()
	{
		// Get the \JInput object
		$input = $this->input;

		$component = $input->getCmd('option', 'com_login');
		$file      = $input->getCmd('tmpl', 'index');

		if ($component === 'com_login')
		{
			$file = 'login';
		}

		$this->set('themeFile', $file . '.php');

		// Safety check for when configuration.php root_user is in use.
		$rootUser = $this->get('root_user');

		if (property_exists('\JConfig', 'root_user'))
		{
			if (\JFactory::getUser()->get('username') === $rootUser || \JFactory::getUser()->id === (string) $rootUser)
			{
				$this->enqueueMessage(
					\JText::sprintf(
						'JWARNING_REMOVE_ROOT_USER',
						'index.php?option=com_config&task=config.removeroot&' . \JSession::getFormToken() . '=1'
					),
					'error'
				);
			}
			// Show this message to superusers too
			elseif (\JFactory::getUser()->authorise('core.admin'))
			{
				$this->enqueueMessage(
					\JText::sprintf(
						'JWARNING_REMOVE_ROOT_USER_ADMIN',
						$rootUser,
						'index.php?option=com_config&task=config.removeroot&' . \JSession::getFormToken() . '=1'
					),
					'error'
				);
			}
		}

		parent::render();
	}

	/**
	 * Route the application.
	 *
	 * Routing is the process of examining the request environment to determine which
	 * component should receive the request. The component optional parameters
	 * are then set in the request object to be processed when the application is being
	 * dispatched.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	protected function route()
	{
		$uri = \JUri::getInstance();

		if ($this->get('force_ssl') >= 1 && strtolower($uri->getScheme()) !== 'https')
		{
			// Forward to https
			$uri->setScheme('https');
			$this->redirect((string) $uri, 301);
		}

		// Trigger the onAfterRoute event.
		\JPluginHelper::importPlugin('system');
		$this->triggerEvent('onAfterRoute');
	}
}
ApplicationHelper.php000064400000014206152344706220010670 0ustar00<?php
/**
 * Joomla! Content Management System
 *
 * @copyright  (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace Joomla\CMS\Application;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Component\ComponentHelper;

/**
 * Application helper functions
 *
 * @since  1.5
 */
class ApplicationHelper
{
	/**
	 * Client information array
	 *
	 * @var    array
	 * @since  1.6
	 */
	protected static $_clients = array();

	/**
	 * Return the name of the request component [main component]
	 *
	 * @param   string  $default  The default option
	 *
	 * @return  string  Option (e.g. com_something)
	 *
	 * @since   1.6
	 */
	public static function getComponentName($default = null)
	{
		static $option;

		if ($option)
		{
			return $option;
		}

		$input = \JFactory::getApplication()->input;
		$option = strtolower($input->get('option'));

		if (empty($option))
		{
			$option = $default;
		}

		$input->set('option', $option);

		return $option;
	}

	/**
	 * Provides a secure hash based on a seed
	 *
	 * @param   string  $seed  Seed string.
	 *
	 * @return  string  A secure hash
	 *
	 * @since   3.2
	 */
	public static function getHash($seed)
	{
		return md5(\JFactory::getConfig()->get('secret') . $seed);
	}

	/**
	 * This method transliterates a string into a URL
	 * safe string or returns a URL safe UTF-8 string
	 * based on the global configuration
	 *
	 * @param   string  $string    String to process
	 * @param   string  $language  Language to transliterate to if unicode slugs are disabled
	 *
	 * @return  string  Processed string
	 *
	 * @since   3.2
	 */
	public static function stringURLSafe($string, $language = '')
	{
		if (\JFactory::getConfig()->get('unicodeslugs') == 1)
		{
			$output = \JFilterOutput::stringURLUnicodeSlug($string);
		}
		else
		{
			if ($language === '*' || $language === '')
			{
				$languageParams = ComponentHelper::getParams('com_languages');
				$language = $languageParams->get('site');
			}

			$output = \JFilterOutput::stringURLSafe($string, $language);
		}

		return $output;
	}

	/**
	 * Gets information on a specific client id.  This method will be useful in
	 * future versions when we start mapping applications in the database.
	 *
	 * This method will return a client information array if called
	 * with no arguments which can be used to add custom application information.
	 *
	 * @param   integer  $id      A client identifier
	 * @param   boolean  $byName  If True, find the client by its name
	 *
	 * @return  mixed  Object describing the client or false if not known
	 *
	 * @since   1.5
	 */
	public static function getClientInfo($id = null, $byName = false)
	{
		// Only create the array if it is empty
		if (empty(self::$_clients))
		{
			$obj = new \stdClass;

			// Site Client
			$obj->id = 0;
			$obj->name = 'site';
			$obj->path = JPATH_SITE;
			self::$_clients[0] = clone $obj;

			// Administrator Client
			$obj->id = 1;
			$obj->name = 'administrator';
			$obj->path = JPATH_ADMINISTRATOR;
			self::$_clients[1] = clone $obj;

			// Installation Client
			$obj->id = 2;
			$obj->name = 'installation';
			$obj->path = JPATH_INSTALLATION;
			self::$_clients[2] = clone $obj;
		}

		// If no client id has been passed return the whole array
		if ($id === null)
		{
			return self::$_clients;
		}

		// Are we looking for client information by id or by name?
		if (!$byName)
		{
			if (isset(self::$_clients[$id]))
			{
				return self::$_clients[$id];
			}
		}
		else
		{
			foreach (self::$_clients as $client)
			{
				if ($client->name == strtolower($id))
				{
					return $client;
				}
			}
		}

		return;
	}

	/**
	 * Adds information for a client.
	 *
	 * @param   mixed  $client  A client identifier either an array or object
	 *
	 * @return  boolean  True if the information is added. False on error
	 *
	 * @since   1.6
	 */
	public static function addClientInfo($client)
	{
		if (is_array($client))
		{
			$client = (object) $client;
		}

		if (!is_object($client))
		{
			return false;
		}

		$info = self::getClientInfo();

		if (!isset($client->id))
		{
			$client->id = count($info);
		}

		self::$_clients[$client->id] = clone $client;

		return true;
	}

	/**
	 * Parse a XML install manifest file.
	 *
	 * XML Root tag should be 'install' except for languages which use meta file.
	 *
	 * @param   string  $path  Full path to XML file.
	 *
	 * @return  array  XML metadata.
	 *
	 * @since       1.5
	 * @deprecated  4.0 Use \JInstaller::parseXMLInstallFile instead.
	 */
	public static function parseXMLInstallFile($path)
	{
		\JLog::add('ApplicationHelper::parseXMLInstallFile is deprecated. Use \JInstaller::parseXMLInstallFile instead.', \JLog::WARNING, 'deprecated');

		return \JInstaller::parseXMLInstallFile($path);
	}

	/**
	 * Parse a XML language meta file.
	 *
	 * XML Root tag  for languages which is meta file.
	 *
	 * @param   string  $path  Full path to XML file.
	 *
	 * @return  array  XML metadata.
	 *
	 * @since       1.5
	 * @deprecated  4.0 Use \JInstaller::parseXMLInstallFile instead.
	 */
	public static function parseXMLLangMetaFile($path)
	{
		\JLog::add('ApplicationHelper::parseXMLLangMetaFile is deprecated. Use \JInstaller::parseXMLInstallFile instead.', \JLog::WARNING, 'deprecated');

		// Check if meta file exists.
		if (!file_exists($path))
		{
			return false;
		}

		// Read the file to see if it's a valid component XML file
		$xml = simplexml_load_file($path);

		if (!$xml)
		{
			return false;
		}

		/*
		 * Check for a valid XML root tag.
		 *
		 * Should be 'metafile'.
		 */
		if ($xml->getName() !== 'metafile')
		{
			unset($xml);

			return false;
		}

		$data = array();

		$data['name'] = (string) $xml->name;
		$data['type'] = $xml->attributes()->type;

		$data['creationDate'] = ((string) $xml->creationDate) ?: \JText::_('JLIB_UNKNOWN');
		$data['author'] = ((string) $xml->author) ?: \JText::_('JLIB_UNKNOWN');

		$data['copyright'] = (string) $xml->copyright;
		$data['authorEmail'] = (string) $xml->authorEmail;
		$data['authorUrl'] = (string) $xml->authorUrl;
		$data['version'] = (string) $xml->version;
		$data['description'] = (string) $xml->description;
		$data['group'] = (string) $xml->group;

		return $data;
	}
}
BaseApplication.php000064400000011166152344706220010325 0ustar00<?php
/**
 * Joomla! Content Management System
 *
 * @copyright  (C) 2012 Open Source Matters, Inc. <https://www.joomla.org>
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace Joomla\CMS\Application;

defined('JPATH_PLATFORM') or die;

use Joomla\Application\AbstractApplication;
use Joomla\CMS\Input\Input;
use Joomla\Registry\Registry;

/**
 * Joomla Platform Base Application Class
 *
 * @property-read  \JInput  $input  The application input object
 *
 * @since  3.0.0
 */
abstract class BaseApplication extends AbstractApplication
{
	/**
	 * The application dispatcher object.
	 *
	 * @var    \JEventDispatcher
	 * @since  3.0.0
	 */
	protected $dispatcher;

	/**
	 * The application identity object.
	 *
	 * @var    \JUser
	 * @since  3.0.0
	 */
	protected $identity;

	/**
	 * Class constructor.
	 *
	 * @param   Input     $input   An optional argument to provide dependency injection for the application's
	 *                             input object.  If the argument is a \JInput object that object will become
	 *                             the application's input object, otherwise a default input object is created.
	 * @param   Registry  $config  An optional argument to provide dependency injection for the application's
	 *                             config object.  If the argument is a Registry object that object will become
	 *                             the application's config object, otherwise a default config object is created.
	 *
	 * @since   3.0.0
	 */
	public function __construct(Input $input = null, Registry $config = null)
	{
		$this->input = $input instanceof Input ? $input : new Input;
		$this->config = $config instanceof Registry ? $config : new Registry;

		$this->initialise();
	}

	/**
	 * Get the application identity.
	 *
	 * @return  mixed  A \JUser object or null.
	 *
	 * @since   3.0.0
	 */
	public function getIdentity()
	{
		return $this->identity;
	}

	/**
	 * Registers a handler to a particular event group.
	 *
	 * @param   string    $event    The event name.
	 * @param   callable  $handler  The handler, a function or an instance of an event object.
	 *
	 * @return  BaseApplication  The application to allow chaining.
	 *
	 * @since   3.0.0
	 */
	public function registerEvent($event, $handler)
	{
		if ($this->dispatcher instanceof \JEventDispatcher)
		{
			$this->dispatcher->register($event, $handler);
		}

		return $this;
	}

	/**
	 * Calls all handlers associated with an event group.
	 *
	 * @param   string  $event  The event name.
	 * @param   array   $args   An array of arguments (optional).
	 *
	 * @return  array   An array of results from each function call, or null if no dispatcher is defined.
	 *
	 * @since   3.0.0
	 */
	public function triggerEvent($event, array $args = null)
	{
		if ($this->dispatcher instanceof \JEventDispatcher)
		{
			return $this->dispatcher->trigger($event, $args);
		}

		return;
	}

	/**
	 * Allows the application to load a custom or default dispatcher.
	 *
	 * The logic and options for creating this object are adequately generic for default cases
	 * but for many applications it will make sense to override this method and create event
	 * dispatchers, if required, based on more specific needs.
	 *
	 * @param   \JEventDispatcher  $dispatcher  An optional dispatcher object. If omitted, the factory dispatcher is created.
	 *
	 * @return  BaseApplication This method is chainable.
	 *
	 * @since   3.0.0
	 */
	public function loadDispatcher(\JEventDispatcher $dispatcher = null)
	{
		$this->dispatcher = ($dispatcher === null) ? \JEventDispatcher::getInstance() : $dispatcher;

		return $this;
	}

	/**
	 * Allows the application to load a custom or default identity.
	 *
	 * The logic and options for creating this object are adequately generic for default cases
	 * but for many applications it will make sense to override this method and create an identity,
	 * if required, based on more specific needs.
	 *
	 * @param   \JUser  $identity  An optional identity object. If omitted, the factory user is created.
	 *
	 * @return  BaseApplication This method is chainable.
	 *
	 * @since   3.0.0
	 */
	public function loadIdentity(\JUser $identity = null)
	{
		$this->identity = ($identity === null) ? \JFactory::getUser() : $identity;

		return $this;
	}

	/**
	 * Method to run the application routines.  Most likely you will want to instantiate a controller
	 * and execute it, or perform some sort of task directly.
	 *
	 * @return  void
	 *
	 * @since   3.4 (CMS)
	 * @deprecated  4.0  The default concrete implementation of doExecute() will be removed, subclasses will need to provide their own implementation.
	 */
	protected function doExecute()
	{
		return;
	}
}
CMSApplication.php000064400000100361152344706220010071 0ustar00<?php
/**
 * Joomla! Content Management System
 *
 * @copyright  (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace Joomla\CMS\Application;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Filter\InputFilter;
use Joomla\CMS\Input\Input;
use Joomla\CMS\Session\MetadataManager;
use Joomla\Registry\Registry;
use Joomla\String\StringHelper;

/**
 * Joomla! CMS Application class
 *
 * @since  3.2
 */
class CMSApplication extends WebApplication
{
	/**
	 * Array of options for the \JDocument object
	 *
	 * @var    array
	 * @since  3.2
	 */
	protected $docOptions = array();

	/**
	 * Application instances container.
	 *
	 * @var    CMSApplication[]
	 * @since  3.2
	 */
	protected static $instances = array();

	/**
	 * The scope of the application.
	 *
	 * @var    string
	 * @since  3.2
	 */
	public $scope = null;

	/**
	 * The client identifier.
	 *
	 * @var    integer
	 * @since  3.2
	 * @deprecated  4.0  Will be renamed $clientId
	 */
	protected $_clientId = null;

	/**
	 * The application message queue.
	 *
	 * @var    array
	 * @since  3.2
	 * @deprecated  4.0  Will be renamed $messageQueue
	 */
	protected $_messageQueue = array();

	/**
	 * The name of the application.
	 *
	 * @var    array
	 * @since  3.2
	 * @deprecated  4.0  Will be renamed $name
	 */
	protected $_name = null;

	/**
	 * The profiler instance
	 *
	 * @var    \JProfiler
	 * @since  3.2
	 */
	protected $profiler = null;

	/**
	 * Currently active template
	 *
	 * @var    object
	 * @since  3.2
	 */
	protected $template = null;

	/**
	 * Class constructor.
	 *
	 * @param   Input                   $input   An optional argument to provide dependency injection for the application's
	 *                                           input object.  If the argument is a \JInput object that object will become
	 *                                           the application's input object, otherwise a default input object is created.
	 * @param   Registry                $config  An optional argument to provide dependency injection for the application's
	 *                                           config object.  If the argument is a Registry object that object will become
	 *                                           the application's config object, otherwise a default config object is created.
	 * @param   \JApplicationWebClient  $client  An optional argument to provide dependency injection for the application's
	 *                                           client object.  If the argument is a \JApplicationWebClient object that object will become
	 *                                           the application's client object, otherwise a default client object is created.
	 *
	 * @since   3.2
	 */
	public function __construct(Input $input = null, Registry $config = null, \JApplicationWebClient $client = null)
	{
		parent::__construct($input, $config, $client);

		// Load and set the dispatcher
		$this->loadDispatcher();

		// If JDEBUG is defined, load the profiler instance
		if (defined('JDEBUG') && JDEBUG)
		{
			$this->profiler = \JProfiler::getInstance('Application');
		}

		// Enable sessions by default.
		if ($this->config->get('session') === null)
		{
			$this->config->set('session', true);
		}

		// Set the session default name.
		if ($this->config->get('session_name') === null)
		{
			$this->config->set('session_name', $this->getName());
		}

		// Create the session if a session name is passed.
		if ($this->config->get('session') !== false)
		{
			$this->loadSession();
		}
	}

	/**
	 * Checks the user session.
	 *
	 * If the session record doesn't exist, initialise it.
	 * If session is new, create session variables
	 *
	 * @return  void
	 *
	 * @since   3.2
	 * @throws  \RuntimeException
	 */
	public function checkSession()
	{
		$metadataManager = new MetadataManager($this, \JFactory::getDbo());
		$metadataManager->createRecordIfNonExisting(\JFactory::getSession(), \JFactory::getUser());
	}

	/**
	 * Enqueue a system message.
	 *
	 * @param   string  $msg   The message to enqueue.
	 * @param   string  $type  The message type. Default is message.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	public function enqueueMessage($msg, $type = 'message')
	{
		// Don't add empty messages.
		if (trim($msg) === '')
		{
			return;
		}

		$inputFilter = InputFilter::getInstance(array(), array(), 1, 1);

		// Build the message array and apply the HTML InputFilter with the default blacklist to the message
		$message = array(
			'message' => $inputFilter->clean($msg, 'html'),
			'type'    => $inputFilter->clean(strtolower($type), 'cmd')
		);

		// For empty queue, if messages exists in the session, enqueue them first.
		$messages = $this->getMessageQueue();

		if (!in_array($message, $this->_messageQueue))
		{
			// Enqueue the message.
			$this->_messageQueue[] = $message;
		}
	}

	/**
	 * Execute the application.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	public function execute()
	{
		$input = $this->input;

		// Get invalid input variables
		$invalidInputVariables = array_filter(
			array('option', 'view', 'format', 'lang', 'Itemid', 'template', 'templateStyle', 'task'),
			function($systemVariable) use ($input) {
				return $input->exists($systemVariable) && is_array($input->getRaw($systemVariable));
			}
		);

		// Unset invalid system variables
		foreach ($invalidInputVariables as $systemVariable)
		{
			$input->set($systemVariable, null);
		}

		// Abort when there are invalid variables
		if ($invalidInputVariables)
		{
			throw new \RuntimeException('Invalid input, aborting application.');
		}

		// Perform application routines.
		$this->doExecute();

		// If we have an application document object, render it.
		if ($this->document instanceof \JDocument)
		{
			// Render the application output.
			$this->render();
		}

		// If gzip compression is enabled in configuration and the server is compliant, compress the output.
		if ($this->get('gzip') && !ini_get('zlib.output_compression') && ini_get('output_handler') !== 'ob_gzhandler')
		{
			$this->compress();

			// Trigger the onAfterCompress event.
			$this->triggerEvent('onAfterCompress');
		}

		// Send the application response.
		$this->respond();

		// Trigger the onAfterRespond event.
		$this->triggerEvent('onAfterRespond');
	}

	/**
	 * Check if the user is required to reset their password.
	 *
	 * If the user is required to reset their password will be redirected to the page that manage the password reset.
	 *
	 * @param   string  $option  The option that manage the password reset
	 * @param   string  $view    The view that manage the password reset
	 * @param   string  $layout  The layout of the view that manage the password reset
	 * @param   string  $tasks   Permitted tasks
	 *
	 * @return  void
	 */
	protected function checkUserRequireReset($option, $view, $layout, $tasks)
	{
		if (\JFactory::getUser()->get('requireReset', 0))
		{
			$redirect = false;

			/*
			 * By default user profile edit page is used.
			 * That page allows you to change more than just the password and might not be the desired behavior.
			 * This allows a developer to override the page that manage the password reset.
			 * (can be configured using the file: configuration.php, or if extended, through the global configuration form)
			 */
			$name = $this->getName();

			if ($this->get($name . '_reset_password_override', 0))
			{
				$option = $this->get($name . '_reset_password_option', '');
				$view = $this->get($name . '_reset_password_view', '');
				$layout = $this->get($name . '_reset_password_layout', '');
				$tasks = $this->get($name . '_reset_password_tasks', '');
			}

			$task = $this->input->getCmd('task', '');

			// Check task or option/view/layout
			if (!empty($task))
			{
				$tasks = explode(',', $tasks);

				// Check full task version "option/task"
				if (array_search($this->input->getCmd('option', '') . '/' . $task, $tasks) === false)
				{
					// Check short task version, must be on the same option of the view
					if ($this->input->getCmd('option', '') !== $option || array_search($task, $tasks) === false)
					{
						// Not permitted task
						$redirect = true;
					}
				}
			}
			else
			{
				if ($this->input->getCmd('option', '') !== $option || $this->input->getCmd('view', '') !== $view
					|| $this->input->getCmd('layout', '') !== $layout)
				{
					// Requested a different option/view/layout
					$redirect = true;
				}
			}

			if ($redirect)
			{
				// Redirect to the profile edit page
				$this->enqueueMessage(\JText::_('JGLOBAL_PASSWORD_RESET_REQUIRED'), 'notice');
				$this->redirect(\JRoute::_('index.php?option=' . $option . '&view=' . $view . '&layout=' . $layout, false));
			}
		}
	}

	/**
	 * Gets a configuration value.
	 *
	 * @param   string  $varname  The name of the value to get.
	 * @param   string  $default  Default value to return
	 *
	 * @return  mixed  The user state.
	 *
	 * @since   3.2
	 * @deprecated  5.0  Use get() instead
	 */
	public function getCfg($varname, $default = null)
	{
		try
		{
			\JLog::add(
				sprintf('%s() is deprecated and will be removed in 5.0. Use JFactory->getApplication()->get() instead.', __METHOD__),
				\JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		return $this->get($varname, $default);
	}

	/**
	 * Gets the client id of the current running application.
	 *
	 * @return  integer  A client identifier.
	 *
	 * @since   3.2
	 */
	public function getClientId()
	{
		return $this->_clientId;
	}

	/**
	 * Returns a reference to the global CMSApplication object, only creating it if it doesn't already exist.
	 *
	 * This method must be invoked as: $web = CMSApplication::getInstance();
	 *
	 * @param   string  $name  The name (optional) of the CMSApplication class to instantiate.
	 *
	 * @return  CMSApplication
	 *
	 * @since   3.2
	 * @throws  \RuntimeException
	 */
	public static function getInstance($name = null)
	{
		if (empty(static::$instances[$name]))
		{
			// Create a CMSApplication object.
			$classname = '\JApplication' . ucfirst($name);

			if (!class_exists($classname))
			{
				throw new \RuntimeException(\JText::sprintf('JLIB_APPLICATION_ERROR_APPLICATION_LOAD', $name), 500);
			}

			static::$instances[$name] = new $classname;
		}

		return static::$instances[$name];
	}

	/**
	 * Returns the application \JMenu object.
	 *
	 * @param   string  $name     The name of the application/client.
	 * @param   array   $options  An optional associative array of configuration settings.
	 *
	 * @return  \JMenu|null
	 *
	 * @since   3.2
	 */
	public function getMenu($name = null, $options = array())
	{
		if (!isset($name))
		{
			$name = $this->getName();
		}

		// Inject this application object into the \JMenu tree if one isn't already specified
		if (!isset($options['app']))
		{
			$options['app'] = $this;
		}

		try
		{
			$menu = \JMenu::getInstance($name, $options);
		}
		catch (\Exception $e)
		{
			return;
		}

		return $menu;
	}

	/**
	 * Get the system message queue.
	 *
	 * @param   boolean  $clear  Clear the messages currently attached to the application object
	 *
	 * @return  array  The system message queue.
	 *
	 * @since   3.2
	 */
	public function getMessageQueue($clear = false)
	{
		// For empty queue, if messages exists in the session, enqueue them.
		if (!$this->_messageQueue)
		{
			$session = \JFactory::getSession();
			$sessionQueue = $session->get('application.queue', array());

			if ($sessionQueue)
			{
				$this->_messageQueue = $sessionQueue;
				$session->set('application.queue', array());
			}
		}

		$messageQueue = $this->_messageQueue;

		if ($clear)
		{
			$this->_messageQueue = array();
		}

		return $messageQueue;
	}

	/**
	 * Gets the name of the current running application.
	 *
	 * @return  string  The name of the application.
	 *
	 * @since   3.2
	 */
	public function getName()
	{
		return $this->_name;
	}

	/**
	 * Returns the application \JPathway object.
	 *
	 * @param   string  $name     The name of the application.
	 * @param   array   $options  An optional associative array of configuration settings.
	 *
	 * @return  \JPathway|null
	 *
	 * @since   3.2
	 */
	public function getPathway($name = null, $options = array())
	{
		if (!isset($name))
		{
			$name = $this->getName();
		}
		else
		{
			// Name should not be used
			$this->getLogger()->warning(
				'Name attribute is deprecated, in the future fetch the pathway '
				. 'through the respective application.',
				array('category' => 'deprecated')
			);
		}

		try
		{
			$pathway = \JPathway::getInstance($name, $options);
		}
		catch (\Exception $e)
		{
			return;
		}

		return $pathway;
	}

	/**
	 * Returns the application \JRouter object.
	 *
	 * @param   string  $name     The name of the application.
	 * @param   array   $options  An optional associative array of configuration settings.
	 *
	 * @return  \JRouter|null
	 *
	 * @since   3.2
	 */
	public static function getRouter($name = null, array $options = array())
	{
		if (!isset($name))
		{
			$app = \JFactory::getApplication();
			$name = $app->getName();
		}

		$options['mode'] = \JFactory::getConfig()->get('sef');

		try
		{
			$router = \JRouter::getInstance($name, $options);
		}
		catch (\Exception $e)
		{
			return;
		}

		return $router;
	}

	/**
	 * Gets the name of the current template.
	 *
	 * @param   boolean  $params  An optional associative array of configuration settings
	 *
	 * @return  mixed  System is the fallback.
	 *
	 * @since   3.2
	 */
	public function getTemplate($params = false)
	{
		$template = new \stdClass;

		$template->template = 'system';
		$template->params   = new Registry;

		if ($params)
		{
			return $template;
		}

		return $template->template;
	}

	/**
	 * Gets a user state.
	 *
	 * @param   string  $key      The path of the state.
	 * @param   mixed   $default  Optional default value, returned if the internal value is null.
	 *
	 * @return  mixed  The user state or null.
	 *
	 * @since   3.2
	 */
	public function getUserState($key, $default = null)
	{
		$session = \JFactory::getSession();
		$registry = $session->get('registry');

		if ($registry !== null)
		{
			return $registry->get($key, $default);
		}

		return $default;
	}

	/**
	 * Gets the value of a user state variable.
	 *
	 * @param   string  $key      The key of the user state variable.
	 * @param   string  $request  The name of the variable passed in a request.
	 * @param   string  $default  The default value for the variable if not found. Optional.
	 * @param   string  $type     Filter for the variable, for valid values see {@link \JFilterInput::clean()}. Optional.
	 *
	 * @return  mixed  The request user state.
	 *
	 * @since   3.2
	 */
	public function getUserStateFromRequest($key, $request, $default = null, $type = 'none')
	{
		$cur_state = $this->getUserState($key, $default);
		$new_state = $this->input->get($request, null, $type);

		if ($new_state === null)
		{
			return $cur_state;
		}

		// Save the new value only if it was set in this request.
		$this->setUserState($key, $new_state);

		return $new_state;
	}

	/**
	 * Initialise the application.
	 *
	 * @param   array  $options  An optional associative array of configuration settings.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	protected function initialiseApp($options = array())
	{
		// Set the configuration in the API.
		$this->config = \JFactory::getConfig();

		// Check that we were given a language in the array (since by default may be blank).
		if (isset($options['language']))
		{
			$this->set('language', $options['language']);
		}

		// Build our language object
		$lang = \JLanguage::getInstance($this->get('language'), $this->get('debug_lang'));

		// Load the language to the API
		$this->loadLanguage($lang);

		// Register the language object with \JFactory
		\JFactory::$language = $this->getLanguage();

		// Load the library language files
		$this->loadLibraryLanguage();

		// Set user specific editor.
		$user = \JFactory::getUser();
		$editor = $user->getParam('editor', $this->get('editor'));

		if (!\JPluginHelper::isEnabled('editors', $editor))
		{
			$editor = $this->get('editor');

			if (!\JPluginHelper::isEnabled('editors', $editor))
			{
				$editor = 'none';
			}
		}

		$this->set('editor', $editor);

		// Trigger the onAfterInitialise event.
		\JPluginHelper::importPlugin('system');
		$this->triggerEvent('onAfterInitialise');
	}

	/**
	 * Is admin interface?
	 *
	 * @return  boolean  True if this application is administrator.
	 *
	 * @since       3.2
	 * @deprecated  4.0 Use isClient('administrator') instead.
	 */
	public function isAdmin()
	{
		try
		{
			\JLog::add(
				sprintf("%s() is deprecated and will be removed in 4.0. Use JFactory->getApplication()->isClient('administrator') instead.", __METHOD__),
				\JLog::WARNING,
				'deprecated'
			);
		}
		catch (\RuntimeException $exception)
		{
			// Informational log only
		}

		return $this->isClient('administrator');
	}

	/**
	 * Is site interface?
	 *
	 * @return  boolean  True if this application is site.
	 *
	 * @since       3.2
	 * @deprecated  4.0 Use isClient('site') instead.
	 */
	public function isSite()
	{
		try
		{
			\JLog::add(
				sprintf("%s() is deprecated and will be removed in 4.0. Use JFactory->getApplication()->isClient('site') instead.", __METHOD__),
				\JLog::WARNING,
				'deprecated'
			);
		}
		catch (\RuntimeException $exception)
		{
			// Informational log only
		}

		return $this->isClient('site');
	}

	/**
	 * Checks if HTTPS is forced in the client configuration.
	 *
	 * @param   integer  $clientId  An optional client id (defaults to current application client).
	 *
	 * @return  boolean  True if is forced for the client, false otherwise.
	 *
	 * @since   3.7.3
	 */
	public function isHttpsForced($clientId = null)
	{
		$clientId = (int) ($clientId !== null ? $clientId : $this->getClientId());
		$forceSsl = (int) $this->get('force_ssl');

		if ($clientId === 0 && $forceSsl === 2)
		{
			return true;
		}

		if ($clientId === 1 && $forceSsl >= 1)
		{
			return true;
		}

		return false;
	}

	/**
	 * Check the client interface by name.
	 *
	 * @param   string  $identifier  String identifier for the application interface
	 *
	 * @return  boolean  True if this application is of the given type client interface.
	 *
	 * @since   3.7.0
	 */
	public function isClient($identifier)
	{
		return $this->getName() === $identifier;
	}

	/**
	 * Load the library language files for the application
	 *
	 * @return  void
	 *
	 * @since   3.6.3
	 */
	protected function loadLibraryLanguage()
	{
		$this->getLanguage()->load('lib_joomla', JPATH_ADMINISTRATOR);
	}

	/**
	 * Allows the application to load a custom or default session.
	 *
	 * The logic and options for creating this object are adequately generic for default cases
	 * but for many applications it will make sense to override this method and create a session,
	 * if required, based on more specific needs.
	 *
	 * @param   \JSession  $session  An optional session object. If omitted, the session is created.
	 *
	 * @return  CMSApplication  This method is chainable.
	 *
	 * @since   3.2
	 */
	public function loadSession(\JSession $session = null)
	{
		if ($session !== null)
		{
			$this->session = $session;

			return $this;
		}

		$this->registerEvent('onAfterSessionStart', array($this, 'afterSessionStart'));

		/*
		 * Note: The below code CANNOT change from instantiating a session via \JFactory until there is a proper dependency injection container supported
		 * by the application. The current default behaviours result in this method being called each time an application class is instantiated.
		 * https://github.com/joomla/joomla-cms/issues/12108 explains why things will crash and burn if you ever attempt to make this change
		 * without a proper dependency injection container.
		 */

		$session = \JFactory::getSession(
			array(
				'name'      => \JApplicationHelper::getHash($this->get('session_name', get_class($this))),
				'expire'    => $this->get('lifetime') ? $this->get('lifetime') * 60 : 900,
				'force_ssl' => $this->isHttpsForced(),
			)
		);

		$session->initialise($this->input, $this->dispatcher);

		// Get the session handler from the configuration.
		$handler = $this->get('session_handler', 'none');

		/*
		 * Check for extra session metadata when:
		 *
		 * 1) The database handler is in use and the session is new
		 * 2) The database handler is not in use and the time is an even numbered second or the session is new
		 */
		if (($handler !== 'database' && (time() % 2 || $session->isNew())) || ($handler === 'database' && $session->isNew()))
		{
			$this->checkSession();
		}

		// Set the session object.
		$this->session = $session;

		return $this;
	}

	/**
	 * Login authentication function.
	 *
	 * Username and encoded password are passed the onUserLogin event which
	 * is responsible for the user validation. A successful validation updates
	 * the current session record with the user's details.
	 *
	 * Username and encoded password are sent as credentials (along with other
	 * possibilities) to each observer (authentication plugin) for user
	 * validation.  Successful validation will update the current session with
	 * the user details.
	 *
	 * @param   array  $credentials  Array('username' => string, 'password' => string)
	 * @param   array  $options      Array('remember' => boolean)
	 *
	 * @return  boolean|\JException  True on success, false if failed or silent handling is configured, or a \JException object on authentication error.
	 *
	 * @since   3.2
	 */
	public function login($credentials, $options = array())
	{
		// Get the global \JAuthentication object.
		$authenticate = \JAuthentication::getInstance();
		$response = $authenticate->authenticate($credentials, $options);

		// Import the user plugin group.
		\JPluginHelper::importPlugin('user');

		if ($response->status === \JAuthentication::STATUS_SUCCESS)
		{
			/*
			 * Validate that the user should be able to login (different to being authenticated).
			 * This permits authentication plugins blocking the user.
			 */
			$authorisations = $authenticate->authorise($response, $options);
			$denied_states = \JAuthentication::STATUS_EXPIRED | \JAuthentication::STATUS_DENIED;

			foreach ($authorisations as $authorisation)
			{
				if ((int) $authorisation->status & $denied_states)
				{
					// Trigger onUserAuthorisationFailure Event.
					$this->triggerEvent('onUserAuthorisationFailure', array((array) $authorisation));

					// If silent is set, just return false.
					if (isset($options['silent']) && $options['silent'])
					{
						return false;
					}

					// Return the error.
					switch ($authorisation->status)
					{
						case \JAuthentication::STATUS_EXPIRED:
							return \JError::raiseWarning('102002', \JText::_('JLIB_LOGIN_EXPIRED'));

						case \JAuthentication::STATUS_DENIED:
							return \JError::raiseWarning('102003', \JText::_('JLIB_LOGIN_DENIED'));

						default:
							return \JError::raiseWarning('102004', \JText::_('JLIB_LOGIN_AUTHORISATION'));
					}
				}
			}

			// OK, the credentials are authenticated and user is authorised.  Let's fire the onLogin event.
			$results = $this->triggerEvent('onUserLogin', array((array) $response, $options));

			/*
			 * If any of the user plugins did not successfully complete the login routine
			 * then the whole method fails.
			 *
			 * Any errors raised should be done in the plugin as this provides the ability
			 * to provide much more information about why the routine may have failed.
			 */
			$user = \JFactory::getUser();

			if ($response->type === 'Cookie')
			{
				$user->set('cookieLogin', true);
			}

			if (in_array(false, $results, true) == false)
			{
				$options['user'] = $user;
				$options['responseType'] = $response->type;

				// The user is successfully logged in. Run the after login events
				$this->triggerEvent('onUserAfterLogin', array($options));

				return true;
			}
		}

		// Trigger onUserLoginFailure Event.
		$this->triggerEvent('onUserLoginFailure', array((array) $response));

		// If silent is set, just return false.
		if (isset($options['silent']) && $options['silent'])
		{
			return false;
		}

		// If status is success, any error will have been raised by the user plugin
		if ($response->status !== \JAuthentication::STATUS_SUCCESS)
		{
			$this->getLogger()->warning($response->error_message, array('category' => 'jerror'));
		}

		return false;
	}

	/**
	 * Logout authentication function.
	 *
	 * Passed the current user information to the onUserLogout event and reverts the current
	 * session record back to 'anonymous' parameters.
	 * If any of the authentication plugins did not successfully complete
	 * the logout routine then the whole method fails. Any errors raised
	 * should be done in the plugin as this provides the ability to give
	 * much more information about why the routine may have failed.
	 *
	 * @param   integer  $userid   The user to load - Can be an integer or string - If string, it is converted to ID automatically
	 * @param   array    $options  Array('clientid' => array of client id's)
	 *
	 * @return  boolean  True on success
	 *
	 * @since   3.2
	 */
	public function logout($userid = null, $options = array())
	{
		// Get a user object from the \JApplication.
		$user = \JFactory::getUser($userid);

		// Build the credentials array.
		$parameters['username'] = $user->get('username');
		$parameters['id'] = $user->get('id');

		// Set clientid in the options array if it hasn't been set already and shared sessions are not enabled.
		if (!$this->get('shared_session', '0') && !isset($options['clientid']))
		{
			$options['clientid'] = $this->getClientId();
		}

		// Import the user plugin group.
		\JPluginHelper::importPlugin('user');

		// OK, the credentials are built. Lets fire the onLogout event.
		$results = $this->triggerEvent('onUserLogout', array($parameters, $options));

		// Check if any of the plugins failed. If none did, success.
		if (!in_array(false, $results, true))
		{
			$options['username'] = $user->get('username');
			$this->triggerEvent('onUserAfterLogout', array($options));

			return true;
		}

		// Trigger onUserLoginFailure Event.
		$this->triggerEvent('onUserLogoutFailure', array($parameters));

		return false;
	}

	/**
	 * Redirect to another URL.
	 *
	 * If the headers have not been sent the redirect will be accomplished using a "301 Moved Permanently"
	 * or "303 See Other" code in the header pointing to the new location. If the headers have already been
	 * sent this will be accomplished using a JavaScript statement.
	 *
	 * @param   string   $url     The URL to redirect to. Can only be http/https URL
	 * @param   integer  $status  The HTTP 1.1 status code to be provided. 303 is assumed by default.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	public function redirect($url, $status = 303)
	{
		// Handle B/C by checking if a message was passed to the method, will be removed at 4.0
		if (func_num_args() > 1)
		{
			$args = func_get_args();

			/*
			 * Do some checks on the $args array, values below correspond to legacy redirect() method
			 *
			 * $args[0] = $url
			 * $args[1] = Message to enqueue
			 * $args[2] = Message type
			 * $args[3] = $status (previously moved)
			 */
			if (isset($args[1]) && !empty($args[1]) && (!is_bool($args[1]) && !is_int($args[1])))
			{
				$this->getLogger()->warning(
					'Passing a message and message type to ' . __METHOD__ . '() is deprecated. '
					. 'Please set your message via ' . __CLASS__ . '::enqueueMessage() prior to calling ' . __CLASS__
					. '::redirect().',
					array('category' => 'deprecated')
				);

				$message = $args[1];

				// Set the message type if present
				if (isset($args[2]) && !empty($args[2]))
				{
					$type = $args[2];
				}
				else
				{
					$type = 'message';
				}

				// Enqueue the message
				$this->enqueueMessage($message, $type);

				// Reset the $moved variable
				$status = isset($args[3]) ? (boolean) $args[3] : false;
			}
		}

		// Persist messages if they exist.
		if ($this->_messageQueue)
		{
			$session = \JFactory::getSession();
			$session->set('application.queue', $this->_messageQueue);
		}

		// Hand over processing to the parent now
		parent::redirect($url, $status);
	}

	/**
	 * Rendering is the process of pushing the document buffers into the template
	 * placeholders, retrieving data from the document and pushing it into
	 * the application response buffer.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	protected function render()
	{
		// Setup the document options.
		$this->docOptions['template'] = $this->get('theme');
		$this->docOptions['file']     = $this->get('themeFile', 'index.php');
		$this->docOptions['params']   = $this->get('themeParams');

		if ($this->get('themes.base'))
		{
			$this->docOptions['directory'] = $this->get('themes.base');
		}
		// Fall back to constants.
		else
		{
			$this->docOptions['directory'] = defined('JPATH_THEMES') ? JPATH_THEMES : (defined('JPATH_BASE') ? JPATH_BASE : __DIR__) . '/themes';
		}

		// Parse the document.
		$this->document->parse($this->docOptions);

		// Trigger the onBeforeRender event.
		\JPluginHelper::importPlugin('system');
		$this->triggerEvent('onBeforeRender');

		$caching = false;

		if ($this->isClient('site') && $this->get('caching') && $this->get('caching', 2) == 2 && !\JFactory::getUser()->get('id'))
		{
			$caching = true;
		}

		// Render the document.
		$data = $this->document->render($caching, $this->docOptions);

		// Set the application output data.
		$this->setBody($data);

		// Trigger the onAfterRender event.
		$this->triggerEvent('onAfterRender');

		// Mark afterRender in the profiler.
		JDEBUG ? $this->profiler->mark('afterRender') : null;
	}

	/**
	 * Route the application.
	 *
	 * Routing is the process of examining the request environment to determine which
	 * component should receive the request. The component optional parameters
	 * are then set in the request object to be processed when the application is being
	 * dispatched.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	protected function route()
	{
		// Get the full request URI.
		$uri = clone \JUri::getInstance();

		$router = static::getRouter();
		$result = $router->parse($uri);

		$active = $this->getMenu()->getActive();

		if ($active !== null
			&& $active->type === 'alias'
			&& $active->params->get('alias_redirect')
			&& in_array($this->input->getMethod(), array('GET', 'HEAD'), true))
		{
			$item = $this->getMenu()->getItem($active->params->get('aliasoptions'));

			if ($item !== null)
			{
				$oldUri = clone \JUri::getInstance();

				if ($oldUri->getVar('Itemid') == $active->id)
				{
					$oldUri->setVar('Itemid', $item->id);
				}

				$base = \JUri::base(true);
				$oldPath = StringHelper::strtolower(substr($oldUri->getPath(), strlen($base) + 1));
				$activePathPrefix = StringHelper::strtolower($active->route);

				$position = strpos($oldPath, $activePathPrefix);

				if ($position !== false)
				{
					$oldUri->setPath($base . '/' . substr_replace($oldPath, $item->route, $position, strlen($activePathPrefix)));

					$this->setHeader('Expires', 'Wed, 17 Aug 2005 00:00:00 GMT', true);
					$this->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT', true);
					$this->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0', false);
					$this->setHeader('Pragma', 'no-cache');
					$this->sendHeaders();

					$this->redirect((string) $oldUri, 301);
				}
			}
		}

		foreach ($result as $key => $value)
		{
			$this->input->def($key, $value);
		}

		// Trigger the onAfterRoute event.
		\JPluginHelper::importPlugin('system');
		$this->triggerEvent('onAfterRoute');
	}

	/**
	 * Sets the value of a user state variable.
	 *
	 * @param   string  $key    The path of the state.
	 * @param   mixed   $value  The value of the variable.
	 *
	 * @return  mixed  The previous state, if one existed.
	 *
	 * @since   3.2
	 */
	public function setUserState($key, $value)
	{
		$session = \JFactory::getSession();
		$registry = $session->get('registry');

		if ($registry !== null)
		{
			return $registry->set($key, $value);
		}

		return;
	}

	/**
	 * Sends all headers prior to returning the string
	 *
	 * @param   boolean  $compress  If true, compress the data
	 *
	 * @return  string
	 *
	 * @since   3.2
	 */
	public function toString($compress = false)
	{
		// Don't compress something if the server is going to do it anyway. Waste of time.
		if ($compress && !ini_get('zlib.output_compression') && ini_get('output_handler') !== 'ob_gzhandler')
		{
			$this->compress();
		}

		if ($this->allowCache() === false)
		{
			$this->setHeader('Cache-Control', 'no-cache', false);

			// HTTP 1.0
			$this->setHeader('Pragma', 'no-cache');
		}

		$this->sendHeaders();

		return $this->getBody();
	}
}
CliApplication.php000064400000016444152344706220010166 0ustar00<?php
/**
 * Joomla! Content Management System
 *
 * @copyright  (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace Joomla\CMS\Application;

defined('JPATH_PLATFORM') or die;

use Joomla\Application\Cli\CliOutput;
use Joomla\CMS\Input\Cli;
use Joomla\CMS\Input\Input;
use Joomla\Registry\Registry;

/**
 * Base class for a Joomla! command line application.
 *
 * @since  2.5.0
 * @note   As of 4.0 this class will be abstract
 */
class CliApplication extends BaseApplication
{
	/**
	 * @var    CliOutput  The output type.
	 * @since  3.3
	 */
	protected $output;

	/**
	 * @var    CliApplication  The application instance.
	 * @since  1.7.0
	 */
	protected static $instance;

	/**
	 * Class constructor.
	 *
	 * @param   Cli                $input       An optional argument to provide dependency injection for the application's
	 *                                          input object.  If the argument is a \JInputCli object that object will become
	 *                                          the application's input object, otherwise a default input object is created.
	 * @param   Registry           $config      An optional argument to provide dependency injection for the application's
	 *                                          config object.  If the argument is a Registry object that object will become
	 *                                          the application's config object, otherwise a default config object is created.
	 * @param   \JEventDispatcher  $dispatcher  An optional argument to provide dependency injection for the application's
	 *                                          event dispatcher.  If the argument is a \JEventDispatcher object that object will become
	 *                                          the application's event dispatcher, if it is null then the default event dispatcher
	 *                                          will be created based on the application's loadDispatcher() method.
	 *
	 * @see     BaseApplication::loadDispatcher()
	 * @since   1.7.0
	 */
	public function __construct(Cli $input = null, Registry $config = null, \JEventDispatcher $dispatcher = null)
	{
		// Close the application if we are not executed from the command line.
		if (!defined('STDOUT') || !defined('STDIN') || !isset($_SERVER['argv']))
		{
			$this->close();
		}

		// If an input object is given use it.
		if ($input instanceof Input)
		{
			$this->input = $input;
		}
		// Create the input based on the application logic.
		else
		{
			if (class_exists('\\Joomla\\CMS\\Input\\Cli'))
			{
				$this->input = new Cli;
			}
		}

		// If a config object is given use it.
		if ($config instanceof Registry)
		{
			$this->config = $config;
		}
		// Instantiate a new configuration object.
		else
		{
			$this->config = new Registry;
		}

		$this->loadDispatcher($dispatcher);

		// Load the configuration object.
		$this->loadConfiguration($this->fetchConfigurationData());

		// Set the execution datetime and timestamp;
		$this->set('execution.datetime', gmdate('Y-m-d H:i:s'));
		$this->set('execution.timestamp', time());

		// Set the current directory.
		$this->set('cwd', getcwd());
	}

	/**
	 * Returns a reference to the global CliApplication object, only creating it if it doesn't already exist.
	 *
	 * This method must be invoked as: $cli = CliApplication::getInstance();
	 *
	 * @param   string  $name  The name (optional) of the JApplicationCli class to instantiate.
	 *
	 * @return  CliApplication
	 *
	 * @since   1.7.0
	 */
	public static function getInstance($name = null)
	{
		// Only create the object if it doesn't exist.
		if (empty(self::$instance))
		{
			if (class_exists($name) && (is_subclass_of($name, '\\Joomla\\CMS\\Application\\CliApplication')))
			{
				self::$instance = new $name;
			}
			else
			{
				self::$instance = new CliApplication;
			}
		}

		return self::$instance;
	}

	/**
	 * Execute the application.
	 *
	 * @return  void
	 *
	 * @since   1.7.0
	 */
	public function execute()
	{
		// Trigger the onBeforeExecute event.
		$this->triggerEvent('onBeforeExecute');

		// Perform application routines.
		$this->doExecute();

		// Trigger the onAfterExecute event.
		$this->triggerEvent('onAfterExecute');
	}

	/**
	 * Load an object or array into the application configuration object.
	 *
	 * @param   mixed  $data  Either an array or object to be loaded into the configuration object.
	 *
	 * @return  CliApplication  Instance of $this to allow chaining.
	 *
	 * @since   1.7.0
	 */
	public function loadConfiguration($data)
	{
		// Load the data into the configuration object.
		if (is_array($data))
		{
			$this->config->loadArray($data);
		}
		elseif (is_object($data))
		{
			$this->config->loadObject($data);
		}

		return $this;
	}

	/**
	 * Write a string to standard output.
	 *
	 * @param   string   $text  The text to display.
	 * @param   boolean  $nl    True (default) to append a new line at the end of the output string.
	 *
	 * @return  CliApplication  Instance of $this to allow chaining.
	 *
	 * @codeCoverageIgnore
	 * @since   1.7.0
	 */
	public function out($text = '', $nl = true)
	{
		$output = $this->getOutput();
		$output->out($text, $nl);

		return $this;
	}

	/**
	 * Get an output object.
	 *
	 * @return  CliOutput
	 *
	 * @since   3.3
	 */
	public function getOutput()
	{
		if (!$this->output)
		{
			// In 4.0, this will convert to throwing an exception and you will expected to
			// initialize this in the constructor. Until then set a default.
			$default = new \Joomla\Application\Cli\Output\Xml;
			$this->setOutput($default);
		}

		return $this->output;
	}

	/**
	 * Set an output object.
	 *
	 * @param   CliOutput  $output  CliOutput object
	 *
	 * @return  CliApplication  Instance of $this to allow chaining.
	 *
	 * @since   3.3
	 */
	public function setOutput(CliOutput $output)
	{
		$this->output = $output;

		return $this;
	}

	/**
	 * Get a value from standard input.
	 *
	 * @return  string  The input string from standard input.
	 *
	 * @codeCoverageIgnore
	 * @since   1.7.0
	 */
	public function in()
	{
		return rtrim(fread(STDIN, 8192), "\n");
	}

	/**
	 * Method to load a PHP configuration class file based on convention and return the instantiated data object.  You
	 * will extend this method in child classes to provide configuration data from whatever data source is relevant
	 * for your specific application.
	 *
	 * @param   string  $file   The path and filename of the configuration file. If not provided, configuration.php
	 *                          in JPATH_CONFIGURATION will be used.
	 * @param   string  $class  The class name to instantiate.
	 *
	 * @return  mixed   Either an array or object to be loaded into the configuration object.
	 *
	 * @since   1.7.0
	 */
	protected function fetchConfigurationData($file = '', $class = '\JConfig')
	{
		// Instantiate variables.
		$config = array();

		if (empty($file))
		{
			$file = JPATH_CONFIGURATION . '/configuration.php';

			// Applications can choose not to have any configuration data by not implementing this method and not having a config file.
			if (!file_exists($file))
			{
				$file = '';
			}
		}

		if (!empty($file))
		{
			\JLoader::register($class, $file);

			if (class_exists($class))
			{
				$config = new $class;
			}
			else
			{
				throw new \RuntimeException('Configuration class does not exist.');
			}
		}

		return $config;
	}
}
DaemonApplication.php000064400000061013152344706220010652 0ustar00<?php
/**
 * Joomla! Content Management System
 *
 * @copyright  (C) 2012 Open Source Matters, Inc. <https://www.joomla.org>
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace Joomla\CMS\Application;

defined('JPATH_PLATFORM') or die;

jimport('joomla.filesystem.folder');

use Joomla\Registry\Registry;

/**
 * Class to turn CliApplication applications into daemons.  It requires CLI and PCNTL support built into PHP.
 *
 * @link   https://www.php.net/manual/en/book.pcntl.php
 * @link   https://www.php.net/manual/en/features.commandline.php
 * @since  1.7.0
 */
class DaemonApplication extends CliApplication
{
	/**
	 * @var    array  The available POSIX signals to be caught by default.
	 * @link   https://www.php.net/manual/pcntl.constants.php
	 * @since  1.7.0
	 */
	protected static $signals = array(
		'SIGHUP',
		'SIGINT',
		'SIGQUIT',
		'SIGILL',
		'SIGTRAP',
		'SIGABRT',
		'SIGIOT',
		'SIGBUS',
		'SIGFPE',
		'SIGUSR1',
		'SIGSEGV',
		'SIGUSR2',
		'SIGPIPE',
		'SIGALRM',
		'SIGTERM',
		'SIGSTKFLT',
		'SIGCLD',
		'SIGCHLD',
		'SIGCONT',
		'SIGTSTP',
		'SIGTTIN',
		'SIGTTOU',
		'SIGURG',
		'SIGXCPU',
		'SIGXFSZ',
		'SIGVTALRM',
		'SIGPROF',
		'SIGWINCH',
		'SIGPOLL',
		'SIGIO',
		'SIGPWR',
		'SIGSYS',
		'SIGBABY',
		'SIG_BLOCK',
		'SIG_UNBLOCK',
		'SIG_SETMASK',
	);

	/**
	 * @var    boolean  True if the daemon is in the process of exiting.
	 * @since  1.7.0
	 */
	protected $exiting = false;

	/**
	 * @var    integer  The parent process id.
	 * @since  3.0.0
	 */
	protected $parentId = 0;

	/**
	 * @var    integer  The process id of the daemon.
	 * @since  1.7.0
	 */
	protected $processId = 0;

	/**
	 * @var    boolean  True if the daemon is currently running.
	 * @since  1.7.0
	 */
	protected $running = false;

	/**
	 * Class constructor.
	 *
	 * @param   \JInputCli         $input       An optional argument to provide dependency injection for the application's
	 *                                         input object.  If the argument is a \JInputCli object that object will become
	 *                                         the application's input object, otherwise a default input object is created.
	 * @param   Registry           $config      An optional argument to provide dependency injection for the application's
	 *                                         config object.  If the argument is a Registry object that object will become
	 *                                         the application's config object, otherwise a default config object is created.
	 * @param   \JEventDispatcher  $dispatcher  An optional argument to provide dependency injection for the application's
	 *                                         event dispatcher.  If the argument is a \JEventDispatcher object that object will become
	 *                                         the application's event dispatcher, if it is null then the default event dispatcher
	 *                                         will be created based on the application's loadDispatcher() method.
	 *
	 * @since   1.7.0
	 * @throws  \RuntimeException
	 */
	public function __construct(\JInputCli $input = null, Registry $config = null, \JEventDispatcher $dispatcher = null)
	{
		// Verify that the process control extension for PHP is available.
		if (!defined('SIGHUP'))
		{
			\JLog::add('The PCNTL extension for PHP is not available.', \JLog::ERROR);
			throw new \RuntimeException('The PCNTL extension for PHP is not available.');
		}

		// Verify that POSIX support for PHP is available.
		if (!function_exists('posix_getpid'))
		{
			\JLog::add('The POSIX extension for PHP is not available.', \JLog::ERROR);
			throw new \RuntimeException('The POSIX extension for PHP is not available.');
		}

		// Call the parent constructor.
		parent::__construct($input, $config, $dispatcher);

		// Set some system limits.
		@set_time_limit($this->config->get('max_execution_time', 0));

		if ($this->config->get('max_memory_limit') !== null)
		{
			ini_set('memory_limit', $this->config->get('max_memory_limit', '256M'));
		}

		// Flush content immediately.
		ob_implicit_flush();
	}

	/**
	 * Method to handle POSIX signals.
	 *
	 * @param   integer  $signal  The received POSIX signal.
	 *
	 * @return  void
	 *
	 * @since   1.7.0
	 * @see     pcntl_signal()
	 * @throws  \RuntimeException
	 */
	public static function signal($signal)
	{
		// Log all signals sent to the daemon.
		\JLog::add('Received signal: ' . $signal, \JLog::DEBUG);

		// Let's make sure we have an application instance.
		if (!is_subclass_of(static::$instance, 'CliApplication'))
		{
			\JLog::add('Cannot find the application instance.', \JLog::EMERGENCY);
			throw new \RuntimeException('Cannot find the application instance.');
		}

		// Fire the onReceiveSignal event.
		static::$instance->triggerEvent('onReceiveSignal', array($signal));

		switch ($signal)
		{
			case SIGINT:
			case SIGTERM:
				// Handle shutdown tasks
				if (static::$instance->running && static::$instance->isActive())
				{
					static::$instance->shutdown();
				}
				else
				{
					static::$instance->close();
				}
				break;
			case SIGHUP:
				// Handle restart tasks
				if (static::$instance->running && static::$instance->isActive())
				{
					static::$instance->shutdown(true);
				}
				else
				{
					static::$instance->close();
				}
				break;
			case SIGCHLD:
				// A child process has died
				while (static::$instance->pcntlWait($signal, WNOHANG || WUNTRACED) > 0)
				{
					usleep(1000);
				}
				break;
			case SIGCLD:
				while (static::$instance->pcntlWait($signal, WNOHANG) > 0)
				{
					$signal = static::$instance->pcntlChildExitStatus($signal);
				}
				break;
			default:
				break;
		}
	}

	/**
	 * Check to see if the daemon is active.  This does not assume that $this daemon is active, but
	 * only if an instance of the application is active as a daemon.
	 *
	 * @return  boolean  True if daemon is active.
	 *
	 * @since   1.7.0
	 */
	public function isActive()
	{
		// Get the process id file location for the application.
		$pidFile = $this->config->get('application_pid_file');

		// If the process id file doesn't exist then the daemon is obviously not running.
		if (!is_file($pidFile))
		{
			return false;
		}

		// Read the contents of the process id file as an integer.
		$fp = fopen($pidFile, 'r');
		$pid = fread($fp, filesize($pidFile));
		$pid = (int) $pid;
		fclose($fp);

		// Check to make sure that the process id exists as a positive integer.
		if (!$pid)
		{
			return false;
		}

		// Check to make sure the process is active by pinging it and ensure it responds.
		if (!posix_kill($pid, 0))
		{
			// No response so remove the process id file and log the situation.
			@ unlink($pidFile);
			\JLog::add('The process found based on PID file was unresponsive.', \JLog::WARNING);

			return false;
		}

		return true;
	}

	/**
	 * Load an object or array into the application configuration object.
	 *
	 * @param   mixed  $data  Either an array or object to be loaded into the configuration object.
	 *
	 * @return  DaemonApplication  Instance of $this to allow chaining.
	 *
	 * @since   1.7.0
	 */
	public function loadConfiguration($data)
	{
		// Execute the parent load method.
		parent::loadConfiguration($data);

		/*
		 * Setup some application metadata options.  This is useful if we ever want to write out startup scripts
		 * or just have some sort of information available to share about things.
		 */

		// The application author name.  This string is used in generating startup scripts and has
		// a maximum of 50 characters.
		$tmp = (string) $this->config->get('author_name', 'Joomla Platform');
		$this->config->set('author_name', (strlen($tmp) > 50) ? substr($tmp, 0, 50) : $tmp);

		// The application author email.  This string is used in generating startup scripts.
		$tmp = (string) $this->config->get('author_email', 'admin@joomla.org');
		$this->config->set('author_email', filter_var($tmp, FILTER_VALIDATE_EMAIL));

		// The application name.  This string is used in generating startup scripts.
		$tmp = (string) $this->config->get('application_name', 'DaemonApplication');
		$this->config->set('application_name', (string) preg_replace('/[^A-Z0-9_-]/i', '', $tmp));

		// The application description.  This string is used in generating startup scripts.
		$tmp = (string) $this->config->get('application_description', 'A generic Joomla Platform application.');
		$this->config->set('application_description', filter_var($tmp, FILTER_SANITIZE_STRING));

		/*
		 * Setup the application path options.  This defines the default executable name, executable directory,
		 * and also the path to the daemon process id file.
		 */

		// The application executable daemon.  This string is used in generating startup scripts.
		$tmp = (string) $this->config->get('application_executable', basename($this->input->executable));
		$this->config->set('application_executable', $tmp);

		// The home directory of the daemon.
		$tmp = (string) $this->config->get('application_directory', dirname($this->input->executable));
		$this->config->set('application_directory', $tmp);

		// The pid file location.  This defaults to a path inside the /tmp directory.
		$name = $this->config->get('application_name');
		$tmp = (string) $this->config->get('application_pid_file', strtolower('/tmp/' . $name . '/' . $name . '.pid'));
		$this->config->set('application_pid_file', $tmp);

		/*
		 * Setup the application identity options.  It is important to remember if the default of 0 is set for
		 * either UID or GID then changing that setting will not be attempted as there is no real way to "change"
		 * the identity of a process from some user to root.
		 */

		// The user id under which to run the daemon.
		$tmp = (int) $this->config->get('application_uid', 0);
		$options = array('options' => array('min_range' => 0, 'max_range' => 65000));
		$this->config->set('application_uid', filter_var($tmp, FILTER_VALIDATE_INT, $options));

		// The group id under which to run the daemon.
		$tmp = (int) $this->config->get('application_gid', 0);
		$options = array('options' => array('min_range' => 0, 'max_range' => 65000));
		$this->config->set('application_gid', filter_var($tmp, FILTER_VALIDATE_INT, $options));

		// Option to kill the daemon if it cannot switch to the chosen identity.
		$tmp = (bool) $this->config->get('application_require_identity', 1);
		$this->config->set('application_require_identity', $tmp);

		/*
		 * Setup the application runtime options.  By default our execution time limit is infinite obviously
		 * because a daemon should be constantly running unless told otherwise.  The default limit for memory
		 * usage is 256M, which admittedly is a little high, but remember it is a "limit" and PHP's memory
		 * management leaves a bit to be desired :-)
		 */

		// The maximum execution time of the application in seconds.  Zero is infinite.
		$tmp = $this->config->get('max_execution_time');

		if ($tmp !== null)
		{
			$this->config->set('max_execution_time', (int) $tmp);
		}

		// The maximum amount of memory the application can use.
		$tmp = $this->config->get('max_memory_limit', '256M');

		if ($tmp !== null)
		{
			$this->config->set('max_memory_limit', (string) $tmp);
		}

		return $this;
	}

	/**
	 * Execute the daemon.
	 *
	 * @return  void
	 *
	 * @since   1.7.0
	 */
	public function execute()
	{
		// Trigger the onBeforeExecute event.
		$this->triggerEvent('onBeforeExecute');

		// Enable basic garbage collection.
		gc_enable();

		\JLog::add('Starting ' . $this->name, \JLog::INFO);

		// Set off the process for becoming a daemon.
		if ($this->daemonize())
		{
			// Declare ticks to start signal monitoring. When you declare ticks, PCNTL will monitor
			// incoming signals after each tick and call the relevant signal handler automatically.
			declare (ticks = 1);

			// Start the main execution loop.
			while (true)
			{
				// Perform basic garbage collection.
				$this->gc();

				// Don't completely overload the CPU.
				usleep(1000);

				// Execute the main application logic.
				$this->doExecute();
			}
		}
		// We were not able to daemonize the application so log the failure and die gracefully.
		else
		{
			\JLog::add('Starting ' . $this->name . ' failed', \JLog::INFO);
		}

		// Trigger the onAfterExecute event.
		$this->triggerEvent('onAfterExecute');
	}

	/**
	 * Restart daemon process.
	 *
	 * @return  void
	 *
	 * @since   1.7.0
	 */
	public function restart()
	{
		\JLog::add('Stopping ' . $this->name, \JLog::INFO);
		$this->shutdown(true);
	}

	/**
	 * Stop daemon process.
	 *
	 * @return  void
	 *
	 * @since   1.7.0
	 */
	public function stop()
	{
		\JLog::add('Stopping ' . $this->name, \JLog::INFO);
		$this->shutdown();
	}

	/**
	 * Method to change the identity of the daemon process and resources.
	 *
	 * @return  boolean  True if identity successfully changed
	 *
	 * @since   1.7.0
	 * @see     posix_setuid()
	 */
	protected function changeIdentity()
	{
		// Get the group and user ids to set for the daemon.
		$uid = (int) $this->config->get('application_uid', 0);
		$gid = (int) $this->config->get('application_gid', 0);

		// Get the application process id file path.
		$file = $this->config->get('application_pid_file');

		// Change the user id for the process id file if necessary.
		if ($uid && (fileowner($file) != $uid) && (!@ chown($file, $uid)))
		{
			\JLog::add('Unable to change user ownership of the process id file.', \JLog::ERROR);

			return false;
		}

		// Change the group id for the process id file if necessary.
		if ($gid && (filegroup($file) != $gid) && (!@ chgrp($file, $gid)))
		{
			\JLog::add('Unable to change group ownership of the process id file.', \JLog::ERROR);

			return false;
		}

		// Set the correct home directory for the process.
		if ($uid && ($info = posix_getpwuid($uid)) && is_dir($info['dir']))
		{
			system('export HOME="' . $info['dir'] . '"');
		}

		// Change the user id for the process necessary.
		if ($uid && (posix_getuid($file) != $uid) && (!@ posix_setuid($uid)))
		{
			\JLog::add('Unable to change user ownership of the proccess.', \JLog::ERROR);

			return false;
		}

		// Change the group id for the process necessary.
		if ($gid && (posix_getgid($file) != $gid) && (!@ posix_setgid($gid)))
		{
			\JLog::add('Unable to change group ownership of the proccess.', \JLog::ERROR);

			return false;
		}

		// Get the user and group information based on uid and gid.
		$user = posix_getpwuid($uid);
		$group = posix_getgrgid($gid);

		\JLog::add('Changed daemon identity to ' . $user['name'] . ':' . $group['name'], \JLog::INFO);

		return true;
	}

	/**
	 * Method to put the application into the background.
	 *
	 * @return  boolean
	 *
	 * @since   1.7.0
	 * @throws  \RuntimeException
	 */
	protected function daemonize()
	{
		// Is there already an active daemon running?
		if ($this->isActive())
		{
			\JLog::add($this->name . ' daemon is still running. Exiting the application.', \JLog::EMERGENCY);

			return false;
		}

		// Reset Process Information
		$this->safeMode = !!@ ini_get('safe_mode');
		$this->processId = 0;
		$this->running = false;

		// Detach process!
		try
		{
			// Check if we should run in the foreground.
			if (!$this->input->get('f'))
			{
				// Detach from the terminal.
				$this->detach();
			}
			else
			{
				// Setup running values.
				$this->exiting = false;
				$this->running = true;

				// Set the process id.
				$this->processId = (int) posix_getpid();
				$this->parentId = $this->processId;
			}
		}
		catch (\RuntimeException $e)
		{
			\JLog::add('Unable to fork.', \JLog::EMERGENCY);

			return false;
		}

		// Verify the process id is valid.
		if ($this->processId < 1)
		{
			\JLog::add('The process id is invalid; the fork failed.', \JLog::EMERGENCY);

			return false;
		}

		// Clear the umask.
		@ umask(0);

		// Write out the process id file for concurrency management.
		if (!$this->writeProcessIdFile())
		{
			\JLog::add('Unable to write the pid file at: ' . $this->config->get('application_pid_file'), \JLog::EMERGENCY);

			return false;
		}

		// Attempt to change the identity of user running the process.
		if (!$this->changeIdentity())
		{
			// If the identity change was required then we need to return false.
			if ($this->config->get('application_require_identity'))
			{
				\JLog::add('Unable to change process owner.', \JLog::CRITICAL);

				return false;
			}
			else
			{
				\JLog::add('Unable to change process owner.', \JLog::WARNING);
			}
		}

		// Setup the signal handlers for the daemon.
		if (!$this->setupSignalHandlers())
		{
			return false;
		}

		// Change the current working directory to the application working directory.
		@ chdir($this->config->get('application_directory'));

		return true;
	}

	/**
	 * This is truly where the magic happens.  This is where we fork the process and kill the parent
	 * process, which is essentially what turns the application into a daemon.
	 *
	 * @return  void
	 *
	 * @since   3.0.0
	 * @throws  \RuntimeException
	 */
	protected function detach()
	{
		\JLog::add('Detaching the ' . $this->name . ' daemon.', \JLog::DEBUG);

		// Attempt to fork the process.
		$pid = $this->fork();

		// If the pid is positive then we successfully forked, and can close this application.
		if ($pid)
		{
			// Add the log entry for debugging purposes and exit gracefully.
			\JLog::add('Ending ' . $this->name . ' parent process', \JLog::DEBUG);
			$this->close();
		}
		// We are in the forked child process.
		else
		{
			// Setup some protected values.
			$this->exiting = false;
			$this->running = true;

			// Set the parent to self.
			$this->parentId = $this->processId;
		}
	}

	/**
	 * Method to fork the process.
	 *
	 * @return  integer  The child process id to the parent process, zero to the child process.
	 *
	 * @since   1.7.0
	 * @throws  \RuntimeException
	 */
	protected function fork()
	{
		// Attempt to fork the process.
		$pid = $this->pcntlFork();

		// If the fork failed, throw an exception.
		if ($pid === -1)
		{
			throw new \RuntimeException('The process could not be forked.');
		}
		// Update the process id for the child.
		elseif ($pid === 0)
		{
			$this->processId = (int) posix_getpid();
		}
		// Log the fork in the parent.
		else
		{
			// Log the fork.
			\JLog::add('Process forked ' . $pid, \JLog::DEBUG);
		}

		// Trigger the onFork event.
		$this->postFork();

		return $pid;
	}

	/**
	 * Method to perform basic garbage collection and memory management in the sense of clearing the
	 * stat cache.  We will probably call this method pretty regularly in our main loop.
	 *
	 * @return  void
	 *
	 * @since   1.7.0
	 */
	protected function gc()
	{
		// Perform generic garbage collection.
		gc_collect_cycles();

		// Clear the stat cache so it doesn't blow up memory.
		clearstatcache();
	}

	/**
	 * Method to attach the DaemonApplication signal handler to the known signals.  Applications
	 * can override these handlers by using the pcntl_signal() function and attaching a different
	 * callback method.
	 *
	 * @return  boolean
	 *
	 * @since   1.7.0
	 * @see     pcntl_signal()
	 */
	protected function setupSignalHandlers()
	{
		// We add the error suppression for the loop because on some platforms some constants are not defined.
		foreach (self::$signals as $signal)
		{
			// Ignore signals that are not defined.
			if (!defined($signal) || !is_int(constant($signal)) || (constant($signal) === 0))
			{
				// Define the signal to avoid notices.
				\JLog::add('Signal "' . $signal . '" not defined. Defining it as null.', \JLog::DEBUG);
				define($signal, null);

				// Don't listen for signal.
				continue;
			}

			// Attach the signal handler for the signal.
			if (!$this->pcntlSignal(constant($signal), array('DaemonApplication', 'signal')))
			{
				\JLog::add(sprintf('Unable to reroute signal handler: %s', $signal), \JLog::EMERGENCY);

				return false;
			}
		}

		return true;
	}

	/**
	 * Method to shut down the daemon and optionally restart it.
	 *
	 * @param   boolean  $restart  True to restart the daemon on exit.
	 *
	 * @return  void
	 *
	 * @since   1.7.0
	 */
	protected function shutdown($restart = false)
	{
		// If we are already exiting, chill.
		if ($this->exiting)
		{
			return;
		}
		// If not, now we are.
		else
		{
			$this->exiting = true;
		}

		// If we aren't already daemonized then just kill the application.
		if (!$this->running && !$this->isActive())
		{
			\JLog::add('Process was not daemonized yet, just halting current process', \JLog::INFO);
			$this->close();
		}

		// Only read the pid for the parent file.
		if ($this->parentId == $this->processId)
		{
			// Read the contents of the process id file as an integer.
			$fp = fopen($this->config->get('application_pid_file'), 'r');
			$pid = fread($fp, filesize($this->config->get('application_pid_file')));
			$pid = (int) $pid;
			fclose($fp);

			// Remove the process id file.
			@ unlink($this->config->get('application_pid_file'));

			// If we are supposed to restart the daemon we need to execute the same command.
			if ($restart)
			{
				$this->close(exec(implode(' ', $GLOBALS['argv']) . ' > /dev/null &'));
			}
			// If we are not supposed to restart the daemon let's just kill -9.
			else
			{
				passthru('kill -9 ' . $pid);
				$this->close();
			}
		}
	}

	/**
	 * Method to write the process id file out to disk.
	 *
	 * @return  boolean
	 *
	 * @since   1.7.0
	 */
	protected function writeProcessIdFile()
	{
		// Verify the process id is valid.
		if ($this->processId < 1)
		{
			\JLog::add('The process id is invalid.', \JLog::EMERGENCY);

			return false;
		}

		// Get the application process id file path.
		$file = $this->config->get('application_pid_file');

		if (empty($file))
		{
			\JLog::add('The process id file path is empty.', \JLog::ERROR);

			return false;
		}

		// Make sure that the folder where we are writing the process id file exists.
		$folder = dirname($file);

		if (!is_dir($folder) && !\JFolder::create($folder))
		{
			\JLog::add('Unable to create directory: ' . $folder, \JLog::ERROR);

			return false;
		}

		// Write the process id file out to disk.
		if (!file_put_contents($file, $this->processId))
		{
			\JLog::add('Unable to write proccess id file: ' . $file, \JLog::ERROR);

			return false;
		}

		// Make sure the permissions for the proccess id file are accurate.
		if (!chmod($file, 0644))
		{
			\JLog::add('Unable to adjust permissions for the proccess id file: ' . $file, \JLog::ERROR);

			return false;
		}

		return true;
	}

	/**
	 * Method to handle post-fork triggering of the onFork event.
	 *
	 * @return  void
	 *
	 * @since   3.0.0
	 */
	protected function postFork()
	{
		// Trigger the onFork event.
		$this->triggerEvent('onFork');
	}

	/**
	 * Method to return the exit code of a terminated child process.
	 *
	 * @param   integer  $status  The status parameter is the status parameter supplied to a successful call to pcntl_waitpid().
	 *
	 * @return  integer  The child process exit code.
	 *
	 * @see     pcntl_wexitstatus()
	 * @since   1.7.3
	 */
	protected function pcntlChildExitStatus($status)
	{
		return pcntl_wexitstatus($status);
	}

	/**
	 * Method to return the exit code of a terminated child process.
	 *
	 * @return  integer  On success, the PID of the child process is returned in the parent's thread
	 *                   of execution, and a 0 is returned in the child's thread of execution. On
	 *                   failure, a -1 will be returned in the parent's context, no child process
	 *                   will be created, and a PHP error is raised.
	 *
	 * @see     pcntl_fork()
	 * @since   1.7.3
	 */
	protected function pcntlFork()
	{
		return pcntl_fork();
	}

	/**
	 * Method to install a signal handler.
	 *
	 * @param   integer   $signal   The signal number.
	 * @param   callable  $handler  The signal handler which may be the name of a user created function,
	 *                              or method, or either of the two global constants SIG_IGN or SIG_DFL.
	 * @param   boolean   $restart  Specifies whether system call restarting should be used when this
	 *                              signal arrives.
	 *
	 * @return  boolean  True on success.
	 *
	 * @see     pcntl_signal()
	 * @since   1.7.3
	 */
	protected function pcntlSignal($signal, $handler, $restart = true)
	{
		return pcntl_signal($signal, $handler, $restart);
	}

	/**
	 * Method to wait on or return the status of a forked child.
	 *
	 * @param   integer  &$status  Status information.
	 * @param   integer  $options  If wait3 is available on your system (mostly BSD-style systems),
	 *                             you can provide the optional options parameter.
	 *
	 * @return  integer  The process ID of the child which exited, -1 on error or zero if WNOHANG
	 *                   was provided as an option (on wait3-available systems) and no child was available.
	 *
	 * @see     pcntl_wait()
	 * @since   1.7.3
	 */
	protected function pcntlWait(&$status, $options = 0)
	{
		return pcntl_wait($status, $options);
	}
}
SiteApplication.php000064400000052430152344706220010356 0ustar00<?php
/**
 * Joomla! Content Management System
 *
 * @copyright  (C) 2005 Open Source Matters, Inc. <https://www.joomla.org>
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace Joomla\CMS\Application;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Input\Input;
use Joomla\Registry\Registry;

/**
 * Joomla! Site Application class
 *
 * @since  3.2
 */
final class SiteApplication extends CMSApplication
{
	/**
	 * Option to filter by language
	 *
	 * @var    boolean
	 * @since  3.2
	 * @deprecated  4.0  Will be renamed $language_filter
	 */
	protected $_language_filter = false;

	/**
	 * Option to detect language by the browser
	 *
	 * @var    boolean
	 * @since  3.2
	 * @deprecated  4.0  Will be renamed $detect_browser
	 */
	protected $_detect_browser = false;

	/**
	 * Class constructor.
	 *
	 * @param   Input                   $input   An optional argument to provide dependency injection for the application's
	 *                                           input object.  If the argument is a \JInput object that object will become
	 *                                           the application's input object, otherwise a default input object is created.
	 * @param   Registry                $config  An optional argument to provide dependency injection for the application's
	 *                                           config object.  If the argument is a Registry object that object will become
	 *                                           the application's config object, otherwise a default config object is created.
	 * @param   \JApplicationWebClient  $client  An optional argument to provide dependency injection for the application's
	 *                                           client object.  If the argument is a \JApplicationWebClient object that object will become
	 *                                           the application's client object, otherwise a default client object is created.
	 *
	 * @since   3.2
	 */
	public function __construct(Input $input = null, Registry $config = null, \JApplicationWebClient $client = null)
	{
		// Register the application name
		$this->_name = 'site';

		// Register the client ID
		$this->_clientId = 0;

		// Execute the parent constructor
		parent::__construct($input, $config, $client);
	}

	/**
	 * Check if the user can access the application
	 *
	 * @param   integer  $itemid  The item ID to check authorisation for
	 *
	 * @return  void
	 *
	 * @since   3.2
	 *
	 * @throws  \Exception When you are not authorised to view the home page menu item
	 */
	protected function authorise($itemid)
	{
		$menus = $this->getMenu();
		$user = \JFactory::getUser();

		if (!$menus->authorise($itemid))
		{
			if ($user->get('id') == 0)
			{
				// Set the data
				$this->setUserState('users.login.form.data', array('return' => \JUri::getInstance()->toString()));

				$url = \JRoute::_('index.php?option=com_users&view=login', false);

				$this->enqueueMessage(\JText::_('JGLOBAL_YOU_MUST_LOGIN_FIRST'), 'error');
				$this->redirect($url);
			}
			else
			{
				// Get the home page menu item
				$home_item = $menus->getDefault($this->getLanguage()->getTag());

				// If we are already in the homepage raise an exception
				if ($menus->getActive()->id == $home_item->id)
				{
					throw new \Exception(\JText::_('JERROR_ALERTNOAUTHOR'), 403);
				}

				// Otherwise redirect to the homepage and show an error
				$this->enqueueMessage(\JText::_('JERROR_ALERTNOAUTHOR'), 'error');
				$this->redirect(\JRoute::_('index.php?Itemid=' . $home_item->id, false));
			}
		}
	}

	/**
	 * Dispatch the application
	 *
	 * @param   string  $component  The component which is being rendered.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	public function dispatch($component = null)
	{
		// Get the component if not set.
		if (!$component)
		{
			$component = $this->input->getCmd('option', null);
		}

		// Load the document to the API
		$this->loadDocument();

		// Set up the params
		$document = $this->getDocument();
		$router   = static::getRouter();
		$params   = $this->getParams();

		// Register the document object with \JFactory
		\JFactory::$document = $document;

		switch ($document->getType())
		{
			case 'html':
				// Get language
				$lang_code = $this->getLanguage()->getTag();
				$languages = \JLanguageHelper::getLanguages('lang_code');

				// Set metadata
				if (isset($languages[$lang_code]) && $languages[$lang_code]->metakey)
				{
					$document->setMetaData('keywords', $languages[$lang_code]->metakey);
				}
				else
				{
					$document->setMetaData('keywords', $this->get('MetaKeys'));
				}

				$document->setMetaData('rights', $this->get('MetaRights'));

				if ($router->getMode() == JROUTER_MODE_SEF)
				{
					$document->setBase(htmlspecialchars(\JUri::current()));
				}

				// Get the template
				$template = $this->getTemplate(true);

				// Store the template and its params to the config
				$this->set('theme', $template->template);
				$this->set('themeParams', $template->params);

				break;

			case 'feed':
				$document->setBase(htmlspecialchars(\JUri::current()));
				break;
		}

		$document->setTitle($params->get('page_title'));
		$document->setDescription($params->get('page_description'));

		// Add version number or not based on global configuration
		if ($this->get('MetaVersion', 0))
		{
			$document->setGenerator('Joomla! - Open Source Content Management - Version ' . JVERSION);
		}
		else
		{
			$document->setGenerator('Joomla! - Open Source Content Management');
		}

		$contents = ComponentHelper::renderComponent($component);
		$document->setBuffer($contents, 'component');

		// Trigger the onAfterDispatch event.
		\JPluginHelper::importPlugin('system');
		$this->triggerEvent('onAfterDispatch');
	}

	/**
	 * Method to run the Web application routines.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	protected function doExecute()
	{
		// Initialise the application
		$this->initialiseApp();

		// Mark afterInitialise in the profiler.
		JDEBUG ? $this->profiler->mark('afterInitialise') : null;

		// Route the application
		$this->route();

		// Mark afterRoute in the profiler.
		JDEBUG ? $this->profiler->mark('afterRoute') : null;

		/*
		 * Check if the user is required to reset their password
		 *
		 * Before $this->route(); "option" and "view" can't be safely read using:
		 * $this->input->getCmd('option'); or $this->input->getCmd('view');
		 * ex: due of the sef urls
		 */
		$this->checkUserRequireReset('com_users', 'profile', 'edit', 'com_users/profile.save,com_users/profile.apply,com_users/user.logout');

		// Dispatch the application
		$this->dispatch();

		// Mark afterDispatch in the profiler.
		JDEBUG ? $this->profiler->mark('afterDispatch') : null;
	}

	/**
	 * Return the current state of the detect browser option.
	 *
	 * @return	boolean
	 *
	 * @since	3.2
	 */
	public function getDetectBrowser()
	{
		return $this->_detect_browser;
	}

	/**
	 * Return the current state of the language filter.
	 *
	 * @return	boolean
	 *
	 * @since	3.2
	 */
	public function getLanguageFilter()
	{
		return $this->_language_filter;
	}

	/**
	 * Return a reference to the \JMenu object.
	 *
	 * @param   string  $name     The name of the application/client.
	 * @param   array   $options  An optional associative array of configuration settings.
	 *
	 * @return  \JMenu  \JMenu object.
	 *
	 * @since   3.2
	 */
	public function getMenu($name = 'site', $options = array())
	{
		return parent::getMenu($name, $options);
	}

	/**
	 * Get the application parameters
	 *
	 * @param   string  $option  The component option
	 *
	 * @return  Registry  The parameters object
	 *
	 * @since   3.2
	 * @deprecated  4.0  Use getParams() instead
	 */
	public function getPageParameters($option = null)
	{
		return $this->getParams($option);
	}

	/**
	 * Get the application parameters
	 *
	 * @param   string  $option  The component option
	 *
	 * @return  Registry  The parameters object
	 *
	 * @since   3.2
	 */
	public function getParams($option = null)
	{
		static $params = array();

		$hash = '__default';

		if (!empty($option))
		{
			$hash = $option;
		}

		if (!isset($params[$hash]))
		{
			// Get component parameters
			if (!$option)
			{
				$option = $this->input->getCmd('option', null);
			}

			// Get new instance of component global parameters
			$params[$hash] = clone ComponentHelper::getParams($option);

			// Get menu parameters
			$menus = $this->getMenu();
			$menu  = $menus->getActive();

			// Get language
			$lang_code = $this->getLanguage()->getTag();
			$languages = \JLanguageHelper::getLanguages('lang_code');

			$title = $this->get('sitename');

			if (isset($languages[$lang_code]) && $languages[$lang_code]->metadesc)
			{
				$description = $languages[$lang_code]->metadesc;
			}
			else
			{
				$description = $this->get('MetaDesc');
			}

			$rights = $this->get('MetaRights');
			$robots = $this->get('robots');

			// Retrieve com_menu global settings
			$temp = clone ComponentHelper::getParams('com_menus');

			// Lets cascade the parameters if we have menu item parameters
			if (is_object($menu))
			{
				// Get show_page_heading from com_menu global settings
				$params[$hash]->def('show_page_heading', $temp->get('show_page_heading'));

				$params[$hash]->merge($menu->params);
				$title = $menu->title;
			}
			else
			{
				// Merge com_menu global settings
				$params[$hash]->merge($temp);

				// If supplied, use page title
				$title = $temp->get('page_title', $title);
			}

			$params[$hash]->def('page_title', $title);
			$params[$hash]->def('page_description', $description);
			$params[$hash]->def('page_rights', $rights);
			$params[$hash]->def('robots', $robots);
		}

		return $params[$hash];
	}

	/**
	 * Return a reference to the \JPathway object.
	 *
	 * @param   string  $name     The name of the application.
	 * @param   array   $options  An optional associative array of configuration settings.
	 *
	 * @return  \JPathway  A \JPathway object
	 *
	 * @since   3.2
	 */
	public function getPathway($name = 'site', $options = array())
	{
		return parent::getPathway($name, $options);
	}

	/**
	 * Return a reference to the \JRouter object.
	 *
	 * @param   string  $name     The name of the application.
	 * @param   array   $options  An optional associative array of configuration settings.
	 *
	 * @return	\JRouter
	 *
	 * @since	3.2
	 */
	public static function getRouter($name = 'site', array $options = array())
	{
		return parent::getRouter($name, $options);
	}

	/**
	 * Gets the name of the current template.
	 *
	 * @param   boolean  $params  True to return the template parameters
	 *
	 * @return  string  The name of the template.
	 *
	 * @since   3.2
	 * @throws  \InvalidArgumentException
	 */
	public function getTemplate($params = false)
	{
		if (is_object($this->template))
		{
			if (!file_exists(JPATH_THEMES . '/' . $this->template->template . '/index.php'))
			{
				throw new \InvalidArgumentException(\JText::sprintf('JERROR_COULD_NOT_FIND_TEMPLATE', $this->template->template));
			}

			if ($params)
			{
				return $this->template;
			}

			return $this->template->template;
		}

		// Get the id of the active menu item
		$menu = $this->getMenu();
		$item = $menu->getActive();

		if (!$item)
		{
			$item = $menu->getItem($this->input->getInt('Itemid', null));
		}

		$id = 0;

		if (is_object($item))
		{
			// Valid item retrieved
			$id = $item->template_style_id;
		}

		$tid = $this->input->getUint('templateStyle', 0);

		if (is_numeric($tid) && (int) $tid > 0)
		{
			$id = (int) $tid;
		}

		$cache = \JFactory::getCache('com_templates', '');

		if ($this->_language_filter)
		{
			$tag = $this->getLanguage()->getTag();
		}
		else
		{
			$tag = '';
		}

		$cacheId = 'templates0' . $tag;

		if ($cache->contains($cacheId))
		{
			$templates = $cache->get($cacheId);
		}
		else
		{
			// Load styles
			$db = \JFactory::getDbo();
			$query = $db->getQuery(true)
				->select('id, home, template, s.params')
				->from('#__template_styles as s')
				->where('s.client_id = 0')
				->where('e.enabled = 1')
				->join('LEFT', '#__extensions as e ON e.element=s.template AND e.type=' . $db->quote('template') . ' AND e.client_id=s.client_id');

			$db->setQuery($query);
			$templates = $db->loadObjectList('id');

			foreach ($templates as &$template)
			{
				// Create home element
				if ($template->home == 1 && !isset($template_home) || $this->_language_filter && $template->home == $tag)
				{
					$template_home = clone $template;
				}

				$template->params = new Registry($template->params);
			}

			// Unset the $template reference to the last $templates[n] item cycled in the foreach above to avoid editing it later
			unset($template);

			// Add home element, after loop to avoid double execution
			if (isset($template_home))
			{
				$template_home->params = new Registry($template_home->params);
				$templates[0] = $template_home;
			}

			$cache->store($templates, $cacheId);
		}

		if (isset($templates[$id]))
		{
			$template = $templates[$id];
		}
		else
		{
			$template = $templates[0];
		}

		// Allows for overriding the active template from the request
		$template_override = $this->input->getCmd('template', '');

		// Only set template override if it is a valid template (= it exists and is enabled)
		if (!empty($template_override))
		{
			if (file_exists(JPATH_THEMES . '/' . $template_override . '/index.php'))
			{
				foreach ($templates as $tmpl)
				{
					if ($tmpl->template === $template_override)
					{
						$template = $tmpl;
						break;
					}
				}
			}
		}

		// Need to filter the default value as well
		$template->template = \JFilterInput::getInstance()->clean($template->template, 'cmd');

		// Fallback template
		if (!file_exists(JPATH_THEMES . '/' . $template->template . '/index.php'))
		{
			$this->enqueueMessage(\JText::_('JERROR_ALERTNOTEMPLATE'), 'error');

			// Try to find data for 'beez3' template
			$original_tmpl = $template->template;

			foreach ($templates as $tmpl)
			{
				if ($tmpl->template === 'beez3')
				{
					$template = $tmpl;
					break;
				}
			}

			// Check, the data were found and if template really exists
			if (!file_exists(JPATH_THEMES . '/' . $template->template . '/index.php'))
			{
				throw new \InvalidArgumentException(\JText::sprintf('JERROR_COULD_NOT_FIND_TEMPLATE', $original_tmpl));
			}
		}

		// Cache the result
		$this->template = $template;

		if ($params)
		{
			return $template;
		}

		return $template->template;
	}

	/**
	 * Initialise the application.
	 *
	 * @param   array  $options  An optional associative array of configuration settings.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	protected function initialiseApp($options = array())
	{
		$user = \JFactory::getUser();

		// If the user is a guest we populate it with the guest user group.
		if ($user->guest)
		{
			$guestUsergroup = ComponentHelper::getParams('com_users')->get('guest_usergroup', 1);
			$user->groups = array($guestUsergroup);
		}

		/*
		 * If a language was specified it has priority, otherwise use user or default language settings
		 * Check this only if the languagefilter plugin is enabled
		 *
		 * @TODO - Remove the hardcoded dependency to the languagefilter plugin
		 */
		if (\JPluginHelper::isEnabled('system', 'languagefilter'))
		{
			$plugin = \JPluginHelper::getPlugin('system', 'languagefilter');

			$pluginParams = new Registry($plugin->params);

			$this->setLanguageFilter(true);
			$this->setDetectBrowser($pluginParams->get('detect_browser', '1') == '1');
		}

		if (empty($options['language']))
		{
			// Detect the specified language
			$lang = $this->input->getString('language', null);

			// Make sure that the user's language exists
			if ($lang && \JLanguageHelper::exists($lang))
			{
				$options['language'] = $lang;
			}
		}

		if (empty($options['language']) && $this->getLanguageFilter())
		{
			// Detect cookie language
			$lang = $this->input->cookie->get(md5($this->get('secret') . 'language'), null, 'string');

			// Make sure that the user's language exists
			if ($lang && \JLanguageHelper::exists($lang))
			{
				$options['language'] = $lang;
			}
		}

		if (empty($options['language']))
		{
			// Detect user language
			$lang = $user->getParam('language');

			// Make sure that the user's language exists
			if ($lang && \JLanguageHelper::exists($lang))
			{
				$options['language'] = $lang;
			}
		}

		if (empty($options['language']) && $this->getDetectBrowser())
		{
			// Detect browser language
			$lang = \JLanguageHelper::detectLanguage();

			// Make sure that the user's language exists
			if ($lang && \JLanguageHelper::exists($lang))
			{
				$options['language'] = $lang;
			}
		}

		if (empty($options['language']))
		{
			// Detect default language
			$params = ComponentHelper::getParams('com_languages');
			$options['language'] = $params->get('site', $this->get('language', 'en-GB'));
		}

		// One last check to make sure we have something
		if (!\JLanguageHelper::exists($options['language']))
		{
			$lang = $this->config->get('language', 'en-GB');

			if (\JLanguageHelper::exists($lang))
			{
				$options['language'] = $lang;
			}
			else
			{
				// As a last ditch fail to english
				$options['language'] = 'en-GB';
			}
		}

		// Finish initialisation
		parent::initialiseApp($options);
	}

	/**
	 * Load the library language files for the application
	 *
	 * @return  void
	 *
	 * @since   3.6.3
	 */
	protected function loadLibraryLanguage()
	{
		/*
		 * Try the lib_joomla file in the current language (without allowing the loading of the file in the default language)
		 * Fallback to the default language if necessary
		 */
		$this->getLanguage()->load('lib_joomla', JPATH_SITE, null, false, true)
			|| $this->getLanguage()->load('lib_joomla', JPATH_ADMINISTRATOR, null, false, true);
	}

	/**
	 * Login authentication function
	 *
	 * @param   array  $credentials  Array('username' => string, 'password' => string)
	 * @param   array  $options      Array('remember' => boolean)
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   3.2
	 */
	public function login($credentials, $options = array())
	{
		// Set the application login entry point
		if (!array_key_exists('entry_url', $options))
		{
			$options['entry_url'] = \JUri::base() . 'index.php?option=com_users&task=user.login';
		}

		// Set the access control action to check.
		$options['action'] = 'core.login.site';

		return parent::login($credentials, $options);
	}

	/**
	 * Rendering is the process of pushing the document buffers into the template
	 * placeholders, retrieving data from the document and pushing it into
	 * the application response buffer.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	protected function render()
	{
		switch ($this->document->getType())
		{
			case 'feed':
				// No special processing for feeds
				break;

			case 'html':
			default:
				$template = $this->getTemplate(true);
				$file     = $this->input->get('tmpl', 'index');

				if ($file === 'offline' && !$this->get('offline'))
				{
					$this->set('themeFile', 'index.php');
				}

				if ($this->get('offline') && !\JFactory::getUser()->authorise('core.login.offline'))
				{
					$this->setUserState('users.login.form.data', array('return' => \JUri::getInstance()->toString()));
					$this->set('themeFile', 'offline.php');
					$this->setHeader('Status', '503 Service Temporarily Unavailable', 'true');
				}

				if (!is_dir(JPATH_THEMES . '/' . $template->template) && !$this->get('offline'))
				{
					$this->set('themeFile', 'component.php');
				}

				// Ensure themeFile is set by now
				if ($this->get('themeFile') == '')
				{
					$this->set('themeFile', $file . '.php');
				}

				break;
		}

		parent::render();
	}

	/**
	 * Route the application.
	 *
	 * Routing is the process of examining the request environment to determine which
	 * component should receive the request. The component optional parameters
	 * are then set in the request object to be processed when the application is being
	 * dispatched.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	protected function route()
	{
		// Execute the parent method
		parent::route();

		$Itemid = $this->input->getInt('Itemid', null);
		$this->authorise($Itemid);
	}

	/**
	 * Set the current state of the detect browser option.
	 *
	 * @param   boolean  $state  The new state of the detect browser option
	 *
	 * @return	boolean	 The previous state
	 *
	 * @since	3.2
	 */
	public function setDetectBrowser($state = false)
	{
		$old = $this->_detect_browser;
		$this->_detect_browser = $state;

		return $old;
	}

	/**
	 * Set the current state of the language filter.
	 *
	 * @param   boolean  $state  The new state of the language filter
	 *
	 * @return	boolean	 The previous state
	 *
	 * @since	3.2
	 */
	public function setLanguageFilter($state = false)
	{
		$old = $this->_language_filter;
		$this->_language_filter = $state;

		return $old;
	}

	/**
	 * Overrides the default template that would be used
	 *
	 * @param   string  $template     The template name
	 * @param   mixed   $styleParams  The template style parameters
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	public function setTemplate($template, $styleParams = null)
	{
		if (is_dir(JPATH_THEMES . '/' . $template))
		{
			$this->template = new \stdClass;
			$this->template->template = $template;

			if ($styleParams instanceof Registry)
			{
				$this->template->params = $styleParams;
			}
			else
			{
				$this->template->params = new Registry($styleParams);
			}

			// Store the template and its params to the config
			$this->set('theme', $this->template->template);
			$this->set('themeParams', $this->template->params);
		}
	}
}
WebApplication.php000064400000112577152344706220010200 0ustar00<?php
/**
 * Joomla! Content Management System
 *
 * @copyright  (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace Joomla\CMS\Application;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Input\Input;
use Joomla\Registry\Registry;
use Joomla\String\StringHelper;

/**
 * Base class for a Joomla! Web application.
 *
 * @since  2.5.0
 * @note   As of 4.0 this class will be abstract
 */
class WebApplication extends BaseApplication
{
	/**
	 * @var    string  Character encoding string.
	 * @since  1.7.3
	 */
	public $charSet = 'utf-8';

	/**
	 * @var    string  Response mime type.
	 * @since  1.7.3
	 */
	public $mimeType = 'text/html';

	/**
	 * @var    \JDate  The body modified date for response headers.
	 * @since  1.7.3
	 */
	public $modifiedDate;

	/**
	 * @var    \JApplicationWebClient  The application client object.
	 * @since  1.7.3
	 */
	public $client;

	/**
	 * @var    \JDocument  The application document object.
	 * @since  1.7.3
	 */
	protected $document;

	/**
	 * @var    \JLanguage  The application language object.
	 * @since  1.7.3
	 */
	protected $language;

	/**
	 * @var    \JSession  The application session object.
	 * @since  1.7.3
	 */
	protected $session;

	/**
	 * @var    object  The application response object.
	 * @since  1.7.3
	 */
	protected $response;

	/**
	 * @var    WebApplication  The application instance.
	 * @since  1.7.3
	 */
	protected static $instance;

	/**
	 * A map of integer HTTP 1.1 response codes to the full HTTP Status for the headers.
	 *
	 * @var    object
	 * @since  3.4
	 * @link   http://tools.ietf.org/pdf/rfc7231.pdf
	 */
	private $responseMap = array(
		100 => 'HTTP/1.1 100 Continue',
		101 => 'HTTP/1.1 101 Switching Protocols',
		102 => 'HTTP/1.1 102 Processing',
		200 => 'HTTP/1.1 200 OK',
		201 => 'HTTP/1.1 201 Created',
		202 => 'HTTP/1.1 202 Accepted',
		203 => 'HTTP/1.1 203 Non-Authoritative Information',
		204 => 'HTTP/1.1 204 No Content',
		205 => 'HTTP/1.1 205 Reset Content',
		206 => 'HTTP/1.1 206 Partial Content',
		207 => 'HTTP/1.1 207 Multi-Status',
		208 => 'HTTP/1.1 208 Already Reported',
		226 => 'HTTP/1.1 226 IM Used',
		300 => 'HTTP/1.1 300 Multiple Choices',
		301 => 'HTTP/1.1 301 Moved Permanently',
		302 => 'HTTP/1.1 302 Found',
		303 => 'HTTP/1.1 303 See other',
		304 => 'HTTP/1.1 304 Not Modified',
		305 => 'HTTP/1.1 305 Use Proxy',
		306 => 'HTTP/1.1 306 (Unused)',
		307 => 'HTTP/1.1 307 Temporary Redirect',
		308 => 'HTTP/1.1 308 Permanent Redirect',
		400 => 'HTTP/1.1 400 Bad Request',
		401 => 'HTTP/1.1 401 Unauthorized',
		402 => 'HTTP/1.1 402 Payment Required',
		403 => 'HTTP/1.1 403 Forbidden',
		404 => 'HTTP/1.1 404 Not Found',
		405 => 'HTTP/1.1 405 Method Not Allowed',
		406 => 'HTTP/1.1 406 Not Acceptable',
		407 => 'HTTP/1.1 407 Proxy Authentication Required',
		408 => 'HTTP/1.1 408 Request Timeout',
		409 => 'HTTP/1.1 409 Conflict',
		410 => 'HTTP/1.1 410 Gone',
		411 => 'HTTP/1.1 411 Length Required',
		412 => 'HTTP/1.1 412 Precondition Failed',
		413 => 'HTTP/1.1 413 Payload Too Large',
		414 => 'HTTP/1.1 414 URI Too Long',
		415 => 'HTTP/1.1 415 Unsupported Media Type',
		416 => 'HTTP/1.1 416 Range Not Satisfiable',
		417 => 'HTTP/1.1 417 Expectation Failed',
		418 => 'HTTP/1.1 418 I\'m a teapot',
		421 => 'HTTP/1.1 421 Misdirected Request',
		422 => 'HTTP/1.1 422 Unprocessable Entity',
		423 => 'HTTP/1.1 423 Locked',
		424 => 'HTTP/1.1 424 Failed Dependency',
		426 => 'HTTP/1.1 426 Upgrade Required',
		428 => 'HTTP/1.1 428 Precondition Required',
		429 => 'HTTP/1.1 429 Too Many Requests',
		431 => 'HTTP/1.1 431 Request Header Fields Too Large',
		451 => 'HTTP/1.1 451 Unavailable For Legal Reasons',
		500 => 'HTTP/1.1 500 Internal Server Error',
		501 => 'HTTP/1.1 501 Not Implemented',
		502 => 'HTTP/1.1 502 Bad Gateway',
		503 => 'HTTP/1.1 503 Service Unavailable',
		504 => 'HTTP/1.1 504 Gateway Timeout',
		505 => 'HTTP/1.1 505 HTTP Version Not Supported',
		506 => 'HTTP/1.1 506 Variant Also Negotiates',
		507 => 'HTTP/1.1 507 Insufficient Storage',
		508 => 'HTTP/1.1 508 Loop Detected',
		510 => 'HTTP/1.1 510 Not Extended',
		511 => 'HTTP/1.1 511 Network Authentication Required',
	);

	/**
	 * A map of HTTP Response headers which may only send a single value, all others
	 * are considered to allow multiple
	 *
	 * @var    object
	 * @since  3.5.2
	 * @link   https://tools.ietf.org/html/rfc7230
	 */
	private $singleValueResponseHeaders = array(
		'status', // This is not a valid header name, but the representation used by Joomla to identify the HTTP Response Code
		'content-length',
		'host',
		'content-type',
		'content-location',
		'date',
		'location',
		'retry-after',
		'server',
		'mime-version',
		'last-modified',
		'etag',
		'accept-ranges',
		'content-range',
		'age',
		'expires',
		'clear-site-data',
		'pragma',
		'strict-transport-security',
		'content-security-policy',
		'content-security-policy-report-only',
		'x-frame-options',
		'x-xss-protection',
		'x-content-type-options',
		'referrer-policy',
		'expect-ct',
		'feature-policy', // @deprecated - see: https://scotthelme.co.uk/goodbye-feature-policy-and-hello-permissions-policy/
		'permissions-policy',
	);

	/**
	 * Class constructor.
	 *
	 * @param   Input                   $input   An optional argument to provide dependency injection for the application's
	 *                                           input object.  If the argument is a \JInput object that object will become
	 *                                           the application's input object, otherwise a default input object is created.
	 * @param   Registry                $config  An optional argument to provide dependency injection for the application's
	 *                                           config object.  If the argument is a Registry object that object will become
	 *                                           the application's config object, otherwise a default config object is created.
	 * @param   \JApplicationWebClient  $client  An optional argument to provide dependency injection for the application's
	 *                                           client object.  If the argument is a \JApplicationWebClient object that object will become
	 *                                           the application's client object, otherwise a default client object is created.
	 *
	 * @since   1.7.3
	 */
	public function __construct(Input $input = null, Registry $config = null, \JApplicationWebClient $client = null)
	{
		// If an input object is given use it.
		if ($input instanceof Input)
		{
			$this->input = $input;
		}
		// Create the input based on the application logic.
		else
		{
			$this->input = new Input;
		}

		// If a config object is given use it.
		if ($config instanceof Registry)
		{
			$this->config = $config;
		}
		// Instantiate a new configuration object.
		else
		{
			$this->config = new Registry;
		}

		// If a client object is given use it.
		if ($client instanceof \JApplicationWebClient)
		{
			$this->client = $client;
		}
		// Instantiate a new web client object.
		else
		{
			$this->client = new \JApplicationWebClient;
		}

		// Load the configuration object.
		$this->loadConfiguration($this->fetchConfigurationData());

		// Set the execution datetime and timestamp;
		$this->set('execution.datetime', gmdate('Y-m-d H:i:s'));
		$this->set('execution.timestamp', time());

		// Setup the response object.
		$this->response = new \stdClass;
		$this->response->cachable = false;
		$this->response->headers = array();
		$this->response->body = array();

		// Set the system URIs.
		$this->loadSystemUris();
	}

	/**
	 * Returns a reference to the global WebApplication object, only creating it if it doesn't already exist.
	 *
	 * This method must be invoked as: $web = WebApplication::getInstance();
	 *
	 * @param   string  $name  The name (optional) of the JApplicationWeb class to instantiate.
	 *
	 * @return  WebApplication
	 *
	 * @since   1.7.3
	 */
	public static function getInstance($name = null)
	{
		// Only create the object if it doesn't exist.
		if (empty(self::$instance))
		{
			if (class_exists($name) && (is_subclass_of($name, '\\Joomla\\CMS\\Application\\WebApplication')))
			{
				self::$instance = new $name;
			}
			else
			{
				self::$instance = new WebApplication;
			}
		}

		return self::$instance;
	}

	/**
	 * Initialise the application.
	 *
	 * @param   mixed  $session     An optional argument to provide dependency injection for the application's
	 *                              session object.  If the argument is a \JSession object that object will become
	 *                              the application's session object, if it is false then there will be no session
	 *                              object, and if it is null then the default session object will be created based
	 *                              on the application's loadSession() method.
	 * @param   mixed  $document    An optional argument to provide dependency injection for the application's
	 *                              document object.  If the argument is a \JDocument object that object will become
	 *                              the application's document object, if it is false then there will be no document
	 *                              object, and if it is null then the default document object will be created based
	 *                              on the application's loadDocument() method.
	 * @param   mixed  $language    An optional argument to provide dependency injection for the application's
	 *                              language object.  If the argument is a \JLanguage object that object will become
	 *                              the application's language object, if it is false then there will be no language
	 *                              object, and if it is null then the default language object will be created based
	 *                              on the application's loadLanguage() method.
	 * @param   mixed  $dispatcher  An optional argument to provide dependency injection for the application's
	 *                              event dispatcher.  If the argument is a \JEventDispatcher object that object will become
	 *                              the application's event dispatcher, if it is null then the default event dispatcher
	 *                              will be created based on the application's loadDispatcher() method.
	 *
	 * @return  WebApplication  Instance of $this to allow chaining.
	 *
	 * @deprecated  4.0
	 * @see     WebApplication::loadSession()
	 * @see     WebApplication::loadDocument()
	 * @see     WebApplication::loadLanguage()
	 * @see     WebApplication::loadDispatcher()
	 * @since   1.7.3
	 */
	public function initialise($session = null, $document = null, $language = null, $dispatcher = null)
	{
		// Create the session based on the application logic.
		if ($session !== false)
		{
			$this->loadSession($session);
		}

		// Create the document based on the application logic.
		if ($document !== false)
		{
			$this->loadDocument($document);
		}

		// Create the language based on the application logic.
		if ($language !== false)
		{
			$this->loadLanguage($language);
		}

		$this->loadDispatcher($dispatcher);

		return $this;
	}

	/**
	 * Execute the application.
	 *
	 * @return  void
	 *
	 * @since   1.7.3
	 */
	public function execute()
	{
		// Trigger the onBeforeExecute event.
		$this->triggerEvent('onBeforeExecute');

		// Perform application routines.
		$this->doExecute();

		// Trigger the onAfterExecute event.
		$this->triggerEvent('onAfterExecute');

		// If we have an application document object, render it.
		if ($this->document instanceof \JDocument)
		{
			// Trigger the onBeforeRender event.
			$this->triggerEvent('onBeforeRender');

			// Render the application output.
			$this->render();

			// Trigger the onAfterRender event.
			$this->triggerEvent('onAfterRender');
		}

		// If gzip compression is enabled in configuration and the server is compliant, compress the output.
		if ($this->get('gzip') && !ini_get('zlib.output_compression') && (ini_get('output_handler') != 'ob_gzhandler'))
		{
			$this->compress();
		}

		// Trigger the onBeforeRespond event.
		$this->triggerEvent('onBeforeRespond');

		// Send the application response.
		$this->respond();

		// Trigger the onAfterRespond event.
		$this->triggerEvent('onAfterRespond');
	}

	/**
	 * Rendering is the process of pushing the document buffers into the template
	 * placeholders, retrieving data from the document and pushing it into
	 * the application response buffer.
	 *
	 * @return  void
	 *
	 * @since   1.7.3
	 */
	protected function render()
	{
		// Setup the document options.
		$options = array(
			'template' => $this->get('theme'),
			'file' => $this->get('themeFile', 'index.php'),
			'params' => $this->get('themeParams'),
		);

		if ($this->get('themes.base'))
		{
			$options['directory'] = $this->get('themes.base');
		}
		// Fall back to constants.
		else
		{
			$options['directory'] = defined('JPATH_THEMES') ? JPATH_THEMES : (defined('JPATH_BASE') ? JPATH_BASE : __DIR__) . '/themes';
		}

		// Parse the document.
		$this->document->parse($options);

		// Render the document.
		$data = $this->document->render($this->get('cache_enabled'), $options);

		// Set the application output data.
		$this->setBody($data);
	}

	/**
	 * Checks the accept encoding of the browser and compresses the data before
	 * sending it to the client if possible.
	 *
	 * @return  void
	 *
	 * @since   1.7.3
	 */
	protected function compress()
	{
		// Supported compression encodings.
		$supported = array(
			'x-gzip' => 'gz',
			'gzip' => 'gz',
			'deflate' => 'deflate',
		);

		// Get the supported encoding.
		$encodings = array_intersect($this->client->encodings, array_keys($supported));

		// If no supported encoding is detected do nothing and return.
		if (empty($encodings))
		{
			return;
		}

		// Verify that headers have not yet been sent, and that our connection is still alive.
		if ($this->checkHeadersSent() || !$this->checkConnectionAlive())
		{
			return;
		}

		// Iterate through the encodings and attempt to compress the data using any found supported encodings.
		foreach ($encodings as $encoding)
		{
			if (($supported[$encoding] == 'gz') || ($supported[$encoding] == 'deflate'))
			{
				// Verify that the server supports gzip compression before we attempt to gzip encode the data.
				if (!extension_loaded('zlib') || ini_get('zlib.output_compression'))
				{
					continue;
				}

				// Attempt to gzip encode the data with an optimal level 4.
				$data = $this->getBody();
				$gzdata = gzencode($data, 4, ($supported[$encoding] == 'gz') ? FORCE_GZIP : FORCE_DEFLATE);

				// If there was a problem encoding the data just try the next encoding scheme.
				if ($gzdata === false)
				{
					continue;
				}

				// Set the encoding headers.
				$this->setHeader('Content-Encoding', $encoding);
				$this->setHeader('Vary', 'Accept-Encoding');

				// Header will be removed at 4.0
				if ($this->get('MetaVersion'))
				{
					$this->setHeader('X-Content-Encoded-By', 'Joomla');
				}

				// Replace the output with the encoded data.
				$this->setBody($gzdata);

				// Compression complete, let's break out of the loop.
				break;
			}
		}
	}

	/**
	 * Method to send the application response to the client.  All headers will be sent prior to the main
	 * application output data.
	 *
	 * @return  void
	 *
	 * @since   1.7.3
	 */
	protected function respond()
	{
		// Send the content-type header.
		$this->setHeader('Content-Type', $this->mimeType . '; charset=' . $this->charSet);

		// If the response is set to uncachable, we need to set some appropriate headers so browsers don't cache the response.
		if (!$this->response->cachable)
		{
			// Expires in the past.
			$this->setHeader('Expires', 'Wed, 17 Aug 2005 00:00:00 GMT', true);

			// Always modified.
			$this->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT', true);
			$this->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0', false);

			// HTTP 1.0
			$this->setHeader('Pragma', 'no-cache');
		}
		else
		{
			// Expires.
			$this->setHeader('Expires', gmdate('D, d M Y H:i:s', time() + 900) . ' GMT');

			// Last modified.
			if ($this->modifiedDate instanceof \JDate)
			{
				$this->setHeader('Last-Modified', $this->modifiedDate->format('D, d M Y H:i:s', false, false) . ' GMT');
			}
		}

		$this->sendHeaders();

		echo $this->getBody();
	}

	/**
	 * Redirect to another URL.
	 *
	 * If the headers have not been sent the redirect will be accomplished using a "301 Moved Permanently"
	 * or "303 See Other" code in the header pointing to the new location. If the headers have already been
	 * sent this will be accomplished using a JavaScript statement.
	 *
	 * @param   string   $url     The URL to redirect to. Can only be http/https URL.
	 * @param   integer  $status  The HTTP 1.1 status code to be provided. 303 is assumed by default.
	 *
	 * @return  void
	 *
	 * @since   1.7.3
	 */
	public function redirect($url, $status = 303)
	{
		// Check for relative internal links.
		if (preg_match('#^index\.php#', $url))
		{
			// We changed this from "$this->get('uri.base.full') . $url" due to the inability to run the system tests with the original code
			$url = \JUri::base() . $url;
		}

		// Perform a basic sanity check to make sure we don't have any CRLF garbage.
		$url = preg_split("/[\r\n]/", $url);
		$url = $url[0];

		/*
		 * Here we need to check and see if the URL is relative or absolute.  Essentially, do we need to
		 * prepend the URL with our base URL for a proper redirect.  The rudimentary way we are looking
		 * at this is to simply check whether or not the URL string has a valid scheme or not.
		 */
		if (!preg_match('#^[a-z]+\://#i', $url))
		{
			// Get a \JUri instance for the requested URI.
			$uri = \JUri::getInstance($this->get('uri.request'));

			// Get a base URL to prepend from the requested URI.
			$prefix = $uri->toString(array('scheme', 'user', 'pass', 'host', 'port'));

			// We just need the prefix since we have a path relative to the root.
			if ($url[0] == '/')
			{
				$url = $prefix . $url;
			}
			// It's relative to where we are now, so lets add that.
			else
			{
				$parts = explode('/', $uri->toString(array('path')));
				array_pop($parts);
				$path = implode('/', $parts) . '/';
				$url = $prefix . $path . $url;
			}
		}

		// If the headers have already been sent we need to send the redirect statement via JavaScript.
		if ($this->checkHeadersSent())
		{
			echo "<script>document.location.href=" . json_encode(str_replace("'", '&apos;', $url)) . ";</script>\n";
		}
		else
		{
			// We have to use a JavaScript redirect here because MSIE doesn't play nice with utf-8 URLs.
			if (($this->client->engine == \JApplicationWebClient::TRIDENT) && !StringHelper::is_ascii($url))
			{
				$html = '<html><head>';
				$html .= '<meta http-equiv="content-type" content="text/html; charset=' . $this->charSet . '" />';
				$html .= '<script>document.location.href=' . json_encode(str_replace("'", '&apos;', $url)) . ';</script>';
				$html .= '</head><body></body></html>';

				echo $html;
			}
			else
			{
				// Check if we have a boolean for the status variable for compatibility with old $move parameter
				// @deprecated 4.0
				if (is_bool($status))
				{
					$status = $status ? 301 : 303;
				}

				// Now check if we have an integer status code that maps to a valid redirect. If we don't then set a 303
				// @deprecated 4.0 From 4.0 if no valid status code is given an InvalidArgumentException will be thrown
				if (!is_int($status) || !$this->isRedirectState($status))
				{
					$status = 303;
				}

				// All other cases use the more efficient HTTP header for redirection.
				$this->setHeader('Status', $status, true);
				$this->setHeader('Location', $url, true);
			}
		}

		// Trigger the onBeforeRespond event.
		$this->triggerEvent('onBeforeRespond');

		// Set appropriate headers
		$this->respond();

		// Trigger the onAfterRespond event.
		$this->triggerEvent('onAfterRespond');

		//  Close the application after the redirect.
		$this->close();
	}

	/**
	 * Checks if a state is a redirect state
	 *
	 * @param   integer  $state  The HTTP 1.1 status code.
	 *
	 * @return  boolean
	 *
	 * @since   3.8.0
	 */
	protected function isRedirectState($state)
	{
		$state = (int) $state;

		return ($state > 299 && $state < 400);
	}

	/**
	 * Load an object or array into the application configuration object.
	 *
	 * @param   mixed  $data  Either an array or object to be loaded into the configuration object.
	 *
	 * @return  WebApplication  Instance of $this to allow chaining.
	 *
	 * @since   1.7.3
	 */
	public function loadConfiguration($data)
	{
		// Load the data into the configuration object.
		if (is_array($data))
		{
			$this->config->loadArray($data);
		}
		elseif (is_object($data))
		{
			$this->config->loadObject($data);
		}

		return $this;
	}

	/**
	 * Set/get cachable state for the response.  If $allow is set, sets the cachable state of the
	 * response.  Always returns the current state.
	 *
	 * @param   boolean  $allow  True to allow browser caching.
	 *
	 * @return  boolean
	 *
	 * @since   1.7.3
	 */
	public function allowCache($allow = null)
	{
		if ($allow !== null)
		{
			$this->response->cachable = (bool) $allow;
		}

		return $this->response->cachable;
	}

	/**
	 * Method to set a response header.  If the replace flag is set then all headers
	 * with the given name will be replaced by the new one.  The headers are stored
	 * in an internal array to be sent when the site is sent to the browser.
	 *
	 * @param   string   $name     The name of the header to set.
	 * @param   string   $value    The value of the header to set.
	 * @param   boolean  $replace  True to replace any headers with the same name.
	 *
	 * @return  WebApplication  Instance of $this to allow chaining.
	 *
	 * @since   1.7.3
	 */
	public function setHeader($name, $value, $replace = false)
	{
		// Sanitize the input values.
		$name = (string) $name;
		$value = (string) $value;

		// Create an array of duplicate header names
		$keys = false;

		if ($this->response->headers)
		{
			$names = array();

			foreach ($this->response->headers as $key => $header)
			{
				$names[$key] = $header['name'];
			}

			// Find existing headers by name
			$keys = array_keys($names, $name);
		}

		// Remove if $replace is true and there are duplicate names
		if ($replace && $keys)
		{
			$this->response->headers = array_diff_key($this->response->headers, array_flip($keys));
		}

		/*
		 * If no keys found, safe to insert (!$keys)
		 * If ($keys && $replace) it's a replacement and previous have been deleted
		 * If ($keys && !in_array...) it's a multiple value header
		 */
		$single = in_array(strtolower($name), $this->singleValueResponseHeaders);

		if ($value && (!$keys || ($keys && ($replace || !$single))))
		{
			// Add the header to the internal array.
			$this->response->headers[] = array('name' => $name, 'value' => $value);
		}

		return $this;
	}

	/**
	 * Method to get the array of response headers to be sent when the response is sent
	 * to the client.
	 *
	 * @return  array	 *
	 *
	 * @since   1.7.3
	 */
	public function getHeaders()
	{
		return $this->response->headers;
	}

	/**
	 * Method to clear any set response headers.
	 *
	 * @return  WebApplication  Instance of $this to allow chaining.
	 *
	 * @since   1.7.3
	 */
	public function clearHeaders()
	{
		$this->response->headers = array();

		return $this;
	}

	/**
	 * Send the response headers.
	 *
	 * @return  WebApplication  Instance of $this to allow chaining.
	 *
	 * @since   1.7.3
	 */
	public function sendHeaders()
	{
		if (!$this->checkHeadersSent())
		{
			// Creating an array of headers, making arrays of headers with multiple values
			$val = array();

			foreach ($this->response->headers as $header)
			{
				if ('status' == strtolower($header['name']))
				{
					// 'status' headers indicate an HTTP status, and need to be handled slightly differently
					$status = $this->getHttpStatusValue($header['value']);
					$this->header($status, true, (int) $header['value']);
				}
				else
				{
					$val[$header['name']] = !isset($val[$header['name']]) ? $header['value'] : implode(', ', array($val[$header['name']], $header['value']));
					$this->header($header['name'] . ': ' . $val[$header['name']], true);
				}
			}
		}

		return $this;
	}

	/**
	 * Check if a given value can be successfully mapped to a valid http status value
	 *
	 * @param   string  $value  The given status as int or string
	 *
	 * @return  string
	 *
	 * @since   3.8.0
	 */
	protected function getHttpStatusValue($value)
	{
		$code = (int) $value;

		if (array_key_exists($code, $this->responseMap))
		{
			return $this->responseMap[$code];
		}

		return 'HTTP/1.1 ' . $code;
	}

	/**
	 * Set body content.  If body content already defined, this will replace it.
	 *
	 * @param   string  $content  The content to set as the response body.
	 *
	 * @return  WebApplication  Instance of $this to allow chaining.
	 *
	 * @since   1.7.3
	 */
	public function setBody($content)
	{
		$this->response->body = array((string) $content);

		return $this;
	}

	/**
	 * Prepend content to the body content
	 *
	 * @param   string  $content  The content to prepend to the response body.
	 *
	 * @return  WebApplication  Instance of $this to allow chaining.
	 *
	 * @since   1.7.3
	 */
	public function prependBody($content)
	{
		array_unshift($this->response->body, (string) $content);

		return $this;
	}

	/**
	 * Append content to the body content
	 *
	 * @param   string  $content  The content to append to the response body.
	 *
	 * @return  WebApplication  Instance of $this to allow chaining.
	 *
	 * @since   1.7.3
	 */
	public function appendBody($content)
	{
		$this->response->body[] = (string) $content;

		return $this;
	}

	/**
	 * Return the body content
	 *
	 * @param   boolean  $asArray  True to return the body as an array of strings.
	 *
	 * @return  mixed  The response body either as an array or concatenated string.
	 *
	 * @since   1.7.3
	 */
	public function getBody($asArray = false)
	{
		return $asArray ? $this->response->body : implode((array) $this->response->body);
	}

	/**
	 * Method to get the application document object.
	 *
	 * @return  \JDocument  The document object
	 *
	 * @since   1.7.3
	 */
	public function getDocument()
	{
		return $this->document;
	}

	/**
	 * Method to get the application language object.
	 *
	 * @return  \JLanguage  The language object
	 *
	 * @since   1.7.3
	 */
	public function getLanguage()
	{
		return $this->language;
	}

	/**
	 * Method to get the application session object.
	 *
	 * @return  \JSession  The session object
	 *
	 * @since   1.7.3
	 */
	public function getSession()
	{
		return $this->session;
	}

	/**
	 * Method to check the current client connection status to ensure that it is alive.  We are
	 * wrapping this to isolate the connection_status() function from our code base for testing reasons.
	 *
	 * @return  boolean  True if the connection is valid and normal.
	 *
	 * @see     connection_status()
	 * @since   1.7.3
	 */
	protected function checkConnectionAlive()
	{
		return connection_status() === CONNECTION_NORMAL;
	}

	/**
	 * Method to check to see if headers have already been sent.  We are wrapping this to isolate the
	 * headers_sent() function from our code base for testing reasons.
	 *
	 * @return  boolean  True if the headers have already been sent.
	 *
	 * @see     headers_sent()
	 * @since   1.7.3
	 */
	protected function checkHeadersSent()
	{
		return headers_sent();
	}

	/**
	 * Method to detect the requested URI from server environment variables.
	 *
	 * @return  string  The requested URI
	 *
	 * @since   1.7.3
	 */
	protected function detectRequestUri()
	{
		// First we need to detect the URI scheme.
		if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS']) != 'off'))
		{
			$scheme = 'https://';
		}
		else
		{
			$scheme = 'http://';
		}

		/*
		 * There are some differences in the way that Apache and IIS populate server environment variables.  To
		 * properly detect the requested URI we need to adjust our algorithm based on whether or not we are getting
		 * information from Apache or IIS.
		 */
		// Define variable to return
		$uri = '';

		// If PHP_SELF and REQUEST_URI are both populated then we will assume "Apache Mode".
		if (!empty($_SERVER['PHP_SELF']) && !empty($_SERVER['REQUEST_URI']))
		{
			// The URI is built from the HTTP_HOST and REQUEST_URI environment variables in an Apache environment.
			$uri = $scheme . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
		}
		// If not in "Apache Mode" we will assume that we are in an IIS environment and proceed.
		elseif (isset($_SERVER['HTTP_HOST']))
		{
			// IIS uses the SCRIPT_NAME variable instead of a REQUEST_URI variable... thanks, MS
			$uri = $scheme . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'];

			// If the QUERY_STRING variable exists append it to the URI string.
			if (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING']))
			{
				$uri .= '?' . $_SERVER['QUERY_STRING'];
			}
		}

		return trim($uri);
	}

	/**
	 * Method to load a PHP configuration class file based on convention and return the instantiated data object.  You
	 * will extend this method in child classes to provide configuration data from whatever data source is relevant
	 * for your specific application.
	 *
	 * @param   string  $file   The path and filename of the configuration file. If not provided, configuration.php
	 *                          in JPATH_CONFIGURATION will be used.
	 * @param   string  $class  The class name to instantiate.
	 *
	 * @return  mixed   Either an array or object to be loaded into the configuration object.
	 *
	 * @since   1.7.3
	 * @throws  \RuntimeException
	 */
	protected function fetchConfigurationData($file = '', $class = '\JConfig')
	{
		// Instantiate variables.
		$config = array();

		if (empty($file))
		{
			$file = JPATH_CONFIGURATION . '/configuration.php';

			// Applications can choose not to have any configuration data
			// by not implementing this method and not having a config file.
			if (!file_exists($file))
			{
				$file = '';
			}
		}

		if (!empty($file))
		{
			\JLoader::register($class, $file);

			if (class_exists($class))
			{
				$config = new $class;
			}
			else
			{
				throw new \RuntimeException('Configuration class does not exist.');
			}
		}

		return $config;
	}

	/**
	 * Flush the media version to refresh versionable assets
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	public function flushAssets()
	{
		$version = new \JVersion;
		$version->refreshMediaVersion();
	}

	/**
	 * Method to send a header to the client.  We are wrapping this to isolate the header() function
	 * from our code base for testing reasons.
	 *
	 * @param   string   $string   The header string.
	 * @param   boolean  $replace  The optional replace parameter indicates whether the header should
	 *                             replace a previous similar header, or add a second header of the same type.
	 * @param   integer  $code     Forces the HTTP response code to the specified value. Note that
	 *                             this parameter only has an effect if the string is not empty.
	 *
	 * @return  void
	 *
	 * @see     header()
	 * @since   1.7.3
	 */
	protected function header($string, $replace = true, $code = null)
	{
		$string = str_replace(chr(0), '', $string);

		if ($code === null)
		{
			$code = 0;
		}

		header($string, $replace, $code);
	}

	/**
	 * Determine if we are using a secure (SSL) connection.
	 *
	 * @return  boolean  True if using SSL, false if not.
	 *
	 * @since   3.0.1
	 */
	public function isSSLConnection()
	{
		return (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on')) || getenv('SSL_PROTOCOL_VERSION');
	}

	/**
	 * Allows the application to load a custom or default document.
	 *
	 * The logic and options for creating this object are adequately generic for default cases
	 * but for many applications it will make sense to override this method and create a document,
	 * if required, based on more specific needs.
	 *
	 * @param   \JDocument  $document  An optional document object. If omitted, the factory document is created.
	 *
	 * @return  WebApplication This method is chainable.
	 *
	 * @since   1.7.3
	 */
	public function loadDocument(\JDocument $document = null)
	{
		$this->document = ($document === null) ? \JFactory::getDocument() : $document;

		return $this;
	}

	/**
	 * Allows the application to load a custom or default language.
	 *
	 * The logic and options for creating this object are adequately generic for default cases
	 * but for many applications it will make sense to override this method and create a language,
	 * if required, based on more specific needs.
	 *
	 * @param   \JLanguage  $language  An optional language object. If omitted, the factory language is created.
	 *
	 * @return  WebApplication This method is chainable.
	 *
	 * @since   1.7.3
	 */
	public function loadLanguage(\JLanguage $language = null)
	{
		$this->language = ($language === null) ? \JFactory::getLanguage() : $language;

		return $this;
	}

	/**
	 * Allows the application to load a custom or default session.
	 *
	 * The logic and options for creating this object are adequately generic for default cases
	 * but for many applications it will make sense to override this method and create a session,
	 * if required, based on more specific needs.
	 *
	 * @param   \JSession  $session  An optional session object. If omitted, the session is created.
	 *
	 * @return  WebApplication This method is chainable.
	 *
	 * @since   1.7.3
	 */
	public function loadSession(\JSession $session = null)
	{
		if ($session !== null)
		{
			$this->session = $session;

			return $this;
		}

		// Generate a session name.
		$name = md5($this->get('secret') . $this->get('session_name', get_class($this)));

		// Calculate the session lifetime.
		$lifetime = (($this->get('sess_lifetime')) ? $this->get('sess_lifetime') * 60 : 900);

		// Get the session handler from the configuration.
		$handler = $this->get('sess_handler', 'none');

		// Initialize the options for \JSession.
		$options = array(
			'name' => $name,
			'expire' => $lifetime,
			'force_ssl' => $this->get('force_ssl'),
		);

		$this->registerEvent('onAfterSessionStart', array($this, 'afterSessionStart'));

		// Instantiate the session object.
		$session = \JSession::getInstance($handler, $options);
		$session->initialise($this->input, $this->dispatcher);

		if ($session->getState() == 'expired')
		{
			$session->restart();
		}
		else
		{
			$session->start();
		}

		// Set the session object.
		$this->session = $session;

		return $this;
	}

	/**
	 * After the session has been started we need to populate it with some default values.
	 *
	 * @return  void
	 *
	 * @since   3.0.1
	 */
	public function afterSessionStart()
	{
		$session = \JFactory::getSession();

		if ($session->isNew())
		{
			$session->set('registry', new Registry);
			$session->set('user', new \JUser);
		}
	}

	/**
	 * Method to load the system URI strings for the application.
	 *
	 * @param   string  $requestUri  An optional request URI to use instead of detecting one from the
	 *                               server environment variables.
	 *
	 * @return  void
	 *
	 * @since   1.7.3
	 */
	protected function loadSystemUris($requestUri = null)
	{
		// Set the request URI.
		if (!empty($requestUri))
		{
			$this->set('uri.request', $requestUri);
		}
		else
		{
			$this->set('uri.request', $this->detectRequestUri());
		}

		// Check to see if an explicit base URI has been set.
		$siteUri = trim($this->get('site_uri', ''));

		if ($siteUri != '')
		{
			$uri = \JUri::getInstance($siteUri);
			$path = $uri->toString(array('path'));
		}
		// No explicit base URI was set so we need to detect it.
		else
		{
			// Start with the requested URI.
			$uri = \JUri::getInstance($this->get('uri.request'));

			// If we are working from a CGI SAPI with the 'cgi.fix_pathinfo' directive disabled we use PHP_SELF.
			if (strpos(php_sapi_name(), 'cgi') !== false && !ini_get('cgi.fix_pathinfo') && !empty($_SERVER['REQUEST_URI']))
			{
				// We aren't expecting PATH_INFO within PHP_SELF so this should work.
				$path = dirname($_SERVER['PHP_SELF']);
			}
			// Pretty much everything else should be handled with SCRIPT_NAME.
			else
			{
				$path = dirname($_SERVER['SCRIPT_NAME']);
			}
		}

		$host = $uri->toString(array('scheme', 'user', 'pass', 'host', 'port'));

		// Check if the path includes "index.php".
		if (strpos($path, 'index.php') !== false)
		{
			// Remove the index.php portion of the path.
			$path = substr_replace($path, '', strpos($path, 'index.php'), 9);
		}

		$path = rtrim($path, '/\\');

		// Set the base URI both as just a path and as the full URI.
		$this->set('uri.base.full', $host . $path . '/');
		$this->set('uri.base.host', $host);
		$this->set('uri.base.path', $path . '/');

		// Set the extended (non-base) part of the request URI as the route.
		if (stripos($this->get('uri.request'), $this->get('uri.base.full')) === 0)
		{
			$this->set('uri.route', substr_replace($this->get('uri.request'), '', 0, strlen($this->get('uri.base.full'))));
		}

		// Get an explicitly set media URI is present.
		$mediaURI = trim($this->get('media_uri', ''));

		if ($mediaURI)
		{
			if (strpos($mediaURI, '://') !== false)
			{
				$this->set('uri.media.full', $mediaURI);
				$this->set('uri.media.path', $mediaURI);
			}
			else
			{
				// Normalise slashes.
				$mediaURI = trim($mediaURI, '/\\');
				$mediaURI = !empty($mediaURI) ? '/' . $mediaURI . '/' : '/';
				$this->set('uri.media.full', $this->get('uri.base.host') . $mediaURI);
				$this->set('uri.media.path', $mediaURI);
			}
		}
		// No explicit media URI was set, build it dynamically from the base uri.
		else
		{
			$this->set('uri.media.full', $this->get('uri.base.full') . 'media/');
			$this->set('uri.media.path', $this->get('uri.base.path') . 'media/');
		}
	}
}
ApplicationSmartSlider3.php000064400000002532152356646020011770 0ustar00<?php


namespace Nextend\SmartSlider3\Application;


use Exception;
use Nextend\Framework\Application\AbstractApplication;
use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Platform\Platform;
use Nextend\SmartSlider3\Application\Admin\ApplicationTypeAdmin;
use Nextend\SmartSlider3\Application\Frontend\ApplicationTypeFrontend;

class ApplicationSmartSlider3 extends AbstractApplication {

    protected $key = 'ss3';

    /** @var ApplicationTypeAdmin */
    protected $applicationTypeAdmin;

    /** @var ApplicationTypeFrontend */
    protected $applicationTypeFrontend;

    /**
     * @throws Exception
     */
    protected function init() {
        parent::init();

        $this->applicationTypeAdmin    = new ApplicationTypeAdmin($this);
        $this->applicationTypeFrontend = new ApplicationTypeFrontend($this);
    }

    /**
     * @return ApplicationTypeAdmin
     */
    public function getApplicationTypeAdmin() {

        return $this->applicationTypeAdmin;
    }

    /**
     * @return ApplicationTypeFrontend
     */
    public function getApplicationTypeFrontend() {

        return $this->applicationTypeFrontend;
    }

    public function enqueueAssets() {
        if (Platform::isAdmin()) {
            Js::addGlobalInline('window.N2SSPRO=' . N2SSPRO . ';');
        }
    
    }
}Model/ModelGenerator.php000064400000047671152356646020011254 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Model;


use Exception;
use Nextend\Framework\Data\Data;
use Nextend\Framework\Database\Database;
use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\Form\Element\Button\ButtonRecordViewer;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Misc\Base64;
use Nextend\Framework\Model\AbstractModelTable;
use Nextend\SmartSlider3\Generator\AbstractGeneratorGroup;
use Nextend\SmartSlider3\Generator\GeneratorFactory;
use Nextend\SmartSlider3\SlideBuilder\BuilderComponentCol;
use Nextend\SmartSlider3\SlideBuilder\BuilderComponentLayer;
use Nextend\SmartSlider3\SlideBuilder\BuilderComponentRow;
use Nextend\SmartSlider3\SlideBuilder\BuilderComponentSlide;

class ModelGenerator extends AbstractModelTable {

    protected function createConnectorTable() {

        return Database::getTable('nextend2_smartslider3_generators');
    }

    private static function getLayout($type) {

        $slideBuilder = new BuilderComponentSlide();

        switch ($type) {
            case 'image':
                $slideBuilder->set(array(
                    'title'           => "{title}",
                    'thumbnail'       => "{thumbnail}",
                    'backgroundImage' => "{image}",
                    'background-type' => 'image'
                ));
                break;

            case 'image_extended':
                $slideBuilder->set(array(
                    'title'           => "{title}",
                    'thumbnail'       => "{thumbnail}",
                    'backgroundImage' => "{image}",
                    'background-type' => 'image'
                ));

                $slideBuilder->content->set(array(
                    'verticalalign'          => 'flex-end',
                    'desktopportraitpadding' => '0|*|0|*|0|*|0|*|px'
                ));
                $row = new BuilderComponentRow($slideBuilder->content);
                $row->set(array(
                    'bgcolor' => '00000080',
                ));
                $col = new BuilderComponentCol($row, '1');
                $col->set(array(
                    'desktopportraitinneralign' => "left"
                ));
                $heading = new BuilderComponentLayer($col, 'heading');
                $heading->set(array(
                    'desktopportraitselfalign' => 'inherit'
                ));
                $heading->item->set(array(
                    'heading' => '{title/1}',
                ));
                break;

            case 'article':
                $slideBuilder->set(array(
                    'title'           => "{title}",
                    'description'     => '{description}',
                    'href'            => '{url}',
                    'thumbnail'       => "{thumbnail}",
                    'backgroundImage' => "{image}",
                    'background-type' => 'image'
                ));

                $slideBuilder->content->set(array(
                    'verticalalign'          => 'flex-end',
                    'desktopportraitpadding' => '0|*|0|*|0|*|0|*|px',
                ));
                $row = new BuilderComponentRow($slideBuilder->content);
                $row->set(array(
                    'bgcolor' => '00000080',
                ));
                $col = new BuilderComponentCol($row, '1');
                $col->set(array(
                    'desktopportraitinneralign' => "left",
                ));
                $heading = new BuilderComponentLayer($col, 'heading');
                $heading->set(array(
                    'desktopportraitselfalign' => 'inherit'
                ));
                $heading->item->set(array(
                    'heading' => '{title}',
                    'font'    => Base64::encode('{"data":[{"extra":"","color":"ffffffff","size":"36||px","tshadow":"0|*|0|*|0|*|000000ff","afont":"Roboto,Arial","lineheight":"1.5","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"},{"extra":""}]}')
                ));
                break;

            case 'product':
                $slideBuilder->set(array(
                    'title'           => "{title}",
                    'description'     => '{description}',
                    'href'            => '{url}',
                    'thumbnail'       => "{thumbnail}",
                    'backgroundImage' => "{image}",
                    'background-type' => 'image'
                ));

                $slideBuilder->content->set(array(
                    'verticalalign'          => 'flex-end',
                    'desktopportraitpadding' => '0|*|0|*|0|*|0|*|px',
                ));
                $row = new BuilderComponentRow($slideBuilder->content);
                $row->set(array(
                    'bgcolor' => '00000080',
                ));
                $col = new BuilderComponentCol($row, '1/2');
                $col->set(array(
                    'desktopportraitinneralign' => "left",
                ));
                $heading = new BuilderComponentLayer($col, 'heading');
                $heading->set(array(
                    'desktopportraitselfalign' => 'inherit'
                ));
                $heading->item->set(array(
                    'heading' => '{title}',
                    'font'    => Base64::encode('{"data":[{"extra":"","color":"ffffffff","size":"36||px","tshadow":"0|*|0|*|0|*|000000ff","afont":"Roboto,Arial","lineheight":"1.5","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"},{"extra":""}]}'),
                ));
                $col2 = new BuilderComponentCol($row, '1/2');
                $col2->set(array(
                    'desktopportraitinneralign' => "right",
                ));
                $text = new BuilderComponentLayer($col2, 'text');
                $text->set(array(
                    'desktopportraitselfalign' => 'inherit'
                ));
                $text->item->set(array(
                    'content' => '{price}',
                    'font'    => Base64::encode('{"data":[{"extra":"","color":"ffffffff","size":"36||px","tshadow":"0|*|0|*|0|*|000000ff","afont":"Roboto,Arial","lineheight":"1.5","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"},{"extra":""}]}'),
                ));

                break;

            case 'event':
                $slideBuilder->set(array(
                    'title'           => "{title}",
                    'description'     => '{description}',
                    'href'            => '{url}',
                    'thumbnail'       => "{thumbnail}",
                    'backgroundImage' => "{image}",
                    'background-type' => 'image'
                ));
                $slideBuilder->content->set(array(
                    'verticalalign'          => 'flex-end',
                    'desktopportraitpadding' => '0|*|0|*|0|*|0|*|px',
                ));
                $row = new BuilderComponentRow($slideBuilder->content);
                $row->set(array(
                    'bgcolor' => '00000080',
                ));
                $col = new BuilderComponentCol($row, '1/2');
                $col->set(array(
                    'desktopportraitinneralign' => "left",
                ));
                $heading = new BuilderComponentLayer($col, 'heading');
                $heading->set(array(
                    'desktopportraitselfalign' => 'inherit'
                ));
                $heading->item->set(array(
                    'heading' => '{title}',
                    'font'    => Base64::encode('{"data":[{"extra":"","color":"ffffffff","size":"36||px","tshadow":"0|*|0|*|0|*|000000ff","afont":"Roboto,Arial","lineheight":"1.5","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"},{"extra":""}]}'),
                ));
                $col2 = new BuilderComponentCol($row, '1/2');
                $col2->set(array(
                    'desktopportraitinneralign' => "right",
                ));
                $heading = new BuilderComponentLayer($col2, 'heading');
                $heading->set(array(
                    'desktopportraitselfalign' => 'inherit'
                ));
                $heading->item->set(array(
                    'heading' => '{start_date}',
                    'font'    => Base64::encode('{"data":[{"extra":"","color":"ffffffff","size":"36||px","tshadow":"0|*|0|*|0|*|000000ff","afont":"Roboto,Arial","lineheight":"1.5","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"},{"extra":""}]}'),
                ));

                break;

            case 'youtube':
                $slideBuilder->set(array(
                    'title'                  => "{title}",
                    'description'            => '{description}',
                    'thumbnail'              => "{thumbnail}",
                    'backgroundColor'        => "ffffff00",
                    'background-type'        => 'color',
                    'desktopportraitpadding' => '0|*|0|*|0|*|0|*|px',
                ));
                
                $youtube = new BuilderComponentLayer($slideBuilder->content, 'youtube');
                $youtube->item->set(array(
                    "youtubeurl" => "{video_url}",
                ));
                break;

            case 'vimeo':
                $slideBuilder->set(array(
                    'title'                  => "{title}",
                    'description'            => '{description}',
                    'thumbnail'              => "{image200x150/1}",
                    'backgroundColor'        => "ffffff00",
                    'background-type'        => 'color',
                    'desktopportraitpadding' => '0|*|0|*|0|*|0|*|px',
                ));

                $vimeo = new BuilderComponentLayer($slideBuilder->content, 'vimeo');
                $vimeo->item->set(array(
                    "vimeourl" => "{url}",
                    'image'    => '{image}'
                ));

                break;

            case 'video_mp4':
                $slideBuilder->set(array(
                    'title'                  => "{name}",
                    'desktopportraitpadding' => '0|*|0|*|0|*|0|*|px',
                ));

                $video = new BuilderComponentLayer($slideBuilder->content, 'video');
                $video->item->set(array(
                    "video_mp4" => "{video}",
                ));
                break;

            case 'social_post':
                $slideBuilder->set(array(
                    'title'           => "{title}",
                    'description'     => '{description}',
                    'href'            => '{url}',
                    'thumbnail'       => "{author_image}",
                    'backgroundColor' => "ffffff00",
                    'background-type' => 'color',
                ));

                $slideBuilder->content->set(array(
                    'verticalalign'          => 'center',
                    'desktopportraitpadding' => '0|*|0|*|0|*|0|*|px',
                    'desktopportraitmargin'  => '0|*|0|*|0|*|0|*|px'
                ));

                $row = new BuilderComponentRow($slideBuilder->content);
                $row->set(array(
                    'bgcolor'                => '00000080',
                    'desktopportraitpadding' => '10|*|10|*|10|*|10|*|px',
                    'desktopportraitmargin'  => '0|*|0|*|0|*|0|*|px'
                ));
                $col = new BuilderComponentCol($row, '1');
                $col->set(array(
                    'desktopportraitinneralign' => "left",
                    'desktopportraitmargin'     => '0|*|0|*|0|*|0|*|px',
                    'desktopportraitpadding'    => '10|*|10|*|10|*|10|*|px'
                ));
                $heading = new BuilderComponentLayer($col, 'heading');
                $heading->set(array(
                    'desktopportraitmargin'    => '0|*|0|*|0|*|0|*|px',
                    'desktopportraitselfalign' => 'inherit'
                ));
                $heading->item->set(array(
                    'heading' => '{message}',
                ));
                $image = new BuilderComponentLayer($col, 'image');
                $image->set(array(
                    'desktopportraitmargin'    => '0|*|0|*|0|*|0|*|px',
                    'desktopportraitselfalign' => 'inherit'
                ));
                $image->item->set(array(
                    'image' => '{author_image}',
                ));
                $button = new BuilderComponentLayer($col, 'button');
                $button->set(array(
                    'desktopportraitmargin'    => '0|*|0|*|0|*|0|*|px',
                    'desktopportraitselfalign' => 'inherit'
                ));
                $button->item->set(array(
                    'content' => '{url_label}',
                ));

                break;

            case 'text':
                $slideBuilder->set(array(
                    'title' => "{title}"
                ));
                $slideBuilder->content->set(array(
                    'verticalalign'          => 'flex-end',
                    'desktopportraitpadding' => '0|*|0|*|0|*|0|*|px',
                ));
                $row = new BuilderComponentRow($slideBuilder->content);
                $row->set(array(
                    'bgcolor' => '00000080',
                ));
                $col = new BuilderComponentCol($row, '1');
                $col->set(array(
                    'desktopportraitinneralign' => "left",
                ));
                $heading = new BuilderComponentLayer($col, 'heading');
                $heading->set(array(
                    'desktopportraitselfalign' => 'inherit'
                ));
                $heading->item->set(array(
                    'heading' => '{title}',
                    'font'    => Base64::encode('{"data":[{"extra":"","color":"ffffffff","size":"36||px","tshadow":"0|*|0|*|0|*|000000ff","afont":"Roboto,Arial","lineheight":"1.5","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"},{"extra":""}]}')
                ));
                break;

            case 'text_generator':
                $slideBuilder->set(array(
                    'title' => "{variable1}"
                ));
                $slideBuilder->content->set(array(
                    'verticalalign'          => 'flex-end',
                    'desktopportraitpadding' => '0|*|0|*|0|*|0|*|px',
                ));
                $row = new BuilderComponentRow($slideBuilder->content);
                $row->set(array(
                    'bgcolor' => '00000080',
                ));
                $col = new BuilderComponentCol($row, '1');
                $col->set(array(
                    'desktopportraitinneralign' => "left",
                ));
                $heading = new BuilderComponentLayer($col, 'heading');
                $heading->set(array(
                    'desktopportraitselfalign' => 'inherit'
                ));
                $heading->item->set(array(
                    'heading' => '{variable1}',
                    'font'    => Base64::encode('{"data":[{"extra":"","color":"ffffffff","size":"36||px","tshadow":"0|*|0|*|0|*|000000ff","afont":"Roboto,Arial","lineheight":"1.5","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"},{"extra":""}]}')
                ));
                break;

            default:
                return $slideBuilder->set(array(
                    'title'           => "title",
                    'description'     => '',
                    'backgroundColor' => "ffffff00",
                    'background-type' => 'color',
                ));
        }

        return $slideBuilder->getData();
    }

    public function createGenerator($sliderId, $params) {

        $data = new Data($params);

        unset($params['type']);
        unset($params['group']);
        unset($params['record-slides']);

        try {
            $generatorId = $this->_create($data->get('type'), $data->get('group'), json_encode($params));


            $source = $this->getGeneratorGroup($data->get('group'))
                           ->getSource($data->get('type'));

            $slideData = self::getLayout($source->getLayout());

            $slideData['record-slides'] = intval($data->get('record-slides', 5));

            $slidesModel = new ModelSlides($this);
            $slideId     = $slidesModel->createSlideWithGenerator($sliderId, $generatorId, $slideData);

            return array(
                'slideId'     => $slideId,
                'generatorId' => $generatorId
            );
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }
    }

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

        $settings = new ContainerTable($container, 'generator', n2_('Generator settings'));

        $generatorRow = $settings->createRow('generator-row');

        new Number($generatorRow, 'record-slides', n2_('Slides'), 5, array(
            'unit' => n2_x('slides', 'Unit'),
            'wide' => 3,
        ));

        new Number($generatorRow, 'cache-expiration', n2_('Cache expiration'), 24, array(
            'wide' => 3,
            'unit' => n2_('Hours')
        ));
        new Number($generatorRow, 'record-start', n2_('Start index'), 1, array(
            'wide' => 3
        ));
        new Number($generatorRow, 'record-group', n2_('Group result'), 1, array(
            'wide' => 3
        ));
    

        new ButtonRecordViewer($generatorRow, 'record-viewer');

    }

    /**
     * @param $type
     *
     * @return AbstractGeneratorGroup
     */
    public function getGeneratorGroup($type) {

        return GeneratorFactory::getGenerator($type);
    }

    public function get($id) {
        return Database::queryRow("SELECT * FROM " . $this->getTableName() . " WHERE id = :id", array(
            ":id" => $id
        ));
    }

    public function import($generator) {
        $this->table->insert(array(
            'type'   => $generator['type'],
            'group'  => $generator['group'],
            'params' => $generator['params']
        ));

        return $this->table->insertId();
    }

    private function _create($type, $group, $params) {
        $this->table->insert(array(
            'type'   => $type,
            'group'  => $group,
            'params' => $params
        ));

        return $this->table->insertId();
    }

    public function save($generatorId, $params) {

        $this->table->update(array(
            'params' => json_encode($params)
        ), array('id' => $generatorId));

        return $generatorId;
    }

    public function delete($id) {
        $this->table->deleteByAttributes(array(
            "id" => intval($id)
        ));
    }

    public function duplicate($id) {
        $generatorRow = $this->get($id);
        $generatorId  = $this->_create($generatorRow['type'], $generatorRow['group'], $generatorRow['params']);

        return $generatorId;
    }

    public function getSliderId($generatorId) {

        $slidesModal = new ModelSlides($this);
        $slideData   = Database::queryRow("SELECT slider FROM " . $slidesModal->getTableName() . " WHERE generator_id = :id", array(
            ":id" => $generatorId
        ));

        return $slideData['slider'];
    }
}Model/ModelLicense.php000064400000006322152356646020010674 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Model;


use Nextend\Framework\Model\StorageSectionManager;
use Nextend\Framework\Notification\Notification;
use Nextend\Framework\Pattern\SingletonTrait;
use Nextend\SmartSlider3\SmartSlider3Info;

/**
 * Class ModelLicense
 *
 * @package Nextend\SmartSlider3\Application\Model
 *
 */
class ModelLicense {

    use SingletonTrait;

    private $key;

    public function __construct() {
        if (defined('SMART_SLIDER_LICENSE')) {
            $this->key = SMART_SLIDER_LICENSE;
        } else {
            $this->key = StorageSectionManager::getStorage('smartslider')
                                              ->get('license', 'key');
        }
    
    }

    public function hasKey() {
		return true;//mhehm
        return !empty($this->key);
    }

    public function maybeActiveLazy() {
        $lastActive = StorageSectionManager::getStorage('smartslider')
                                           ->get('license', 'isActive');

        return $lastActive > 0;

    }

    public function maybeActive() {
        $lastActive = StorageSectionManager::getStorage('smartslider')
                                           ->get('license', 'isActive');
        if ($lastActive && $lastActive > strtotime("-1 week")) {
            return true;
        }

        return false;
    }

    public function getKey() {
		return '73879A3c9cb691cc8b796c4d63d53802a8b2570e36f34781a044981349bfdf7dd5fece1e1ce6ed34bc3a96e1814582a7ecf9';//mhehm
        return $this->key;
    }

    public function setKey($licenseKey) {
        StorageSectionManager::getStorage('smartslider')
                             ->set('license', 'key', $licenseKey);
        StorageSectionManager::getStorage('smartslider')
                             ->set('license', 'isActive', time());
        if ($licenseKey == '') {
            StorageSectionManager::getStorage('smartslider')
                                 ->set('license', 'isActive', '0');
        }
        $this->key = $licenseKey;
    
    }

    public function checkKey($license, $action = 'licensecheck') {
        $result = SmartSlider3Info::api(array(
            'action'  => $action,
            'license' => $license
        ));
        if ($result === false) {
            return 'CONNECTION_ERROR';
        }

        return $result['status'];
    }

    public function isActive($cacheAccepted = true) {
        if ($cacheAccepted && $this->maybeActive()) {
            return 'OK';
        }
        $status = $this->checkKey($this->key);
        if ($this->hasKey() && $status == 'OK') {
            StorageSectionManager::getStorage('smartslider')
                                 ->set('license', 'isActive', time());

            return $status;
        }
        StorageSectionManager::getStorage('smartslider')
                             ->set('license', 'isActive', '0');

        return $status;
    }

    public function deAuthorize() {
        if ($this->hasKey()) {
            $this->setKey('');
            Notification::notice(n2_('Smart Slider 3 deactivated on this site!'));

            return 'OK';
        }

        return false;
    }
}Model/ModelSettings.php000064400000002445152356646020011114 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Model;


use Nextend\Framework\Model\AbstractModel;
use Nextend\Framework\Model\Section;
use Nextend\Framework\Request\Request;
use Nextend\SmartSlider3\Application\Helper\HelperSliderChanged;
use Nextend\SmartSlider3\Settings;

class ModelSettings extends AbstractModel {

    public function save() {
        $namespace = Request::$REQUEST->getCmd('namespace', 'default');
        $settings  = Request::$REQUEST->getVar('settings');
        if ($namespace && $settings) {
            if ($namespace == 'default') $namespace = 'settings';
            if ($namespace == 'font' && Request::$REQUEST->getInt('sliderid')) {
                $namespace .= Request::$REQUEST->getInt('sliderid');

                $helper = new HelperSliderChanged($this);
                $helper->setSliderChanged(Request::$REQUEST->getInt('sliderid'), 1);
            }

            Settings::store($namespace, json_encode($settings));
        }

        return true;
    }

    public function saveDefaults($defaults) {
        if (!empty($defaults)) {
            foreach ($defaults as $referenceKey => $value) {
                Section::set('smartslider', 'default', $referenceKey, $value);
            }
        }

        return true;
    }
}Model/ModelSliders.php000064400000066611152356646020010726 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Model;


use Exception;
use Nextend\Framework\Cache\AbstractCache;
use Nextend\Framework\Data\Data;
use Nextend\Framework\Database\Database;
use Nextend\Framework\Misc\Str;
use Nextend\Framework\Model\AbstractModelTable;
use Nextend\Framework\Notification\Notification;
use Nextend\Framework\Platform\Platform;
use Nextend\SmartSlider3\Application\Helper\HelperSliderChanged;
use Nextend\SmartSlider3\Slider\Admin\AdminSlider;
use Nextend\SmartSlider3\Slider\Slider;
use Nextend\SmartSlider3\SmartSlider3Info;

class ModelSliders extends AbstractModelTable {

    /**
     * @var ModelSlidersXRef
     */
    private $xref;

    private $sliderTitleLength = 200;

    protected function createConnectorTable() {

        $this->xref = new ModelSlidersXRef($this);

        return Database::getTable('nextend2_smartslider3_sliders');
    }

    public function get($id) {
        return Database::queryRow("SELECT * FROM " . $this->getTableName() . " WHERE id = :id", array(
            ":id" => $id
        ));
    }

    public function getByAlias($alias) {
        return Database::queryRow("SELECT id FROM " . $this->getTableName() . " WHERE alias = :alias", array(
            ":alias" => $alias
        ));
    }

    public function getWithThumbnail($id) {
        $slidesModel = new ModelSlides($this);

        return Database::queryRow("SELECT sliders.*,xref.group_id, IF(sliders.thumbnail != '',sliders.thumbnail,(SELECT slides.thumbnail from " . $slidesModel->getTableName() . " AS slides WHERE slides.slider = sliders.id AND slides.published = 1 AND slides.generator_id = 0 AND slides.thumbnail NOT LIKE '' ORDER BY  slides.first DESC, slides.ordering ASC LIMIT 1)) AS thumbnail,
         IF(sliders.type != 'group', 
                        (SELECT count(*) FROM " . $slidesModel->getTableName() . " AS slides2 WHERE slides2.slider = sliders.id GROUP BY slides2.slider),
                        (SELECT count(*) FROM " . $this->xref->getTableName() . " AS xref2 WHERE xref2.group_id = sliders.id GROUP BY xref2.group_id)
                  ) AS slides
        FROM " . $this->getTableName() . " AS sliders
        LEFT JOIN " . $this->xref->getTableName() . " AS xref ON xref.slider_id = sliders.id
        WHERE sliders.id = :id", array(
            ":id" => $id
        ));
    }

    public function invalidateCache() {
        Database::query("DELETE FROM `" . Database::parsePrefix('#__nextend2_section_storage') . "` WHERE `application` LIKE 'cache'");

        Database::query("DELETE FROM `" . Database::parsePrefix('#__nextend2_section_storage') . "` WHERE `application` LIKE 'smartslider' AND `section` LIKE 'sliderChanged';");
    }

    public function refreshCache($sliderid) {
        AbstractCache::clearGroup(Slider::getCacheId($sliderid));
        AbstractCache::clearGroup(AdminSlider::getCacheId($sliderid));
        $this->markChanged($sliderid);
    }

    public function getSlidersCount($status = '*', $witGroup = false) {
        $wheres = array();
        $join   = "";

        if ($status !== '*') {
            $wheres[] = " WHERE _sliders.slider_status LIKE " . Database::quote($status);
        }

        if ($witGroup) {
            $join     = "LEFT JOIN " . $this->xref->getTableName() . " AS xref ON xref.slider_id = _sliders.id ";
            $wheres[] = "(xref.group_id IS NULL OR xref.group_id = 0)";
        }

        $data = Database::queryRow("SELECT COUNT(*) AS sliders FROM " . $this->getTableName() . " as _sliders " . $join . " " . implode(' AND ', $wheres));


        if (!empty($data)) {
            return intval($data['sliders']);
        }

        return 0;
    }

    /**
     * @return mixed
     */
    public function getAll($groupID = '*', $status = '*', $orderBy = 'ordering', $orderByDirection = 'ASC', $page = null, $limit = 'all') {
        $slidesModel = new ModelSlides($this);

        if (empty($orderBy)) {
            $orderBy = 'ordering';
        }
        if (empty($orderByDirection)) {
            $orderByDirection = 'ASC';
        }

        $_orderby   = $orderBy . ' ' . $orderByDirection;
        $limitQuery = "";

        $wheres = array();
        if ($groupID !== '*') {
            if ($groupID == 0) {
                $wheres[] = "(xref.group_id IS NULL OR xref.group_id = 0)";
                if ($page !== null && $limit != 'all') {
                    $first      = intval($page) * intval($limit);
                    $limitQuery = "LIMIT " . $first . "," . intval($limit);
                }
            } else {
                if ($orderBy == 'ordering') {
                    $_orderby = 'xref.' . $orderBy . ' ' . $orderByDirection;
                }

                $wheres[] = "xref.group_id = '" . $groupID . "'";
            }
        }

        if ($status !== '*') {
            $wheres[] = "sliders.slider_status LIKE " . Database::quote($status);
        }


        $sliders = Database::queryAll("
            SELECT sliders.*, 
                  IF(sliders.thumbnail != '',
                      sliders.thumbnail,
                          IF(sliders.type != 'group',
                              (SELECT slides.thumbnail FROM " . $slidesModel->getTableName() . " AS slides WHERE slides.slider = sliders.id AND slides.published = 1 AND slides.generator_id = 0 AND slides.thumbnail NOT LIKE '' ORDER BY  slides.first DESC, slides.ordering ASC LIMIT 1),
                              ''
                          )
                  ) AS thumbnail,
                  
                  IF(sliders.type != 'group', 
                        (SELECT count(*) FROM " . $slidesModel->getTableName() . " AS slides2 WHERE slides2.slider = sliders.id GROUP BY slides2.slider),
                        (SELECT count(*) FROM " . $this->xref->getTableName() . " AS xref2 LEFT JOIN " . $this->getTableName() . " AS sliders2 ON sliders2.id = xref2.slider_id WHERE xref2.group_id = sliders.id AND sliders2.slider_status LIKE 'published' GROUP BY xref2.group_id)
                  ) AS slides
            FROM " . $this->getTableName() . " AS sliders
            LEFT JOIN " . $this->xref->getTableName() . " AS xref ON xref.slider_id = sliders.id
            WHERE " . implode(' AND ', $wheres) . "
            ORDER BY " . $_orderby . " " . $limitQuery);


        return $sliders;
    }

    public function _getAll() {
        return Database::queryAll("SELECT sliders.* FROM " . $this->getTableName() . " AS sliders");
    }

    public function getSearchResults($keyword = "") {
        $slidesModel  = new ModelSlides($this);
        $wheres       = array();
        $orderByExtra = "";
        $id           = intval($keyword);
        if ($id > 0) {
            $wheres[]     = "sliders.id LIKE '%" . $id . "%'";
            $orderByExtra = "(sliders.id = '" . $id . "') DESC, ";
        }

        $wheres[] = "sliders.alias LIKE " . Database::quote('%' . $keyword . '%') . " OR sliders.title LIKE " . Database::quote('%' . $keyword . '%');

        return Database::queryAll("SELECT sliders.*,
                          xref.group_id,
                          IF(sliders.thumbnail != '',
                          sliders.thumbnail,
                              IF(sliders.type != 'group',
                                  (SELECT slides.thumbnail FROM " . $slidesModel->getTableName() . " AS slides WHERE slides.slider = sliders.id AND slides.published = 1 AND slides.generator_id = 0 AND slides.thumbnail NOT LIKE '' ORDER BY  slides.first DESC, slides.ordering ASC LIMIT 1),
                                  ''
                              )
                        ) AS thumbnail,
                         IF(sliders.type != 'group', 
                        (SELECT count(*) FROM " . $slidesModel->getTableName() . " AS slides2 WHERE slides2.slider = sliders.id GROUP BY slides2.slider),
                        (SELECT count(*) FROM " . $this->xref->getTableName() . " AS xref2 LEFT JOIN " . $this->getTableName() . " AS sliders2 ON sliders2.id = xref2.slider_id WHERE xref2.group_id = sliders.id AND sliders2.slider_status LIKE 'published' GROUP BY xref2.group_id)
                        ) AS slides
                        FROM " . $this->getTableName() . " AS sliders
                        LEFT JOIN " . $this->xref->getTableName() . " AS xref ON xref.slider_id = sliders.id
                        WHERE 
                            (
                                xref.group_id IS NULL 
                                OR xref.group_id = 0
                                OR (SELECT _sliders.slider_status FROM " . $this->getTableName() . " AS _sliders WHERE _sliders.id = xref.group_id ) LIKE 'published'
                            )
                            AND sliders.slider_status LIKE 'published'
                            AND (" . implode(' OR ', $wheres) . ")
                            GROUP BY sliders.id 
                        ORDER BY " . $orderByExtra . "sliders.title ASC");

    }

    public function getGroups($status = '*') {

        $wheres = array(
            "type LIKE 'group'"
        );

        if ($status !== '*') {
            $wheres[] = "slider_status LIKE " . Database::quote($status);
        }

        return Database::queryAll("SELECT id, title FROM " . $this->getTableName() . " WHERE " . implode(' AND ', $wheres) . " ORDER BY title ASC");
    }

    public function getFallbackUsage($sliderIDs) {
        $wheres = array();
        foreach ($sliderIDs as $id) {
            $wheres[] = 'params LIKE \'%"fallback-slider":"' . $id . '"%\'';
        }

        return Database::queryAll("SELECT id FROM " . $this->getTableName() . " as sliders WHERE " . implode(" OR  ", $wheres));
    }

    public function import($slider, $groupID = 0) {
        try {
            $this->table->insert(array(
                'title'     => $slider['title'],
                'type'      => $slider['type'],
                'thumbnail' => empty($slider['thumbnail']) ? '' : $slider['thumbnail'],
                'params'    => $slider['params']->toJSON(),
                'time'      => date('Y-m-d H:i:s', Platform::getTimestamp()),
                'ordering'  => -1
            ));

            $sliderID = $this->table->insertId();

            if (isset($slider['alias'])) {
                $this->updateAlias($sliderID, $slider['alias']);
            }

            $this->xref->add($groupID, $sliderID);
            $this->reindexOrdering();

            SmartSlider3Info::sliderChanged();

            return $sliderID;
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }
    }

    public function replace($slider, $groupID) {

        if (isset($slider['id']) && $slider['id'] > 0) {

            $groups = $this->xref->getGroups($slider['id']);

            $this->deletePermanently($slider['id']);

            try {
                $this->table->insert(array(
                    'id'        => $slider['id'],
                    'title'     => $slider['title'],
                    'type'      => $slider['type'],
                    'thumbnail' => empty($slider['thumbnail']) ? '' : $slider['thumbnail'],
                    'params'    => $slider['params']->toJSON(),
                    'time'      => date('Y-m-d H:i:s', Platform::getTimestamp())
                ));

                $sliderID = $this->table->insertId();

                if (isset($slider['alias'])) {
                    $this->updateAlias($sliderID, $slider['alias']);
                }

                if ($groupID) {
                    $this->xref->add($groupID, $sliderID);
                }

                if (!empty($groups)) {
                    foreach ($groups as $group) {
                        if ($groupID != $group['group_id']) {
                            $this->xref->add($group['group_id'], $sliderID);
                        }
                    }
                }

                SmartSlider3Info::sliderChanged();

                return $sliderID;
            } catch (Exception $e) {
                throw new Exception($e->getMessage());
            }
        }

        return $this->import($slider);
    }

    /**
     * @param $sliderId
     * @param $params Data
     */
    public function importUpdate($sliderId, $params) {

        $this->table->update(array(
            'params' => $params->toJson()
        ), array(
            "id" => $sliderId
        ));
    }

    public function create($slider, $groupID = 0) {
        if (!isset($slider['version'])) {
            $slider['version'] = SmartSlider3Info::$version;
        }

        if (!isset($slider['title'])) return false;
        if ($slider['title'] == '') $slider['title'] = n2_('New slider');

        if (Str::strlen($slider['title']) > $this->sliderTitleLength) {
            $slider['title'] = Str::substr($slider['title'], 0, $this->sliderTitleLength);
        }

        $title = $slider['title'];
        unset($slider['title']);
        $type = $slider['type'];
        unset($slider['type']);

        $thumbnail = '';
        if (!empty($slider['thumbnail'])) {
            $thumbnail = $slider['thumbnail'];
            unset($slider['thumbnail']);
        }

        try {
            $this->table->insert(array(
                'title'     => $title,
                'type'      => $type,
                'params'    => json_encode($slider),
                'thumbnail' => $thumbnail,
                'time'      => date('Y-m-d H:i:s', Platform::getTimestamp()),
                'ordering'  => -1
            ));

            $sliderID = $this->table->insertId();

            $this->xref->add($groupID, $sliderID);
            $this->reindexOrdering();

            SmartSlider3Info::sliderChanged();

            return $sliderID;
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }
    }

    public function saveSimple($id, $title, $params) {
        if ($id <= 0) return false;

        $params['version'] = SmartSlider3Info::$version;

        if (empty($title)) $title = n2_('New slider');

        if (Str::strlen($title) > $this->sliderTitleLength) {
            $title = Str::substr($title, 0, $this->sliderTitleLength);
        }

        $this->table->update(array(
            'title'  => $title,
            'params' => json_encode($params)
        ), array(
            "id" => $id
        ));
    }

    public function save($id, $slider) {
        $slider['version'] = SmartSlider3Info::$version;

        if (!isset($slider['title']) || $id <= 0) return false;
        $response = array(
            'changedFields' => array()
        );
        if ($slider['title'] == '') $slider['title'] = n2_('New slider');

        $title = $slider['title'];
        unset($slider['title']);
        if (Str::strlen($title) > $this->sliderTitleLength) {
            $title = Str::substr($title, 0, $this->sliderTitleLength);
        }

        $alias = $slider['alias'];
        unset($slider['alias']);
        $type = $slider['type'];
        unset($slider['type']);

        $thumbnail = '';
        if (!empty($slider['thumbnail'])) {
            $thumbnail = $slider['thumbnail'];
            unset($slider['thumbnail']);
        }

        $this->table->update(array(
            'title'     => $title,
            'type'      => $type,
            'params'    => json_encode($slider),
            'thumbnail' => $thumbnail
        ), array(
            "id" => $id
        ));

        $aliasResult = $this->updateAlias($id, $alias);
        if ($aliasResult !== false) {
            if ($aliasResult['oldAlias'] !== $aliasResult['newAlias']) {
                if ($aliasResult['newAlias'] === null) {
                    Notification::notice(n2_('Alias removed'));
                    $response['changedFields']['slideralias'] = '';
                } else if ($aliasResult['newAlias'] === '') {
                    Notification::error(n2_('Alias must contain one or more letters'));
                    $response['changedFields']['slideralias'] = '';
                } else {
                    Notification::notice(sprintf(n2_('Alias updated to: %s'), $aliasResult['newAlias']));
                    $response['changedFields']['slideralias'] = $aliasResult['newAlias'];
                }
            }
        }

        $this->markChanged($id);

        SmartSlider3Info::sliderChanged();

        return $response;
    }

    public function updateAlias($sliderID, $alias) {
        $isNull = false;
        if (empty($alias)) {
            $isNull = true;
        } else {

            $alias = strtolower($alias);
            $alias = preg_replace('/&.+?;/', '', $alias); // kill entities
            $alias = str_replace('.', '-', $alias);

            $alias = preg_replace('/[^%a-z0-9 _-]/', '', $alias);
            $alias = preg_replace('/\s+/', '-', $alias);
            $alias = preg_replace('|-+|', '-', $alias);
            $alias = preg_replace('|^-*|', '', $alias);

            if (empty($alias)) {
                $isNull = true;
            }
        }

        $slider = $this->get($sliderID);
        if ($isNull) {
            if ($slider['alias'] == 'null') {
            } else {
                Database::query('UPDATE ' . $this->table->getTableName() . ' SET `alias` = NULL WHERE id = ' . intval($sliderID));

                return array(
                    'oldAlias' => $slider['alias'],
                    'newAlias' => null
                );
            }
        } else {
            if (!is_numeric($alias)) {
                if ($slider['alias'] == $alias) {
                    return array(
                        'oldAlias' => $slider['alias'],
                        'newAlias' => $alias
                    );
                } else {
                    $_alias = $alias;
                    for ($i = 2; $i < 12; $i++) {
                        $sliderWithAlias = $this->getByAlias($_alias);
                        if (!$sliderWithAlias) {
                            $this->table->update(array(
                                'alias' => $_alias
                            ), array(
                                "id" => $sliderID
                            ));

                            return array(
                                'oldAlias' => $slider['alias'],
                                'newAlias' => $_alias
                            );
                            break;
                        } else {
                            $_alias = $alias . $i;
                        }
                    }
                }
            }

            return array(
                'oldAlias' => $slider['alias'],
                'newAlias' => ''
            );
        }

        return false;
    }

    public function setTitle($id, $title) {

        if (Str::strlen($title) > $this->sliderTitleLength) {
            $title = Str::substr($title, 0, $this->sliderTitleLength);
        }

        $this->table->update(array(
            'title' => $title
        ), array(
            "id" => $id
        ));

        $this->markChanged($id);

        return $id;
    }

    public function setThumbnail($id, $thumbnail) {

        $this->table->update(array(
            'thumbnail' => $thumbnail
        ), array(
            "id" => $id
        ));

        $this->markChanged($id);

        return $id;
    }

    public function changeSliderType($sliderID, $targetSliderType) {

        $this->table->update(array(
            'type' => $targetSliderType
        ), array(
            "id" => $sliderID
        ));

        $this->markChanged($sliderID);
    }

    /**
     * @param $sliderID
     * @param $groupID
     *
     * @return string
     */
    public function trash($sliderID, $groupID) {

        $relatedGroups = $this->xref->getGroups($sliderID);

        if (count($relatedGroups) > 1) {
            /**
             * Delete the connection between the slider and the group
             */
            $this->xref->deleteXref($groupID, $sliderID);

            return 'unlink';
        }

        $this->table->update(array(
            'slider_status' => 'trash'
        ), array(
            "id" => $sliderID
        ));

        $helper = new HelperSliderChanged($this);
        $helper->setSliderChanged($sliderID, 1);
        $helper->setSliderChanged($groupID, 1);

        $slider = $this->get($sliderID);
        if ($slider['type'] == 'group') {
            $subSliders = $this->xref->getSliders($sliderID, 'published');
            foreach ($subSliders as $subSlider) {
                if (!$this->xref->isSliderAvailableInAnyGroups($subSlider['slider_id'])) {
                    $helper->setSliderChanged($subSlider['slider_id'], 1);
                }
            }
        }

        return 'trash';
    }

    public function restore($id) {
        $changedSliders = array();
        $helper         = new HelperSliderChanged($this);

        $slider = $this->get($id);
        if ($slider['type'] == 'group') {
            $subSliders = $this->xref->getSliders($id, 'published');
            foreach ($subSliders as $subSlider) {
                if (!$this->xref->isSliderAvailableInAnyGroups($subSlider['slider_id'])) {
                    $changedSliders[] = $subSlider['slider_id'];
                }
            }
        } else {
            $relatedGroups = $this->xref->getGroups($id);
            if ($relatedGroups && isset($relatedGroups[0]['group_id']) && $relatedGroups[0]['group_id'] > 0) {
                //if a slider was trashed, then it can only be restored to one group
                $helper->setSliderChanged($relatedGroups[0]['group_id'], 1);
            }
        }

        $this->table->update(array(
            'slider_status' => 'published'
        ), array(
            "id" => $id
        ));

        if (!empty($changedSliders)) {
            foreach ($changedSliders as $sliderID) {
                $helper->setSliderChanged($sliderID, 1);
            }
        }
    }

    /**
     * @param $id
     *
     * @return array the IDs of the deleted sliders.
     */
    public function deletePermanently($id) {

        $slidesModel = new ModelSlides($this);
        $slidesModel->deleteBySlider($id);

        $deletedSliders = $this->xref->deleteGroup($id);

        $deletedSliders[] = $id;

        $this->xref->deleteSlider($id);
        $this->table->deleteByPk($id);

        AbstractCache::clearGroup(Slider::getCacheId($id));
        AbstractCache::clearGroup(AdminSlider::getCacheId($id));

        $this->markChanged($id);
        $this->reindexOrdering();

        SmartSlider3Info::sliderChanged();

        return $deletedSliders;
    }

    public function trashOrDelete($id, $groupID) {

        $relatedGroups = $this->xref->getGroups($id);

        if (count($relatedGroups) > 1) {
            /**
             * Delete the connection between the slider and the group
             */
            $this->xref->deleteXref($groupID, $id);

            return 'unlink';
        } else {

            $this->deletePermanently($id);

            return 'delete';
        }
    }

    public function deleteSlides($id) {
        $slidesModel = new ModelSlides($this);
        $slidesModel->deleteBySlider($id);
        $this->markChanged($id);
    }

    public function duplicate($id, $withGroup = true) {

        $slider = $this->get($id);

        unset($slider['id']);

        $slider['title'] .= ' - ' . n2_('Copy');

        if (Str::strlen($slider['title']) > $this->sliderTitleLength) {
            $slider['title'] = Str::substr($slider['title'], 0, $this->sliderTitleLength);
        }

        $slider['time'] = date('Y-m-d H:i:s', Platform::getTimestamp());

        /**
         * Remove alias to prevent override
         */
        $slider['alias'] = '';

        try {
            $this->table->insert($slider);
            $newSliderId = $this->table->insertId();
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }

        if (!$newSliderId) {
            return false;
        }

        if ($slider['type'] == 'group') {
            $subSliders = $this->xref->getSliders($id, 'published');

            foreach ($subSliders as $subSlider) {
                $newSubSliderID = $this->duplicate($subSlider['slider_id'], false);
                $this->xref->add($newSliderId, $newSubSliderID);
            }

        } else {

            $slidesModel = new ModelSlides($this);

            foreach ($slidesModel->getAll($id) as $slide) {
                $slidesModel->copyTo($slide['id'], true, $newSliderId);
            }

            if ($withGroup) {
                $groups = $this->xref->getGroups($id);
                foreach ($groups as $group) {
                    $this->xref->add($group['group_id'], $newSliderId);
                }
            }
        }

        $this->reindexOrdering();

        SmartSlider3Info::sliderChanged();

        return $newSliderId;
    }

    public function markChanged($sliderid) {

        $helper = new HelperSliderChanged($this);
        $helper->setSliderChanged($sliderid, 1);
    }

    public function order($groupID, $ids, $isReverse = false, $orders = array()) {

        if (is_array($ids) && count($ids) > 0) {
            if ($isReverse) {
                $ids = array_reverse($ids);
            }
            $groupID = intval($groupID);
            if ($groupID <= 0) {
                $groupID = false;
            }
            if (!empty($orders)) {
                asort($orders);
                $orders = array_values($orders);
            }

            $i = 0;
            foreach ($ids as $id) {
                $id = intval($id);
                if ($id > 0) {
                    if (!$groupID) {
                        if (!empty($orders)) {
                            $order = intval($orders[$i]);
                        } else {
                            $order = $i;
                        }
                        $this->table->update(array(
                            'ordering' => $order,
                        ), array(
                            "id" => $id
                        ));
                    } else {
                        $this->xref->table->update(array(
                            'ordering' => $i,
                        ), array(
                            "slider_id" => $id,
                            "group_id"  => $groupID
                        ));
                    }

                    $i++;
                }
            }

            return $i;
        }

        return false;
    }

    public function reindexOrdering() {
        $sliders = $this->getAll(0);
        foreach ($sliders as $idx => $slider) {
            $this->table->update(array(
                'ordering' => $idx
            ), array(
                "id" => $slider['id']
            ));
        }

    }

    protected function getMaximalOrderValue() {

        $query  = "SELECT MAX(ordering) AS ordering FROM " . $this->getTableName() . "";
        $result = Database::queryRow($query);

        if (isset($result['ordering'])) return $result['ordering'] + 1;

        return 0;
    }
}Model/ModelSlidersXRef.php000064400000013656152356646020011514 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Model;


use Exception;
use Nextend\Framework\Database\Database;
use Nextend\Framework\Model\AbstractModelTable;
use Nextend\SmartSlider3\Application\Helper\HelperSliderChanged;
use Nextend\SmartSlider3\SmartSlider3Info;

class ModelSlidersXRef extends AbstractModelTable {

    protected function createConnectorTable() {

        return Database::getTable('nextend2_smartslider3_sliders_xref');
    }

    public function add($groupID, $sliderID) {
        try {
            $this->table->insert(array(
                'group_id'  => $groupID,
                'slider_id' => $sliderID,
                'ordering'  => $this->getMaximalOrderValue($groupID)
            ));

            $helper = new HelperSliderChanged($this);
            $helper->setSliderChanged($sliderID, 1);
            $helper->setSliderChanged($groupID, 1);

            SmartSlider3Info::sliderChanged();

            return true;
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * @param int $groupID
     *
     * @return array the IDs of the deleted child sliders.
     */
    public function deleteGroup($groupID) {
        $sliders = $this->getSliders($groupID);

        $deletedSliders = array();

        $slidersModel = new ModelSliders($this);
        foreach ($sliders as $slider) {
            $relatedGroups = $this->getGroups($slider['slider_id']);
            if (count($relatedGroups) == 1) {
                if ($slidersModel->trashOrDelete($slider['slider_id'], $groupID) == 'delete') {
                    $deletedSliders[] = $slider['slider_id'];
                }
            }
        }

        $this->table->deleteByAttributes(array(
            'group_id' => $groupID
        ));

        SmartSlider3Info::sliderChanged();

        return $deletedSliders;
    }

    public function deleteSlider($sliderID) {

        $helper = new HelperSliderChanged($this);
        $helper->setSliderChanged($sliderID, 1);

        SmartSlider3Info::sliderChanged();

        return $this->table->deleteByAttributes(array(
            'slider_id' => $sliderID
        ));
    }

    public function deleteXref($groupID, $sliderID) {

        $helper = new HelperSliderChanged($this);
        $helper->setSliderChanged($sliderID, 1);
        $helper->setSliderChanged($groupID, 1);

        SmartSlider3Info::sliderChanged();

        return $this->table->deleteByAttributes(array(
            'group_id'  => $groupID,
            'slider_id' => $sliderID
        ));
    }

    public function getSliders($groupID, $status = '*') {

        if ($status !== '*') {
            $slidersModel = new ModelSliders($this);

            return Database::queryAll("
            SELECT xref.slider_id
            FROM " . $this->getTableName() . " AS xref
            LEFT JOIN " . $slidersModel->getTableName() . " AS sliders ON sliders.id = xref.slider_id
            WHERE xref.group_id = '" . $groupID . "' AND sliders.slider_status LIKE " . Database::quote($status) . "
            ORDER BY xref.ordering ASC");
        }

        return Database::queryAll("
            SELECT slider_id
            FROM " . $this->getTableName() . "
            WHERE group_id = '" . $groupID . "'
            ORDER BY ordering ASC");
    }

    public function getGroupsIDs($sliderID) {
        $ids = array();

        $result = Database::queryAll("
            SELECT group_id
            FROM " . $this->getTableName() . "
            WHERE slider_id = '" . $sliderID . "'
            ORDER BY ordering ASC");

        foreach ($result as $row) {
            $ids[] = $row['group_id'];
        }

        return $ids;
    }

    public function getGroups($sliderID, $status = '*') {
        $slidersModel = new ModelSliders($this);

        $wheres = array("xref.slider_id = '" . $sliderID . "'");

        if ($status !== '*') {
            $wheres[] = "sliders.slider_status LIKE '" . $status . "'";
        }

        $result = Database::queryAll("
            SELECT xref.group_id, sliders.title
            FROM " . $this->getTableName() . " AS xref
            LEFT JOIN " . $slidersModel->getTableName() . " AS sliders ON sliders.id = xref.group_id
            WHERE " . implode(' AND ', $wheres) . "
            ORDER BY xref.group_id ASC");

        if (!empty($result)) {
            return $result;
        }

        return array(
            array(
                "group_id" => 0,
                "title"    => n2_('Dashboard')
            )
        );
    }

    protected function getMaximalOrderValue($groupID) {

        $query  = "SELECT MAX(ordering) AS ordering FROM " . $this->getTableName() . " WHERE group_id = '" . intval($groupID) . "'";
        $result = Database::queryRow($query);

        if (isset($result['ordering'])) return $result['ordering'] + 1;

        return 0;
    }

    /**
     * @param $sliderID
     *
     * @return bool
     */
    public function isSliderAvailableInAnyGroups($sliderID) {
        $allRelatedGroups = $this->getGroups($sliderID);

        $slidersModel = new ModelSliders($this);

        foreach ($allRelatedGroups as $group) {
            if ($group['group_id'] != 0) {
                /*
                 * It is a group
                 */
                $sliderRow = $slidersModel->get($group['group_id']);
                if (isset($sliderRow['slider_status']) && $sliderRow['slider_status'] === 'published') {
                    return true;
                }
            } else {
                /*
                 * It is a slider
                 */
                $sliderRow = $slidersModel->get($sliderID);
                if (isset($sliderRow['slider_status']) && $sliderRow['slider_status'] === 'published') {
                    return true;
                }
            }
        }

        return false;
    }
}Model/ModelSlides.php000064400000056335152356646020010546 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Model;


use Nextend\Framework\Data\Data;
use Nextend\Framework\Database\Database;
use Nextend\Framework\Misc\Base64;
use Nextend\Framework\Misc\Str;
use Nextend\Framework\Model\AbstractModelTable;
use Nextend\Framework\Request\Request;
use Nextend\SmartSlider3\Application\Helper\HelperSliderChanged;
use Nextend\SmartSlider3\Renderable\Component\AbstractComponent;
use Nextend\SmartSlider3\Renderable\Component\ComponentCol;
use Nextend\SmartSlider3\Renderable\Component\ComponentContent;
use Nextend\SmartSlider3\Renderable\Component\ComponentLayer;
use Nextend\SmartSlider3\Renderable\Component\ComponentRow;
use Nextend\SmartSlider3\SlideBuilder\BuilderComponentLayer;
use Nextend\SmartSlider3\SlideBuilder\BuilderComponentSlide;
use Nextend\SmartSlider3\Slider\Slide;
use Nextend\SmartSlider3\Slider\Slider;
use Nextend\SmartSlider3\SmartSlider3Info;
use Nextend\SmartSlider3Pro\Renderable\Component\ComponentGroup;

class ModelSlides extends AbstractModelTable {

    protected function createConnectorTable() {

        return Database::getTable('nextend2_smartslider3_slides');
    }

    public function get($id) {
        return $this->table->findByPk($id);
    }

    public function getAll($sliderid = 0, $where = '') {
        return Database::queryAll('SELECT * FROM ' . $this->getTableName() . ' WHERE slider = ' . $sliderid . ' ' . $where . ' ORDER BY ordering', false, "assoc", null);
    }

    public function createQuickImage($image, $sliderId) {

        $parameters = array(
            'background-type' => 'image',
            'backgroundImage' => $image['image']
        );

        if (!empty($image['alt'])) {
            $parameters['backgroundAlt'] = $image['alt'];
        }

        $slideID = $this->create($sliderId, $image['title'], array(), $image['image'], $parameters, array(
            'description' => $image['description']
        ));
        $this->markChanged($sliderId);

        return $slideID;
    }

    public function createQuickEmptySlide($sliderId) {

        $parameters = array(
            'background-type' => 'color'
        );

        $slideID = $this->create($sliderId, 'Slide', array(), '', $parameters);
        $this->markChanged($sliderId);

        return $slideID;
    }

    public function createQuickStaticOverlay($sliderId) {

        $parameters = array(
            'static-slide' => 1
        );

        $slideID = $this->create($sliderId, n2_('Static overlay'), array(), '', $parameters);
        $this->markChanged($sliderId);

        return $slideID;
    }

    public function createQuickPost($post, $sliderId) {

        $data = new Data($post);

        $title       = $this->removeFourByteChars($data->get('title'));
        $description = $this->removeFourByteChars($data->get('description'));

        $slideBuilder = new BuilderComponentSlide(array(
            'title'                  => $title,
            'description'            => $description,
            'thumbnail'              => $data->get('image'),
            'background-type'        => 'image',
            'backgroundImage'        => $data->get('image'),
            'backgroundImageOpacity' => 20,
            'backgroundColor'        => '000000FF'
        ));

        $slideBuilder->content->set(array(
            'desktopportraitpadding' => '10|*|100|*|10|*|100|*|px',
            'mobileportraitpadding'  => '10|*|10|*|10|*|10|*|px'
        ));

        if ($title) {
            $heading = new BuilderComponentLayer($slideBuilder->content, 'heading');
            $heading->item->set(array(
                'heading' => '{name/slide}',
                'font'    => Base64::encode('{"data":[{"extra":"","color":"ffffffff","size":"48||px","tshadow":"0|*|0|*|0|*|000000ff","afont":"Roboto,Arial","lineheight":"1.5","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"},{"extra":""}]}'),
            ));

        }

        if ($description) {
            $text = new BuilderComponentLayer($slideBuilder->content, 'text');
            $text->set(array(
                'desktopportraitmargin' => '0|*|0|*|20|*|0|*|px',
            ));
            $text->item->set(array(
                'content' => '{description/slide}',
                'font'    => Base64::encode('{"data":[{"extra":"","color":"ffffffff","size":"18||px","tshadow":"0|*|0|*|0|*|000000ff","afont":"Roboto,Arial","lineheight":"1.5","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"},{"extra":""}]}'),
            ));
        }

        $link = $data->get('link');
        if (!empty($link)) {
            $buttonLayer = new BuilderComponentLayer($slideBuilder->content, 'button');
            $buttonLayer->item->set(array(
                'content' => n2_('Read more'),
                'link'    => $link . '|*|_self'
            ));
        }

        $row = $this->convertSlideDataToDatabaseRow($slideBuilder->getData(), $sliderId);

        $slideID = $this->create($row['slider'], $row['title'], $row['slide'], $row['thumbnail'], $row['params'], array(
            'description'  => $row['description'],
            'published'    => $row['published'],
            'publish_up'   => $row['publish_up'],
            'publish_down' => $row['publish_down']
        ));

        $this->markChanged($sliderId);

        return $slideID;
    }

    public function createSimpleEditAdd($postData, $sliderId) {

        $data = new Data($postData);

        $title       = $data->get('title', '');
        $description = $data->get('description', '');

        $slideBuilder = new BuilderComponentSlide(array(
            'title'                  => $title,
            'description'            => $description,
            'thumbnailType'          => $data->get('thumbnailType', ''),
            'thumbnail'              => $data->get('backgroundImage', ''),
            'background-type'        => 'image',
            'backgroundImage'        => $data->get('backgroundImage', ''),
            'backgroundImageOpacity' => 100,
            'backgroundColor'        => '000000FF',
            'href'                   => $data->get('href', ''),
            'href-target'            => $data->get('href-target', '')
        ));

        $slideBuilder->content->set(array(
            'desktopportraitpadding' => '10|*|100|*|10|*|100|*|px',
            'mobileportraitpadding'  => '10|*|10|*|10|*|10|*|px'
        ));

        $videoUrl = $data->get('video', '');

        if (!empty($videoUrl)) {
            preg_match('/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/', $videoUrl, $matches);

            if (!empty($matches)) {
                /**
                 * YouTube
                 */
                $thumbnail = 'https://i.ytimg.com/vi/' . $matches[2] . '/hqdefault.jpg';
                $slideBuilder->set('thumbnail', $thumbnail);


                $youtubeLayer = new BuilderComponentLayer($slideBuilder->content, 'youtube');
                $youtubeLayer->item->set(array(
                    'code'       => $matches[2],
                    'youtubeurl' => $videoUrl,
                    'image'      => $thumbnail
                ));
            } else {

                preg_match('/https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)/', $videoUrl, $matches);
                if (!empty($matches)) {
                    /**
                     * Vimeo
                     */

                    $vimeoLayer = new BuilderComponentLayer($slideBuilder->content, 'vimeo');
                    $vimeoLayer->item->set(array(
                        'vimeourl' => $videoUrl
                    ));
                } else {
                    /**
                     * MP4
                     */

                    $mp4Layer = new BuilderComponentLayer($slideBuilder->content, 'video');
                    $mp4Layer->item->set(array(
                        'video_mp4' => $videoUrl
                    ));
                }
            }
        }

        /*
        if ($title) {
            $heading = new BuilderComponentLayer($slideBuilder->content, 'heading');
            $heading->item->set(array(
                'heading' => '{name/slide}'
            ));
        }
        */

        $row = $this->convertSlideDataToDatabaseRow($slideBuilder->getData(), $sliderId);

        $slideID = $this->create($row['slider'], $row['title'], $row['slide'], $row['thumbnail'], $row['params'], array(
            'description'  => $row['description'],
            'published'    => $row['published'],
            'publish_up'   => $row['publish_up'],
            'publish_down' => $row['publish_down']
        ));

        $this->markChanged($sliderId);

        return $slideID;
    }

    public function import($row, $sliderId) {

        if (!$row['params']->has('version')) {
            /**
             * We must set the missing empty version to allow upgrade of the old slides
             */
            $row['params']->set('version', '');
        }

        return $this->create($sliderId, $row['title'], $row['slide'], $row['thumbnail'], $row['params']->toArray(), array(
            'description'  => $row['description'],
            'published'    => $row['published'],
            'publish_up'   => $row['publish_up'],
            'publish_down' => $row['publish_down'],
            'first'        => $row['first'],
            'ordering'     => $row['ordering'],
            'generator_id' => $row['generator_id']
        ));
    }

    private function create($sliderID, $title, $layers, $thumbnail, $params = array(), $optional = array()) {

        if (!isset($optional['ordering'])) {
            $optional['ordering'] = $this->getNextOrdering($sliderID);
        }

        if (!isset($params['version'])) {
            $params['version'] = SmartSlider3Info::$version;
        }

        $data = array_merge(array(
            'description'  => '',
            'first'        => 0,
            'published'    => 1,
            'publish_up'   => '1970-01-01 00:00:00',
            'publish_down' => '1970-01-01 00:00:00',
            'generator_id' => 0
        ), $optional, array(
            'title'     => $title,
            'slide'     => json_encode($layers, JSON_UNESCAPED_SLASHES),
            'thumbnail' => $thumbnail,
            'params'    => json_encode($params, JSON_UNESCAPED_SLASHES),
            'slider'    => $sliderID
        ));

        $this->table->insert($data);

        return $this->table->insertId();
    }

    /**
     * @param      $sliderId
     * @param int  $generatorID
     * @param      $slide
     *
     * @return bool
     */
    public function createSlideWithGenerator($sliderId, $generatorID, $slide) {

        $row = $this->convertSlideDataToDatabaseRow($slide, $sliderId);

        $slideId = $this->create($row['slider'], $row['title'], $row['slide'], $row['thumbnail'], $row['params'], array(
            'description'  => $row['description'],
            'published'    => $row['published'],
            'publish_up'   => $row['publish_up'],
            'publish_down' => $row['publish_down'],
            'generator_id' => $generatorID
        ));

        $this->markChanged($sliderId);

        return $slideId;
    }

    /**
     * @param int    $slideID
     * @param string $slide
     * @param string $guides
     *
     * @return bool
     */
    public function save($slideID, $slide, $guides) {

        $slideData           = json_decode(Base64::decode($slide), true);
        $slideData['guides'] = $guides;

        $row = $this->convertSlideDataToDatabaseRow($slideData);

        $this->table->update(array(
            'title'        => $row['title'],
            'slide'        => json_encode($row['slide'], JSON_UNESCAPED_SLASHES),
            'description'  => $row['description'],
            'thumbnail'    => $row['thumbnail'],
            'published'    => $row['published'],
            'publish_up'   => $row['publish_up'],
            'publish_down' => $row['publish_down'],
            'params'       => json_encode($row['params'], JSON_UNESCAPED_SLASHES)
        ), array('id' => $slideID));

        $this->markChanged(Request::$REQUEST->getInt('sliderid'));

        return true;
    }

    public function saveSimple($slideID, $title, $description, $params) {

        $this->table->update(array(
            'title'       => $title,
            'description' => $description,
            'params'      => json_encode($params, JSON_UNESCAPED_SLASHES)
        ), array('id' => $slideID));
    }

    /**
     * Updates the params field of the slide;
     *
     * @param $id
     * @param $params
     */
    public function updateSlideParams($id, $params) {

        $this->table->update(array(
            'params' => json_encode($params)
        ), array('id' => $id));

    }

    public function delete($id) {

        $slide = $this->get($id);

        if ($slide['generator_id'] > 0) {
            $slidesWithSameGenerator = $this->getAll($slide['slider'], 'AND generator_id = ' . intval($slide['generator_id']));
            if (count($slidesWithSameGenerator) == 1) {
                $generatorModel = new ModelGenerator($this);
                $generatorModel->delete($slide['generator_id']);
            }
        }

        $this->table->deleteByAttributes(array(
            "id" => intval($id)
        ));

        $this->markChanged($slide['slider']);

    }

    /**
     * @param int      $id
     * @param bool     $maintainOrdering
     * @param bool|int $targetSliderId
     *
     * @return int The new slide ID;
     */
    public function copyTo($id, $maintainOrdering = false, $targetSliderId = false) {
        $row = $this->get($id);
        unset($row['id']);

        $row['first'] = 0;

        if ($targetSliderId === false || $row['slider'] == $targetSliderId) {
            /**
             * Copy the slide to the same slider
             */

            $this->shiftSlideOrdering($row['slider'], $row['ordering']);
        } else {
            /**
             * Copy the slide to another slider
             */
            $row['slider'] = $targetSliderId;

            if (!$maintainOrdering) {
                $row['ordering'] = 0;
            }
        }

        if (!empty($row['generator_id'])) {
            $generatorModel      = new ModelGenerator($this);
            $row['generator_id'] = $generatorModel->duplicate($row['generator_id']);
        }

        $row['slide'] = json_encode(AbstractComponent::translateUniqueIdentifier(json_decode($row['slide'], true)), JSON_UNESCAPED_SLASHES);

        $this->table->insert($row);

        $id = $this->table->insertId();

        $this->markChanged($row['slider']);

        return $id;
    }

    public function setTitle($id, $title) {
        $slide = $this->get($id);

        $this->table->update(array(
            "title" => $title
        ), array(
            "id" => $id
        ));

        $this->markChanged($slide['slider']);
    }

    public function first($id) {
        $slide = $this->get($id);

        $this->table->update(array(
            "first" => 0
        ), array(
            "slider" => $slide['slider']
        ));

        $this->table->update(array(
            "first" => 1
        ), array(
            "id" => $id
        ));

        $this->markChanged($slide['slider']);
    }

    public function publish($id) {

        $this->markChanged(Request::$REQUEST->getInt('sliderid'));

        return $this->table->update(array(
            "published" => 1
        ), array("id" => intval($id)));
    }

    public function unPublish($id) {
        $this->table->update(array(
            "published" => 0
        ), array(
            "id" => intval($id)
        ));

        $this->markChanged(Request::$REQUEST->getInt('sliderid'));

    }

    public function convertToSlide($id) {
        $slide = $this->get($id);

        $data = new Data($slide['params'], true);
        $data->set('static-slide', 0);

        $this->table->update(array(
            "params" => $data->toJSON()
        ), array(
            "id" => intval($id)
        ));

        $this->markChanged($slide['slider']);
    }

    public function deleteBySlider($sliderid) {

        $slides = $this->getAll($sliderid);
        foreach ($slides as $slide) {
            $this->delete($slide['id']);
        }
        $this->markChanged($sliderid);
    }

    /**
     * @param $sliderid
     * @param $ids
     *
     * @return bool|int
     */
    public function order($sliderid, $ids) {
        if (is_array($ids) && count($ids) > 0) {
            $i = 0;
            foreach ($ids as $id) {
                $id = intval($id);
                if ($id > 0) {
                    $this->table->update(array(
                        'ordering' => $i + 1,
                    ), array(
                        "id"     => $id,
                        "slider" => $sliderid
                    ));

                    $i++;
                }
            }

            $this->markChanged($sliderid);

            return $i;
        }

        return false;
    }

    private function markChanged($sliderid) {

        $helper = new HelperSliderChanged($this);
        $helper->setSliderChanged($sliderid, 1);
    }

    public function convertDynamicSlideToSlides($slideId) {
        $slideData = $this->get($slideId);
        if ($slideData['generator_id'] > 0) {
            $sliderObj = new Slider($this, $slideData['slider'], array(), true);
            $rootSlide = new Slide($sliderObj, $slideData);
            $rootSlide->initGenerator(array());
            $slides = $rootSlide->expandSlide();

            $this->shiftSlideOrdering($slideData['slider'], $slideData['ordering'], count($slides));

            $firstUsed = false;
            $i         = 1;
            foreach ($slides as $slide) {
                $row                = $slide->getRow();
                $row['title']       = Str::substr($row['title'], 0, 200);
                $row['description'] = Str::substr($row['description'], 0, 2000);
                // set the proper ordering
                $row['ordering'] += $i;
                if ($row['first']) {
                    // Make sure to mark only one slide as start slide
                    if ($firstUsed) {
                        $row['first'] = 0;
                    } else {
                        $firstUsed = true;
                    }
                }
                $this->table->insert($row);
                $i++;
            }

            Database::query("UPDATE {$this->getTableName()} SET published = 0, first = 0 WHERE id = :id", array(
                ":id" => $slideData['id']
            ));

            return count($slides);
        } else {
            return false;
        }
    }

    public static function prepareSample(&$layers) {
        for ($i = 0; $i < count($layers); $i++) {

            if (isset($layers[$i]['type'])) {
                switch ($layers[$i]['type']) {
                    case 'content':
                        ComponentContent::prepareSample($layers[$i]);
                        break;
                    case 'row':
                        ComponentRow::prepareSample($layers[$i]);
                        break;
                    case 'col':
                        ComponentCol::prepareSample($layers[$i]);
                        break;
                    default:
                        ComponentLayer::prepareSample($layers[$i]);
                }
            } else {
                ComponentLayer::prepareSample($layers[$i]);
            }
        }
    }

    public function convertSlideDataToDatabaseRow($slideData, $sliderID = false) {

        $slideData['version'] = SmartSlider3Info::$version;

        $publish_up = '1970-01-01 00:00:00';
        if (isset($slideData['publish_up'])) {
            if ($slideData['publish_up'] != '0000-00-00 00:00:00') {
                $publish_up = date('Y-m-d H:i:s', strtotime($slideData['publish_up']));
            } else {
                $publish_up = '1970-01-01 00:00:00';
            }
        }

        $publish_down = '1970-01-01 00:00:00';
        if (isset($slideData['publish_down'])) {
            if ($slideData['publish_down'] != '0000-00-00 00:00:00') {
                $publish_down = date('Y-m-d H:i:s', strtotime($slideData['publish_down']));
            } else {
                $publish_down = '1970-01-01 00:00:00';
            }
        }

        $row = array(
            'title'        => $slideData['title'],
            'slide'        => '',
            'description'  => $slideData['description'],
            'thumbnail'    => $slideData['thumbnail'],
            'published'    => (isset($slideData['published']) ? $slideData['published'] : 1),
            'publish_up'   => $publish_up,
            'publish_down' => $publish_down
        );

        if ($sliderID !== false) {
            $row['slider'] = $sliderID;
        }

        $row['slide'] = $slideData['layers'];

        if (isset($slideData['first'])) {
            $row['first'] = intval($slideData['first']);
        }

        if (isset($slideData['generator_id']) && $slideData['generator_id'] > 0) {
            $row['generator_id'] = intval($slideData['generator_id']);
        }

        unset($slideData['title']);
        unset($slideData['layers']);
        unset($slideData['description']);
        unset($slideData['thumbnail']);
        unset($slideData['published']);
        unset($slideData['first']);
        unset($slideData['publish_up']);
        unset($slideData['publish_down']);
        unset($slideData['ordering']);
        unset($slideData['generator_id']);

        $row['params'] = $slideData;

        return $row;
    }

    private function removeFourByteChars($text) {
        return preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $text);
    }

    /**
     * @param int $sliderID
     *
     * @return int
     */
    private function getNextOrdering($sliderID) {

        $query  = "SELECT MAX(ordering) AS ordering FROM " . $this->getTableName() . " WHERE slider = :id";
        $result = Database::queryRow($query, array(
            ":id" => intval($sliderID)
        ));

        if (isset($result['ordering'])) {
            return $result['ordering'] + 1;
        }

        return 1;
    }

    /**
     * @param int $sliderID
     * @param int $offset
     * @param int $slidesCount
     */
    private function shiftSlideOrdering($sliderID, $offset, $slidesCount = 1) {

        // Shift the afterwards slides with the slides count
        Database::query("UPDATE {$this->getTableName()} SET ordering = ordering + " . $slidesCount . " WHERE slider = :sliderid AND ordering > :ordering", array(
            ":sliderid" => intval($sliderID),
            ":ordering" => intval($offset)
        ), '');
    }
}Helper/HelperSliderChanged.php000064400000004321152356646020012341 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Helper;


use Nextend\Framework\Data\Data;
use Nextend\Framework\Model\ApplicationSection;
use Nextend\Framework\Model\StorageSectionManager;
use Nextend\Framework\Pattern\MVCHelperTrait;
use Nextend\SmartSlider3\Application\Model\ModelSliders;
use Nextend\SmartSlider3\Application\Model\ModelSlidersXRef;
use WP_Post;

class HelperSliderChanged {

    use MVCHelperTrait;

    /** @var ApplicationSection */
    protected $storage;

    /**
     * HelperSliderChanged constructor.
     *
     * @param MVCHelperTrait $MVCHelper
     */
    public function __construct($MVCHelper) {

        $this->setMVCHelper($MVCHelper);

        $this->storage = StorageSectionManager::getStorage('smartslider');
    }


    public function isSliderChanged($sliderId, $value = 1) {
        return intval($this->storage->get('sliderChanged', $sliderId, $value));
    }


    public function setGroupChanged($sliderId, $value = 1) {
        $xref     = new ModelSlidersXRef($this);
        $groupIDs = array();
        foreach ($xref->getGroups($sliderId) as $row) {
            if ($row['group_id'] > 0) {
                $this->storage->set('sliderChanged', $row['group_id'], $value);
            }
            $groupIDs[] = $row['group_id'];
        }

        return $groupIDs;

    }

    public function setSliderChanged($sliderId, $value = 1, &$changedSliders = array()) {
        $this->storage->set('sliderChanged', $sliderId, $value);
        $changedSliders[] = $sliderId;

        $xref        = new ModelSlidersXRef($this);
        $sliderModel = new ModelSliders($this);

        array_merge($changedSliders, $this->setGroupChanged($sliderId));

        foreach ($xref->getGroups($sliderId) as $group) {
            $changedSliders[] = $group['group_id'];
        }

        $fallbackSliders = $sliderModel->getFallbackUsage($changedSliders);

        if (!empty($fallbackSliders)) {
            foreach ($fallbackSliders as $slider) {
                if (!in_array($slider['id'], $changedSliders)) {
                    $this->setSliderChanged($slider['id'], 1, $changedSliders);
                }
            }
        }
    }
}Frontend/ApplicationTypeFrontend.php000064400000002005152356646020013647 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Frontend;

use Nextend\Framework\Application\AbstractApplicationType;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\SmartSlider3\Application\Frontend\Slider\ControllerPreRenderSlider;
use Nextend\SmartSlider3\Application\Frontend\Slider\ControllerSlider;

class ApplicationTypeFrontend extends AbstractApplicationType {

    protected $key = 'frontend';

    public function __construct($application) {

        ResourceTranslator::createResource('$system$', self::getAssetsPath(), self::getAssetsUri());

        parent::__construct($application);
    }

    protected function getControllerSlider() {

        return new ControllerSlider($this);
    }

    protected function getControllerPreRenderSlider() {

        return new ControllerPreRenderSlider($this);
    }

    protected function getDefaultController($controllerName, $ajax = false) {
        // TODO: Implement getDefaultController() method.
    }

}Frontend/Slider/ControllerPreRenderSlider.php000064400000001560152356646020015366 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Frontend\Slider;


use Nextend\Framework\Asset\Css\Css;
use Nextend\Framework\Controller\AbstractController;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\Request\Request;

class ControllerPreRenderSlider extends AbstractController {


    public function actionIframe() {

        $sliderIDorAlias = Request::$GET->getVar('sliderid') !== null ? Request::$GET->getVar('sliderid') : false;

        if (empty($sliderIDorAlias)) {
            echo 'Slider ID or alias is empty.';
        } else {
            Css::addStaticGroup(ResourceTranslator::toPath('$ss3-frontend$/dist/normalize.min.css'), 'normalize');


            $view = new ViewIframe($this);

            $view->setSliderIDorAlias($sliderIDorAlias);

            $view->display();
        }
    }
}Frontend/Slider/ControllerSlider.php000064400000000626152356646020013561 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Frontend\Slider;


use Nextend\Framework\Controller\AbstractController;

class ControllerSlider extends AbstractController {

    public function actionDisplay($sliderID, $usage) {

        $view = new ViewDisplay($this);

        $view->setSliderIDorAlias($sliderID);
        $view->setUsage($usage);

        $view->display();
    }
}Frontend/Slider/ViewDisplay.php000064400000002636152356646020012536 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Frontend\Slider;


use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\SliderManager\SliderManager;

class ViewDisplay extends AbstractView {

    /** @var string|integer */
    protected $sliderIDorAlias;

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

    public function display() {

        $this->getApplicationType()
             ->enqueueAssets();

        $locale = setlocale(LC_NUMERIC, 0);
        setlocale(LC_NUMERIC, "C");

        $sliderManager = new SliderManager($this, $this->sliderIDorAlias, false);
        $sliderManager->setUsage($this->usage);

        // PHPCS - Content already escaped
        echo $sliderManager->render(true); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

        setlocale(LC_NUMERIC, $locale);
    }

    /**
     * @return string|integer
     */
    public function getSliderIDorAlias() {
        return $this->sliderIDorAlias;
    }

    /**
     * @param string|integer $sliderIDorAlias
     */
    public function setSliderIDorAlias($sliderIDorAlias) {
        $this->sliderIDorAlias = $sliderIDorAlias;
    }

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

    /**
     * @param string $usage
     */
    public function setUsage($usage) {
        $this->usage = $usage;
    }


}Frontend/Slider/ViewIframe.php000064400000003543152356646020012332 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Frontend\Slider;


use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\SliderManager\SliderManager;

class ViewIframe extends AbstractView {

    /** @var string|integer */
    protected $sliderIDorAlias;

    /**
     * @var integer
     */
    protected $sliderID;

    protected $isGroup = false;

    protected $sliderHTML = '';

    public function display() {

        $this->getApplicationType()
             ->enqueueAssets();

        $locale = setlocale(LC_NUMERIC, 0);
        setlocale(LC_NUMERIC, "C");

        $sliderManager = new SliderManager($this, $this->sliderIDorAlias, false);
        $sliderManager->setUsage('iframe');
        $this->sliderHTML = $sliderManager->render(true);

        $slider = $sliderManager->getSlider();

        if ($slider) {
            $this->sliderID = $slider->sliderId;
            $this->isGroup  = $slider->isGroup();
        }

        setlocale(LC_NUMERIC, $locale);


        // PHPCS - Content already escaped
        echo $this->render('Iframe'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }

    /**
     * @return string|integer
     */
    public function getSliderIDorAlias() {
        return $this->sliderIDorAlias;
    }

    /**
     * @param string|integer $sliderIDorAlias
     */
    public function setSliderIDorAlias($sliderIDorAlias) {
        $this->sliderIDorAlias = $sliderIDorAlias;
    }

    /**
     * @return string already escaped
     */
    public function getSliderHTML() {
        return $this->sliderHTML;
    }

    /**
     * @return int
     */
    public function getSliderID() {
        return $this->sliderID;
    }

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

}Frontend/Slider/Template/Iframe.php000064400000016426152356646020013256 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Frontend\Slider;

use Nextend\Framework\Asset\AssetManager;
use Nextend\Framework\Request\Request;
use Nextend\SmartSlider3\Settings;
use Nextend\WordPress\OutputBuffer;

/**
 * @var ViewIframe $this
 */

?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="robots" content="noindex">
    <title>Slider</title>
    <style>
        html, body {
            overflow: hidden;
        }

        body * {
            background-attachment: scroll !important;
        }
    </style>
    <?php
    /**
     * In page builder -> editors, we must force sliders to be visible on every device.
     */
    if (Request::$GET->getInt('iseditor')):
        ?>
        <script>
            window.ssOverrideHideOn = {
                desktopLandscape: 0,
                desktopPortrait: 0,
                tabletLandscape: 0,
                tabletPortrait: 0,
                mobileLandscape: 0,
                mobilePortrait: 0
            };
        </script>
    <?php
    endif;
    ?>

    <?php


    $handlers = ob_list_handlers();
    if (!in_array(OutputBuffer::class . '::outputCallback', $handlers)) {
        if (class_exists('\\Nextend\\Framework\\Asset\\AssetManager', false)) {

            // PHPCS - Content already escaped
            echo AssetManager::getCSS(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

            // PHPCS - Content already escaped
            echo AssetManager::getJs(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        }
    }

    $externals = esc_attr(Settings::get('external-css-files'));
    if (!empty($externals)) {
        $externals = explode("\n", $externals);
        foreach ($externals as $external) {
            echo "<link rel='stylesheet' href='" . esc_url($external) . "' type='text/css' media='all' />";
        }
    }
    ?>
</head>
<body>
<?php


// PHPCS - Content already escaped
echo $this->getSliderHTML(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
?>
<script>

    _N2.r('windowLoad', function () {
        if (window.n2ss) {
            var body = document.body,
                options = {
                    forceFullWidth: 0,
                    fullPage: 0,
                    focusOffsetTop: '',
                    focusOffsetBottom: '',
                    margin: 0,
                    height: 0
                },
                setOption = function (name, value) {
                    if (options[name] != value) {
                        options[name] = value;
                        parent.postMessage({
                            key: 'option',
                            name: name,
                            value: value
                        }, "*");
                    }
                },
                sliders = [],
                promise = new Promise(function (resolve) {
                    var checkSliders = function () {
                            if (Object.keys(n2ss.sliders).length) {
                                initSliders();
                            } else {
                                setTimeout(checkSliders, 16);
                            }
                        },
                        initSliders = function () {
                            var promises = [];
                            for (var k in n2ss.sliders) {
                                promises.push(new Promise(function (resolve) {
                                    n2ss.ready(k, (function (slider) {
                                        sliders.push(slider);
                                        resolve();
                                    }).bind(this));
                                }));
                            }

                            Promise.all(promises).then(resolve);
                        };

                    checkSliders();
                });

            promise.then(function () {

                if (sliders.length === 1) {
                    var sliderElement = sliders[0].sliderElement,
                        marginElement = sliderElement.closest('.n2-ss-margin');

                    if (marginElement) {
                        var cs = window.getComputedStyle(marginElement);
                        setOption('margin', [cs.marginTop, cs.marginRight, cs.marginBottom, cs.marginLeft].join(' '));
                        marginElement.style.margin = '0';
                    }
                }

                for (var i = 0; i < sliders.length; i++) {
                    var slider = sliders[i];
                    slider.stages.done('ResizeFirst', (function (slider) {
                        if (slider.sliderElement.closest('ss3-force-full-width')) {
                            setOption('forceFullWidth', true);
                        }

                        if (slider.responsive.parameters.type === 'fullpage') {
                            setOption('fullPage', true);
                        }

                        if (sliders.length === 1) {
                            setOption('focusOffsetTop', slider.responsive.parameters.focus.offsetTop);
                            setOption('focusOffsetBottom', slider.responsive.parameters.focus.offsetBottom);
                        }
                    }).bind(this, slider));

                    slider.stages.done('HasDimension', function () {
                        document.querySelectorAll('a:not([target="_parent"]):not([target="_blank"])').forEach(function (a) {
                            a.target = '_parent';
                        });
                    });
                }

                var observer = new ResizeObserver((function (entries) {
                    setOption('height', entries[0].contentRect.height);
                }).bind(this));

                observer.observe(body);
            });

            var interval = setInterval(function () {
                parent.postMessage({key: 'ready'}, "*");
            }, 40);
            window.addEventListener("message", function (e) {
                var data = e.data;
                switch (data["key"]) {
                    case "ackReady":
                        window.n2Height = data.windowInnerHeight;
                        window.n2OffsetTop = 0;
                        window.n2OffsetBottom = 0;
                        clearInterval(interval);

                        document.body.style.setProperty('--target-height', window.n2Height + 'px');
                        break;
                    case 'fullpage':
                        window.n2Height = data.height;
                        window.n2OffsetTop = data.offsetTop;
                        window.n2OffsetBottom = data.offsetBottom;

                        document.body.style.setProperty('--target-height', window.n2Height + 'px');
                        window.dispatchEvent(new Event('resize'));
                        break;
                }
            });

            n2const.setLocation = function (l) {
                parent.postMessage({
                    key: 'setLocation',
                    location: l
                }, "*");
            };
        }
    });
</script>
</body>
</html>


Admin/AbstractControllerAdmin.php000064400000004552152356646020013104 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Controller\Admin\AbstractAdminController;
use Nextend\Framework\Model\StorageSectionManager;
use Nextend\Framework\Platform\Platform;
use Nextend\Framework\Request\Request;
use Nextend\SmartSlider3\Application\Model\ModelSlidersXRef;
use Nextend\SmartSlider3\SmartSlider3Info;

abstract class AbstractControllerAdmin extends AbstractAdminController {

    use TraitAdminUrl;

    public function initialize() {
        parent::initialize();

        Js::addFirstCode('window.ss2lang = {};');

        require_once dirname(__FILE__) . '/JavaScriptTranslation.php';
    }

    public function loadSliderManager() {

        $groupID = Request::$REQUEST->getInt('sliderid', 0);

        $storage = StorageSectionManager::getStorage('smartslider');

        $options = array(
            'userEmail'      => Platform::getUserEmail(),
            'skipNewsletter' => intval($storage->get('free', 'subscribeOnImport')) || intval($storage->get('free', 'dismissNewsletterSampleSliders')),
            'exportAllUrl'   => $this->getUrlDashboardExportAll($groupID),
            'ajaxUrl'        => $this->getAjaxUrlSlidesCreate(),
            'previewUrl'     => $this->getUrlPreviewIndex(0),
            'importUrl'      => $this->getUrlImport($groupID),
            'paginationUrl'  => $this->getUrlPaginator()
        );

        Js::addInline("new _N2.ManageSliders('" . $groupID . "', " . json_encode($options) . ", " . json_encode(SmartSlider3Info::shouldSkipLicenseModal()) . ");");

    }

    public function redirectToSliders() {
        $this->redirect($this->getUrlDashboard());
    }

    /**
     * @param int $sliderID
     *
     * @return bool
     */
    protected function getGroupData($sliderID) {

        $groupID = Request::$REQUEST->getInt('groupID');

        $xref         = new ModelSlidersXRef($this);
        $groups       = $xref->getGroups($sliderID, 'published');
        $currentGroup = false;
        foreach ($groups as $group) {
            if ($group['group_id'] == $groupID) {
                $currentGroup = $group;
                break;
            }
        }
        if ($currentGroup === false) {
            $currentGroup = $groups[0];
        }

        return $currentGroup;
    }
}Admin/ApplicationTypeAdmin.php000064400000014117152356646020012400 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin;


use Exception;
use Nextend\Framework\Application\AbstractApplicationType;
use Nextend\Framework\Asset\Css\Css;
use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Browse\ControllerAjaxBrowse;
use Nextend\Framework\Content\ControllerAjaxContent;
use Nextend\Framework\Font\ControllerAjaxFont;
use Nextend\Framework\Image\ControllerAjaxImage;
use Nextend\Framework\Image\Image;
use Nextend\Framework\Platform\Platform;
use Nextend\Framework\Router\Router;
use Nextend\Framework\Style\ControllerAjaxStyle;
use Nextend\SmartSlider3\Application\Admin\Generator\ControllerAjaxGenerator;
use Nextend\SmartSlider3\Application\Admin\Generator\ControllerGenerator;
use Nextend\SmartSlider3\Application\Admin\GoPro\ControllerGoPro;
use Nextend\SmartSlider3\Application\Admin\Help\ControllerHelp;
use Nextend\SmartSlider3\Application\Admin\Layout\AbstractLayoutMenu;
use Nextend\SmartSlider3\Application\Admin\Preview\ControllerPreview;
use Nextend\SmartSlider3\Application\Admin\Settings\ControllerAjaxSettings;
use Nextend\SmartSlider3\Application\Admin\Settings\ControllerSettings;
use Nextend\SmartSlider3\Application\Admin\Slider\ControllerAjaxSlider;
use Nextend\SmartSlider3\Application\Admin\Slider\ControllerSlider;
use Nextend\SmartSlider3\Application\Admin\Sliders\ControllerAjaxSliders;
use Nextend\SmartSlider3\Application\Admin\Sliders\ControllerSliders;
use Nextend\SmartSlider3\Application\Admin\Slides\ControllerAjaxSlides;
use Nextend\SmartSlider3\Application\Admin\Slides\ControllerSlides;
use Nextend\SmartSlider3\Application\Admin\Update\ControllerUpdate;
use Nextend\SmartSlider3\Application\Admin\Visuals\ControllerAjaxCss;
use Nextend\SmartSlider3\BackgroundAnimation\ControllerAjaxBackgroundAnimation;
use Nextend\SmartSlider3\Platform\Joomla\JoomlaShim;
use Nextend\SmartSlider3\Platform\SmartSlider3Platform;
use Nextend\SmartSlider3\SmartSlider3Info;

class ApplicationTypeAdmin extends AbstractApplicationType {

    use TraitAdminUrl;

    protected $key = 'admin';

    protected function createRouter() {

        $this->router = new Router(SmartSlider3Platform::getAdminUrl(), SmartSlider3Platform::getAdminAjaxUrl(), SmartSlider3Platform::getNetworkAdminUrl());
    }

    public function setLayout($layout) {
        parent::setLayout($layout);

        if ($this->layout instanceof AbstractLayoutMenu) {
            $this->layout->addBreadcrumb(n2_('Dashboard'), 'ssi_16 ssi_16--dashboard', $this->getUrlDashboard());
        }

        Js::addGlobalInline("window.N2SS3VERSION='" . SmartSlider3Info::$version . "';");
    }

    protected function getControllerSliders() {

        return new ControllerSliders($this);
    }

    protected function getControllerAjaxSliders() {

        return new ControllerAjaxSliders($this);
    }

    protected function getControllerSlider() {

        return new ControllerSlider($this);
    }

    protected function getControllerAjaxSlider() {

        return new ControllerAjaxSlider($this);
    }

    protected function getControllerSlides() {

        return new ControllerSlides($this);
    }

    protected function getControllerAjaxSlides() {

        return new ControllerAjaxSlides($this);
    }

    protected function getControllerGenerator() {

        return new ControllerGenerator($this);
    }

    protected function getControllerAjaxGenerator() {

        return new ControllerAjaxGenerator($this);
    }

    protected function getControllerPreview() {

        return new ControllerPreview($this);
    }

    protected function getControllerSettings() {

        return new ControllerSettings($this);
    }

    protected function getControllerAjaxSettings() {

        return new ControllerAjaxSettings($this);
    }

    protected function getControllerHelp() {

        return new ControllerHelp($this);
    }

    protected function getControllerGoPro() {

        return new ControllerGoPro($this);
    }

    protected function getControllerAjaxBackgroundAnimation() {

        return new ControllerAjaxBackgroundAnimation($this);
    }

    protected function getControllerAjaxFont() {

        return new ControllerAjaxFont($this);
    }

    protected function getControllerAjaxStyle() {

        return new ControllerAjaxStyle($this);
    }

    protected function getControllerAjaxCss() {

        return new ControllerAjaxCss($this);
    }

    protected function getControllerAjaxImage() {

        return new ControllerAjaxImage($this);
    }

    protected function getControllerAjaxContent() {

        return new ControllerAjaxContent($this);
    }

    protected function getControllerUpdate() {

        return new ControllerUpdate($this);
    }

    protected function getControllerAjaxBrowse() {

        return new ControllerAjaxBrowse($this);
    }


    protected function getDefaultController($controllerName, $ajax = false) {

        if ($controllerName !== 'sliders') {
            return $this->getControllerSliders();
        }

        throw new Exception('Missing default controller for application type.');
    }

    public function enqueueAssets() {

        Js::addInline('_N2.AjaxHelper.addAdminUrl(' . json_encode($this->getKey()) . ', ' . json_encode($this->createAjaxUrl('/')) . ');');


        JS::addInline('_N2.BrowserCompatibility(' . json_encode($this->getUrlHelpBrowserIncompatible()) . ');');

        parent::enqueueAssets();
        if (Platform::isAdmin()) {
            Js::addGlobalInline('window.N2SS3C="' . SmartSlider3Info::$campaign . '";');
        }
        Js::addGlobalInline('window.N2Joomla4=' . JoomlaShim::$isJoomla4 . ';');
    

        Image::enqueueHelper();

        static $once;
        if ($once != null) {
            return;
        }
        $once = true;

        $path = self::getAssetsPath();

        Css::addStaticGroup($path . '/dist/smartslider-admin.min.css', 'smartslider-admin');

        Js::addStaticGroup($path . '/dist/smartslider-backend.min.js', 'smartslider-backend');
    }
}Admin/JavaScriptTranslation.php000064400000014153152356646020012607 0ustar00<?php

\Nextend\Framework\Localization\Localization::addJS(array("%s or newer required for this feature.","Above %s pixels.","Action","Activate","Activate Smart Slider 3 Pro","Activation is required to unlock all features!","Add animation","Add keyframe","Add Layer","Add post","Adjust","Advanced","Align (Absolute)","All","All layers, all devices","All layers, current device","An event you use to trigger layer animation(s) with","Animated heading","Animation","Animation tab","Are you sure?","Area","Arrows","Audio","Auto","Autoplay duration","Backward","Before After","Below %s pixels.","Between %s and %s pixels.","Block","bottom","Bottom","Boxed","Button","Cancel","Caption","Carousel","Center","Change group","Change slider type","Changing your slider type is irreversible. After changing your slider type, %syou will lose all slider type related settings%s.","Child layers","Choose folder","Choose images","Circle counter","Clean HTML","Clear device specific settings","Clear guides","Close","Column","Content","Content List - One Per Line","Content tab","Convert","Convert to slide","Copy","Copy slide to","Countdown","Counter","Create","Create a New Project","Create group","Create new project","Current layer, all devices","Current layer, current device","Current path","Dashboard","Data","Days","Delete","Delete permanently","delete these slides","delete this slide","delete this slider","Deleted.","Desktop","Direction","Disabled","Done","Drop files here","Duplicate","Edit","Edit generator","Edit Slider","Editor settings","Empty","empty the trash","Enabled","Event name","Examples","Filter","Find image","Find link","Forward","Full page","Full width","General","Go Pro","Go to slide","Go to slide ID","Got it","Group","Group created","Group name","Groups","Guide settings","Heading","Height","Hide on","Highlighted heading","Hours","HTML","Icon","Icon not found","Icons","Iframe","Image","Image area","Image box","Image field can not be empty!","Input","Insert","Insert a slider into your content","Insert group","Join more than 120,000 subscribers and get access to the latest slider templates, tips, tutorials and other exclusive contents directly to your inbox.","Join The Smart Slider 3 Community","Joomla module","Keyboard shortcuts","Keyframe","Landscape","Laptop","Large desktop","Large mobile","Large tablet","Layer","Layer Animation - Basic","Layer Animation - Reveal","Layer design options affect every device. If you need to make responsive adjustments, look for the options with the device icon.","Layer List","Layer(s)","Layout","left","Left","Lightbox","List","Load style","Loop","Loops %s and returns to starting slide.","Loops %s and stops before starting slide.","Margin","Max width","Middle","Minutes","Mobile","Move (Absolute)","Move to trash","My project","Name","Next slide","No","No file selected.","None","Notice","Numeric keys","Off","On","Oops, Something Went Wrong","Open docs","Open/Close","or import your own files","Orientation","Outer %s","Overwrite preset","Padding","Parent","Parent directory","Paste","Pick the align point of the child layer!","Pick the align point of the parent layer!","Pick the parent layer!","Play animations","Please fill the name field!","Please select a Post first!","Portrait","Posts","Preset","Preset deleted.","Preset saved.","Preview","Previous slide","Pro","Progress bar","Project type","Publish","Records","Redo","Register Smart Slider 3 Pro on this domain to enable auto update, slider templates and slide library.","Remove animations","Remove HTML","Remove line breaks","Remove links","Rename","Reset style to default","Respect words","Result","right","Right","Round to 5px","Row","Ruler","Save","Save as","Save as New","Save style as new preset","Saved.","Scroll to","Scroll to alias","Scrolls to the bottom of the page.","Scrolls to the top of the page.","Search","Search keyword","Seconds","Select","Select image","Select Slider","Select the slider you want to insert.","Set","Set as first","Settings","Show/Hide in editor","Showcase","Simple","Size","Skip","Slide","Slide event","Slide height","Slide ID","Slide index","slide index: 2 %s direction: backward","slide index: 5 %s direction: forward","Slide title","Slide width","Slider","Slider alias","Slider alias set at Slider settings > General","Slider type","Smart Slider 3 activated!","Smart snap","Special Zero","Split by Chars","Start a new project from scratch and build exactly what you’ve imagined. You can easily customize every pixels and create anything with layers.","Start with a Template","Start with a template and make it your own with the innovative drag and drop interface. You can choose from hundreds of premade templates.","Static","Strict","Style tab","Subscribe","Success","Switches %s slide(s).","Switches to the %s. slide.","Switches to the fifth slide as if the next arrow was pressed","Switches to the second slide as if the previous arrow was pressed","Switches to the slide with the #2 ID as if the previous arrow was pressed","Switches to the slide with the #5 ID as if the next arrow was pressed","Tablet","Text","Text animation in","Text animation out","The changes you made will be lost if you navigate away from this page.","The deletion is irreversible, and it's not possible to recover %s.","The image is empty","Theme","There is no layer available to be parent of the current layer!","This block is not available in the free version. %s","This section requires activated Pro version.","This slide is hidden on the following devices: %s","Timeline","Titles - One Per Line","top","Top","Top and bottom","Transition","Undo","Unexpected response","Unpublish","Up","Upgrade to Pro","URL","Use default selector","Use Joomla selector","Use our powerful visual editor, or simply import one of our existing template.","Video","View","What do you want to create today?","Width","You can use any jQuery selector to scroll to a specific element on the page. Example: \"#pricing\" scrolls to the element with the id of \"pricing\".","You can use presets to save style settings for later use. Clicking on any preset will load its styling to your current layer, and the previous style settings will be lost.","You have not created any presets for this layer yet.","You're about to %s. "));Admin/TraitAdminUrl.php000064400000040502152356646020011036 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin;

use Joomla\CMS\Uri\Uri;
use Nextend\Framework\Pattern\MVCHelperTrait;

trait TraitAdminUrl {

    /** @var MVCHelperTrait */
    protected $MVCHelper;

    public function getUrlGettingStarted() {

        return $this->createUrl(array(
            "sliders/gettingstarted"
        ));
    }

    public function getUrlGettingStartedDontShow() {

        return $this->createUrl(array(
            "sliders/gettingStartedDontShow"
        ));
    }

    public function getUrlDashboard() {

        return $this->createUrl(array(
            "sliders/index"
        ));
    }

    public function getUrlPaginator() {

        return $this->createAjaxUrl(array(
            'sliders/pagination',
        ));
    }

    public function getUrlDashboardOrderBy($orderBy, $direction, $page = null, $limit = null) {
        $args              = array();
        $args[$orderBy]    = $direction;
        $args['pageIndex'] = $page;
        $args['limit']     = $limit;

        return $this->createAjaxUrl(array(
            'sliders/orderby',
            $args
        ), true);
    }

    public function getUrlDashboardExportAll($groupID) {

        return $this->createUrl(array(
            "sliders/exportAll",
            array(
                'currentGroupID' => $groupID,
                'sliders'        => array()
            )
        ), true);
    }

    public function getAjaxUrlHideReview() {

        return $this->createAjaxUrl(array(
            'sliders/HideReview'
        ));
    }

    public function getUrlHidePromoUpgrade() {

        return $this->createUrl(array(
            'sliders/hidePromoUpgrade'
        ), true);
    }

    /**
     * @return string
     */
    public function getUrlTrash() {

        return $this->createUrl(array(
            "sliders/trash"
        ));
    }

    /**
     * @return string
     */
    public function getUrlImport($groupID = 0) {

        return $this->createUrl(array(
            "sliders/import",
            array(
                'groupID' => $groupID
            )
        ));
    }

    /**
     * @return string
     */
    public function getAjaxUrlImport($groupID = 0) {

        return $this->createAjaxUrl(array(
            "sliders/import",
            array(
                'groupID' => $groupID
            )
        ));
    }

    /**
     * @param int $sliderID
     * @param int $groupID
     *
     * @return string
     */
    public function getUrlSliderEdit($sliderID, $groupID = 0) {

        return $this->createUrl(array(
            "slider/edit",
            array(
                'sliderid' => $sliderID,
                'groupID'  => $groupID
            )
        ));
    }

    public function getAjaxUrlSliderEdit($sliderID) {

        return $this->createAjaxUrl(array(
            "slider/edit",
            array(
                'sliderid' => $sliderID
            )
        ));
    }

    /**
     * @param int $sliderID
     * @param int $groupID
     *
     * @return string
     */
    public function getUrlSliderSimpleEdit($sliderID, $groupID = 0) {

        return $this->createUrl(array(
            "slider/simpleedit",
            array(
                'sliderid' => $sliderID,
                'groupID'  => $groupID
            )
        ));
    }

    /**
     * @param int $sliderID
     * @param int $groupID
     *
     * @return string
     */
    public function getUrlSliderSimpleEditAddSlide($sliderID, $groupID = 0) {

        return $this->createUrl(array(
            "slider/simpleeditaddslide",
            array(
                'sliderid' => $sliderID,
                'groupID'  => $groupID
            )
        ));
    }

    /**
     * @param int $sliderID
     * @param int $groupID
     *
     * @return string
     */
    public function getUrlSliderMoveToTrash($sliderID, $groupID) {
        return $this->createUrl(array(
            'slider/trash',
            array(
                'sliderid' => $sliderID,
                'groupID'  => $groupID
            )
        ), true);
    }

    /**
     * @param int $sliderID
     * @param int $groupID
     *
     * @return string
     */
    public function getUrlSliderDuplicate($sliderID, $groupID) {
        return $this->createUrl(array(
            'slider/duplicate',
            array(
                'sliderid' => $sliderID,
                'groupID'  => $groupID
            )
        ), true);
    }

    /**
     * @param int $sliderID
     *
     * @return string
     */
    public function getUrlSliderExport($sliderID) {
        return $this->createUrl(array(
            'slider/export',
            array(
                'sliderid' => $sliderID
            )
        ), true);
    }

    /**
     * @param int $sliderID
     *
     * @return string
     */
    public function getUrlSliderExportHtml($sliderID) {
        return $this->createUrl(array(
            'slider/exporthtml',
            array(
                'sliderid' => $sliderID
            )
        ), true);
    }

    /**
     * @param int $sliderID
     *
     * @return string
     */
    public function getUrlSliderClearCache($sliderID) {
        return $this->createUrl(array(
            'slider/clearcache',
            array(
                'sliderid' => $sliderID
            )
        ), true);
    }

    /**
     * @param int $sliderID
     *
     * @return string
     */
    public function getUrlPreviewIndex($sliderID) {

        return $this->createUrl(array(
            "preview/index",
            array(
                'sliderid' => $sliderID
            )
        ), true);
    }

    public function getUrlPreviewFull($sliderID) {

        return $this->createUrl(array(
            "preview/full",
            array(
                'sliderid' => $sliderID
            )
        ), true);
    }

    /**
     * @param int         $sliderID
     * @param bool|string $slideID
     *
     * @return string
     */
    public function getUrlPreviewSlider($sliderID, $slideID = false) {
        $args = array(
            'sliderid' => $sliderID
        );
        if ($slideID) {
            $args['slideId'] = $slideID;
        }

        return $this->createUrl(array(
            "preview/slider",
            $args
        ), true);
    }

    /**
     * @param int $generatorID
     *
     * @return string
     */
    public function getUrlPreviewGenerator($generatorID) {

        return $this->createUrl(array(
            "preview/generator",
            array(
                'generator_id' => $generatorID
            )
        ), true);
    }

    public function getUrlSlidesUniversal($sliderID, $groupID) {

        return $this->createUrl(array(
            "slides/index",
            array(
                'groupID'  => $groupID,
                'sliderid' => $sliderID
            )
        ));
    }

    public function getAjaxUrlSlidesUniversal($sliderID, $groupID) {

        return $this->createAjaxUrl(array(
            "slides/index",
            array(
                'groupID'  => $groupID,
                'sliderid' => $sliderID
            )
        ));
    }

    public function getAjaxUrlSlidesCreate() {

        return $this->createAjaxUrl(array(
            "slider/create"
        ));
    }

    public function getUrlSlideEdit($slideID, $sliderID, $groupID) {

        return $this->createUrl(array(
            "slides/edit",
            array(
                'groupID'  => $groupID,
                'sliderid' => $sliderID,
                'slideid'  => $slideID
            )
        ));
    }

    public function getUrlSlidePublish($slideID, $sliderID, $groupID) {

        return $this->createUrl(array(
            "slides/publish",
            array(
                'groupID'  => $groupID,
                'sliderid' => $sliderID,
                'slideid'  => $slideID
            )
        ), true);
    }

    public function getUrlSlideUnPublish($slideID, $sliderID, $groupID) {

        return $this->createUrl(array(
            "slides/unpublish",
            array(
                'groupID'  => $groupID,
                'sliderid' => $sliderID,
                'slideid'  => $slideID
            )
        ), true);
    }

    public function getUrlGeneratorCreate($sliderID, $groupID) {

        return $this->createUrl(array(
            "generator/create",
            array(
                'sliderid' => $sliderID,
                'groupID'  => $groupID
            )
        ));
    }

    /**
     * @param string $generatorGroupName
     * @param int    $sliderID
     * @param int    $groupID
     *
     * @return string
     */
    public function getUrlGeneratorCheckConfiguration($generatorGroupName, $sliderID, $groupID) {

        return $this->createUrl(array(
            "generator/checkConfiguration",
            array(
                'sliderid' => $sliderID,
                'groupID'  => $groupID,
                'group'    => $generatorGroupName
            )
        ));
    }

    /**
     * @param string $generatorGroupName
     * @param int    $sliderID
     * @param int    $groupID
     *
     * @return string
     */
    public function getAjaxUrlGeneratorCheckConfiguration($generatorGroupName, $sliderID, $groupID) {

        return $this->createAjaxUrl(array(
            "generator/checkConfiguration",
            array(
                'sliderid' => $sliderID,
                'groupID'  => $groupID,
                'group'    => $generatorGroupName
            )
        ));
    }

    /**
     * @param string $generatorGroupName
     * @param int    $sliderID
     * @param int    $groupID
     *
     * @return string
     */
    public function getUrlGeneratorCreateStep2($generatorGroupName, $sliderID, $groupID) {

        return $this->createUrl(array(
            "generator/createStep2",
            array(
                'sliderid' => $sliderID,
                'groupID'  => $groupID,
                'group'    => $generatorGroupName
            )
        ));
    }

    /**
     * @param string $generatorGroupName
     * @param string $generatorTypeName
     * @param int    $sliderID
     * @param int    $groupID
     *
     * @return string
     */
    public function getUrlGeneratorCreateSettings($generatorGroupName, $generatorTypeName, $sliderID, $groupID) {

        return $this->createUrl(array(
            "generator/createSettings",
            array(
                'sliderid' => $sliderID,
                'groupID'  => $groupID,
                'group'    => $generatorGroupName,
                'type'     => $generatorTypeName
            )
        ));
    }

    /**
     * @param string $generatorGroupName
     * @param string $generatorTypeName
     * @param int    $sliderID
     * @param int    $groupID
     *
     * @return string
     */
    public function getAjaxUrlGeneratorCreateSettings($generatorGroupName, $generatorTypeName, $sliderID, $groupID) {

        return $this->createAjaxUrl(array(
            "generator/createSettings",
            array(
                'sliderid' => $sliderID,
                'groupID'  => $groupID,
                'group'    => $generatorGroupName,
                'type'     => $generatorTypeName
            )
        ));
    }

    public function getUrlGeneratorEdit($generatorID, $groupID) {

        return $this->createUrl(array(
            "generator/edit",
            array(
                'generator_id' => $generatorID,
                'groupID'      => $groupID
            )
        ));
    }

    public function getAjaxUrlGeneratorEdit($generatorID, $groupID) {

        return $this->createAjaxUrl(array(
            "generator/edit",
            array(
                'generator_id' => $generatorID,
                'groupID'      => $groupID
            )
        ));
    }

    /**
     *
     * @return string
     */
    public function getUrlSettingsDefault() {
        return $this->createUrl(array(
            'settings/default'
        ));
    }

    /**
     *
     * @return string
     */
    public function getAjaxUrlSettingsDefault() {
        return $this->createAjaxUrl(array(
            'settings/default'
        ));
    }

    /**
     *
     * @return string
     */
    public function getUrlSettingsClearCache() {
        return $this->createUrl(array(
            'settings/clearcache',
        ));
    }

    /**
     *
     * @return string
     */
    public function getAjaxUrlSettingsClearCache() {
        return $this->createAjaxUrl(array(
            'settings/clearcache',
        ));
    }

    /**
     *
     * @return string
     */
    public function getUrlSettingsFramework() {
        return $this->createUrl(array(
            'settings/framework'
        ));
    }

    /**
     *
     * @return string
     */
    public function getAjaxUrlSettingsFramework() {
        return $this->createAjaxUrl(array(
            'settings/framework'
        ));
    }

    /**
     *
     * @return string
     */
    public function getUrlSettingsFonts() {
        return $this->createUrl(array(
            'settings/fonts'
        ));
    }

    /**
     *
     * @return string
     */
    public function getAjaxUrlSettingsFonts() {
        return $this->createAjaxUrl(array(
            'settings/fonts'
        ));
    }

    /**
     *
     * @return string
     */
    public function getUrlSettingsItemDefaults() {
        return $this->createUrl(array(
            'settings/itemDefaults'
        ));
    }

    /**
     *
     * @return string
     */
    public function getAjaxUrlSettingsItemDefaults() {
        return $this->createAjaxUrl(array(
            'settings/itemDefaults'
        ));
    }

    /**
     * @param string $generatorName
     *
     * @return string
     */
    public function getUrlSettingsGenerator($generatorName) {
        return $this->createUrl(array(
            'settings/generatorconfigure',
            array(
                'group' => $generatorName
            )
        ));
    }

    public function getAjaxUrlSettingsGenerator($generatorName) {
        return $this->createAjaxUrl(array(
            'settings/generatorconfigure',
            array(
                'group' => $generatorName
            )
        ));
    }

    /**
     *
     * @return string
     */
    public function getUrlHelp() {
        return $this->createUrl(array(
            'help/index'
        ));
    }

    /**
     *
     * @return string
     */
    public function getUrlHelpBrowserIncompatible() {
        return $this->createUrl(array(
            'help/browserincompatible'
        ));
    }

    /**
     *
     * @return string
     */
    public function getUrlHelpTestApi() {
        return $this->createUrl(array(
            'help/testApi'
        ));
    }

    /**
     *
     * @return string
     */
    public function getUrlHelpRepairDatabase() {
        $currentUrl = Uri::getInstance();
        $currentUrl->setVar('repairss3', 1);

        return $currentUrl;
    
    }

    public function getUrlUpdateDownload() {
        return $this->createUrl(array(
            'update/update'
        ), true);
    }

    public function getUrlDeauthorizeLicense() {
        return $this->createUrl(array('license/deauthorize'), true);
    }

    public function getAjaxUrlLicenseAdd() {

        return $this->createAjaxUrl(array(
            'license/add'
        ));
    }

    public function getAjaxUrlImage() {

        return $this->createAjaxUrl(array(
            'image/index'
        ));
    }

    public function getAjaxUrlBrowse() {

        return $this->createAjaxUrl(array(
            'browse/index'
        ));
    }

    public function getAjaxUrlContentSearchContent() {

        return $this->createAjaxUrl(array(
            'content/searchcontent'
        ));
    }

    public function getAjaxUrlSubscribed() {

        return $this->createAjaxUrl(array(
            'settings/subscribed'
        ));
    }
}Admin/Visuals/ControllerAjaxCss.php000064400000005541152356646020013351 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Visuals;


use Nextend\Framework\Controller\Admin\AdminAjaxController;
use Nextend\Framework\Notification\Notification;
use Nextend\Framework\Request\Request;
use Nextend\Framework\Style\ModelCss;

class ControllerAjaxCss extends AdminAjaxController {

    public function getModel() {
        return new ModelCss($this);
    }

    public function actionLoadVisuals() {
        $this->validateToken();


        $type = Request::$REQUEST->getCmd('type');
        $this->validateVariable(!empty($type), 'type');

        $model   = $this->getModel();
        $visuals = $model->getVisuals($type);
        if (is_array($visuals)) {
            $this->response->respond(array(
                'visuals' => $visuals
            ));
        }

        Notification::error(n2_('Unexpected error'));
        $this->response->error();
    }

    public function actionAddVisual() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $type = Request::$REQUEST->getCmd('type');
        $this->validateVariable(!empty($type), 'type');

        $model = $this->getModel();

        if (($visual = $model->addVisual($type, Request::$REQUEST->getVar('value')))) {
            $this->response->respond(array(
                'visual' => $visual
            ));
        }

        Notification::error(n2_('Not editable'));
        $this->response->error();
    }

    public function actionDeleteVisual() {
        $this->validateToken();

        $this->validatePermission('smartslider_delete');

        $type = Request::$REQUEST->getCmd('type');
        $this->validateVariable(!empty($type), 'type');

        $visualId = Request::$REQUEST->getInt('visualId');
        $this->validateVariable($visualId > 0, 'visual');

        $model = $this->getModel();

        if (($visual = $model->deleteVisual($type, $visualId))) {
            $this->response->respond(array(
                'visual' => $visual
            ));
        }

        Notification::error(n2_('Not editable'));
        $this->response->error();
    }

    public function actionChangeVisual() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $type = Request::$REQUEST->getCmd('type');
        $this->validateVariable(!empty($type), 'type');

        $visualId = Request::$REQUEST->getInt('visualId');
        $this->validateVariable($visualId > 0, 'visual');

        $model = $this->getModel();

        if (($visual = $model->changeVisual($type, $visualId, Request::$REQUEST->getVar('value')))) {
            $this->response->respond(array(
                'visual' => $visual
            ));
        }

        Notification::error(n2_('Unexpected error'));
        $this->response->error();
    }
}Admin/Update/ControllerUpdate.php000064400000000761152356646020013032 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Update;


use Joomla\CMS\Router\Route;
use Nextend\SmartSlider3\Application\Admin\AbstractControllerAdmin;

class ControllerUpdate extends AbstractControllerAdmin {

    public function actionUpdate() {
        if ($this->validateToken()) {
            header('LOCATION: ' . Route::_('index.php?option=com_installer&view=update', false));
            exit;
        
        }

        $this->redirectToSliders();
    }
}Admin/Slides/ControllerAjaxSlides.php000064400000027420152356646020013641 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Slides;


use Nextend\Framework\Controller\Admin\AdminAjaxController;
use Nextend\Framework\Filesystem\Filesystem;
use Nextend\Framework\Misc\Base64;
use Nextend\Framework\Notification\Notification;
use Nextend\Framework\Request\Request;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Application\Model\ModelSliders;
use Nextend\SmartSlider3\Application\Model\ModelSlides;
use Nextend\SmartSlider3\Settings;
use Nextend\SmartSlider3\Slider\Feature\Optimize;
use Nextend\SmartSlider3\Slider\Slide;
use Nextend\SmartSlider3\Slider\Slider;

class ControllerAjaxSlides extends AdminAjaxController {

    use TraitAdminUrl;

    public function actionEdit() {
        $this->validateToken();
        $this->validatePermission('smartslider_edit');

        $groupID = Request::$REQUEST->getInt('groupID', 0);
        $this->validateVariable($groupID >= 0, 'groupID');

        $slidersModel = new ModelSliders($this);
        $sliderId     = Request::$REQUEST->getInt('sliderid');
        $slider       = $slidersModel->get($sliderId);

        $this->validateDatabase($slider);

        $slidesModel = new ModelSlides($this);
        $this->validateDatabase($slidesModel->get(Request::$REQUEST->getInt('slideid')));

        $response = array();

        $file = Request::$FILES->getVar('slide');
        if (Settings::get('slide-as-file', 0) && $file !== null) {
            $slide = Filesystem::readFile($file['tmp_name']);
        } else {
            $slide = Request::$REQUEST->getVar('slide');
        }

        $guides = Request::$REQUEST->getVar('guides');

        if ($slidesModel->save(Request::$REQUEST->getInt('slideid'), $slide, $guides)) {
            Notification::success(n2_('Slide saved.'));

            if (Request::$REQUEST->getInt('generatorStatic') == 1) {
                $slideCount = $slidesModel->convertDynamicSlideToSlides(Request::$REQUEST->getInt('slideid'));
                if ($slideCount) {
                    Notification::success(sprintf(n2_('%d static slides generated.'), $slideCount));

                    $this->response->redirect($this->getUrlSliderEdit($sliderId, $groupID));
                }
            }
        }
        $this->response->respond($response);
    }

    public function actionRename() {
        $this->validateToken();
        $this->validatePermission('smartslider_edit');

        $slideID = Request::$REQUEST->getInt('slideid');
        $this->validateVariable($slideID > 0, 'Slide');

        $title = Request::$REQUEST->getVar('title');

        $slidersModel = new ModelSlides($this);
        $slidersModel->setTitle($slideID, $title);

        Notification::success(n2_('Slide renamed.'));

        $this->response->respond();
    }

    public function actionFirst() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $slideId = Request::$REQUEST->getInt('id');
        $this->validateVariable($slideId > 0, 'Slide id');

        $slidesModel = new ModelSlides($this);
        $slidesModel->first($slideId);
        Notification::success(n2_('First slide changed.'));

        $this->response->respond();
    }

    public function actionConvertToSlide() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $slideId = Request::$REQUEST->getInt('slideid');
        $this->validateVariable($slideId > 0, 'Slide id');

        $slidesModel = new ModelSlides($this);
        $slidesModel->convertToSlide($slideId);

        Notification::success(n2_('Static overlay converted to slide.'));

        $this->response->respond();
    }

    public function actionPublish() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $ids = array_map('intval', array_filter((array)Request::$REQUEST->getVar('slides'), 'is_numeric'));

        $this->validateVariable(count($ids), 'Slides');

        $slidesModel = new ModelSlides($this);
        foreach ($ids as $id) {
            if ($id > 0) {
                $slidesModel->publish($id);
            }
        }
        Notification::success(n2_('Slide published.'));
        $this->response->respond();
    }

    public function actionUnPublish() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $ids = array_map('intval', array_filter((array)Request::$REQUEST->getVar('slides'), 'is_numeric'));
        $this->validateVariable(count($ids), 'Slides');

        $slidesModel = new ModelSlides($this);
        foreach ($ids as $id) {
            if ($id > 0) {
                $slidesModel->unPublish($id);
            }
        }
        Notification::success(n2_('Slide unpublished.'));
        $this->response->respond();
    }

    public function actionOrder() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $sliderid = Request::$REQUEST->getInt('sliderid');
        $this->validateVariable($sliderid > 0, 'Slider');

        $slidesModel = new ModelSlides($this);

        $result = $slidesModel->order($sliderid, Request::$REQUEST->getVar('slideorder'));
        $this->validateDatabase($result);

        Notification::success(n2_('Slide order saved.'));
        $this->response->respond();
    }

    public function actionCopy() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $groupID = Request::$REQUEST->getInt('targetGroupID', 0);
        $this->validateVariable($groupID >= 0, 'targetGroupID');

        $slideId = Request::$REQUEST->getInt('slideid');
        $this->validateVariable($slideId > 0, 'Slide');

        $sliderID = Request::$REQUEST->getInt('targetSliderID');
        $this->validateVariable($sliderID > 0, 'Slider ID');

        $slidesModel = new ModelSlides($this);
        $newSlideId  = $slidesModel->copyTo($slideId, false, $sliderID);
        $slide       = $slidesModel->get($newSlideId);

        $this->validateDatabase($slide);

        Notification::success(n2_('Slide(s) copied.'));


        $this->response->redirect($this->getUrlSliderEdit($sliderID, $groupID));
    }

    public function actionCopySlides() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $groupID = Request::$REQUEST->getInt('targetGroupID', 0);
        $this->validateVariable($groupID >= 0, 'targetGroupID');

        $ids = array_map('intval', array_filter((array)Request::$REQUEST->getVar('slides'), 'is_numeric'));

        $this->validateVariable(count($ids), 'Slides');

        $sliderID = Request::$REQUEST->getInt('targetSliderID');
        $this->validateVariable($sliderID > 0, 'Slider ID');

        $slidesModel = new ModelSlides($this);
        foreach ($ids as $id) {
            $slidesModel->copyTo($id, false, $sliderID);
        }
        Notification::success(n2_('Slide(s) copied.'));

        $this->response->redirect($this->getUrlSliderEdit($sliderID, $groupID));
    }

    public function actionDuplicate() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $groupID = Request::$REQUEST->getInt('groupID');
        $this->validateVariable($groupID >= 0, 'groupID');

        $slideId = Request::$REQUEST->getInt('slideid');
        $this->validateVariable($slideId > 0, 'Slide');

        $slidesModel = new ModelSlides($this);
        $newSlideId  = $slidesModel->copyTo($slideId);
        $slide       = $slidesModel->get($newSlideId);

        $this->validateDatabase($slide);

        Notification::success(n2_('Slide duplicated.'));

        $sliderObj = new Slider($this, $slide['slider'], array(), true);
        $sliderObj->initSlider();
        $optimize = new Optimize($sliderObj);

        $slideObj = new Slide($sliderObj, $slide);
        $slideObj->initGenerator();
        $slideObj->fillSample();

        $view = new ViewAjaxSlideBox($this);
        $view->setGroupID($groupID);
        $view->setSlider($sliderObj);
        $view->setSlide($slideObj);
        $view->setOptimize($optimize);

        $this->response->respond($view->display());
    }


    public function actionDelete() {
        $this->validateToken();

        $this->validatePermission('smartslider_delete');

        $ids = array_map('intval', array_filter((array)Request::$REQUEST->getVar('slides'), 'is_numeric'));

        $this->validateVariable(count($ids), 'Slide');

        $slidesModel = new ModelSlides($this);
        foreach ($ids as $id) {
            if ($id > 0) {
                $slidesModel->delete($id);
            }
        }
        Notification::success(n2_('Slide deleted.'));
        $this->response->respond();
    }

    public function actionCreate() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $type = Request::$REQUEST->getVar('type');

        $groupID = Request::$REQUEST->getInt('groupID');
        $this->validateVariable($groupID >= 0, 'groupID');

        $sliderId = Request::$REQUEST->getInt('sliderid');
        $this->validateVariable($sliderId > 0, 'Slider');

        $slidesModel = new ModelSlides($this);

        $createdSlidesID = array();
        switch ($type) {
            case 'image':
                $images = json_decode(Base64::decode(Request::$REQUEST->getVar('images')), true);
                $this->validateVariable(count($images), 'Images');
                foreach ($images as $image) {
                    $createdSlidesID[] = $slidesModel->createQuickImage($image, $sliderId);
                }
                break;
            case 'empty-slide':
                $createdSlidesID[] = $slidesModel->createQuickEmptySlide($sliderId);
                break;
            case 'video':
                $video = json_decode(urldecode(Base64::decode(Request::$REQUEST->getVar('video'))), true);
                $this->validateVariable($video, 'Video');

                $createdSlidesID[] = $slidesModel->createQuickVideo($video, $sliderId);
                break;
            case 'post':
                $post = Request::$REQUEST->getVar('post');
                $this->validateVariable($post, 'Post');

                $createdSlidesID[] = $slidesModel->createQuickPost($post, $sliderId);
                break;
            case 'static-overlay':
                $createdSlidesID[] = $slidesModel->createQuickStaticOverlay($sliderId);
                break;
        }

        if (!empty($createdSlidesID)) {

            $sliderObj = new Slider($this, $sliderId, array());
            $sliderObj->initSlider();
            $optimize = new Optimize($sliderObj);

            $responseBody = '';
            foreach ($createdSlidesID as $slideID) {
                $slide = $slidesModel->get($slideID);

                $slideObj = new Slide($sliderObj, $slide);
                $slideObj->initGenerator();
                $slideObj->fillSample();

                $view = new ViewAjaxSlideBox($this);
                $view->setGroupID($groupID);
                $view->setSlider($sliderObj);
                $view->setSlide($slideObj);
                $view->setOptimize($optimize);

                $responseBody .= $view->display();
            }

            if (count($createdSlidesID) > 1) {
                Notification::success(n2_('Slides created.'));
            } else {
                Notification::success(n2_('Slide created.'));
            }

            $this->response->respond($responseBody);
        } else {

            Notification::error(n2_('Failed to create slides.'));
            $this->response->respond();
        }
    }
}Admin/Slides/ControllerSlides.php000064400000006107152356646020013034 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Slides;


use Nextend\Framework\Notification\Notification;
use Nextend\Framework\Request\Request;
use Nextend\SmartSlider3\Application\Admin\AbstractControllerAdmin;
use Nextend\SmartSlider3\Application\Model\ModelSliders;
use Nextend\SmartSlider3\Application\Model\ModelSlides;
use Nextend\SmartSlider3\SmartSlider3Info;

class ControllerSlides extends AbstractControllerAdmin {

    public function initialize() {
        parent::initialize();

        SmartSlider3Info::$forceDesktop    = true;
        SmartSlider3Info::$forceAllDevices = true;
    }

    public function actionEdit() {
        if ($this->validatePermission('smartslider_edit')) {
            $slidersModel = new ModelSliders($this);

            $sliderID = Request::$REQUEST->getInt('sliderid');
            $slider   = $slidersModel->get($sliderID);

            if ($this->validateDatabase($slider, false)) {

                $slidesModel = new ModelSlides($this);

                $slideID = Request::$REQUEST->getInt('slideid');
                $slide   = $slidesModel->get($slideID);

                if ($slide) {

                    $groupData = $this->getGroupData($sliderID);

                    $view = new ViewSlidesEdit($this);
                    $view->setGroupData($groupData['group_id'], $groupData['title']);
                    $view->setSlider($slider);
                    $view->setSlide($slide);
                    $view->display();
                } else {

                    $this->redirect($this->getUrlDashboard());
                }
            } else {

                $this->redirect($this->getUrlDashboard());
            }
        }
    }

    public function actionDelete() {
        if ($this->validateToken() && $this->validatePermission('smartslider_delete')) {
            if ($slideId = Request::$REQUEST->getInt('slideid')) {
                $slidesModel = new ModelSlides($this);
                $slidesModel->delete($slideId);
            }

            $sliderId = Request::$REQUEST->getInt("sliderid");
            if ($sliderId) {
                $groupData = $this->getGroupData($sliderId);
                $this->redirect($this->getUrlSliderEdit($sliderId, $groupData['group_id']));
            }

            $this->redirect($this->getUrlDashboard());
        }
    }

    public function actionDuplicate() {
        if ($this->validateToken() && $this->validatePermission('smartslider_edit')) {
            if ($slideId = Request::$REQUEST->getInt('slideid')) {
                $slidesModel = new ModelSlides($this);
                $newSlideId  = $slidesModel->copyTo($slideId);

                Notification::success(n2_('Slide duplicated.'));

                $sliderID = Request::$REQUEST->getInt("sliderid");

                $groupData = $this->getGroupData($sliderID);

                $this->redirect($this->getUrlSlideEdit($newSlideId, $sliderID, $groupData['group_id']));
            }

            $this->redirect($this->getUrlDashboard());
        }
    }
}Admin/Slides/ViewAjaxSlideBox.php000064400000003566152356646020012723 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Slides;


use Nextend\Framework\View\AbstractViewAjax;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\SlideBox\BlockSlideBox;
use Nextend\SmartSlider3\Slider\Feature\Optimize;
use Nextend\SmartSlider3\Slider\Slide;
use Nextend\SmartSlider3\Slider\Slider;

class ViewAjaxSlideBox extends AbstractViewAjax {

    protected $groupID = 0;

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

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

    /** @var Optimize */
    protected $optimize;

    public function display() {

        return $this->render('AjaxSlideBox');
    }

    public function renderSlideBlock() {

        $blockSlideBox = new BlockSlideBox($this);

        $blockSlideBox->setGroupID($this->groupID);
        $blockSlideBox->setSlider($this->slider);
        $blockSlideBox->setSlide($this->slide);
        $blockSlideBox->setOptimize($this->optimize);

        $blockSlideBox->display();
    }

    /**
     * @param int $groupID
     */
    public function setGroupID($groupID) {
        $this->groupID = $groupID;
    }

    /**
     * @return Slider
     */
    public function getSlider() {
        return $this->slider;
    }

    /**
     * @param Slider $slider
     */
    public function setSlider($slider) {
        $this->slider = $slider;
    }

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

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

    /**
     * @return Optimize
     */
    public function getOptimize() {
        return $this->optimize;
    }

    /**
     * @param Optimize $optimize
     */
    public function setOptimize($optimize) {
        $this->optimize = $optimize;
    }
}Admin/Slides/ViewSlidesEdit.php000064400000022725152356646020012435 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Slides;


use Nextend\Framework\Request\Request;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\FormManager\FormManagerSlide;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header\BlockHeader;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarGroup\BlockTopBarGroup;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButton;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonBack;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonPlainIcon;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonSave;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonSpacer;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\AddLayer\BlockAddLayer;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\EditorOverlay\BlockEditorOverlay;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\BlockLayerWindow;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\SlideManager\BlockSlideManager;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\DeviceZoom\BlockDeviceZoom;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutEditor;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Application\Model\ModelSlides;
use Nextend\SmartSlider3\Slider\Admin\AdminSlider;
use Nextend\SmartSlider3\Slider\Slider;

class ViewSlidesEdit extends AbstractView {

    use TraitAdminUrl;

    /** @var LayoutEditor */
    protected $layout;

    /**
     * @var BlockEditorOverlay
     */
    protected $editorOverlay;

    /** @var ModelSlides */
    protected $model;

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

    /**
     * @var string contains already escaped data
     */
    protected $renderedSlider;

    protected $groupID = 0;

    protected $groupTitle = '';

    protected $slider;

    protected $slide = false;

    /**
     * @var BlockHeader
     */
    protected $blockHeader;

    /**
     * @var FormManagerSlide
     */
    protected $formManager;

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

        $this->model = new ModelSlides($this);

    }

    public function display() {

        $locale = setlocale(LC_NUMERIC, 0);
        setlocale(LC_NUMERIC, "C");

        $this->layout = new LayoutEditor($this);

        $this->editorOverlay = new BlockEditorOverlay($this);
        $this->layout->setEditorOverlay($this->editorOverlay);

        $this->frontendSlider = new AdminSlider($this->MVCHelper, Request::$GET->getInt('sliderid'), array(
            'disableResponsive' => true
        ));
        $this->frontendSlider->setEditedSlideID($this->getSlideID());
        $this->frontendSlider->initSlider();
        $this->frontendSlider->initSlides();

        /**
         * Layer window should be rendered before the slider render as layers items might add CSS and JS codes to it.
         */
        $layerWindowBlock = new BlockLayerWindow($this);
        $layerWindowBlock->setRenderableAdminSlider($this->frontendSlider);
        $this->editorOverlay->setContentLayerWindow($layerWindowBlock->toHTML());

        $this->frontendSlider->initAll();
        $this->frontendSlider->addScript('new _N2.DeviceChanger(this);');
        $this->renderedSlider = $this->frontendSlider->render();

        $this->formManager = new FormManagerSlide($this, $this->groupID, $this->frontendSlider, $this->slide);

        $this->layout->addBreadcrumb(n2_('Dashboard'), 'ssi_16 ssi_16--dashboard', $this->getUrlDashboard());

        if ($this->groupID) {
            $this->layout->addBreadcrumb(Sanitize::esc_html($this->groupTitle), 'ssi_16 ssi_16--folderclosed', $this->getUrlSliderEdit($this->groupID));
        }

        $this->layout->addBreadcrumb(Sanitize::esc_html($this->slider['title']), 'ssi_16 ssi_16--image', $this->getUrlSliderEdit($this->slider['id'], $this->groupID));

        $this->addActiveBreadcrumb();

        if (!empty($this->slide['generator_id'])) {
            $this->layout->addBreadcrumb(n2_('Generator'), 'ssi_16 ssi_16--cog', $this->getUrlGeneratorEdit($this->slide['generator_id'], $this->groupID));
        }


        $slideManager = new BlockSlideManager($this);
        $slideManager->setGroupID($this->groupID);
        $slideManager->setSliderID($this->slider['id']);
        $slideManager->setBreadcrumbOpener(true);

        $this->editorOverlay->setSlideManager($slideManager);


        $this->renderTopBar();

        $blockAddLayer = new BlockAddLayer($this);
        $blockAddLayer->setSliderType($this->frontendSlider->data->get('type'));

        $this->editorOverlay->setBlockAddLayer($blockAddLayer);

        $this->layout->addContent($this->render('Edit'));

        $this->renderLayout();

        setlocale(LC_NUMERIC, $locale);
    }

    protected function renderLayout() {

        $this->layout->render();
    }

    protected function addActiveBreadcrumb() {

        $breadCrumb = $this->layout->addBreadcrumb(n2_('Slides') . '<i class="ssi_16 ssi_16--selectarrow"></i>', 'ssi_16 ssi_16--slides', '#');

        $breadCrumb->addClass('n2_nav_bar__breadcrumb_button_slides');
        $breadCrumb->setIsActive(true);
    }

    private function renderTopBar() {

        $topBar = $this->editorOverlay->getTopBar();

        $buttonSave = new BlockButtonSave($this);
        $buttonSave->addClass('n2_button--inactive');
        $buttonSave->addClass('n2_slide_settings_save');
        $topBar->addPrimaryBlock($buttonSave);

        $buttonBack = new BlockButtonBack($this);
        $buttonBack->setUrl($this->getUrlSliderEdit($this->getSliderID(), $this->groupID));
        $buttonBack->addClass('n2_slide_settings_back');
        $topBar->addPrimaryBlock($buttonBack);

        if ($this->slide && $this->slide['generator_id'] > 0) {
            $buttonStaticSave = new BlockButton($this);
            $buttonStaticSave->setLabel(n2_('Static save'));
            $buttonStaticSave->addClass('n2_slide_generator_static_save');
            $topBar->addPrimaryBlock($buttonStaticSave);
        }

        $narrowGroup = new BlockTopBarGroup($this);
        $narrowGroup->setNarrow();

        $buttonRedo = new BlockButtonPlainIcon($this);
        $buttonRedo->addClass('n2_top_bar_button_icon');
        $buttonRedo->addClass('n2_ss_history_action');
        $buttonRedo->addClass('n2_ss_history_action--redo');
        $buttonRedo->setIcon('ssi_24 ssi_24--redo');
        $buttonRedo->addAttribute('data-n2tip', n2_('Redo'));
        $buttonRedo->addAttribute('data-n2tipv', -20);
        $narrowGroup->addBlock($buttonRedo);

        $buttonUndo = new BlockButtonPlainIcon($this);
        $buttonUndo->addClass('n2_top_bar_button_icon');
        $buttonUndo->addClass('n2_ss_history_action');
        $buttonUndo->addClass('n2_ss_history_action--undo');
        $buttonUndo->setIcon('ssi_24 ssi_24--undo');
        $buttonUndo->addAttribute('data-n2tip', n2_('Undo'));
        $buttonUndo->addAttribute('data-n2tipv', -20);
        $narrowGroup->addBlock($buttonUndo);

        $topBar->addPrimaryBlock($narrowGroup);

        $spacer = new BlockButtonSpacer($this);
        $spacer->setIsVisible(true);
        $topBar->addPrimaryBlock($spacer);

        $deviceZoom = new BlockDeviceZoom($this);
        $topBar->addPrimaryBlock($deviceZoom);

        $buttonPreview = new BlockButtonPlainIcon($this);
        $buttonPreview->addAttribute('id', 'n2-ss-preview');
        $buttonPreview->addClass('n2_top_bar_button_icon');
        $buttonPreview->addClass('n2_top_bar_main__preview');
        $buttonPreview->setIcon('ssi_24 ssi_24--preview');
        $buttonPreview->addAttribute('data-n2tip', n2_('Preview'));
        $buttonPreview->setUrl($this->getUrlPreviewIndex($this->getSliderID()));
        $topBar->addPrimaryBlock($buttonPreview);

    }

    public function getModel() {

        return $this->model;
    }

    /**
     * @param int    $groupID
     * @param string $groupTitle
     */
    public function setGroupData($groupID, $groupTitle) {
        $this->groupID    = $groupID;
        $this->groupTitle = $groupTitle;
    }

    public function getSliderID() {
        return $this->slider['id'];
    }

    /**
     * @param array $slider
     */
    public function setSlider($slider) {
        $this->slider = $slider;
    }

    /**
     * @param array $slide
     */
    public function setSlide($slide) {
        $this->slide = $slide;
    }

    public function getSlideID() {

        return $this->slide['id'];
    }

    public function getAjaxUrl() {
        if ($this->slide) {
            return $this->createAjaxUrl(array(
                'slides/edit',
                array(
                    'groupID'  => $this->groupID,
                    'sliderid' => $this->getSliderID(),
                    'slideid'  => $this->getSlideID()
                )
            ));
        }

        return $this->createAjaxUrl(array(
            'slides/create',
            array(
                'groupID'  => $this->groupID,
                'sliderid' => $this->getSliderID(),
                'slideid'  => $this->getSlideID()
            )
        ));
    }
}Admin/Slides/Template/AjaxSlideBox.php000064400000000215152356646020013627 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Slides;

/**
 * @var $this ViewAjaxSlideBox
 */


$this->renderSlideBlock();Admin/Slides/Template/Edit.php000064400000006567152356646020012217 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Slides;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Platform\Platform;
use Nextend\Framework\Request\Request;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Application\Model\ModelLicense;
use Nextend\SmartSlider3\Settings;
use Nextend\SmartSlider3\SmartSlider3Info;
use Nextend\SmartSlider3Pro\LayerAnimation\LayerAnimationStorage;

/**
 * @var $this ViewSlidesEdit
 */


JS::addGlobalInline('document.documentElement.classList.add("n2_html--application-only");');
Js::addGlobalInline("window.ss3LayerAnimationPresets=" . LayerAnimationStorage::getInstance()
                                                                              ->getData() . ";");


$externals = esc_attr(Settings::get('external-css-files'));
if (!empty($externals)) {
    $externals = explode("\n", $externals);
    foreach ($externals as $external) {
        echo "<link rel='stylesheet' href='" . esc_url($external) . "' type='text/css' media='all'>";
    }
}


$slider = $this->frontendSlider;

$renderedSlider = $this->renderedSlider;
?>

    <form id="n2-ss-form-slide-edit" action="#" method="post">
        <?php
        $this->formManager->render();
        ?>
    </form>

    <div id='n2-ss-slide-canvas-container' class='n2_slide_editor_slider'>
        <div class="n2_slide_editor_slider__editor" style="width: <?php esc_attr($slider->features->responsive->sizes['desktopPortrait']['width']); ?>px">
            <div class="n2_slide_editor_slider__editor_inner">
                <?php
                // PHPCS - Content already escaped
                echo $renderedSlider; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
                ?>
            </div>
        </div>
    </div>

    <?php

$fillMode = $slider->params->get('backgroundMode', 'fill');
if ($fillMode == 'fixed' || $fillMode == 'tile') {
    $fillMode = 'fill';
}

$options = array(
    'isUploadDisabled'    => defined('N2_IMAGE_UPLOAD_DISABLE'),
    'slideBackgroundMode' => $fillMode,
    'settingsGoProUrl'    => SmartSlider3Info::getProUrlPricing(array(
        'utm_source'   => 'go-pro-button-editor-settings',
        'utm_medium'   => 'smartslider-' . Platform::getName() . '-' . SmartSlider3Info::$plan,
        'utm_campaign' => SmartSlider3Info::$campaign
    ))
);
if (!defined('N2_IMAGE_UPLOAD_DISABLE')) {
    $options['uploadUrl'] = $this->createAjaxUrl(array('browse/upload'));
    $options['uploadDir'] = 'slider' . $slider->sliderId;
}
if (ModelLicense::getInstance()
                ->maybeActiveLazy()) {
    $options['sectionLibraryFree'] = false;
    $options['sectionLibraryUrl']  = 'https://smartslider3.com/slides/v2/pro2e4G2dR';
} else {
    $options['sectionLibraryUrl'] = 'https://smartslider3.com/slides/v2/free';
}


JS::addInline('new _N2.SlideEdit(' . json_encode(array(
        'ajaxUrl'            => $this->getAjaxUrl(),
        'slideAsFile'        => intval(Settings::get('slide-as-file', 0)),
        'nextendAction'      => Request::$GET->getCmd('nextendaction'),
        'previewInNewWindow' => !!Settings::get('preview-new-window', 0),
        'previewUrl'         => $this->getUrlPreviewSlider($slider->data->get('id'), $this->getSlideID()),
        'sliderElementID'    => $slider->elementId,
        'slideEditorOptions' => $options
    )) . ');');
Admin/Sliders/ControllerAjaxSliders.php000064400000027454152356646020014214 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Sliders;


use Nextend\Framework\Controller\Admin\AdminAjaxController;
use Nextend\Framework\Data\Data;
use Nextend\Framework\Filesystem\Filesystem;
use Nextend\Framework\Misc\HttpClient;
use Nextend\Framework\Model\StorageSectionManager;
use Nextend\Framework\Notification\Notification;
use Nextend\Framework\Platform\Platform;
use Nextend\Framework\Request\Request;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Application\Model\ModelSliders;
use Nextend\SmartSlider3\BackupSlider\ImportSlider;
use Nextend\SmartSlider3\Settings;
use RuntimeException;

class ControllerAjaxSliders extends AdminAjaxController {

    use TraitAdminUrl;

    public function actionList() {
        $this->validateToken();

        $parentID = Request::$REQUEST->getInt('parentID');
        $this->validateVariable($parentID >= 0, 'parentID');

        if ($parentID > 0) {
            $orderBy          = 'ordering';
            $orderByDirection = 'ASC';
        } else {
            $orderBy          = Settings::get('slidersOrder2', 'ordering');
            $orderByDirection = Settings::get('slidersOrder2Direction', 'ASC');
        }

        $slidersModel = new ModelSliders($this);
        $sliders      = $slidersModel->getAll($parentID, 'published', $orderBy, $orderByDirection);

        $data = array();
        foreach ($sliders as $slider) {
            $data[] = array(
                'id'            => $slider['id'],
                'alias'         => $slider['alias'],
                'title'         => $slider['title'],
                'thumbnail'     => $this->getSliderThumbnail($slider),
                'isGroup'       => $slider['type'] == 'group',
                'childrenCount' => $slider['slides'] > 0 ? $slider['slides'] : 0
            );
        }

        $this->response->respond($data);
    }

    private function getSliderThumbnail($slider) {

        $thumbnail = $slider['thumbnail'];
        if (empty($thumbnail)) {
            return '';
        } else {
            return ResourceTranslator::toUrl($thumbnail);
        }
    }

    public function actionOrder() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $slidersModel = new ModelSliders($this);
        $result       = $slidersModel->order(Request::$REQUEST->getVar('groupID', 0), Request::$REQUEST->getVar('sliderorder'), Request::$REQUEST->getInt('isReversed', 1), Request::$REQUEST->getVar('orders', array()));
        $this->validateDatabase($result);

        Notification::success(n2_('Slider order saved.'));
        $this->response->respond();
    }

    public function actionTrash() {
        $this->validateToken();

        $this->validatePermission('smartslider_delete');

        $groupID = Request::$REQUEST->getInt('groupID', 0);
        $this->validateVariable($groupID >= 0, 'groupID');

        $ids = array_map('intval', array_filter((array)Request::$REQUEST->getVar('sliders'), 'is_numeric'));

        $this->validateVariable(count($ids), 'Slider');

        $slidersModel = new ModelSliders($this);

        $isTrash  = false;
        $isUnlink = false;
        foreach ($ids as $id) {
            if ($id > 0) {
                $mode = $slidersModel->trash($id, $groupID);
                switch ($mode) {
                    case 'trash':
                        $isTrash = true;
                        break;
                    case 'unlink':
                        $isUnlink = true;
                        break;
                }
            }
        }

        if ($isTrash) {
            Notification::success(n2_('Slider(s) moved to the trash.'));
        }

        if ($isUnlink) {
            Notification::success(n2_('Slider(s) removed from the group.'));
        }

        $this->response->respond();
    }

    public function actionEmptyTrash() {
        $this->validateToken();

        $this->validatePermission('smartslider_delete');

        $slidersModel = new ModelSliders($this);

        $slidersInTrash = $slidersModel->getAll('*', 'trash');

        foreach ($slidersInTrash as $slider) {
            $slidersModel->deletePermanently($slider['id']);
        }

        Notification::success(n2_('Slider(s) deleted permanently from the trash.'));

        $this->response->respond();
    }

    public function actionHideReview() {
        $this->validateToken();

        $this->validatePermission('smartslider_config');

        StorageSectionManager::getStorage('smartslider')
                             ->set('free', 'review', 1);

        $this->response->respond();
    }

    public function actionSearch() {
        $this->validateToken();

        $this->validatePermission('smartslider_config');

        $slidersModel = new ModelSliders($this);

        $keyword = Request::$REQUEST->getVar('keyword', '');
        $sliders = array();

        $url     = parse_url($keyword);
        $baseUrl = parse_url(Platform::getSiteUrl());

        if (isset($url['host']) && $url['host'] === $baseUrl['host']) {
            $content = HttpClient::get($keyword);
            preg_match_all('/data-ssid="(?<id>[0-9]+)/', $content, $matches);

            foreach ($matches['id'] as $sliderID) {
                if ($_slider = $slidersModel->getWithThumbnail($sliderID)) {
                    array_push($sliders, $_slider);
                }
            }
        }

        $sliders = array_merge($sliders, $slidersModel->getSearchResults($keyword));
        $result  = array();
        if (!empty($sliders)) {
            foreach ($sliders as $slider) {
                $result[] = array(
                    'id'            => $slider['id'],
                    'alias'         => $slider['alias'],
                    'title'         => $slider['title'],
                    'thumbnail'     => $this->getSliderThumbnail($slider),
                    'isGroup'       => $slider['type'] == 'group',
                    'childrenCount' => $slider['slides'] > 0 ? $slider['slides'] : 0,
                    'editUrl'       => $this->getUrlSliderEdit($slider['id'], $slider['group_id']),
                    'order'         => $slider['ordering']
                );
            }
        }

        $this->response->respond($result);

    }

    public function actionPagination() {
        $this->validateToken();

        $this->validatePermission('smartslider_config');

        $slidersModel   = new ModelSliders($this);
        $pageIndex      = Request::$REQUEST->getInt('pageIndex', 0);
        $limit          = Request::$REQUEST->getVar('limit', 20);
        $orderBy        = Request::$REQUEST->getCmd('orderBy', 'ordering');
        $orderDirection = Request::$REQUEST->getCmd('orderDirection', 'ASC');

        Settings::set('limit', $limit);
        Settings::set('slidersOrder2', $orderBy);
        Settings::set('slidersOrder2Direction', $orderDirection);

        if ($pageIndex < 0) {
            $pageIndex = 0;
        }

        $sliderCount = $slidersModel->getSlidersCount('published', true);
        $result      = array();

        $sliders = $slidersModel->getAll(0, 'published', $orderBy, $orderDirection, $pageIndex, $limit);

        //if last page is empty
        if (empty($sliders) && $sliderCount) {
            $lastPageIndex       = intval(ceil(($sliderCount - $limit) / $limit));
            $sliders             = $slidersModel->getAll(0, 'published', $orderBy, $orderDirection, $lastPageIndex, $limit);
            $result['pageIndex'] = $lastPageIndex;
        }

        if (!empty($sliders)) {
            foreach ($sliders as $slider) {
                $result['sliders'][] = array(
                    'id'            => $slider['id'],
                    'alias'         => $slider['alias'],
                    'title'         => $slider['title'],
                    'thumbnail'     => $this->getSliderThumbnail($slider),
                    'isGroup'       => $slider['type'] == 'group',
                    'childrenCount' => $slider['slides'] > 0 ? $slider['slides'] : 0,
                    'editUrl'       => $this->getUrlSliderEdit($slider['id'], 0),
                    'order'         => $slider['ordering']
                );
            }
            $result['slidersPerPage'] = count($sliders);
        }
        $result['sliderCount'] = $sliderCount;

        $this->response->respond($result);
    }

    protected function actionImport() {

        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        if (empty($_FILES) && empty($_POST)) {
            Notification::error(sprintf(n2_('Your server has an upload file limit at %s, so if you have bigger export file, please use the local import file method.'), @ini_get('post_max_size')));
            $this->response->respond();
        } else if (!empty($_POST)) {
            $data = new Data(Request::$REQUEST->getVar('slider'));


            $restore = $data->get('restore', 0);

            $file = '';

            $slider = Request::$FILES->getVar('slider');

            if ($slider['tmp_name']['import-file'] !== null) {

                switch ($slider['error']['import-file']) {
                    case UPLOAD_ERR_OK:
                    case UPLOAD_ERR_NO_FILE:
                        break;
                    case UPLOAD_ERR_INI_SIZE:
                    case UPLOAD_ERR_FORM_SIZE:
                        throw new RuntimeException('Exceeded filesize limit.');
                    default:
                        throw new RuntimeException('Unknown errors.');
                }

                $file = $slider['tmp_name']['import-file'];
            }

            if (empty($file)) {
                $_file = $data->get('local-import-file');
                if (!empty($_file)) {
                    $file = Platform::getPublicDirectory() . '/' . $_file;
                }
            }

            if (Filesystem::fileexists($file)) {

                $import = new ImportSlider($this);
                if ($restore) {
                    $import->enableReplace();
                }

                $groupID = Request::$REQUEST->getVar('groupID', 0);

                $sliderId = $import->import($file, $groupID, $data->get('image-mode', 'clone'), 0);

                if ($sliderId !== false) {
                    Notification::success(n2_('Slider imported.'));

                    if ($data->get('delete')) {
                        @unlink($file);
                    }

                    $this->response->redirect($this->getUrlSliderEdit($sliderId, $groupID));
                } else {
                    $extension = pathinfo($slider['name']['import-file'], PATHINFO_EXTENSION);
                    if (strpos($slider['name']['import-file'], 'sliders_unzip_to_import') !== false) {
                        Notification::error(sprintf(n2_('You have to unzip your %1$s file to find the importable *.ss3 files!'), $slider['name']['import-file']));
                        $this->response->error();
                    } else if ($extension != 'ss3') {
                        Notification::error(n2_('Only *.ss3 files can be uploaded!'));
                        $this->response->error();
                    } else {
                        Notification::error(n2_('Import error!'));
                        $this->response->error();
                    }
                    $this->response->redirect($this->getUrlImport());
                }
            } else {
                Notification::error(n2_('The imported file is not readable!'));
                $this->response->error();
            }

        }
    
    }
}Admin/Sliders/ControllerSliders.php000064400000006730152356646020013402 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Sliders;


use Nextend\Framework\Misc\Zip\Creator;
use Nextend\Framework\Model\StorageSectionManager;
use Nextend\Framework\PageFlow;
use Nextend\Framework\Request\Request;
use Nextend\SmartSlider3\Application\Admin\AbstractControllerAdmin;
use Nextend\SmartSlider3\Application\Admin\Sliders\Pro\ViewSlidersActivate;
use Nextend\SmartSlider3\Application\Model\ModelLicense;
use Nextend\SmartSlider3\Application\Model\ModelSliders;
use Nextend\SmartSlider3\BackupSlider\ExportSlider;
use Nextend\SmartSlider3\Settings;

class ControllerSliders extends AbstractControllerAdmin {

    protected function actionGettingStarted() {

        if (!StorageSectionManager::getStorage('smartslider')
                                  ->get('tutorial', 'GettingStarted')) {

            $view = new ViewSlidersGettingStarted($this);

            $view->display();
        } else {
            $modelLicense = ModelLicense::getInstance();
            if (!$modelLicense->hasKey()) {

                $view = new ViewSlidersActivate($this);
                $view->display();

            } else {
                $this->redirectToSliders();
            }
        }
    }

    protected function actionGettingStartedDontShow() {
        StorageSectionManager::getStorage('smartslider')
                             ->set('tutorial', 'GettingStarted', 1);

        $this->redirectToSliders();
    }

    protected function actionIndex() {
        $this->loadSliderManager();

        $view = new ViewSlidersIndex($this);
        $view->setPaginationIndex(max(0, intval(Request::$REQUEST->getInt('pageIndex', 0)) - 1));   /*-1 needs because beautified query string*/

        $view->display();
    }

    protected function actionTrash() {

        $view = new ViewSlidersTrash($this);

        $view->display();
    }

    protected function actionExportAll() {
        $slidersModel = new ModelSliders($this);
        $groupID      = (Request::$REQUEST->getVar('inSearch', false)) ? '*' : Request::$REQUEST->getInt('currentGroupID', 0);
        $sliders      = $slidersModel->getAll($groupID, 'published');
        $ids          = Request::$REQUEST->getVar('sliders');

        $files      = array();
        $saveAsFile = count($ids) == 1 ? false : true;
        foreach ($sliders as $slider) {
            if (!empty($ids) && !in_array($slider['id'], $ids)) {
                continue;
            }
            $export  = new ExportSlider($this, $slider['id']);
            $files[] = $export->create($saveAsFile);
        }

        $zip = new Creator();
        foreach ($files as $file) {
            $zip->addFile(file_get_contents($file), basename($file));
            unlink($file);
        }
        PageFlow::cleanOutputBuffers();
        header('Content-disposition: attachment; filename=sliders_unzip_to_import.zip');
        header('Content-type: application/zip');
        // PHPCS - Contains binary zip data, so nothing to escape.
        echo $zip->file(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        PageFlow::exitApplication();
    
    }

    protected function actionImport() {
        if ($this->validatePermission('smartslider_edit')) {

            $groupID = Request::$REQUEST->getVar('groupID', 0);

            $view = new ViewSlidersImport($this);
            $view->setGroupID($groupID);
            $view->display();
        }
    
    }
}Admin/Sliders/ViewSlidersGettingStarted.php000064400000001020152356646020015025 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Sliders;


use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;

class ViewSlidersGettingStarted extends AbstractView {

    use TraitAdminUrl;

    public function display() {

        $this->layout = new LayoutDefault($this);

        $this->layout->addContent($this->render('GettingStarted'));

        $this->layout->render();
    }
}Admin/Sliders/ViewSlidersImport.php000064400000012251152356646020013357 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Sliders;

use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Grouping;
use Nextend\Framework\Form\Element\Message\Notice;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\SelectFile;
use Nextend\Framework\Form\Element\Token;
use Nextend\Framework\Form\Element\Upload;
use Nextend\Framework\Form\Form;
use Nextend\Framework\Platform\Platform;
use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain\BlockTopBarMain;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonBack;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonImport;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;

class ViewSlidersImport extends AbstractView {

    use TraitAdminUrl;

    /**
     * @var LayoutDefault
     */
    protected $layout;

    /**
     * @var int
     */
    protected $groupID;

    public function display() {

        $this->layout = new LayoutDefault($this);

        $this->layout->addBreadcrumb(n2_('Import project'), '', $this->getUrlImport());

        $this->displayTopBar();

        $this->displayHeader();

        $this->layout->render();

    }

    protected function displayTopBar() {

        $topBar = new BlockTopBarMain($this);

        $buttonImport = new BlockButtonImport($this);
        $buttonImport->addClass('n2_button--inactive');
        $buttonImport->addClass('n2_slider_import');
        $topBar->addPrimaryBlock($buttonImport);

        $buttonBack = new BlockButtonBack($this);
        $buttonBack->setUrl($this->getUrlDashboard());
        $buttonBack->addClass('n2_slider_import_back');
        $topBar->addPrimaryBlock($buttonBack);

        $this->layout->setTopBar($topBar->toHTML());
    }

    protected function displayHeader() {

        $this->layout->addContent($this->render('Import'));
    }


    public function renderForm() {

        $form = new Form($this, 'slider');

        new Token($form->getFieldsetHidden());

        $settings = new ContainerTable($form->getContainer(), 'import-slider', n2_('Import project'));


        $row1 = $settings->createRow('import-row-1');

        $instructions = n2_('You can upload *.ss3 files which were exported by Smart Slider 3.') . '<br>';
        new Notice($row1, 'instructions', n2_('Instruction'), $instructions);


        $row2 = $settings->createRow('import-row-2');

        new OnOff($row2, 'upload_or_local', n2_('Local import'), 0, array(
            'relatedFieldsOff' => array(
                'sliderupload-grouping'
            ),
            'relatedFieldsOn'  => array(
                'sliderlocal-import-grouping'
            )
        ));


        $uploadGrouping = new Grouping($row2, 'upload-grouping');

        new Upload($uploadGrouping, 'import-file', n2_('Upload file'));
        new Notice($uploadGrouping, 'instructions', '', sprintf(n2_('Your server\'s upload filesize limitation is %s, so if your file is bigger, use the local import.'), @ini_get('post_max_size')));


        $localImportGrouping = new Grouping($row2, 'local-import-grouping');

        new SelectFile($localImportGrouping, 'local-import-file', n2_('File'), '', 'ss3');

        new Notice($localImportGrouping, 'instructions', '', sprintf(n2_('Files with %1$s.ss3%2$s extension are listed from: %3$s'), '<i>', '</i>', Platform::getPublicDirectory()));

        new OnOff($localImportGrouping, 'delete', n2_('Delete file'), 0, array(
            'tipLabel'       => n2_('Delete file'),
            'tipDescription' => n2_('Removes the selected .ss3 file from your sever after the import.'),
        ));


        $row3 = $settings->createRow('import-row-3');

        new OnOff($row3, 'restore', n2_('Restore slider'), 0, array(
            'tipLabel'       => n2_('Restore'),
            'tipDescription' => n2_('The imported slider will have the same ID as the original export has. If you have a slider with the same ID, it will be overwritten.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1728-export-import-slider#import'
        ));

        new Select($row3, 'image-mode', n2_('Image mode'), 'clone', array(
            'options'        => array(
                'clone'    => n2_('Clone'),
                'update'   => n2_('Old site url'),
                'original' => n2_('Original')
            ),
            'tipLabel'       => n2_('Image mode'),
            'tipDescription' => n2_('You can choose how the slide images are loaded.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1728-export-import-slider#image-mode'
        ));

        $form->render();
    }

    /**
     * @return int
     */
    public function getGroupID() {
        return $this->groupID;
    }

    /**
     * @param int $groupID
     */
    public function setGroupID($groupID) {
        $this->groupID = $groupID;
    }
}Admin/Sliders/ViewSlidersIndex.php000064400000003576152356646020013166 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Sliders;

use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Banner\BlockBannerActivate;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Dashboard\DashboardInfo\BlockDashboardInfo;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Dashboard\DashboardManager\BlockDashboardManager;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderManager\BlockSliderManager;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Model\ModelLicense;

class ViewSlidersIndex extends AbstractView {

    /**
     * @var LayoutDefault
     */
    protected $layout;
    protected $paginationIndex = 0;

    public function display() {

        $this->layout = new LayoutDefault($this);

        $dashboardInfo = new BlockDashboardInfo($this);
        $this->layout->addHeaderMenuItem($dashboardInfo->toHTML());

        $this->displayHeader();

        $this->displaySliderManager();

        $dashboardManager = new BlockDashboardManager($this);
        $this->layout->addContentBlock($dashboardManager);


        $this->layout->render();
    }

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

    protected function displayHeader() {
        $model = ModelLicense::getInstance();
        if (!$model->hasKey()) {
            ob_start();

            $banner = new BlockBannerActivate($this);
            $banner->display();
            $this->layout->addContent(ob_get_clean());
        }
    
    }

    protected function displaySliderManager() {

        $sliderManager = new BlockSliderManager($this);
        $sliderManager->setPaginationIndex($this->paginationIndex);
        $this->layout->addContentBlock($sliderManager);
    }
} Admin/Sliders/ViewSlidersTrash.php000064400000003414152356646020013167 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Sliders;


use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain\BlockTopBarMain;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButton;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonBack;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderTrash\BlockSliderTrash;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;

class ViewSlidersTrash extends AbstractView {

    use TraitAdminUrl;

    public function display() {

        $this->layout = new LayoutDefault($this);

        $this->layout->addBreadcrumb(n2_('Trash'), 'ssi_16 ssi_16--delete', $this->getUrlTrash());

        $topBar = new BlockTopBarMain($this);

        $buttonEmptyTrash = new BlockButton($this);
        $buttonEmptyTrash->setLabel(n2_('Empty trash'));
        $buttonEmptyTrash->setBig();
        $buttonEmptyTrash->setRed();
        $buttonEmptyTrash->addClass('n2_slider_empty_trash');
        $buttonEmptyTrash->addClass('n2_button--inactive');
        $topBar->addPrimaryBlock($buttonEmptyTrash);


        $buttonBack = new BlockButtonBack($this);
        $buttonBack->setUrl($this->getUrlDashboard());
        $buttonBack->addClass('n2_slider_settings_back');
        $topBar->addPrimaryBlock($buttonBack);

        $this->layout->setTopBar($topBar->toHTML());

        $this->displaySliderTrash();

        $this->layout->render();
    }

    protected function displaySliderTrash() {

        $sliderManager = new BlockSliderTrash($this);
        $this->layout->addContentBlock($sliderManager);
    }
}Admin/Sliders/Template/GettingStarted.php000064400000002344152356646020014431 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Sliders;

/**
 * @var $this ViewSlidersGettingStarted
 */

?>
<div class="n2_getting_started">
    <div class="n2_getting_started__heading">
        <?php n2_e('Welcome to Smart Slider 3'); ?>
    </div>
    <div class="n2_getting_started__subheading">
        <?php n2_e('To help you get started, we\'ve put together a super tutorial video that shows you the basic settings.'); ?>
    </div>
    <div class="n2_getting_started__video">
        <div class="n2_getting_started__video_placeholder"></div>
        <iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/3PPtkRU7D74?rel=0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
    </div>
    <div class="n2_getting_started__buttons">
        <div class="n2_getting_started__button_dont_show">
            <a href="<?php echo esc_url($this->getUrlGettingStartedDontShow()); ?>"><?php n2_e('Don\'t show again'); ?></a>
        </div>
        <div class="n2_getting_started__button_dashboard">
            <a href="<?php echo esc_url($this->getUrlDashboard()); ?>"><?php n2_e('Go to dashboard'); ?></a>
        </div>
    </div>
</div>Admin/Sliders/Template/Import.php000064400000000604152356646020012750 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Sliders;


use Nextend\Framework\Asset\Js\Js;


/**
 * @var ViewSlidersImport $this
 */

JS::addInline('new _N2.SliderImport();');
?>

<form id="n2-ss-form-slider-import" action="<?php echo esc_url($this->getAjaxUrlImport($this->getGroupID())); ?>" method="post">
    <?php
    $this->renderForm();
    ?>
</form>Admin/Sliders/Pro/ViewSlidersActivate.php000064400000001010152356646020014374 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Sliders\Pro;


use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;

class ViewSlidersActivate extends AbstractView {

    use TraitAdminUrl;

    public function display() {

        $this->layout = new LayoutDefault($this);

        $this->layout->addContent($this->render('Activate'));

        $this->layout->render();
    }
}Admin/Sliders/Pro/Template/Activate.php000064400000002507152356646020014002 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Sliders\Pro;

/**
 * @var $this ViewSlidersActivate
 */
?>

<div class="n2_page_activate">
    <div class="n2_page_activate__heading">
        <?php n2_e('Activate Smart Slider 3 Pro'); ?>
    </div>
    <div class="n2_page_activate__subheading">
        <?php n2_e('Register Smart Slider 3 Pro on this domain to enable auto update, slider templates and slide library.'); ?>
    </div>
    <div class="n2_page_activate__video">
        <div class="n2_page_activate__video_placeholder"></div>
        <iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/8t5p1Xxysfw?rel=0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
    </div>
    <div class="n2_page_activate__buttons">
        <div class="n2_page_activate__button_dont_show">
            <a href="<?php echo esc_url($this->getUrlDashboard()); ?>"><?php n2_e('Go to dashboard'); ?></a>
        </div>
        <div class="n2_page_activate__button_dashboard">
            <a href="<?php echo esc_url($this->getUrlDashboard()); ?>" onclick="_N2.License.get().startActivation().done((function(){window.location=this.getAttribute('href');}).bind(this));return false;"><?php n2_e('Activate'); ?></a>
        </div>
    </div>
</div>
Admin/Slider/ControllerAjaxSlider.php000064400000031173152356646020013637 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Slider;


use Nextend\Framework\Asset\AssetManager;
use Nextend\Framework\Controller\Admin\AdminAjaxController;
use Nextend\Framework\Form\Form;
use Nextend\Framework\Misc\Base64;
use Nextend\Framework\Notification\Notification;
use Nextend\Framework\PageFlow;
use Nextend\Framework\Request\Request;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Application\Model\ModelLicense;
use Nextend\SmartSlider3\Application\Model\ModelSliders;
use Nextend\SmartSlider3\BackupSlider\ImportSlider;
use Nextend\SmartSlider3\Slider\ResponsiveType\ResponsiveTypeFactory;
use Nextend\SmartSlider3\Slider\SliderType\SliderTypeFactory;
use Nextend\SmartSlider3\SmartSlider3Info;
use Nextend\SmartSlider3\Widget\WidgetGroupFactory;

class ControllerAjaxSlider extends AdminAjaxController {

    use TraitAdminUrl;

    public function actionRestore() {

        $this->validateToken();
        $this->validatePermission('smartslider_edit');

        $sliderID = Request::$REQUEST->getVar('slider');
        $this->validateVariable(!empty($sliderID), 'slider');

        $slidersModel = new ModelSliders($this);
        $slidersModel->restore($sliderID);


        Notification::success(n2_('Slider restored.'));

        $this->response->respond();
    }

    public function actionDeletePermanently() {

        $this->validateToken();
        $this->validatePermission('smartslider_edit');

        $sliderID = Request::$REQUEST->getVar('slider');
        $this->validateVariable(!empty($sliderID), 'slider');

        $slidersModel     = new ModelSliders($this);
        $deletedSliderIDs = $slidersModel->deletePermanently($sliderID);


        Notification::success(n2_('Slider permanently deleted.'));

        $this->response->respond(array(
            'sliderIDs' => $deletedSliderIDs
        ));
    }

    public function actionCreate() {

        $this->validateToken();
        $this->validatePermission('smartslider_edit');

        $slidersModel = new ModelSliders($this);

        $projectName = Request::$REQUEST->getVar('projectName');
        $this->validateVariable(!empty($projectName), 'projectName');

        $slider = array(
            'title'                     => $projectName,
            'width'                     => max(Request::$REQUEST->getInt('sliderWidth', 1200), 200),
            'height'                    => max(Request::$REQUEST->getInt('sliderHeight', 600), 100),
            'responsiveLimitSlideWidth' => 1
        );

        $projectType = Request::$REQUEST->getVar('projectType', 'slider');

        if ($projectType == 'block') {
            $slider['type'] = 'block';
        } else {

            switch (Request::$REQUEST->getVar('sliderType', 'simple')) {

                case 'carousel':
                    $slider['type']               = 'carousel';
                    $slider['maximum-pane-width'] = $slider['width'];
                    $slider['slide-width']        = max(Request::$REQUEST->getInt('slideWidth', 600), 200);
                    $slider['slide-height']       = max(Request::$REQUEST->getInt('slideHeight', 400), 100);

                    $slider['widget-bullet-enabled'] = 1;
                    $slider['widgetbullet']          = 'transitionRectangle';

                    $slider['widget-arrow-enabled'] = 1;
                    $slider['widgetarrow']          = 'imageEmpty';
                    break;

                case 'showcase':
                    $slider['type']         = 'showcase';
                    $slider['slide-width']  = max(Request::$REQUEST->getInt('slideWidth', 600), 200);
                    $slider['slide-height'] = max(Request::$REQUEST->getInt('slideHeight', 400), 100);

                    $slider['widget-bullet-enabled'] = 1;
                    $slider['widgetbullet']          = 'transitionRectangle';
                    break;

                case 'simple':
                default:
                    $slider['type'] = 'simple';

                    $slider['widget-arrow-enabled'] = 1;
                    $slider['widgetarrow']          = 'imageEmpty';
                    break;
            }
        }

        switch (Request::$REQUEST->getVar('responsiveMode', 'fullwidth')) {
            case 'fullpage':
                $slider['responsive-mode'] = 'fullpage';
                break;
            case 'boxed':
                $slider['responsive-mode'] = 'auto';
                break;
            case 'fullwidth':
            default:
                $slider['responsive-mode'] = 'fullwidth';
                break;
        }

        $groupID = Request::$REQUEST->getVar('groupID', 0);

        $sliderid = $slidersModel->create($slider, $groupID);


        Notification::success(n2_('Slider created.'));

        $this->response->redirect($this->getUrlSliderEdit($sliderid, $groupID));
    }

    public function actionRename() {
        $this->validateToken();
        $this->validatePermission('smartslider_edit');

        $sliderId = Request::$REQUEST->getInt('sliderid');
        $this->validateVariable($sliderId > 0, 'Slider');

        $title = Request::$REQUEST->getVar('title');

        $slidersModel = new ModelSliders($this);
        $slidersModel->setTitle($sliderId, $title);

        Notification::success(n2_('Slider renamed.'));

        $this->response->respond();
    }

    public function actionEdit() {
        $this->validateToken();
        $this->validatePermission('smartslider_edit');

        $slidersModel = new ModelSliders($this);

        $slider = $slidersModel->get(Request::$REQUEST->getInt('sliderid'));
        $this->validateDatabase($slider);

        $responseData = $slidersModel->save($slider['id'], Request::$REQUEST->getVar('slider'));
        if ($responseData !== false) {
            Notification::success(n2_('Slider saved.'));
            $this->response->respond($responseData);
        }
    }

    public function actionImportDemo() {
        $this->validateToken();
        $this->validatePermission('smartslider_edit');

        $key = 'http:' . Base64::decode(Request::$REQUEST->getVar('key'));
        if (strpos($key, 'http://smartslider3.com/') !== 0) {
            Notification::error(sprintf(n2_('Import url is not valid: %s'), $key));
            $this->response->error();
        }
        if (!ModelLicense::getInstance()
                         ->hasKey()) {
            Notification::error(n2_('License key required for premium features!'));
            $this->response->error();
        }
    

        $posts  = array(
            'action'  => 'asset',
            'asset'   => $key,
            'version' => SmartSlider3Info::$version
        );
        $result = SmartSlider3Info::api($posts);

        if (!is_string($result)) {
            $hasError = SmartSlider3Info::hasApiError($result['status'], array(
                'key' => $key
            ));

            if ($hasError == 'dashboard') {
                $this->redirect($this->getUrlDashboard());
            } else if ($hasError !== false) {
                $this->response->error();
            }
        } else {

            $import = new ImportSlider($this);

            $groupID = Request::$REQUEST->getVar('groupID', 0);

            $sliderId = $import->import($result, $groupID, 'clone', 1, false);

            if ($sliderId !== false) {
                Notification::success(n2_('Slider imported.'));

                $this->response->redirect($this->getUrlSliderEdit($sliderId, $groupID));
            } else {
                Notification::error(n2_('Import error!'));
                $this->response->error();
            }
        }

        $this->response->respond();
    }


    public function actionDuplicate() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $sliderId = Request::$REQUEST->getInt('sliderid');
        $this->validateVariable($sliderId > 0, 'Slider');

        $slidersModel = new ModelSliders($this);
        $newSliderId  = $slidersModel->duplicate($sliderId, true);
        $slider       = $slidersModel->getWithThumbnail($newSliderId);

        $this->validateDatabase($slider);

        Notification::success(n2_('Slide duplicated.'));

        $view = new ViewAjaxSliderBox($this);
        $view->setSlider($slider);

        $this->response->respond(array(
            'html'        => $view->display(),
            'sliderCount' => $slidersModel->getSlidersCount('published', true)
        ));
    }

    public function actionChangeSliderType() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $sliderID = Request::$GET->getInt('sliderID');
        if ($sliderID > 0) {
            $targetSliderType = Request::$POST->getVar('targetSliderType');
            $availableTypes   = SliderTypeFactory::getAdminTypes();
            if (isset($availableTypes[$targetSliderType])) {
                $slidersModel = new ModelSliders($this);
                $slidersModel->changeSliderType($sliderID, $targetSliderType);

                $this->response->respond();
            } else {
                Notification::error(sprintf(n2_('%s slider type is not available.'), ucfirst($targetSliderType)));
                $this->response->error();
            }

        } else {
            Notification::error('Slider ID error: ' . $sliderID);
            $this->response->error();
        }
    }

    public function actionRenderResponsiveType() {
        $this->validateToken();

        $this->validatePermission('smartslider_config');

        $responsiveType = ResponsiveTypeFactory::getType(Request::$POST->getVar('value'))
                                               ->createAdmin();
        if ($responsiveType) {
            $values = Request::$REQUEST->getVar('values', array());

            $form = new Form($this->applicationType, 'slider');
            $form->loadArray($values);

            PageFlow::cleanOutputBuffers();
            ob_start();

            $responsiveType->renderFields($form->getContainer());
            $form->render();

            $scripts = AssetManager::generateAjaxJS();
            $html    = ob_get_clean();
            $this->response->respond(array(
                'html'    => $html,
                'scripts' => $scripts
            ));
        } else {

            Notification::error('Responsive type not found: ' . Request::$POST->getVar('value'));
            $this->response->error();
        }
    }

    public function actionRenderWidgetArrow() {

        $this->renderWidgetForm('arrow');
    }

    public function actionRenderWidgetAutoplay() {

        $this->renderWidgetForm('autoplay');
    }

    public function actionRenderWidgetBar() {

        $this->renderWidgetForm('bar');
    }

    public function actionRenderWidgetBullet() {

        $this->renderWidgetForm('bullet');
    }

    public function actionRenderWidgetFullscreen() {

        $this->renderWidgetForm('fullscreen');
    }

    public function actionRenderWidgetHtml() {

        $this->renderWidgetForm('html');
    }

    public function actionRenderWidgetIndicator() {

        $this->renderWidgetForm('indicator');
    }

    public function actionRenderWidgetShadow() {

        $this->renderWidgetForm('shadow');
    }

    public function actionRenderWidgetThumbnail() {

        $this->renderWidgetForm('thumbnail');
    }

    private function renderWidgetForm($type) {
        $this->validateToken();
        
        $this->validatePermission('smartslider_config');

        $group = WidgetGroupFactory::getGroup($type);

        $value  = Request::$POST->getVar('value');
        $widget = $group->getWidget($value);
        if ($widget) {
            $values = Request::$REQUEST->getVar('values', array());

            $form = new Form($this->applicationType, 'slider');

            $values = array_merge($widget->getDefaults(), $values);
            $form->loadArray($values);

            PageFlow::cleanOutputBuffers();
            ob_start();

            $widget->renderFields($form->getContainer());
            $form->render();

            $scripts = AssetManager::generateAjaxJS();
            $html    = ob_get_clean();
            $this->response->respond(array(
                'html'    => $html,
                'scripts' => $scripts
            ));
        } else {
            Notification::error('Not found: ' . $value);
            $this->response->error();
        }
    }
}Admin/Slider/ControllerSlider.php000064400000022347152356646020013036 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Slider;


use Nextend\Framework\Data\Data;
use Nextend\Framework\Notification\Notification;
use Nextend\Framework\Parser\Common;
use Nextend\Framework\Request\Request;
use Nextend\SmartSlider3\Application\Admin\AbstractControllerAdmin;
use Nextend\SmartSlider3\Application\Model\ModelSliders;
use Nextend\SmartSlider3\Application\Model\ModelSlides;
use Nextend\SmartSlider3\BackupSlider\ExportSlider;

class ControllerSlider extends AbstractControllerAdmin {

    protected $sliderID = 0;

    protected $sliderAliasOrID = 0;

    protected $groupID = 0;

    public function initialize() {
        parent::initialize();

        $this->sliderID = Request::$REQUEST->getInt('sliderid');
        $this->groupID  = Request::$REQUEST->getInt('groupID', 0);

        $this->setSliderIDFromAlias();
    }

    /**
     * @return int
     */
    public function getSliderID() {
        return $this->sliderID;
    }

    public function setSliderIDFromAlias() {
        $this->sliderAliasOrID = Request::$REQUEST->getVar('slideraliasorid');
        if (!empty($this->sliderAliasOrID)) {
            if (is_numeric($this->sliderAliasOrID)) {
                $this->sliderID = $this->sliderAliasOrID;
            } else {
                $slidersModel   = new ModelSliders($this);
                $slider         = $slidersModel->getByAlias($this->sliderAliasOrID);
                $this->sliderID = $slider['id'];
            }
        }
    }

    public function actionClearCache() {
        if ($this->validateToken()) {
            $slidersModel = new ModelSliders($this);
            $slider       = $slidersModel->get($this->sliderID);
            if ($this->validateDatabase($slider)) {

                $slidersModel->refreshCache($this->sliderID);
                Notification::success(n2_('Cache cleared.'));

                $groupData = $this->getGroupData($this->sliderID);

                $this->redirect($this->getUrlSliderEdit($this->sliderID, $groupData['group_id']));
            }
        }
    }

    public function actionEdit() {


        if ($this->validatePermission('smartslider_edit')) {

            $slidersModel = new ModelSliders($this);

            $slider = $slidersModel->get($this->sliderID);

            if (!$slider) {
                $this->redirectToSliders();
            }

            if ($slider['type'] == 'group') {

                if (N2SSPRO) {
                    $this->doAction('editGroup', array(
                        $slider
                    ));
                }  //N2SSPRO

            } else {

                $groupData = $this->getGroupData($this->sliderID);

                $view = new ViewSliderEdit($this);
                $view->setGroupData($groupData['group_id'], $groupData['title']);
                $view->setSlider($slider);
                $view->display();

            }
        }
    }

    public function actionSimpleEdit() {

        if ($this->validatePermission('smartslider_edit')) {

            $slidersModel = new ModelSliders($this);

            $slider = $slidersModel->get($this->sliderID);

            if (!$slider) {
                $this->redirectToSliders();
            }

            $groupData = $this->getGroupData($this->sliderID);

            if (Request::$POST->getInt('save') && $this->validateToken()) {
                $sliderData = new Data(Request::$POST->getVar('slider'));

                if ($sliderData->get('delete-slider') == 1) {
                    $slidersModel->trash($this->sliderID, $groupData['group_id']);
                    $this->redirectToSliders();
                } else {

                    $params = json_decode($slider['params'], true);

                    $params['aria-label'] = $sliderData->get('aria-label', '');

                    $slidersModel->saveSimple($this->sliderID, $sliderData->get('title'), $params);

                    $slidesModel = new ModelSlides($this);

                    $slides = Request::$POST->getVar('slide');

                    $ordering = array();
                    foreach ($slides as $slideID => $slide) {
                        $slideData = new Data($slide);
                        if ($slideData->get('delete-slide') == 1) {
                            $slidesModel->delete($slideID);
                        } else {

                            $ordering[$slideID] = $slideData->get('ordering');

                            $slideRow = $slidesModel->get($slideID);

                            $slideParamsData = new Data($slideRow['params']);

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

                            $slideParamsData->set('href', $slideData->get('href'));
                            $slideParamsData->set('href-target', $slideData->get('href-target'));
                            $slideParamsData->set('thumbnailType', $slideData->get('thumbnailType'));
                            $slideParamsData->set('backgroundImage', $slideData->get('backgroundImage'));

                            $slidesModel->saveSimple($slideID, $slideData->get('title'), $slideData->get('description'), $slideParamsData->toArray());
                        }
                    }
                    asort($ordering, SORT_NUMERIC);

                    $slidesModel->order($this->sliderID, array_keys($ordering));


                    $this->redirect($this->getUrlSliderSimpleEdit($this->sliderID, $groupData['group_id']));
                }
            }

            $view = new ViewSliderSimpleEdit($this);
            $view->setGroupData($groupData['group_id'], $groupData['title']);
            $view->setSlider($slider);
            $view->display();
        }
    }

    public function actionSimpleEditAddSlide() {

        if ($this->validatePermission('smartslider_edit')) {

            $slidersModel = new ModelSliders($this);

            $slider = $slidersModel->get($this->sliderID);

            if (!$slider) {
                $this->redirectToSliders();
            }

            $groupData = $this->getGroupData($this->sliderID);

            if (Request::$POST->getInt('save') && $this->validateToken()) {

                $slidesModel = new ModelSlides($this);
                $slidesModel->createSimpleEditAdd(Request::$POST->getVar('slide'), $this->sliderID);

                $this->redirect($this->getUrlSliderSimpleEdit($this->sliderID, $groupData['group_id']));
            }

            $view = new ViewSliderSimpleEditAddSlide($this);
            $view->setGroupData($groupData['group_id'], $groupData['title']);
            $view->setSlider($slider);
            $view->display();
        }
    }

    public function actionTrash() {
        if ($this->validateToken() && $this->validatePermission('smartslider_delete')) {
            $slidersModel = new ModelSliders($this);
            $mode         = $slidersModel->trash($this->sliderID, $this->groupID);
            switch ($mode) {
                case 'trash':
                    Notification::success(n2_('Slider moved to the trash.'));
                    break;
                case 'unlink':
                    Notification::success(n2_('Slider removed from the group.'));
                    break;
            }

            if ($this->groupID > 0) {
                $this->redirect($this->getUrlSliderEdit($this->groupID));
            } else {
                $this->redirectToSliders();
            }
        }
    }

    public function actionDuplicate() {
        if ($this->validateToken() && $this->validatePermission('smartslider_edit')) {
            $slidersModel = new ModelSliders($this);
            if (($sliderid = Request::$REQUEST->getInt('sliderid')) && $slidersModel->get($sliderid)) {
                $newSliderId = $slidersModel->duplicate($sliderid);
                if ($newSliderId) {
                    Notification::success(n2_('Slider duplicated.'));

                    $groupData = $this->getGroupData($newSliderId);

                    $this->redirect($this->getUrlSliderEdit($newSliderId, $groupData['group_id']));
                } else {
                    Notification::error(n2_('Database error'));
                }

            }
            $this->redirectToSliders();
        }
    }

    public function actionExport() {
        if ($this->validateToken() && $this->validatePermission('smartslider_edit')) {
            $export = new ExportSlider($this, $this->sliderID);
            $export->create();
        }
    
    }

    public function actionExportHTML() {
        if ($this->validateToken() && $this->validatePermission('smartslider_edit')) {
            $export = new ExportSlider($this, $this->sliderID);
            $export->createHTML();
        }
    
    }
}Admin/Slider/ViewAjaxSliderBox.php000064400000001062152356646020013071 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Slider;

use Nextend\Framework\View\AbstractViewAjax;

class ViewAjaxSliderBox extends AbstractViewAjax {

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

    public function display() {

        return $this->render('AjaxSliderBox');
    }

    /**
     * @return array
     */
    public function getSlider() {
        return $this->slider;
    }

    /**
     * @param array $slider
     */
    public function setSlider($slider) {
        $this->slider = $slider;
    }

}Admin/Slider/ViewSliderEdit.php000064400000016714152356646020012434 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Slider;


use Nextend\Framework\Acl\Acl;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\FormManager\FormManagerSlider;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Banner\BlockBannerActivate;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header\BlockHeader;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain\BlockTopBarMain;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButton;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonBack;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonPlainIcon;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonSave;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\FloatingMenu\BlockFloatingMenu;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\FloatingMenu\BlockFloatingMenuItem;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\SlideManager\BlockSlideManager;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Application\Model\ModelLicense;

class ViewSliderEdit extends AbstractView {

    use TraitAdminUrl;

    protected $groupID = 0;

    protected $groupTitle = '';

    protected $slider;

    /**
     * @var BlockHeader
     */
    protected $blockHeader;

    /**
     * @var FormManagerSlider
     */
    protected $formManager;

    /**
     * @param int    $groupID
     * @param string $groupTitle
     */
    public function setGroupData($groupID, $groupTitle) {
        $this->groupID    = $groupID;
        $this->groupTitle = $groupTitle;
    }

    /**
     * @param mixed $slider
     */
    public function setSlider($slider) {
        $this->slider = $slider;
    }

    public function display() {
        $this->formManager = new FormManagerSlider($this, $this->slider);

        $this->layout = new LayoutDefault($this);

        if ($this->groupID) {
            $this->layout->addBreadcrumb(Sanitize::esc_html($this->groupTitle), 'ssi_16 ssi_16--folderclosed', $this->getUrlSliderEdit($this->groupID));
        }

        $this->layout->addBreadcrumb(Sanitize::esc_html($this->slider['title']), 'ssi_16 ssi_16--image', $this->getUrlSliderEdit($this->slider['id'], $this->groupID));


        $slideManager = new BlockSlideManager($this);
        $slideManager->setGroupID($this->groupID);
        $slideManager->setSliderID($this->slider['id']);

        $subNavigationHTML = '';
        $model = ModelLicense::getInstance();
        if (!$model->hasKey()) {
            $banner = new BlockBannerActivate($this);

            $subNavigationHTML .= $banner->toHTML();
        }
    

        $subNavigationHTML .= $slideManager->toHTML();

        $this->layout->setSubNavigation($subNavigationHTML);


        $topBar = new BlockTopBarMain($this);

        $buttonSave = new BlockButtonSave($this);
        $buttonSave->addClass('n2_slider_settings_save');
        $buttonSave->addClass('n2_button--inactive');
        $topBar->addPrimaryBlock($buttonSave);


        $buttonBack = new BlockButtonBack($this);
        if ($this->groupID != 0) {
            $buttonBack->setUrl($this->getUrlSliderEdit($this->groupID));
        } else {
            $buttonBack->setUrl($this->getUrlDashboard());
        }
        $buttonBack->addClass('n2_slider_settings_back');
        $topBar->addPrimaryBlock($buttonBack);

        $buttonPreview = new BlockButtonPlainIcon($this);
        $buttonPreview->addClass('n2_top_bar_button_icon');
        $buttonPreview->addClass('n2_top_bar_main__preview');
        $buttonPreview->setIcon('ssi_24 ssi_24--preview');
        $buttonPreview->addAttribute('data-n2tip', n2_('Preview'));
        $buttonPreview->setUrl($this->getUrlPreviewIndex($this->slider['id']));
        $topBar->addPrimaryBlock($buttonPreview);


        $this->layout->setTopBar($topBar->toHTML());

        $this->displayHeader();

        $this->layout->addContent($this->render('Edit'));

        $this->layout->render();
    }

    protected function displayHeader() {


        $this->blockHeader = new BlockHeader($this);
        $this->blockHeader->setHeading($this->slider['title']);
        $this->blockHeader->setHeadingAfter('ID: ' . $this->slider['id']);

        $this->formManager->addTabsToHeader($this->blockHeader);

        $this->addHeaderActions();

        $this->layout->addContentBlock($this->blockHeader);
    }

    public function getSlider() {

        return $this->slider;
    }

    private function addHeaderActions() {

        $accessEdit   = Acl::canDo('smartslider_edit', $this);
        $accessDelete = Acl::canDo('smartslider_delete', $this);

        if ($accessEdit || $accessDelete) {

            $sliderid = $this->slider['id'];

            $actionsMenu = new BlockFloatingMenu($this);

            $actions = new BlockButton($this);
            $actions->setBig();
            $actions->setLabel(n2_('Actions'));
            $actions->setIcon('ssi_16 ssi_16--buttonarrow');
            $actionsMenu->setButton($actions);


            if ($accessEdit) {

                $item = new BlockFloatingMenuItem($this);
                $item->setLabel(n2_('Change slider type'));
                $item->setIcon('ssi_16 ssi_16--arrowright');
                $item->addClass('n2_slider_action__change_slider_type');
                $actionsMenu->addMenuItem($item);

                $item = new BlockFloatingMenuItem($this);
                $item->setLabel(n2_('Clear cache'));
                $item->setIcon('ssi_16 ssi_16--reset');
                $item->setUrl($this->getUrlSliderClearCache($sliderid));
                $actionsMenu->addMenuItem($item);

                $item = new BlockFloatingMenuItem($this);
                $item->setLabel(sprintf(n2_('Export %1$s as HTML'), n2_('Slider')));
                $item->setIcon('ssi_16 ssi_16--download');
                $item->setUrl($this->getUrlSliderExportHtml($sliderid));
                $actionsMenu->addMenuItem($item);

                $item = new BlockFloatingMenuItem($this);
                $item->setLabel(n2_('Export'));
                $item->setIcon('ssi_16 ssi_16--download');
                $item->setUrl($this->getUrlSliderExport($sliderid));
                $actionsMenu->addMenuItem($item);
            


                $item = new BlockFloatingMenuItem($this);
                $item->setLabel(n2_('Duplicate slider'));
                $item->setIcon('ssi_16 ssi_16--duplicate');
                $item->setUrl($this->getUrlSliderDuplicate($sliderid, $this->groupID));
                $actionsMenu->addMenuItem($item);
            }

            if ($accessDelete) {

                $item = new BlockFloatingMenuItem($this);
                $item->setRed();
                $item->setLabel(n2_('Move to trash'));
                $item->setIcon('ssi_16 ssi_16--delete');
                $item->setUrl($this->getUrlSliderMoveToTrash($sliderid, $this->groupID));
                $actionsMenu->addMenuItem($item);

            }

            $this->blockHeader->addAction($actionsMenu->toHTML());
        }
    }

    public function renderForm() {

        $this->formManager->render();
    }

}Admin/Slider/ViewSliderSimpleEdit.php000064400000006444152356646020013605 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Slider;

use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header\BlockHeader;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain\BlockTopBarMain;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButton;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonBack;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonSave;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;

class ViewSliderSimpleEdit extends AbstractView {

    use TraitAdminUrl;

    protected $groupID = 0;

    protected $groupTitle = '';

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

    /**
     * @param int    $groupID
     * @param string $groupTitle
     */
    public function setGroupData($groupID, $groupTitle) {
        $this->groupID    = $groupID;
        $this->groupTitle = $groupTitle;
    }

    /**
     * @param array $slider
     */
    public function setSlider($slider) {
        $this->slider = $slider;
    }

    /**
     * @return array
     */
    public function getSlider() {
        return $this->slider;
    }

    public function display() {

        $this->layout = new LayoutDefault($this);

        if ($this->groupID) {
            $this->layout->addBreadcrumb(Sanitize::esc_html($this->groupTitle), 'ssi_16 ssi_16--folderclosed', $this->getUrlSliderEdit($this->groupID));
        }

        $this->layout->addBreadcrumb(Sanitize::esc_html($this->slider['title']), 'ssi_16 ssi_16--image', $this->getUrlSliderEdit($this->slider['id'], $this->groupID));

        $this->layout->addBreadcrumb(n2_('Simple edit'), 'ssi_16 ssi_16--cog', $this->getUrlSliderSimpleEdit($this->slider['id'], $this->groupID));


        $topBar = new BlockTopBarMain($this);

        $buttonSave = new BlockButtonSave($this);
        $buttonSave->addClass('n2_slider_save');
        $topBar->addPrimaryBlock($buttonSave);


        $buttonBack = new BlockButtonBack($this);
        if ($this->groupID != 0) {
            $buttonBack->setUrl($this->getUrlSliderEdit($this->groupID));
        } else {
            $buttonBack->setUrl($this->getUrlDashboard());
        }
        $buttonBack->addClass('n2_slider_settings_back');
        $topBar->addPrimaryBlock($buttonBack);

        $this->layout->setTopBar($topBar->toHTML());

        $this->displayHeader();

        $this->layout->addContent($this->render('SimpleEdit'));

        $this->layout->render();

    }

    protected function displayHeader() {

        $blockHeader = new BlockHeader($this);
        $blockHeader->setHeading($this->slider['title']);
        $blockHeader->setHeadingAfter('ID: ' . $this->slider['id']);

        $addSlide = new BlockButton($this);
        $addSlide->setGreen();
        $addSlide->setBig();
        $addSlide->setLabel(n2_('Add slide'));
        $addSlide->setUrl($this->getUrlSliderSimpleEditAddSlide($this->slider['id'], $this->groupID));
        $blockHeader->addAction($addSlide->toHTML());

        $this->layout->addContentBlock($blockHeader);
    }
}Admin/Slider/ViewSliderSimpleEditAddSlide.php000064400000004651152356646020015175 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Slider;

use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain\BlockTopBarMain;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonBack;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonSave;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;

class ViewSliderSimpleEditAddSlide extends AbstractView {

    use TraitAdminUrl;

    protected $groupID = 0;

    protected $groupTitle = '';

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

    /**
     * @param int    $groupID
     * @param string $groupTitle
     */
    public function setGroupData($groupID, $groupTitle) {
        $this->groupID    = $groupID;
        $this->groupTitle = $groupTitle;
    }

    /**
     * @param array $slider
     */
    public function setSlider($slider) {
        $this->slider = $slider;
    }

    /**
     * @return array
     */
    public function getSlider() {
        return $this->slider;
    }

    public function display() {

        $this->layout = new LayoutDefault($this);

        if ($this->groupID) {
            $this->layout->addBreadcrumb(Sanitize::esc_html($this->groupTitle), 'ssi_16 ssi_16--folderclosed', $this->getUrlSliderEdit($this->groupID));
        }

        $this->layout->addBreadcrumb(Sanitize::esc_html($this->slider['title']), 'ssi_16 ssi_16--image', $this->getUrlSliderEdit($this->slider['id'], $this->groupID));

        $this->layout->addBreadcrumb(n2_('Simple edit'), 'ssi_16 ssi_16--cog', $this->getUrlSliderSimpleEdit($this->slider['id'], $this->groupID));


        $topBar = new BlockTopBarMain($this);

        $buttonSave = new BlockButtonSave($this);
        $buttonSave->setLabel(n2_('Add slide'));
        $buttonSave->addClass('n2_slider_add_slide');
        $topBar->addPrimaryBlock($buttonSave);


        $buttonBack = new BlockButtonBack($this);
        $buttonBack->setUrl($this->getUrlSliderSimpleEdit($this->slider['id'], $this->groupID));
        $topBar->addPrimaryBlock($buttonBack);

        $this->layout->setTopBar($topBar->toHTML());

        $this->layout->addContent($this->render('SimpleEditAddSlide'));

        $this->layout->render();

    }

}Admin/Slider/Template/AjaxSliderBox.php000064400000000516152356646020014014 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Slider;


use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderBox\BlockSliderBox;

/**
 * @var $this ViewAjaxSliderBox
 */

$blockSliderBox = new BlockSliderBox($this);
$blockSliderBox->setSlider($this->getSlider());
$blockSliderBox->display();

Admin/Slider/Template/Edit.php000064400000001414152356646020012200 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Slider;

use Nextend\Framework\Asset\Js\Js;
use Nextend\SmartSlider3\Settings;

/**
 * @var $this ViewSliderEdit
 */

$slider = $this->getSlider();

JS::addInline('new _N2.SliderEdit(' . json_encode(array(
        'previewInNewWindow' => !!Settings::get('preview-new-window', 0),
        'saveAjaxUrl'        => $this->getAjaxUrlSliderEdit($slider['id']),
        'previewUrl'         => $this->getUrlPreviewSlider($slider['id']),
        'ajaxUrl'            => $this->getAjaxUrlSliderEdit($slider['id']),
        'formData'           => $this->formManager->getData()
    )) . ');');
?>

<form id="n2-ss-edit-slider-form" action="#" method="post">
    <?php
    $this->renderForm();
    ?>
</form>Admin/Slider/Template/SimpleEdit.php000064400000012464152356646020013361 0ustar00<?php
namespace Nextend\SmartSlider3\Application\Admin\Slider;

/**
 * @var $this ViewSliderSimpleEdit
 */

use Nextend\Framework\Data\Data;
use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Textarea;
use Nextend\Framework\Form\Element\Token;
use Nextend\Framework\Form\Form;
use Nextend\Framework\Sanitize;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonSave;
use Nextend\SmartSlider3\Application\Model\ModelSlides;
use Nextend\SmartSlider3\Slider\SliderParams;


$slider = $this->getSlider();

$sliderParams = new SliderParams($slider['id'], $slider['type'], $slider['params'], true);

$sliderData              = $sliderParams->toArray();
$sliderData['title']     = $slider['title'];
$sliderData['type']      = $slider['type'];
$sliderData['thumbnail'] = $slider['thumbnail'];
$sliderData['alias']     = isset($slider['alias']) ? $slider['alias'] : '';

?>
<form id="n2_slider_form" action="<?php echo esc_url($this->getUrlSliderSimpleEdit($slider['id'], $this->groupID)); ?>" method="post">
    <div id="slider-settings-region" role="region" tabindex="0" aria-label="<?php echo esc_attr(n2_('Slider settings') . ': ' . $slider['title']); ?>">
        <?php
        $form = new Form($this, 'slider');

        new Token($form->getFieldsetHidden());

        $form->loadArray($sliderData);

        $table = new ContainerTable($form->getContainer(), 'general', n2_('Slider settings'));

        $row1 = $table->createRow('general-1');

        new OnOff($row1, 'delete-slider', n2_('Delete slider'), 0);

        new Text($row1, 'title', n2_('Name'), n2_('Slider'), array(
            'style' => 'width:300px;'
        ));

        new Text($row1, 'aria-label', n2_('ARIA label'), n2_('Slider'), array(
            'style'          => 'width:200px;',
            'tipLabel'       => n2_('ARIA label'),
            'tipDescription' => n2_('It allows you to label your slider for screen readers.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1722-slider-settings-general#aria-label'
        ));

        $form->render();
        ?>
    </div>
    <?php

    $modelSlides = new ModelSlides($this);
    $slides      = $modelSlides->getAll($slider['id']);

    foreach ($slides as $slide) {
        $slideParams              = new Data($slide['params']);
        $slideData                = $slideParams->toArray();
        $slideData['ordering']    = $slide['ordering'];
        $slideData['title']       = $slide['title'];
        $slideData['description'] = $slide['description'];
        ?>
        <div role="region" tabindex="0" aria-label="<?php echo esc_attr(n2_('Edit slide') . ': ' . $slide['title']); ?>">
            <?php

            $form = new Form($this, 'slide[' . $slide['id'] . ']');

            $form->loadArray($slideData);

            $table = new ContainerTable($form->getContainer(), 'general', n2_('Slide') . ': ' . $slideData['title']);

            $row1 = $table->createRow('general-1');

            new OnOff($row1, 'delete-slide', n2_('Delete slide'), 0);

            new Text\Number($row1, 'ordering', n2_('Ordering'), 0, array(
                'wide' => 4
            ));

            new Text($row1, 'title', n2_('Slide title'), '', array(
                'style' => 'width:300px;'
            ));

            new Textarea($row1, 'description', n2_('Description'), '', array(
                'width' => 314
            ));

            new Text\FieldImage($row1, 'backgroundImage', n2_('Slide background'), '', array(
                'width' => 300
            ));


            new Select($row1, 'thumbnailType', n2_('Thumbnail type'), 'default', array(
                'options' => array(
                    'default'   => n2_('Default'),
                    'videoDark' => n2_('Video')
                )
            ));

            new Text($row1, 'href', n2_('Link'), '');
            new LinkTarget($row1, 'href-target', n2_('Target window'));

            $form->render();

            ?>
        </div>
        <?php
    }

    ?>
    <div style="margin: 20px;">
        <?php
        $buttonSave = new BlockButtonSave($this);
        $buttonSave->addClass('n2_slider_save');
        $buttonSave->display();
        ?>
    </div>
    <input type="hidden" name="save" value="1">
</form>

<script>
    _N2.r(['$', 'windowLoad'], function () {
        var $ = _N2.$;
        var $form = $('#n2_slider_form');

        $('#slider-settings-region').trigger("focus");

        $('.n2_slider_save').on('click', function (e) {
            e.preventDefault();

            $form.trigger("submit");
        });

        document.addEventListener('keydown', function (e) {
            if (e.ctrlKey || e.metaKey) {
                if (e.code === 'KeyS') { // ctrl + s
                    e.preventDefault();

                    $form.trigger("submit");
                }
            }
        }, {
            capture: true
        });
    });
</script>

<style>
    :FOCUS {
        box-shadow: 0 0 3px 1px #1d81f9 !important;
    }
</style>
Admin/Slider/Template/SimpleEditAddSlide.php000064400000006032152356646020014745 0ustar00<?php
namespace Nextend\SmartSlider3\Application\Admin\Slider;

use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Textarea;
use Nextend\Framework\Form\Element\Token;
use Nextend\Framework\Form\Form;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonSave;

/**
 * @var $this ViewSliderSimpleEditAddSlide
 */

$slider = $this->getSlider();

?>
<form id="n2_slider_add_slide_form" action="<?php echo esc_url($this->getUrlSliderSimpleEditAddSlide($slider['id'], $this->groupID)); ?>" method="post">
    <div id="slider-add-slide-region" role="region" tabindex="0" aria-label="<?php n2_e('Add slide'); ?>">
        <?php
        $form = new Form($this, 'slide');

        new Token($form->getFieldsetHidden());

        $table = new ContainerTable($form->getContainer(), 'general', n2_('Add slide'));

        $row1 = $table->createRow('general-1');

        new Text($row1, 'title', n2_('Slide title'), '', array(
            'style' => 'width:300px;'
        ));

        new Textarea($row1, 'description', n2_('Description'), '', array(
            'width' => 314
        ));

        new Text\FieldImage($row1, 'backgroundImage', n2_('Slide background'), '', array(
            'width' => 300
        ));

        new Text($row1, 'video', n2_('Video url'), '', array(
            'style' => 'width:300px;'
        ));

        new Select($row1, 'thumbnailType', n2_('Thumbnail type'), 'default', array(
            'options' => array(
                'default'   => n2_('Default'),
                'videoDark' => n2_('Video')
            )
        ));

        new Text($row1, 'href', n2_('Link'), '');
        new LinkTarget($row1, 'href-target', n2_('Target window'));

        $form->render();
        ?>
    </div>
    <div style="margin: 20px;">
        <?php
        $buttonSave = new BlockButtonSave($this);
        $buttonSave->setLabel(n2_('Add slide'));
        $buttonSave->addClass('n2_slider_add_slide');
        $buttonSave->display();
        ?>
    </div>
    <input type="hidden" name="save" value="1">
</form>

<script>
    _N2.r(['$', 'windowLoad'], function () {
        var $ = _N2.$;
        var $form = $('#n2_slider_add_slide_form');

        $('#slider-add-slide-region').trigger("focus");

        $('.n2_slider_add_slide').on('click', function (e) {
            e.preventDefault();

            $form.trigger("submit");
        });

        document.addEventListener('keydown', function (e) {
            if (e.ctrlKey || e.metaKey) {
                if (e.code === 'KeyS') { // ctrl + s
                    e.preventDefault();

                    $form.trigger("submit");
                }
            }
        }, {
            capture: true
        });
    });
</script>

<style>
    :FOCUS {
        box-shadow: 0 0 3px 1px #1d81f9 !important;
    }
</style>
Admin/Settings/AbstractViewSettings.php000064400000006144152356646020014242 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Settings;


use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header\BlockHeader;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header\MenuItem;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain\BlockTopBarMain;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonSave;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Generator\GeneratorFactory;

abstract class AbstractViewSettings extends AbstractView {

    use TraitAdminUrl;

    protected $active = 'general';

    /** @var LayoutDefault */
    protected $layout;

    /**
     * @var BlockHeader
     */
    protected $blockHeader;

    public function display() {

        $this->layout = new LayoutDefault($this);

        $this->layout->addBreadcrumb(n2_('Settings'), 'ssi_16 ssi_16--cog', $this->getUrlSettingsDefault());

        $this->displayTopBar();

        $this->displayHeader();
    }

    protected function displayTopBar() {

        $topBar = new BlockTopBarMain($this);

        $buttonSave = new BlockButtonSave($this);
        $buttonSave->addClass('n2_button--inactive');
        $buttonSave->addClass('n2_settings_save');
        $topBar->addPrimaryBlock($buttonSave);

        $this->layout->setTopBar($topBar->toHTML());
    }

    protected function displayHeader() {


        $this->blockHeader = new BlockHeader($this);
        $this->blockHeader->setHeading(n2_('Settings'));

        $general = new MenuItem(n2_('General'));
        $general->setUrl($this->getUrlSettingsDefault());
        $general->setActive($this->active == 'general');
        $this->blockHeader->addMenuItem($general);

        $framework = new MenuItem(n2_('Framework'));
        $framework->setUrl($this->getUrlSettingsFramework());
        $framework->setActive($this->active == 'framework');
        $this->blockHeader->addMenuItem($framework);

        $fonts = new MenuItem(n2_('Fonts'));
        $fonts->setUrl($this->getUrlSettingsFonts());
        $fonts->setActive($this->active == 'fonts');
        $this->blockHeader->addMenuItem($fonts);

        $itemDefaults = new MenuItem(n2_('Layer defaults'));
        $itemDefaults->setUrl($this->getUrlSettingsItemDefaults());
        $itemDefaults->setActive($this->active == 'itemDefaults');
        $this->blockHeader->addMenuItem($itemDefaults);

        foreach (GeneratorFactory::getGenerators() as $generator) {
            if ($generator->hasConfiguration()) {
                $generators = new MenuItem(n2_('Generators'));
                $generators->setUrl($this->getUrlSettingsGenerator($generator->getName()));
                $this->blockHeader->addMenuItem($generators);

                break;
            }
        }

        $this->addHeaderActions();

        $this->layout->addContentBlock($this->blockHeader);
    }

    protected function addHeaderActions() {

    }
}Admin/Settings/ControllerAjaxSettings.php000064400000013103152356646020014564 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Settings;


use Nextend\Framework\Cache\AbstractCache;
use Nextend\Framework\Cache\CacheImage;
use Nextend\Framework\Controller\Admin\AdminAjaxController;
use Nextend\Framework\Data\Data;
use Nextend\Framework\Filesystem\Filesystem;
use Nextend\Framework\Font\FontSettings;
use Nextend\Framework\Model\StorageSectionManager;
use Nextend\Framework\Notification\Notification;
use Nextend\Framework\Request\Request;
use Nextend\Framework\Settings;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Application\Model\ModelGenerator;
use Nextend\SmartSlider3\Application\Model\ModelSettings;
use Nextend\SmartSlider3\Application\Model\ModelSliders;

class ControllerAjaxSettings extends AdminAjaxController {

    use TraitAdminUrl;

    public function actionDefault() {
        $this->validateToken();

        $this->validatePermission('smartslider_config');

        $settingsModel = new ModelSettings($this);
        if ($settingsModel->save()) {
            $this->invalidateSliderCache();

            Notification::success(n2_('Saved and slider cache invalidated.'));
        }

        $this->response->redirect($this->getUrlSettingsDefault());
    }

    public function actionFramework() {
        $this->validateToken();

        $this->validatePermission('smartslider_config');

        $data = Request::$POST->getVar('global');
        if (is_array($data)) {
            Settings::setAll($data);
            $this->invalidateSliderCache();

            Notification::success(n2_('Saved and slider cache invalidated.'));
        }

        $this->response->redirect($this->getUrlSettingsFramework());
    }

    public function actionFonts() {
        $this->validateToken();

        $this->validatePermission('smartslider_config');

        $fonts = Request::$REQUEST->getVar('fonts', false);

        if ($fonts) {
            FontSettings::store($fonts);

            $this->invalidateSliderCache();

            Notification::success(n2_('Saved and slider cache invalidated.'));
        }

        $this->response->redirect($this->getUrlSettingsFonts());
    }

    public function actionItemDefaults() {
        $this->validateToken();

        $this->validatePermission('smartslider_config');

        $settingsModel = new ModelSettings($this);
        $settingsModel->saveDefaults(Request::$REQUEST->getVar('defaults', array()));

        $this->response->redirect($this->getUrlSettingsItemDefaults());
    }

    public function actionGeneratorConfigure() {
        $this->validateToken();

        $this->validatePermission('smartslider_config');

        $group = Request::$REQUEST->getVar('group');
        $this->validateVariable($group, 'group');

        $generatorModel = new ModelGenerator($this);

        $generatorGroup = $generatorModel->getGeneratorGroup($group);

        $configuration = $generatorGroup->getConfiguration();
        $configuration->addData(Request::$POST->getVar('generator'));

        $this->response->redirect($this->getUrlSettingsGenerator($generatorGroup->getName()));
    }

    public function actionDismissUpgradePro() {
        $this->validateToken();
        $storage = StorageSectionManager::getStorage('smartslider');
        $storage->set('free', 'upgrade-pro', 1);
        $this->response->respond();
    }

    public function actionRated() {
        $this->validateToken();
        $storage = StorageSectionManager::getStorage('smartslider');
        $storage->set('free', 'rated', 1);
        $this->response->respond();
    }

    public function actionDismissNewsletterSampleSliders() {
        $this->validateToken();

        $storage = StorageSectionManager::getStorage('smartslider');
        $storage->set('free', 'dismissNewsletterSampleSliders', 1);

        $this->response->respond();
    }

    public function actionDismissNewsletterDashboard() {
        $this->validateToken();

        $storage = StorageSectionManager::getStorage('smartslider');
        $storage->set('free', 'dismissNewsletterDashboard', 1);

        $this->response->respond();
    }

    public function actionSubscribed() {
        $this->validateToken();

        $storage = StorageSectionManager::getStorage('smartslider');
        $storage->set('free', 'subscribeOnImport', 1);

        $this->response->respond();
    }

    private function invalidateSliderCache() {

        $slidersModel = new ModelSliders($this);
        $slidersModel->invalidateCache();
    }

    public function actionClearCache() {

        $this->validateToken();

        $this->validatePermission('smartslider_config');

        $formData = new Data(Request::$POST->getVar('clear_cache', array()));
        if ($formData->get('delete-image-cache')) {

            $imageCachePath = CacheImage::getStorage()
                                        ->getPath('slider/cache', '', 'image');
            if (Filesystem::existsFolder($imageCachePath) && Filesystem::is_writable($imageCachePath)) {
                Filesystem::deleteFolder($imageCachePath);
            }
        }

        $slidersModel = new ModelSliders($this);
        foreach ($slidersModel->_getAll() as $slider) {
            $slidersModel->refreshCache($slider['id']);
        }
        AbstractCache::clearGroup('n2-ss-0');
        AbstractCache::clearGroup('combined');
        AbstractCache::clearAll();
        Notification::success(n2_('Cache cleared.'));

        Request::redirect($this->getUrlSettingsDefault());
    }
}Admin/Settings/ControllerSettings.php000064400000005173152356646020013770 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Settings;


use Nextend\Framework\Notification\Notification;
use Nextend\Framework\Request\Request;
use Nextend\Framework\Settings;
use Nextend\SmartSlider3\Application\Admin\AbstractControllerAdmin;
use Nextend\SmartSlider3\Application\Model\ModelGenerator;
use Nextend\SmartSlider3\Application\Model\ModelSliders;

class ControllerSettings extends AbstractControllerAdmin {

    public function actionDefault() {

        if ($this->validatePermission('smartslider_config')) {

            $view = new ViewSettingsGeneral($this);
            $view->display();

        }
    }

    public function actionFramework() {
        if ($this->canDo('smartslider_config')) {

            $data = Request::$POST->getVar('global');
            if (is_array($data)) {
                if ($this->validateToken()) {
                    Settings::setAll($data);
                    $this->invalidateSliderCache();

                    Notification::success(n2_('Saved and slider cache invalidated.'));
                }

                $this->redirect($this->getUrlSettingsFramework());
            }


            $view = new ViewSettingsFramework($this);
            $view->display();

        }
    }

    public function actionFonts() {
        if ($this->canDo('smartslider_config')) {

            $view = new ViewSettingsFonts($this);
            $view->display();

        }
    }

    public function actionItemDefaults() {

        if ($this->validatePermission('smartslider_config')) {

            $view = new ViewSettingsItemDefaults($this);
            $view->display();

        }
    }

    public function actionGeneratorConfigure() {
        if ($this->validatePermission('smartslider_config')) {

            $view = new ViewGeneratorConfigure($this);

            $generatorModel = new ModelGenerator($this);

            $group = Request::$REQUEST->getVar('group');

            $generatorGroup = $generatorModel->getGeneratorGroup($group);

            $configuration = $generatorGroup->getConfiguration();

            $view->setGeneratorGroup($generatorGroup);
            $view->setConfiguration($configuration);

            $view->display();
        }
    }

    public function actionClearCache() {
        if ($this->validatePermission('smartslider_config')) {
            $view = new ViewSettingsClearCache($this);
            $view->display();
        }
    }

    private function invalidateSliderCache() {

        $slidersModel = new ModelSliders($this);
        $slidersModel->invalidateCache();
    }
}Admin/Settings/ViewGeneratorConfigure.php000064400000005557152356646020014555 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Settings;


use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header\BlockHeader;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header\MenuItem;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain\BlockTopBarMain;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonSave;
use Nextend\SmartSlider3\Generator\AbstractGeneratorGroup;
use Nextend\SmartSlider3\Generator\AbstractGeneratorGroupConfiguration;
use Nextend\SmartSlider3\Generator\GeneratorFactory;

class ViewGeneratorConfigure extends AbstractViewSettings {

    protected $active = 'generator';

    /** @var AbstractGeneratorGroup */
    protected $generatorGroup;

    /** @var AbstractGeneratorGroupConfiguration */
    protected $configuration;

    public function display() {

        parent::display();


        $this->layout->addBreadcrumb($this->generatorGroup->getLabel(), '');

        $this->layout->addContent($this->render('GeneratorConfigure'));

        $this->layout->render();
    }

    protected function displayTopBar() {

        $topBar = new BlockTopBarMain($this);

        $buttonSave = new BlockButtonSave($this);
        $buttonSave->addClass('n2_button--inactive');
        $buttonSave->addClass('n2_generator_configuration_save');
        $topBar->addPrimaryBlock($buttonSave);

        $this->layout->setTopBar($topBar->toHTML());
    }

    protected function displayHeader() {

        $this->blockHeader = new BlockHeader($this);
        $this->blockHeader->setHeading(n2_('Generators'));

        foreach (GeneratorFactory::getGenerators() as $generatorGroup) {
            if ($generatorGroup->hasConfiguration()) {
                $button = new MenuItem($generatorGroup->getLabel());
                $button->setActive($this->generatorGroup === $generatorGroup);
                $button->setUrl($this->getUrlSettingsGenerator($generatorGroup->getName()));
                $this->blockHeader->addMenuItem($button);
            }
        }

        $this->layout->addContentBlock($this->blockHeader);
    }

    /**
     * @return AbstractGeneratorGroup
     */
    public function getGeneratorGroup() {
        return $this->generatorGroup;
    }

    /**
     * @param AbstractGeneratorGroup $generatorGroup
     */
    public function setGeneratorGroup($generatorGroup) {
        $this->generatorGroup = $generatorGroup;
    }

    /**
     * @return mixed
     */
    public function getConfiguration() {
        return $this->configuration;
    }

    /**
     * @param mixed $configuration
     */
    public function setConfiguration($configuration) {
        $this->configuration = $configuration;
    }

    public function renderForm() {

        $this->configuration->render($this);
    }

}Admin/Settings/ViewSettingsClearCache.php000064400000005573152356646020014456 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Settings;


use Nextend\Framework\Cache\CacheImage;
use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Message\Notice;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Token;
use Nextend\Framework\Form\Form;
use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain\BlockTopBarMain;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButton;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonBack;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;

class ViewSettingsClearCache extends AbstractView {

    use TraitAdminUrl;

    /**
     * @var LayoutDefault
     */
    protected $layout;

    public function display() {

        $this->layout = new LayoutDefault($this);

        $this->layout->addBreadcrumb(n2_('Settings'), 'ssi_16 ssi_16--cog', $this->getUrlSettingsDefault());

        $this->layout->addBreadcrumb(n2_('Clear cache'), '', $this->getUrlSettingsClearCache());

        $this->displayTopBar();

        $this->displayHeader();

        $this->layout->render();

    }

    protected function displayTopBar() {

        $topBar = new BlockTopBarMain($this);

        $buttonClearCache = new BlockButton($this);
        $buttonClearCache->addClass('n2_slider_clear_cache');
        $buttonClearCache->setLabel(n2_('Clear cache'));
        $buttonClearCache->setBig();
        $buttonClearCache->setGreen();
        $topBar->addPrimaryBlock($buttonClearCache);

        $buttonBack = new BlockButtonBack($this);
        $buttonBack->setUrl($this->getUrlSettingsDefault());
        $topBar->addPrimaryBlock($buttonBack);

        $this->layout->setTopBar($topBar->toHTML());
    }

    protected function displayHeader() {

        $this->layout->addContent($this->render('ClearCache'));
    }


    public function renderForm() {

        $form = new Form($this, 'clear_cache');

        new Token($form->getFieldsetHidden());

        $settings = new ContainerTable($form->getContainer(), 'clear-cache-options', n2_('Clear cache options'));


        $row1 = $settings->createRow('clear-cache');

        new OnOff($row1, 'delete-image-cache', n2_('Delete resized image cache'), 0);

        $instructions = sprintf(n2_('If enabled the following folder will be %1$spermanently deleted%2$s: %3$s'), '<b>', '</b>', CacheImage::getStorage()
                                                                                                                                           ->getPath('slider/cache', '', 'image'));
        new Notice($row1, 'instructions', n2_('Instruction'), $instructions);

        $form->render();
    }
}Admin/Settings/ViewSettingsFonts.php000064400000005167152356646020013574 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Settings;


use Nextend\Framework\Font\FontSettings;
use Nextend\Framework\Font\FontSources;
use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Message\Notice;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Textarea;
use Nextend\Framework\Form\Element\Token;
use Nextend\Framework\Form\Form;

class ViewSettingsFonts extends AbstractViewSettings {

    protected $active = 'fonts';

    public function display() {

        parent::display();

        $this->layout->addBreadcrumb(n2_('Fonts'), '');

        $this->layout->addContent($this->render('Fonts'));

        $this->layout->render();
    }

    public function renderForm() {

        $form = new Form($this, 'fonts');
        new Token($form->getFieldsetHidden());

        $form->loadArray(FontSettings::getData()
                                     ->toArray());
        $form->loadArray(FontSettings::getPluginsData()
                                     ->toArray());

        $table = new ContainerTable($form->getContainer(), 'fonts', n2_('Configuration'));

        $row1 = $table->createRow('fonts-1');

        $instruction = sprintf(n2_('Here you can configure the default font your layers have, and the dropdown list of the fonts. Google Fonts are recognized automatically, but you can use your own custom fonts, too. %1$sLearn how to do that.%2$s'), '<a href="https://smartslider.helpscoutdocs.com/article/1828-using-your-own-fonts" target="_blank">', '</a>');
        new Notice($row1, 'instructions', n2_('Instruction'), $instruction);

        $row2 = $table->createRow('fonts-2');

        new Text($row2, 'default-family', n2_('Default family'), '', array(
            'tipLabel'       => n2_('Default family'),
            'tipDescription' => n2_('This font family is used for the newly added layers.')
        ));


        $row3 = $table->createRow('fonts-1');
        new Textarea($row3, 'preset-families', n2_('Preset font families'), '', array(
            'width'          => 200,
            'height'         => 300,
            'tipLabel'       => n2_('Preset font families'),
            'tipDescription' => n2_('These font families appear in the dropdown list.')
        ));

        $fountSources = FontSources::getFontSources();


        foreach ($fountSources as $fountSource) {

            $table = new ContainerTable($form->getContainer(), $fountSource->getName(), $fountSource->getLabel());

            $fountSource->renderFields($table);
        }

        $form->render();
    }
}Admin/Settings/ViewSettingsFramework.php000064400000006412152356646020014432 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Settings;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Token;
use Nextend\Framework\Form\Form;
use Nextend\Framework\Settings;

class ViewSettingsFramework extends AbstractViewSettings {

    protected $active = 'framework';

    public function display() {

        parent::display();

        $this->layout->addBreadcrumb(n2_('Framework'), '');

        $this->layout->addContent($this->render('Framework'));

        $this->layout->render();
    }

    public function renderForm() {

        $values = Settings::getAll();

        $form = new Form($this, 'global');
        $form->loadArray($values);


        $table = new ContainerTable($form->getContainer(), 'framework', n2_('Framework'));

        $row1 = $table->createRow('framework-1');

        new Token($row1);
        new OnOff($row1, 'protocol-relative', n2_('Use protocol-relative URL'), 1, array(
            'tipLabel'       => n2_('Use protocol-relative URL'),
            'tipDescription' => n2_('Loads the URLs without a http or https protocol.')
        ));
        new OnOff($row1, 'header-preload', n2_('Header preload'), 0, array(
            'tipLabel'       => n2_('Header preload'),
            'tipDescription' => n2_('If the slider is an important part of your site, tell the browser to preload its files.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1785-framework#header-preload'
        ));

        new OnOff($row1, 'force-english-backend', n2_('English UI'), 0, array(
            'tipLabel'       => n2_('English UI'),
            'tipDescription' => n2_('You can keep using Smart Slider 3 in English, even if your backend isn\'t in English.')
        ));

        new OnOff($row1, 'frontend-accessibility', n2_('Improved frontend accessibility'), 1, array(
            'tipLabel'       => n2_('Improved frontend accessibility'),
            'tipDescription' => n2_('Keeps the clicked element (like a button) in focus unless the focus is changed by clicking away.')
        ));


        $table = new ContainerTable($form->getContainer(), 'javascript', 'JavaScript');

        $row1 = $table->createRow('javascript-1');

        new Text($row1, 'scriptattributes', n2_('Script attributes'), '');
        new Select($row1, 'javascript-inline', n2_('Slider\'s inline JavaScript'), 'head', array(
            'options' => array(
                'head' => n2_('Head'),
                'body' => n2_('Into the slider')
            )
        ));
    

        $table = new ContainerTable($form->getContainer(), 'css', 'CSS');

        $row1 = $table->createRow('css-1');
        new OnOff($row1, 'async-non-primary-css', n2_('Async non-primary CSS'), 0, array(
            'tipLabel'       => n2_('Async non-primary CSS'),
            'tipDescription' => n2_('Google Fonts, icon and lightbox CSS are loaded in a non-blocking way. Disable if you see missing icons, fonts or styles.')
        ));
        new OnOff($row1, 'icon-fa', n2_('Load Font Awesome 4'), 1);
    


        $form->render();
    }
}Admin/Settings/ViewSettingsGeneral.php000064400000023720152356646020014053 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Settings;

use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Breakpoint;
use Nextend\Framework\Form\Element\Hidden;
use Nextend\Framework\Form\Element\Message\Notice;
use Nextend\Framework\Form\Element\MixedField;
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\Element\Text\TextAutoComplete;
use Nextend\Framework\Form\Element\Textarea;
use Nextend\Framework\Form\Element\Token;
use Nextend\Framework\Form\Form;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButton;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Platform\Joomla\JoomlaShim;
use Nextend\SmartSlider3\Settings;

class ViewSettingsGeneral extends AbstractViewSettings {

    use TraitAdminUrl;

    protected $active = 'general';

    const defaults = array(
        'desktop-large-portrait'  => 1440,
        'desktop-large-landscape' => 1440,
        'tablet-large-portrait'   => 1300,
        'tablet-large-landscape'  => 1300,
        'tablet-portrait'         => 1199,
        'tablet-landscape'        => 1199,
        'mobile-large-portrait'   => 900,
        'mobile-large-landscape'  => 1050,
        'mobile-portrait'         => 700,
        'mobile-landscape'        => 900,
    );

    public function display() {

        parent::display();

        $this->layout->addContent($this->render('General'));

        $this->layout->render();
    }

    protected function addHeaderActions() {

        $buttonClearCache = new BlockButton($this);
        $buttonClearCache->setBig();
        $buttonClearCache->setLabel(n2_('Clear cache'));
        $buttonClearCache->setUrl($this->getUrlSettingsClearCache());
        $this->blockHeader->addAction($buttonClearCache->toHTML());

    }

    public function renderForm() {
        $data = Settings::getAll();

        $form = new Form($this, 'settings');
        $form->loadArray($data);

        $table = new ContainerTable($form->getContainer(), 'general', n2_('General settings'));

        $row1 = $table->createRow('general-1');

        new Token($row1);

        new Hidden($row1, 'slidersOrder2', '');

        new Hidden($row1, 'slidersOrder2Direction', '');

        new OnOff($row1, 'autoupdatecheck', n2_('Automatic update check'), 1);

        new OnOff($row1, 'slide-as-file', n2_('Alternative save slide'), 0, array(
            'tipLabel'       => n2_('Alternative save slide'),
            'tipDescription' => n2_('If you experience problems during the save this option might solve them.')
        ));
        new OnOff($row1, 'preview-new-window', n2_('Preview in new window'), 0);

        $row3 = $table->createRow('general-3');
        new OnOff($row3, 'lightbox-mobile-new-tab', n2_('Lightbox videos in new tab on Mobile'), 1, array(
            'tipLabel'       => n2_('Lightbox videos in new tab on Mobile'),
            'tipDescription' => n2_('Opens the lightbox videos in the YouTube app to avoid the mobile disabling the video.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1783-general#lightbox-videos-in-new-tab-on-mobile'
        ));
    

        new OnOff($row3, 'youtube-privacy-enhanced', n2_('YouTube and Vimeo privacy enhanced mode'), 0);

        new Number($row3, 'smooth-scroll-speed', n2_('Smooth scroll speed'), 400, array(
            'wide' => 5,
            'unit' => 'ms'
        ));


        $row4 = $table->createRow('general-4');
        new Textarea($row4, 'external-css-files', n2_('Editor - additional CSS files'), '', array(
            'width'          => 300,
            'tipLabel'       => n2_('Editor - additional CSS files'),
            'tipDescription' => n2_('You can call your own CSS files to our backend, for example, to be able to use custom fonts. Write each URL to a new line.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1783-general#editor-additional-css-files'
        ));
        $table     = new ContainerTable($form->getContainer(), 'joomla', n2_('Joomla settings'));
        $rowJoomla = $table->createRow('joomla-row');

        new OnOff($rowJoomla, 'force-rtl-backend', n2_('Force RTL backend'), 0);

        new OnOff($rowJoomla, 'joomla-plugins-content-enabled', n2_('Run content plugins on sliders'), 1, array(
            'relatedFieldsOn' => array(
                'settingsjoomla-plugins-content-excluded'
            )
        ));

        new Select($rowJoomla, 'joomla-plugins-content-excluded', n2_('Exclude plugins'), '', array(
            'isMultiple' => true,
            'options'    => JoomlaShim::getOnContentPreparePluginsList()
        ));

    

        $table = new ContainerTable($form->getContainer(), 'breakpoints-table', n2_('Breakpoints'));

        $instructionRow = $table->createRow('breakpoints-row-instruction');
        $instructions   = n2_('Breakpoints define the browser width in pixel when the slider switches to a different device.') . ' ' . n2_('At each slider you can override the global breakpoints with local values.');
        new Notice($instructionRow, 'breakpoints-instructions', n2_('Instruction'), $instructions);
        new Text\HiddenText($table->getFieldsetLabel(), 'responsive-screen-width-desktop-portrait', false, self::defaults['desktop-large-portrait']);
        new Text\HiddenText($table->getFieldsetLabel(), 'responsive-screen-width-desktop-portrait-landscape', false, self::defaults['desktop-large-landscape']);

        new Text\HiddenText($table->getFieldsetLabel(), 'responsive-screen-width-tablet-landscape', false, self::defaults['tablet-large-portrait']);
        new Text\HiddenText($table->getFieldsetLabel(), 'responsive-screen-width-tablet-landscape-landscape', false, self::defaults['tablet-large-landscape']);
    

        new Text\HiddenText($table->getFieldsetLabel(), 'responsive-screen-width-tablet-portrait', false, self::defaults['tablet-portrait']);
        new Text\HiddenText($table->getFieldsetLabel(), 'responsive-screen-width-tablet-portrait-landscape', false, self::defaults['tablet-landscape']);
        new Text\HiddenText($table->getFieldsetLabel(), 'responsive-screen-width-mobile-landscape', false, self::defaults['mobile-large-portrait']);
        new Text\HiddenText($table->getFieldsetLabel(), 'responsive-screen-width-mobile-landscape-landscape', false, self::defaults['mobile-large-landscape']);
    

        new Text\HiddenText($table->getFieldsetLabel(), 'responsive-screen-width-mobile-portrait', false, self::defaults['mobile-portrait']);
        new Text\HiddenText($table->getFieldsetLabel(), 'responsive-screen-width-mobile-portrait-landscape', false, self::defaults['mobile-landscape']);

        $rowBreakpoints = $table->createRow('breakpoints-row-1');
        new Breakpoint($rowBreakpoints, 'breakpoints', array(
            'desktoplandscape-portrait'  => 'settingsresponsive-screen-width-desktop-portrait',
            'desktoplandscape-landscape' => 'settingsresponsive-screen-width-desktop-portrait-landscape',
            'tabletlandscape-portrait'   => 'settingsresponsive-screen-width-tablet-landscape',
            'tabletlandscape-landscape'  => 'settingsresponsive-screen-width-tablet-landscape-landscape',
            'tabletportrait-portrait'    => 'settingsresponsive-screen-width-tablet-portrait',
            'tabletportrait-landscape'   => 'settingsresponsive-screen-width-tablet-portrait-landscape',
            'mobilelandscape-portrait'   => 'settingsresponsive-screen-width-mobile-landscape',
            'mobilelandscape-landscape'  => 'settingsresponsive-screen-width-mobile-landscape-landscape',
            'mobileportrait-portrait'    => 'settingsresponsive-screen-width-mobile-portrait',
            'mobileportrait-landscape'   => 'settingsresponsive-screen-width-mobile-portrait-landscape'
        ));
    

        $table = new ContainerTable($form->getContainer(), 'focus-offset', n2_('Focus offset'));
        $row1  = $table->createRow('focus-offset-1');
        new Notice($row1, 'focus-instructions', n2_('Instruction'), n2_('This option is used at the full page layout to decrease the slider height. The "Scroll to slider" option also uses this option to determine where to scroll the slider.'));

        $row2 = $table->createRow('focus-offset-2');
        $row2HeightOffsetValue = '';
    
        new TextAutoComplete($row2, 'responsive-focus-top', n2_('Top'), $row2HeightOffsetValue, array(
            'style'  => 'width:200px;',
            'values' => array($row2HeightOffsetValue)
        ));
        new Text($row2, 'responsive-focus-bottom', n2_('Bottom'), '', array(
            'style' => 'width:200px;'
        ));


        $table = new ContainerTable($form->getContainer(), 'translate-url', n2_('Translate url'));
        $row1  = $table->createRow('translate-url-1');
        new Notice($row1, 'translate-url-instruction', n2_('Instruction'), n2_('You can change the frontend URL our assets are loading from. It can be useful after moving to a new domain.'));

        $row2 = $table->createRow('translate-url-2');

        $translateUrl = new MixedField($row2, 'translate-url', false, '|*|');
        new Text($translateUrl, 'translate-url-1', n2_('From'), '', array(
            'style'          => 'width:200px;',
            'tipLabel'       => n2_('From'),
            'tipDescription' => n2_('The old URL you want to replace. E.g. https://oldsite.com/')
        ));
        new Text($translateUrl, 'translate-url-2', n2_('To'), '', array(
            'style'          => 'width:200px;',
            'tipLabel'       => n2_('To'),
            'tipDescription' => n2_('The new URL you want to use. E.g. https://newsite.com')
        ));

        $form->render();

        echo '<input name="namespace" value="default" type="hidden">';
    }
}Admin/Settings/ViewSettingsItemDefaults.php000064400000001551152356646020015062 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Settings;


use Nextend\Framework\Form\Element\Token;
use Nextend\Framework\Form\Form;
use Nextend\SmartSlider3\Renderable\Item\ItemFactory;

class ViewSettingsItemDefaults extends AbstractViewSettings {

    protected $active = 'itemDefaults';

    public function display() {

        parent::display();

        $this->layout->addBreadcrumb(n2_('Layer defaults'), '');

        $this->layout->addContent($this->render('ItemDefaults'));

        $this->layout->render();
    }

    public function renderForm() {

        $form = new Form($this, 'defaults');

        new Token($form->getFieldsetHidden());

        foreach (ItemFactory::getItems() as $item) {
            $item->globalDefaultItemFontAndStyle($form->getContainer());
        }

        $form->render();
    }
}Admin/Settings/Template/ClearCache.php000064400000000763152356646020013651 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Settings;

/**
 * @var $this ViewSettingsClearCache
 */
?>
<form id="n2_slider_clear_cache_form" action="<?php echo esc_url($this->getAjaxUrlSettingsClearCache()); ?>" method="post">
    <?php
    $this->renderForm();
    ?>
</form>

<script>
    document.querySelector('.n2_slider_clear_cache').addEventListener('click', function () {
        document.getElementById('n2_slider_clear_cache_form').submit();
    });
</script>Admin/Settings/Template/Fonts.php000064400000000573152356646020012767 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Settings;

use Nextend\Framework\Asset\Js\Js;

/**
 * @var $this ViewSettingsFonts
 */

JS::addInline('new _N2.SettingsFonts();');

?>

<form id="n2-ss-form-settings-fonts" method="post" action="<?php echo esc_url($this->getAjaxUrlSettingsFonts()); ?>">
    <?php
    $this->renderForm();
    ?>
</form>
Admin/Settings/Template/Framework.php000064400000000607152356646020013631 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Settings;

use Nextend\Framework\Asset\Js\Js;

/**
 * @var $this ViewSettingsFramework
 */

JS::addInline('new _N2.SettingsFramework();');
?>
<form id="n2-ss-form-settings-framework" method="post" action="<?php echo esc_url($this->getAjaxUrlSettingsFramework()); ?>">
    <?php
    $this->renderForm();
    ?>
</form>
Admin/Settings/Template/General.php000064400000000601152356646020013243 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Settings;


use Nextend\Framework\Asset\Js\Js;

/**
 * @var $this ViewSettingsGeneral
 */

JS::addInline('new _N2.SettingsGeneral();');
?>

<form id="n2-ss-form-settings-general" action="<?php echo esc_url($this->getAjaxUrlSettingsDefault()); ?>" method="post">
    <?php
    $this->renderForm();
    ?>
</form>Admin/Settings/Template/ItemDefaults.php000064400000000626152356646020014263 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Settings;


use Nextend\Framework\Asset\Js\Js;

/**
 * @var $this ViewSettingsItemDefaults
 */

JS::addInline('new _N2.SettingsItemDefaults();');
?>

<form id="n2-ss-form-settings-item-defaults" action="<?php echo esc_url($this->getAjaxUrlSettingsItemDefaults()); ?>" method="post">
    <?php
    $this->renderForm();
    ?>
</form>Admin/Settings/Template/GeneratorConfigure.php000064400000001101152356646020015452 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Settings;

use Nextend\Framework\Asset\Js\Js;

/**
 * @var ViewGeneratorConfigure $this
 */

JS::addInline('new _N2.GeneratorConfigure();');
?>
<form id="n2-ss-form-generator-configure" action="<?php echo esc_url($this->getAjaxUrlSettingsGenerator($this->getGeneratorGroup()
                                                                                                             ->getName())); ?>" method="post">
    <?php
    $this->renderForm();
    ?>
</form>

<div style="height: 200px"></div>Admin/Preview/ControllerPreview.php000064400000011067152356646020013431 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Preview;


use Nextend\Framework\Misc\Base64;
use Nextend\Framework\Request\Request;
use Nextend\SmartSlider3\Application\Admin\AbstractControllerAdmin;
use Nextend\SmartSlider3\Application\Model\ModelGenerator;
use Nextend\SmartSlider3\Application\Model\ModelSlides;
use Nextend\SmartSlider3\SmartSlider3Info;

class ControllerPreview extends AbstractControllerAdmin {

    private $sliderId = 0;

    public function initialize() {
        parent::initialize();

        $this->sliderId = Request::$REQUEST->getInt('sliderid');

        SmartSlider3Info::$forceDesktop = true;
    }

    public function actionIndex() {

        if ($this->validateToken() && $this->validatePermission('smartslider_edit')) {

            $view = new ViewPreviewIndex($this);

            $view->setSliderID($this->sliderId);


            $sliderData = Request::$POST->getVar('slider', false);
            if (!is_array($sliderData)) {
                $sliderData = false;
            }
            $view->setSliderData($sliderData);

            $view->display();

        } else {

            $this->permissionError();
        }
    }

    public function actionFull() {

        if ($this->validateToken()) {
            $view = new ViewPreviewFull($this);

            $view->setSliderData(json_decode(Request::$POST->getVar('sliderData', '[]'), true));
            $view->setSlidesData(json_decode(Request::$POST->getVar('slidesData', '[]'), true));
            $view->setGeneratorData(json_decode(Request::$POST->getVar('generatorData', '[]'), true));
            $view->setSliderID($this->sliderId);

            $view->display();
        } else {

            $this->permissionError();
        }
    }

    public function actionSlider() {
        if ($this->validateToken() && $this->validatePermission('smartslider_edit')) {

            $view = new ViewPreviewIndex($this);
            $view->setIsIframe(true);
            $view->setSliderID($this->sliderId);


            $sliderData = Request::$POST->getVar('slider', false);
            if (!is_array($sliderData)) {
                $sliderData = false;
            }
            $view->setSliderData($sliderData);

            $view->display();

        } else {

            $this->permissionError();
        }
    }

    public function actionSlide() {
        if ($this->validateToken() && $this->validatePermission('smartslider_edit')) {
            $slideId = Request::$REQUEST->getInt('slideId');
            if ($this->sliderId) {
                $slidesData  = array();
                $slidesModel = new ModelSlides($this);
                $slideData   = Request::$REQUEST->getVar('slide');
                if (!empty($slideData)) {
                    $slide           = $slidesModel->convertSlideDataToDatabaseRow(json_decode(Base64::decode($slideData), true));
                    $slide['slide']  = json_encode($slide['slide']);
                    $slide['params'] = json_encode($slide['params']);
                    if ($slideId) {
                        $slide['id']          = $slideId;
                        $slidesData[$slideId] = $slide;
                    }
                }

                $view = new ViewPreviewIndex($this);
                if (Request::$REQUEST->getVar('frame')) {
                    $view->setIsIframe(true);
                }
                $view->setSliderID($this->sliderId);
                $view->setSlidesData($slidesData);

                $view->display();
            }
        } else {

            $this->permissionError();
        }
    }

    public function actionGenerator() {
        if ($this->validateToken() && $this->validatePermission('smartslider_edit')) {
            $generator_id = Request::$REQUEST->getInt('generator_id');

            $generatorModel = new ModelGenerator($this);
            $sliderID       = $generatorModel->getSliderId($generator_id);

            if ($sliderID) {
                $generatorData = array();

                $generatorData[$generator_id] = Request::$REQUEST->getVar('generator');


                $view = new ViewPreviewIndex($this);
                $view->setIsIframe(true);
                $view->setSliderID($sliderID);
                $view->setGeneratorData($generatorData);

                $view->display();
            }
        } else {

            $this->permissionError();
        }
    }

    private function permissionError() {

        $this->redirectToSliders();
    }
}Admin/Preview/ViewPreviewFull.php000064400000004566152356646020013051 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Preview;


use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutEmpty;
use Nextend\SmartSlider3\SliderManager\SliderManager;

class ViewPreviewFull extends AbstractView {

    /** @var integer */
    protected $sliderID;

    /** @var array */
    protected $sliderData;

    /** @var array */
    protected $slidesData;

    /** @var array */
    protected $generatorData;

    public function display() {
        $this->layout = new LayoutEmpty($this);

        $this->layout->addContent($this->render('Full'));

        $this->layout->render();

    }

    /**
     * @return int
     */
    public function getSliderID() {
        return $this->sliderID;
    }

    /**
     * @param int $sliderID
     */
    public function setSliderID($sliderID) {
        $this->sliderID = $sliderID;
    }

    /**
     * @return array
     */
    public function getSliderData() {
        return $this->sliderData;
    }

    /**
     * @param array $sliderData
     */
    public function setSliderData($sliderData) {
        $this->sliderData = $sliderData;
    }

    /**
     * @return array
     */
    public function getSlidesData() {
        return $this->slidesData;
    }

    /**
     * @param array $slidesData
     */
    public function setSlidesData($slidesData) {
        $this->slidesData = $slidesData;
    }

    /**
     * @return array
     */
    public function getGeneratorData() {
        return $this->generatorData;
    }

    /**
     * @param array $generatorData
     */
    public function setGeneratorData($generatorData) {
        $this->generatorData = $generatorData;
    }

    /**
     * @return string Return value is already escaped
     */
    public function renderSlider() {

        $locale = setlocale(LC_NUMERIC, 0);
        setlocale(LC_NUMERIC, "C");

        $sliderManager = new SliderManager($this, $this->sliderID, true, array(
            'sliderData'    => $this->sliderData,
            'slidesData'    => $this->slidesData,
            'generatorData' => $this->generatorData
        ));
        $sliderManager->allowDisplayWhenEmpty();

        $sliderHTML = $sliderManager->render();

        setlocale(LC_NUMERIC, $locale);

        return $sliderHTML;
    }
}Admin/Preview/ViewPreviewIndex.php000064400000012643152356646020013211 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Preview;


use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButton;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutIframe;
use Nextend\SmartSlider3\Application\Admin\Preview\Block\PreviewToolbar\BlockPreviewToolbar;
use Nextend\SmartSlider3\Application\Admin\Settings\ViewSettingsGeneral;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Application\Model\ModelSliders;
use Nextend\SmartSlider3\Settings;
use Nextend\SmartSlider3\Slider\SliderParams;

class ViewPreviewIndex extends AbstractView {

    use TraitAdminUrl;

    /** @var integer */
    protected $sliderID;

    /** @var array */
    protected $sliderData = array();

    /** @var array */
    protected $slidesData = array();

    /** @var array */
    protected $generatorData = array();

    protected $isIframe = false;

    public function display() {
        $this->layout = new LayoutIframe($this);

        $this->layout->setLabel(n2_('Preview'));

        $blockPreviewToolbar = new BlockPreviewToolbar($this);
        $blockPreviewToolbar->setSliderID($this->sliderID);
        $this->layout->addAction($blockPreviewToolbar);

        if ($this->isIframe) {
            $buttonClose = new BlockButton($this);
            $buttonClose->addClass('n2_preview_slider__close');
            $buttonClose->setLabel(n2_('Close'));
            $buttonClose->setBig();
            $buttonClose->setGreyDark();
            $this->layout->addAction($buttonClose);
        }

        $this->layout->addContent($this->render('Index'));

        $this->layout->render();
    }

    /**
     * @return int
     */
    public function getSliderID() {
        return $this->sliderID;
    }

    /**
     * @param int $sliderID
     */
    public function setSliderID($sliderID) {
        $this->sliderID = $sliderID;
    }

    /**
     * @return array
     */
    public function getSliderData() {
        return $this->sliderData;
    }

    /**
     * @param array $sliderData
     */
    public function setSliderData($sliderData) {
        $this->sliderData = $sliderData;
    }

    public function getWidthCSS() {
        if ($this->sliderData) {
            $sliderParams = new SliderParams($this->sliderID, $this->sliderData['type'], $this->sliderData);
        } else {
            $model        = new ModelSliders($this);
            $slider       = $model->get($this->sliderID);
            $sliderParams = new SliderParams($this->sliderID, $slider['type'], $slider['params'], true);
        }

        if ($sliderParams->get('responsive-mode') == 'fullwidth' || $sliderParams->get('responsive-mode') == 'fullpage') {
            return '';
        }

        $minScreenWidth = $sliderParams->get('width');

        if (intval($sliderParams->get('responsive-breakpoint-tablet-landscape-enabled', 0))) {
            $useLocalBreakpoints = !$sliderParams->get('responsive-breakpoint-global', 0);

            $minScreenWidth = max($minScreenWidth, 1 + intval($useLocalBreakpoints ? $sliderParams->get('responsive-breakpoint-tablet-landscape', ViewSettingsGeneral::defaults['tablet-large-portrait']) : Settings::get('responsive-screen-width-tablet-landscape', ViewSettingsGeneral::defaults['tablet-large-portrait'])));
            $minScreenWidth = max($minScreenWidth, 1 + ($useLocalBreakpoints ? $sliderParams->get('responsive-breakpoint-tablet-landscape-landscape', ViewSettingsGeneral::defaults['tablet-large-landscape']) : Settings::get('responsive-screen-width-tablet-landscape-landscape', ViewSettingsGeneral::defaults['tablet-large-landscape'])));

        }
        if (intval($sliderParams->get('responsive-breakpoint-tablet-portrait-enabled', 0))) {
            $useLocalBreakpoints = !$sliderParams->get('responsive-breakpoint-global', 0);

            $minScreenWidth = max($minScreenWidth, 1 + intval($useLocalBreakpoints ? $sliderParams->get('responsive-breakpoint-tablet-portrait', ViewSettingsGeneral::defaults['tablet-portrait']) : Settings::get('responsive-screen-width-tablet-portrait', ViewSettingsGeneral::defaults['tablet-portrait'])));
            $minScreenWidth = max($minScreenWidth, 1 + intval($useLocalBreakpoints ? $sliderParams->get('responsive-breakpoint-tablet-portrait-landscape', ViewSettingsGeneral::defaults['tablet-landscape']) : Settings::get('responsive-screen-width-tablet-portrait-landscape', ViewSettingsGeneral::defaults['tablet-landscape'])));

        }

        return 'max-width:' . $minScreenWidth . 'px;';
    }

    /**
     * @return array
     */
    public function getSlidesData() {
        return $this->slidesData;
    }

    /**
     * @param array $slidesData
     */
    public function setSlidesData($slidesData) {
        $this->slidesData = $slidesData;
    }

    /**
     * @return array
     */
    public function getGeneratorData() {
        return $this->generatorData;
    }

    /**
     * @param array $generatorData
     */
    public function setGeneratorData($generatorData) {
        $this->generatorData = $generatorData;
    }

    /**
     * @return bool
     */
    public function isIframe() {
        return $this->isIframe;
    }

    /**
     * @param bool $isIframe
     */
    public function setIsIframe($isIframe) {
        $this->isIframe = $isIframe;
    }
}Admin/Preview/Block/PreviewToolbar/BlockPreviewToolbar.php000064400000001255152356646020017657 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Preview\Block\PreviewToolbar;


use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;

class BlockPreviewToolbar extends AbstractBlock {

    use TraitAdminUrl;

    /** @var integer */
    protected $sliderID;

    public function display() {

        $this->renderTemplatePart('PreviewToolbar');
    }

    /**
     * @return int
     */
    public function getSliderID() {
        return $this->sliderID;
    }

    /**
     * @param int $sliderID
     */
    public function setSliderID($sliderID) {
        $this->sliderID = $sliderID;
    }
}Admin/Preview/Block/PreviewToolbar/PreviewToolbar.php000064400000004253152356646020016705 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Preview\Block\PreviewToolbar;

use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonPlainIcon;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonSpacer;

/**
 * @var $this BlockPreviewToolbar
 */

?>
<div class="n2_preview_toolbar">
    <div class="n2_preview_toolbar__size">
        <div class="n2_preview_toolbar__editable n2_preview_toolbar__width">
            1200
        </div>
        <div class="n2_preview_toolbar__x">
            X
        </div>
        <div class="n2_preview_toolbar__editable n2_preview_toolbar__height">
            800
        </div>
    </div>
    <select class="n2_preview_toolbar__scale">
        <option value="25">25%</option>
        <option value="50">50%</option>
        <option value="75">75%</option>
        <option value="100" selected>100%</option>
        <option value="125">125%</option>
        <option value="150">150%</option>
    </select>
    <?php

    $buttonOrientation = new BlockButtonPlainIcon($this);
    $buttonOrientation->addClass('n2_button_preview_orientation');
    $buttonOrientation->addAttribute('data-n2tip', n2_('Toggle orientation'));
    $buttonOrientation->setBig();
    $buttonOrientation->setIcon('ssi_24 ssi_24--orientation');
    $buttonOrientation->display();

    $spacer = new BlockButtonSpacer($this);
    $spacer->setIsVisible(true);
    $spacer->display();

    $buttonReload = new BlockButtonPlainIcon($this);
    $buttonReload->addClass('n2_button_preview_reload');
    $buttonReload->addAttribute('data-n2tip', n2_('Reload preview'));
    $buttonReload->setBig();
    $buttonReload->setIcon('ssi_24 ssi_24--redo');
    $buttonReload->display();

    $buttonFullPreview = new BlockButtonPlainIcon($this);
    $buttonFullPreview->setUrl($this->getUrlPreviewFull($this->getSliderID()));
    $buttonFullPreview->addAttribute('data-n2tip', n2_('Open preview in full'));
    $buttonFullPreview->setTarget('_blank');
    $buttonFullPreview->setBig();
    $buttonFullPreview->setIcon('ssi_24 ssi_24--newwindow');
    $buttonFullPreview->display();
    ?>
</div>
Admin/Preview/Template/Full.php000064400000014420152356646020012415 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Preview;

use Nextend\Framework\Asset\Js\Js;
use Nextend\SmartSlider3\Settings;

/**
 * @var $this ViewPreviewFull
 */

JS::addGlobalInline('document.documentElement.classList.add("n2_html--application-only");');
JS::addGlobalInline('document.documentElement.classList.add("n2_html--slider-preview");');

$slider = $this->renderSlider();

$externals = Settings::get('external-css-files');
if (!empty($externals)) {
    $externals = explode("\n", $externals);
    foreach ($externals as $external) {
        echo "<link rel='stylesheet' href='" . esc_url($external) . "' type='text/css' media='all'>";
    }
}

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


$slidesData = $this->getSlidesData();
if (!empty($slidesData)) {
    $slideId = key($slidesData);
    if ($slideId > 0) {
        ?>
        <script>
            n2ss.ready(<?php echo esc_html($this->getSliderID()); ?>, function (slider) {
                slider.visible(function () {
                    slider.slideToID(<?php echo esc_html($slideId); ?>);
                });
            });
        </script>
        <?php
    }
}
?>

<script>

    document.addEventListener('keydown', function (e) {
        if (e.key === 'Escape') {
            parent.postMessage(JSON.stringify({action: 'cancel'}), "*");
        }
    });
    if (window.parent !== window) {
        _N2.r(['$', 'documentReady'], function () {
            var $ = _N2.$,
                html = document.documentElement,
                body = document.body,
                $sliders = $('.n2-ss-slider');

            function syncDeviceDetails() {
                $sliders.each(function () {
                    var match = $(this).attr('id').match(/n2-ss-([0-9]+)/);
                    if (match) {
                        n2ss.ready(match[1], function (slider) {
                            slider.stages.done('Show', function () {
                                syncDeviceDetailsSlider(slider);
                            });
                        });
                    }
                });
            }

            function syncDeviceDetailsSlider(slider) {
                var isLandscape = window.matchMedia("(orientation: landscape)").matches,
                    breakpoints = slider.responsive.parameters.breakpoints,
                    breakpoint, screenWidthLimit, maxWidth = -1, minWidth = 0, hadMinScreenWidth = false, i;

                for (i = breakpoints.length - 1; i >= 0; i--) {
                    breakpoint = breakpoints[i];
                    screenWidthLimit = isLandscape ? breakpoint.landscapeWidth : breakpoint.portraitWidth;

                    if (breakpoint.type === 'max-screen-width') {
                        minWidth = maxWidth + 1;
                        maxWidth = screenWidthLimit;
                    } else if (breakpoint.type === 'min-screen-width') {
                        hadMinScreenWidth = true;
                        if (slider.responsive.device === 'desktopPortrait') {
                            maxWidth = screenWidthLimit - 1;
                        } else {
                            minWidth = screenWidthLimit;
                            maxWidth = 100000;
                        }
                    }

                    if (breakpoint.device === slider.responsive.device) {
                        break;
                    }
                }

                if (!hadMinScreenWidth && slider.responsive.device === 'desktopPortrait') {
                    minWidth = screenWidthLimit + 1;
                    maxWidth = 100000;
                }

                window.parent.postMessage(
                    JSON.stringify({
                        action: 'device_info',
                        data: {
                            id: slider.id,
                            top: slider.sliderElement.getBoundingClientRect().top + document.documentElement.scrollTop,
                            device: slider.responsive.device,
                            isLandscape: isLandscape,
                            minScreenWidth: minWidth,
                            maxScreenWidth: maxWidth
                        }
                    }),
                    "*"
                );
            }

            if (window.ResizeObserver !== undefined) {
                var observer = new ResizeObserver((function () {
                    syncDeviceDetails();
                }).bind(this));
                observer.observe(body);
            } else {
                try {
                    /**
                     * We can detect every width changes with a dummy iframe.
                     */
                    $('<iframe sandbox="allow-same-origin allow-scripts" style="position:absolute;left:0;top:0;margin:0;padding:0;border:0;display:block;width:100%;height:100%;min-height:0;max-height:none;z-index:10;"></iframe>')
                        .on('load', function (e) {
                            $(e.target.contentWindow ? e.target.contentWindow : e.target.contentDocument.defaultView)
                                .on('resize', function () {
                                    syncDeviceDetails();
                                });
                        })
                        .appendTo(body);
                } catch (e) {
                }
            }

            n2ss.on('SliderDeviceOrientation', function (slider) {
                syncDeviceDetailsSlider(slider);
            })

            function broadcastScrollTop(scrollTop) {

                window.parent.postMessage(
                    JSON.stringify({
                        action: 'scrollTop',
                        data: {
                            scrollTop: scrollTop
                        }
                    }),
                    "*"
                );
            }

            document.addEventListener('scroll', function () {
                broadcastScrollTop(html.scrollTop || body.scrollTop);
            }, {
                passive: true,
                capture: true
            });
            broadcastScrollTop(html.scrollTop || body.scrollTop);
        });
    }

</script>Admin/Preview/Template/Index.php000064400000003331152356646020012561 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Preview;

use Nextend\Framework\Asset\Js\Js;

/**
 * @var $this ViewPreviewIndex
 */

JS::addGlobalInline('document.documentElement.classList.add("n2_html--application-only");');

Js::addFirstCode("new _N2.SliderPreview();");

?>
<div class="n2_preview">
    <form target="n2_preview__device_screen_inner_frame" action="<?php echo esc_url($this->getUrlPreviewFull($this->getSliderID())); ?>" method="post">
        <input type="hidden" name="sliderData" value="<?php echo esc_attr(json_encode($this->sliderData)); ?>">
        <input type="hidden" name="slidesData" value="<?php echo esc_attr(json_encode($this->slidesData)); ?>">
        <input type="hidden" name="generatorData" value="<?php echo esc_attr(json_encode($this->generatorData)); ?>">
    </form>
    <div class="n2_preview__ruler">
        <div class="n2_preview__ruler_label"></div>
    </div>
    <div class="n2_preview__device_info">
        <div class="n2_preview__device_info_label"><?php n2_e('State'); ?>:&nbsp;</div>
        <div class="n2_preview__device_info_state"><?php n2_e('Desktop'); ?></div>
        <i class="ssi_16 ssi_16--info" data-tip-description="" data-tip-label="<?php n2_e('Reason'); ?>"></i>
    </div>

    <div class="n2_preview__device_screen">
        <div class="n2_preview__device_screen_inner" style="<?php echo esc_attr($this->getWidthCSS()); ?>">
            <iframe name="n2_preview__device_screen_inner_frame"></iframe>
            <div class="n2_preview__frame_overlay"></div>
            <div class="n2_preview__resize_width">
            </div>

            <div class="n2_preview__resize_height">

            </div>
        </div>
    </div>
</div>Admin/Layout/AbstractLayoutMenu.php000064400000003514152356646020013364 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout;


use Nextend\Framework\Platform\Platform;
use Nextend\Framework\Request\Request;
use Nextend\Framework\View\AbstractLayout;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\NavBar\BlockNavBar;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\SmartSlider3Info;

abstract class AbstractLayoutMenu extends AbstractLayout {

    use TraitAdminUrl;

    /** @var BlockNavBar */
    protected $header;

    protected $classes = array();

    public function __construct($view) {

        $this->header = new BlockNavBar($this);

        parent::__construct($view);

        $this->header->setLogo($this->getApplicationType()
                                    ->getLogo());
        $this->header->setSidebarLink($this->getUrlDashboard());

        $cmd = Request::$REQUEST->getVar("nextendcontroller", "sliders");
        $this->header->addMenuItem(Html::link(n2_('Settings'), $this->getUrlSettingsDefault()), $cmd == "settings");
    

        $this->header->addMenuItem(Html::link(n2_('Help'), $this->getUrlHelp()), $cmd == "help");

    }

    public function addHeaderMenuItem($item) {
        $this->header->addMenuItem($item);
    }

    /**
     * @param        $label
     * @param        $icon
     * @param string $url
     *
     * @return Helper\Breadcrumb
     */
    public function addBreadcrumb($label, $icon = '', $url = '#') {

        return $this->header->addBreadcrumb($label, $icon, $url);
    }

    public function getHeader() {

        return $this->header->toHTML();
    }

    public function getClasses() {

        return $this->classes;
    }

    public function addClass($class) {

        $this->classes[] = $class;
    }
}Admin/Layout/LayoutDefault.php000064400000002033152356646020012353 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout;


use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Admin\BlockAdmin;

class LayoutDefault extends AbstractLayoutMenu {

    protected $subNavigation = '';

    protected $topBar = '';

    public function render() {
        $admin = new BlockAdmin($this);
        $admin->setLayout($this);

        foreach ($this->state as $name => $value) {
            $admin->setAttribute('data-' . $name, $value);
        }

        $admin->addClasses($this->getClasses());
        $admin->setHeader($this->getHeader());
        $admin->setSubNavigation($this->subNavigation);

        $admin->setTopBar($this->topBar);

        $admin->display();
    }

    /**
     * @param string $subNavigation
     */
    public function setSubNavigation($subNavigation) {
        $this->subNavigation = $subNavigation;
    }

    /**
     * @param string $topBar
     */
    public function setTopBar($topBar) {
        $this->topBar = $topBar;
    }
}Admin/Layout/LayoutDefaultSidebar.php000064400000002316152356646020013651 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout;


use Nextend\Framework\Sanitize;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Admin\BlockAdmin;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\ContentSidebar\BlockContentSidebar;

class LayoutDefaultSidebar extends AbstractLayoutMenu {

    protected $sidebar = array();

    protected function enqueueAssets() {

        $this->getApplicationType()
             ->enqueueAssets();
    }

    public function addSidebarBlock($html) {

        $this->sidebar[] = $html;
    }

    public function renderSidebarBlock() {
        echo wp_kses($this->getSidebarBlock(), Sanitize::$adminTemplateTags);
    }

    public function getSidebarBlock() {
        return implode("\n\n", $this->sidebar);
    }

    public function render() {

        $admin = new BlockAdmin($this);
        $admin->setLayout($this);

        $admin->addClasses($this->getClasses());
        $admin->setHeader($this->getHeader());

        $content = new BlockContentSidebar($this);
        $content->setSidebar($this->getSidebarBlock());
        $this->addContentBlock($content);

        $admin->display();
    }
}Admin/Layout/LayoutEditor.php000064400000003157152356646020012225 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout;

use Nextend\Framework\View\AbstractLayout;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\AdminEditor\BlockAdminEditor;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\BlockBreadCrumb\BlockBreadCrumb;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\EditorOverlay\BlockEditorOverlay;
use Nextend\SmartSlider3\Application\Admin\Layout\Helper\Breadcrumb;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;

class LayoutEditor extends AbstractLayout {

    use TraitAdminUrl;

    /**
     * @var BlockEditorOverlay
     */
    protected $editorOverlay;

    /**
     * @var BlockBreadCrumb
     */
    protected $blockBreadCrumb;

    public function render() {
        $admin = new BlockAdminEditor($this);
        $admin->setLayout($this);
        foreach ($this->state as $name => $value) {
            $admin->setAttribute('data-' . $name, $value);
        }

        $admin->setEditorOverlay($this->editorOverlay);

        $admin->display();
    }

    /**
     * @param        $label
     * @param        $icon
     * @param string $url
     *
     * @return Breadcrumb
     */
    public function addBreadcrumb($label, $icon, $url = '#') {

        return $this->blockBreadCrumb->addBreadcrumb($label, $icon, $url);
    }

    /**
     * @param BlockEditorOverlay $editorOverlay
     */
    public function setEditorOverlay($editorOverlay) {
        $this->editorOverlay   = $editorOverlay;
        $this->blockBreadCrumb = $editorOverlay->getBlockBreadCrumb();
    }


}Admin/Layout/LayoutEmpty.php000064400000000630152356646020012066 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout;


use Nextend\Framework\View\AbstractLayout;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\AdminEmpty\BlockAdminEmpty;

class LayoutEmpty extends AbstractLayout {

    public function render() {
        $admin = new BlockAdminEmpty($this);
        $admin->setLayout($this);

        $admin->display();
    }

}Admin/Layout/LayoutError.php000064400000001476152356646020012072 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout;


use Nextend\Framework\View\AbstractLayout;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\AdminError\BlockAdminError;

class LayoutError extends AbstractLayout {

    protected $title, $content, $url = '';

    /**
     * Override to prevent backend JS load
     */
    protected function enqueueAssets() {

    }

    public function setError($title, $content, $url = '') {
        $this->title   = $title;
        $this->content = $content;
        $this->url     = $url;
    }

    public function render() {
        $adminError = new BlockAdminError($this);
        $adminError->setLayout($this);

        $adminError->setError($this->title, $this->content, $this->url);

        $adminError->display();
    }
}Admin/Layout/LayoutIframe.php000064400000001633152356646020012177 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout;


use Nextend\Framework\View\AbstractBlock;
use Nextend\Framework\View\AbstractLayout;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\AdminIframe\BlockAdminIframe;

class LayoutIframe extends AbstractLayout {

    protected $label = '';

    /**
     * @var AbstractBlock[]
     */
    protected $actions = array();

    public function render() {

        $admin = new BlockAdminIframe($this);
        $admin->setLayout($this);
        $admin->setLabel($this->label);
        $admin->setActions($this->actions);

        $admin->display();
    }

    /**
     * @param string $label
     */
    public function setLabel($label) {
        $this->label = $label;
    }

    /**
     * @param AbstractBlock $block
     */
    public function addAction($block) {
        $this->actions[] = $block;
    }
}Admin/Layout/Block/Slider/SliderTrash/BlockSliderTrash.php000064400000004037152356646020017476 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderTrash;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Application\Model\ModelSliders;

class BlockSliderTrash extends AbstractBlock {

    use TraitAdminUrl;

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

    public function display() {

        $options = array(
            'ajaxUrl'    => $this->getAjaxUrlSlidesCreate(),
            'previewUrl' => $this->getUrlPreviewIndex(0)
        );

        Js::addInline("new _N2.SlidersTrash(" . json_encode($options) . ");");


        $this->renderTemplatePart('SliderTrash');
    }

    public function getSliders() {

        $slidersModel = new ModelSliders($this);

        return $slidersModel->getAll('*', 'trash');
    }

    /**
     * @param array $slider
     */
    public function setSlider($slider) {
        $this->slider = $slider;
    }

    public function isGroup() {
        return $this->slider['type'] == 'group';
    }

    public function getSliderTitle() {

        return $this->slider['title'];
    }

    public function getSliderID() {
        return $this->slider['id'];
    }

    public function hasSliderAlias() {
        return !empty($this->slider['alias']);
    }

    public function getSliderAlias() {
        return $this->slider['alias'];
    }

    public function getThumbnail() {

        $thumbnail = $this->slider['thumbnail'];
        if (empty($thumbnail)) {
            return '';
        } else {
            return ResourceTranslator::toUrl($thumbnail);
        }
    }

    public function isThumbnailEmpty() {
        return empty($this->slider['thumbnail']);
    }

    public function getChildrenCount() {
        if ($this->slider['slides'] > 0) {

            return $this->slider['slides'];
        }

        return 0;
    }
}Admin/Layout/Block/Slider/SliderTrash/BlockSliderTrashBox.php000064400000004105152356646020020143 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderTrash;


use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;

class BlockSliderTrashBox extends AbstractBlock {

    use TraitAdminUrl;

    protected $groupID = 0;

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

    public function display() {

        $this->renderTemplatePart('SliderTrashBox');
    }

    /**
     * @return array
     */
    public function getSlider() {
        return $this->slider;
    }

    /**
     * @param array $slider
     */
    public function setSlider($slider) {
        $this->slider = $slider;
    }

    public function getEditUrl() {

        return $this->getUrlSliderEdit($this->slider['id'], $this->groupID);
    }

    public function isGroup() {
        return $this->slider['type'] == 'group';
    }

    public function getSliderTitle() {

        return $this->slider['title'];
    }

    public function getSliderID() {
        return $this->slider['id'];
    }

    public function hasSliderAlias() {
        return !empty($this->slider['alias']);
    }

    public function getSliderAlias() {
        return $this->slider['alias'];
    }

    public function getThumbnail() {

        $thumbnail = $this->slider['thumbnail'];
        if (empty($thumbnail)) {
            return '';
        } else {
            return ResourceTranslator::toUrl($thumbnail);
        }
    }

    public function isThumbnailEmpty() {
        return empty($this->slider['thumbnail']);
    }

    public function getChildrenCount() {
        if ($this->slider['slides'] > 0) {

            return $this->slider['slides'];
        }

        return 0;
    }

    /**
     * @return int
     */
    public function getGroupID() {
        return $this->groupID;
    }

    /**
     * @param int $groupID
     */
    public function setGroupID($groupID) {
        $this->groupID = $groupID;
    }

}Admin/Layout/Block/Slider/SliderTrash/SliderTrash.php000064400000001325152356646020016520 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderTrash;

/**
 * @var BlockSliderTrash $this
 */

$sliders = $this->getSliders();
?>
<div class="n2_slider_trash">

    <div class="n2_slider_manager__box n2_slider_manager__dummy_slider">
        <i class="n2_slider_manager__dummy_slider_icon ssi_48 ssi_48--delete"></i>
        <div class="n2_slider_manager__dummy_slider_label">
            <?php n2_e('Trash is empty.'); ?>
        </div>
    </div>

    <?php
    foreach ($sliders as $sliderObj) {

        $blockSliderBox = new BlockSliderTrashBox($this);
        $blockSliderBox->setSlider($sliderObj);
        $blockSliderBox->display();
    }
    ?>
</div>
Admin/Layout/Block/Slider/SliderTrash/SliderTrashBox.php000064400000006362152356646020017177 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderTrash;

use Nextend\Framework\Sanitize;

/**
 * @var BlockSliderTrashBox $this
 */
?>

<div class="n2_slider_manager__box n2_slider_box<?php echo $this->isGroup() ? ' n2_slider_box--group' : ' n2_slider_box--slider'; ?>"
     data-group="<?php echo $this->isGroup() ? '1' : '0'; ?>"
     data-sliderid="<?php echo esc_attr($this->getSliderID()); ?>">

    <?php
    $thumbnailUrl   = esc_url($this->getThumbnail());
    $thumbnailStyle = '';
    if (!empty($thumbnailUrl)) {
        $thumbnailStyle = "background-image: url('" . $thumbnailUrl . "');";
    }
    ?>

    <div class="n2_slider_box__content" style="<?php echo esc_attr($thumbnailStyle); ?>">
        <?php
        if ($this->isThumbnailEmpty()):
            $icon = "ssi_64 ssi_64--image";
            if ($this->isGroup()) {
                $icon = "ssi_64 ssi_64--folder";
            }
            ?>

            <div class="n2_slider_box__icon">
                <div class="n2_slider_box__icon_container">
                    <i class="<?php echo esc_attr($icon); ?>"></i>
                </div>
            </div>

        <?php
        endif;
        ?>

        <div class="n2_slider_box__slider_overlay">
            <a class="n2_slider_box__slider_overlay_restore_button n2_button n2_button--small n2_button--green" href="#">
                <?php
                n2_e('Restore');
                ?>
            </a>
        </div>

        <div class="n2_slider_box__slider_identifiers">
            <div class="n2_slider_box__slider_identifier">
                <?php
                echo '#' . esc_html($this->getSliderID());
                ?>
            </div>
            <?php
            if ($this->isGroup()):
                ?>
                <div class="n2_slider_box__slider_identifier">
                    <?php
                    echo 'GROUP';
                    ?>
                </div>
            <?php
            endif;
            ?>
            <?php
            if ($this->hasSliderAlias()):
                ?>
                <div class="n2_slider_box__slider_identifier">
                    <?php
                    echo esc_html($this->getSliderAlias());
                    ?>
                </div>
            <?php
            endif;
            ?>
        </div>

        <div class="n2_slider_box__slider_actions">
            <a class="n2_slider_box__slider_action_more n2_button_icon n2_button_icon--small n2_button_icon--grey-dark" href="#"><i class="ssi_16 ssi_16--more"></i></a>
        </div>
    </div>

    <div class="n2_slider_box__footer">
        <?php
        if ($this->isGroup()):
            ?>
            <div class="n2_slider_box__footer_icon">
                <i class="ssi_16 ssi_16--folderclosed"></i>
            </div>
        <?php
        endif;
        ?>
        <div class="n2_slider_box__footer_title">
            <?php
            echo esc_html($this->getSliderTitle());
            ?>
        </div>
        <div class="n2_slider_box__footer_children_count">
            <?php
            echo esc_html($this->getChildrenCount());
            ?>
        </div>
    </div>
</div>
Admin/Layout/Block/Slider/SliderPublish/BlockPublishSlider.php000064400000001727152356646020020353 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderPublish;

use Nextend\Framework\View\AbstractBlock;

class BlockPublishSlider extends AbstractBlock {

    /** @var int */
    protected $sliderID;

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

    public function display() {

        $this->renderTemplatePart('Common');
        $this->renderTemplatePart('Joomla');
    
    }

    /**
     * @return int
     */
    public function getSliderID() {
        return $this->sliderID;
    }

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

    /**
     * @param int $sliderID
     */
    public function setSliderID($sliderID) {
        $this->sliderID = $sliderID;
    }

    /**
     * @param string $sliderAlias
     */
    public function setSliderAlias($sliderAlias) {
        $this->sliderAlias = $sliderAlias;
    }


}Admin/Layout/Block/Slider/SliderPublish/Common.php000064400000002653152356646020016056 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderPublish;

/**
 * @var $this BlockPublishSlider
 */
?>

<script>

    _N2.r(['$', 'documentReady'], function () {
        var $ = _N2.$;

        $('.n2_ss_slider_publish__option_code')
            .on('click', function (e) {
                var element = e.currentTarget;
                if (document.selection) {
                    var range = body.createTextRange();
                    range.moveToElementText(this);
                    range.select();
                } else if (window.getSelection) {
                    var range = document.createRange();
                    range.selectNode(element);
                    var selection = window.getSelection();
                    selection.removeAllRanges();
                    selection.addRange(range);
                }
                return false;
            });

        document.addEventListener('copy', function (e) {
            if ($(e.target).hasClass('n2_ss_slider_publish__option_code')) {
                try {
                    e.clipboardData.setData('text/plain', window.getSelection().toString());
                    e.clipboardData.setData('text/html', '<div>' + window.getSelection().toString() + '</div>');
                    e.preventDefault();
                } catch (e) {

                }
            }
        });
    });
</script>
Admin/Layout/Block/Slider/SliderPublish/Joomla.php000064400000004446152356646020016051 0ustar00<?php
/**
 * @required N2JOOMLA
 */

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderPublish;

/**
 * @var $this BlockPublishSlider
 */

$sliderID    = $this->getSliderID();
$publishData = new JoomlaPublishSlider($sliderID);
$modules     = $publishData->getModuleList();

?>

<div class="n2_ss_slider_publish">

    <div class="n2_ss_slider_publish__option">
        <div class="n2_ss_slider_publish__option_label"><?php n2_e('Module'); ?></div>

        <div class="n2_ss_slider_publish__option_description"><?php n2_e('Displays the slider in a template module position.'); ?></div>

        <a class="n2_button n2_button--big n2_button--green" href="<?php echo esc_url($publishData->getCreateModuleLink()); ?>" target="_blank"><span class="n2_button__label"><?php n2_e('Create module') ?></span></a>
    </div>

    <?php if (!empty($modules)): ?>
        <div class="n2_ss_slider_publish__option">
            <div class="n2_ss_slider_publish__option_label"><?php n2_e('Related modules'); ?></div>
            <div class="n2_ss_slider_publish__related_modules">
                <?php foreach ($modules as $module): ?>
                    <a class="n2_button n2_button--small n2_button--grey" href="<?php echo esc_url($module['url']); ?>" target="_blank"><?php echo esc_html($module['label']); ?></a>
                <?php endforeach; ?>
            </div>
        </div>
    <?php endif; ?>

    <div class="n2_ss_slider_publish__option">
        <div class="n2_ss_slider_publish__option_label"><?php n2_e('Articles'); ?></div>

        <div class="n2_ss_slider_publish__option_description"><?php n2_e('Paste the code into article:'); ?></div>

        <div class="n2_ss_slider_publish__option_code" dir="ltr">
            smartslider3[<?php echo esc_html($sliderID); ?>]
        </div>
    </div>

    <div class="n2_ss_slider_publish__option">
        <div class="n2_ss_slider_publish__option_label"><?php n2_e('PHP code'); ?></div>

        <div class="n2_ss_slider_publish__option_description"><?php n2_e('Paste the PHP code into source code:'); ?></div>

        <div class="n2_ss_slider_publish__option_code" dir="ltr">
            &lt;?php <br>echo nextend_smartslider3(<?php echo esc_html($sliderID); ?>);<br>?&gt;
        </div>
    </div>
</div>Admin/Layout/Block/Slider/SliderPublish/JoomlaPublishSlider.php000064400000004352152356646020020537 0ustar00<?php
/**
 * @required N2JOOMLA
 */

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderPublish;

use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Nextend\Framework\Database\Database;

class JoomlaPublishSlider {

    protected $db;
    protected $sliderID;
    protected $moduleType;

    public function __construct($sliderID) {
        $this->sliderID   = $sliderID;
        $this->db         = Database::getInstance();
        $this->moduleType = ComponentHelper::getComponent('com_advancedmodules', true)->enabled ? 'com_advancedmodules' : 'com_modules';
    }

    public function getCreateModuleLink() {
        $ss3Module = $this->db->queryRow("SELECT extension_id FROM `#__extensions` WHERE `element` LIKE  'mod_smartslider3'");
        if (count($ss3Module)) {
            return 'index.php?option=' . $this->moduleType . '&task=module.add&eid=' . $ss3Module['extension_id'] . '&params[slider]=' . $this->sliderID;
        } else {
            return 'index.php?option=' . $this->moduleType . '&view=select';
        }
    }

    public function getModuleList() {
        $modulesData = array();
        $modules     = $this->db->queryAll("SELECT * FROM `#__modules` WHERE `module` LIKE 'mod_smartslider3' AND `params` LIKE '%\"slider\":\"" . $this->sliderID . "\"%'");
        if (count($modules)) {
            $list = '<ul>';
            $IDs  = array();
            foreach ($modules as $module) {
                $IDs[] = intval($module['id']);

                $modulesData[] = array(
                    'url'   => 'index.php?option=' . $this->moduleType . '&view=module&layout=edit&id=' . $module['id'],
                    'label' => $module['title']
                );
                $list          .= '
                        <li>
                            <a href="index.php?option=' . $this->moduleType . '&view=module&layout=edit&id=' . $module['id'] . '" target="_blank">' . $module['title'] . '</a>
                        </li>';
            }

            $context = 'com_modules.edit.module';
            $app     = Factory::getApplication();
            $app->setUserState($context . '.id', $IDs);
        }

        return $modulesData;
    }
}Admin/Layout/Block/Slider/SliderPublish/WordPress.php000064400000004442152356646020016554 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderPublish;

use Nextend\SmartSlider3\Application\Model\ModelSliders;

/**
 * @var $this BlockPublishSlider
 */
$model    = new ModelSliders($this);
$sliderID = $this->getSliderID();
if ($sliderID === 0) {
    $helper   = $model->getByAlias($this->getSliderAlias());
    $sliderID = $helper['id'];
}
$slider = $model->get($sliderID);
?>

<div class="n2_ss_slider_publish">

    <div class="n2_ss_slider_publish__option">
        <div class="n2_ss_slider_publish__option_label"><?php n2_e('Shortcode'); ?></div>

        <div class="n2_ss_slider_publish__option_description"><?php n2_e('Copy and paste this shortcode into your posts or pages:'); ?></div>
        <div class="n2_ss_slider_publish__option_code" data-mode="id" dir="ltr">
            [smartslider3 slider="<?php echo esc_html($sliderID); ?>"]
        </div>
        <?php if (!empty($slider['alias'])): ?>
            <div class="n2_ss_slider_publish__option_code" data-mode="alias" dir="ltr">
                [smartslider3 alias="<?php echo esc_html($slider['alias']); ?>"]
            </div>
        <?php endif; ?>
    </div>

    <div class="n2_ss_slider_publish__option">
        <div class="n2_ss_slider_publish__option_label"><?php n2_e('Pages and Posts'); ?></div>

        <?php
        $pageBuilders = array(
            'Gutenberg',
            'Classic Editor',
            'Elementor',
            'Divi',
            'Beaver Builder',
            'Visual Composer',
            'WPBakery Page Builder'
        );
        ?>
        <div class="n2_ss_slider_publish__option_description"><?php echo sprintf(n2_('Smart Slider 3 has integration with %s.'), esc_html(implode(', ', $pageBuilders))); ?></div>
    </div>

    <div class="n2_ss_slider_publish__option">
        <div class="n2_ss_slider_publish__option_label"><?php n2_e('PHP code'); ?></div>

        <div class="n2_ss_slider_publish__option_description"><?php n2_e('Paste the PHP code into your theme\'s file:'); ?></div>
        <div class="n2_ss_slider_publish__option_code" dir="ltr">
            &lt;?php <br>
            echo do_shortcode('[smartslider3 slider="<?php echo esc_html($sliderID); ?>"]');<br>
            ?&gt;
        </div>
    </div>
</div>Admin/Layout/Block/Slider/SliderManager/BlockSliderManager.php000064400000005547152356646020020267 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderManager;


use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Model\ModelSliders;
use Nextend\SmartSlider3\Settings;

class BlockSliderManager extends AbstractBlock {

    protected $groupID = 0;

    protected $orderBy = 'ordering';

    protected $orderByDirection = 'ASC';

    protected $paginationIndex = 0;

    protected $paginationLimit = 'all';

    public function display() {
        if ($this->groupID <= 0) {
            $this->orderBy          = Settings::get('slidersOrder2', 'ordering');
            $this->orderByDirection = Settings::get('slidersOrder2Direction', 'ASC');
            $this->paginationLimit  = Settings::get('limit', 'all');
        }


        $this->renderTemplatePart('SliderManager');
    }

    /**
     * @return int
     */
    public function getGroupID() {
        return $this->groupID;
    }

    /**
     * @param int $groupID
     */
    public function setGroupID($groupID) {
        $this->groupID = $groupID;
    }

    /**
     * @return int
     */
    public function getPaginationIndex() {
        return $this->paginationIndex;
    }

    /**
     * @param int $index
     */
    public function setPaginationIndex($index) {
        $this->paginationIndex = $index;
    }


    /**
     * @return int
     */

    public function getPaginationLimit() {
        return $this->paginationLimit;
    }

    /**
     * @param string $status
     *
     */
    public function getSliders($status = '*') {
        $slidersModel = new ModelSliders($this);

        $sliders = $slidersModel->getAll($this->groupID, $status, $this->orderBy, $this->orderByDirection, $this->paginationIndex, $this->paginationLimit);
        if ($this->groupID <= 0 && empty($sliders) && $sliderCount = $this->getSliderCount('published', true)) {
            $lastPageIndex         = intval(ceil(($sliderCount - $this->paginationLimit) / $this->paginationLimit));
            $sliders               = $slidersModel->getAll($this->groupID, $status, $this->orderBy, $this->orderByDirection, $lastPageIndex, $this->paginationLimit);
            $this->paginationIndex = $lastPageIndex;
        }

        return $sliders;
    }

    /**
     * @param string $status
     * @param false  $withGroup
     *
     * @return int
     */

    public function getSliderCount($status = '*', $withGroup = false) {
        $slidersModel = new ModelSliders($this);

        return $slidersModel->getSlidersCount($status, $withGroup);
    }

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

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

}Admin/Layout/Block/Slider/SliderManager/SliderManager.php000064400000006512152356646020017305 0ustar00<?php
namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderManager;

use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderBox\BlockSliderBox;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderManager\ActionBar\BlockActionBar;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderManager\Paginator\BlockPaginator;

/**
 * @var BlockSliderManager $this
 */
$groupID          = $this->getGroupID();
$orderBy          = $this->getOrderBy();
$orderByDirection = $this->getOrderByDirection();

$sliders     = $this->getSliders('published');
$sliderCount = $this->getSliderCount('published', true);

$limit           = $this->getPaginationLimit();
$paginationIndex = $this->getPaginationIndex();

?>
<div class="n2_slider_manager" data-groupid="<?php echo esc_attr($groupID); ?>" data-orderby="<?php echo esc_attr($orderBy); ?>" data-orderbydirection="<?php echo esc_attr($orderByDirection); ?>">
    <?php

    $actionBar = new BlockActionBar($this);
    $actionBar->setSliderManager($this);
    $actionBar->display();

    ?>
    <div class="n2_slider_manager__content">

        <div class="n2_slider_manager__box n2_slider_manager__new_slider">
            <i class="n2_slider_manager__new_slider_icon ssi_48 ssi_48--plus"></i>
            <span class="n2_slider_manager__new_slider_label">
                <?php n2_e('New project'); ?>
            </span>
        </div>
        <?php

        foreach ($sliders as $sliderObj) {

            $blockSliderBox = new BlockSliderBox($this);
            $blockSliderBox->setGroupID($groupID);
            $blockSliderBox->setSlider($sliderObj);
            $blockSliderBox->display();
        }
        ?>
        <?php if ($groupID <= 0) { ?>
            <div class="n2_slider_manager__content--empty">
                <div class="n2_slider_manager__content--empty__logo">
                    <i class="ssi_48 ssi_48--bug"></i>
                </div>
                <div class="n2_slider_manager__content--empty__heading">
                    <?php n2_e('Sorry we couldn’t find any matches'); ?>
                </div>
                <div class="n2_slider_manager__content--empty__paragraph">
                    <?php n2_e('Please try searching with another term.'); ?>
                </div>
            </div>
        <?php } ?>

    </div>
    <?php if ($groupID <= 0) { ?>
        <div class="n2_slider_manager__paginator" data-countstart="<?php echo esc_attr($sliderCount); ?>" data-currentstart="<?php echo esc_attr($paginationIndex); ?>" data-limitstart="<?php echo esc_attr($limit); ?>">
            <?php
            $blockPaginator = new BlockPaginator($this);
            $blockPaginator->setSliderManager($this);
            $blockPaginator->setSliderCount($sliderCount);
            $blockPaginator->setPaginationLimit($limit);
            $blockPaginator->display();
            ?>
        </div>
        <div class="n2_slider_manager__search_label">
            <p class="n2_slider_manager__search_label_item n2_slider_manager__search_label_item"><?php echo sprintf(n2_("Showing %s results for %s."), "<span class='n2_slider_manager__search_label_item__counter'>0</span>", "<span class='n2_slider_manager__search_label_item__keyword'></span>") ?></p>
        </div>
    <?php } ?>
</div>
Admin/Layout/Block/Slider/SliderManager/Paginator/BlockPaginator.php000064400000014606152356646020021416 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderManager\Paginator;

use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonPlain;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonPlainIcon;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\FloatingMenu\BlockFloatingMenu;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\FloatingMenu\BlockFloatingMenuItem;

class BlockPaginator extends AbstractBlock {

    protected $sliderCount;
    protected $paginationLimit;

    /**
     * @var BlockSliderManager
     */
    protected $sliderManager;

    public function display() {

        $this->renderTemplatePart('Paginator');
    }

    /**
     * @param BlockSliderManager $sliderManager
     */
    public function setSliderManager($sliderManager) {
        $this->sliderManager = $sliderManager;
    }


    public function setSliderCount($sliderCount) {
        $this->sliderCount = $sliderCount;
    }

    public function setPaginationLimit($limit) {
        $this->paginationLimit = $limit;
    }

    private function transformedPaginationLimit() {
        if ($this->paginationLimit === 'all') {
            /*used in calculations*/
            return $this->sliderCount;
        } else {
            return $this->paginationLimit;
        }
    }


    public function displayPaginationButtons() {

        $totalPages = $this->sliderCount ? ceil(($this->sliderCount / $this->transformedPaginationLimit())) : 0;
        $delta      = 2;
        $left       = intval($this->sliderManager->getPaginationIndex()) - $delta;
        $right      = intval($this->sliderManager->getPaginationIndex()) + $delta;

        /*PageList*/
        if ($totalPages > 1) {
            for ($i = 0; $i < $totalPages; $i++) {
                if ($i == 0 || $i == $totalPages - 1 || $i >= $left && $i <= $right) {
                    $blockButton = new BlockButtonPlain($this);
                    $blockButton->setUrl('#');
                    $blockButton->setLabel($i + 1);
                    $blockButton->addAttribute('data-page', $i);
                    $blockButton->setSmall();
                    $blockButton->setTabIndex(-1);
                    $class = 'n2_slider_manager__paginator_item ' . (($i === intval($this->sliderManager->getPaginationIndex())) ? 'n2_slider_manager__paginator_item--active' : '');
                    $blockButton->addAttribute('class', $class);
                    $blockButton->display();
                } else if ($i === $left - 1 || $i === $right + 1) {
                    echo "<div class='n2_slider_manager__paginator_item n2_slider_manager__paginator_item_spacer'>...</div>";
                }
            }
        }

    }

    public function displayPaginationPrevious() {

        $blockButtonPrev = new BlockButtonPlainIcon($this);
        $blockButtonPrev->setUrl('#');
        $blockButtonPrev->setIcon('ssi_16 ssi_16--paginatiorarrow');
        $blockButtonPrev->setSmall();
        $blockButtonPrev->setTabIndex(-1);
        $blockButtonPrev->addAttribute('data-page', 'prev');
        $blockButtonPrev->addAttribute('class', 'n2_slider_manager__paginator_item n2_slider_manager__paginator_item_arrow n2_slider_manager__paginator_item_arrow--prev n2_slider_manager__paginator_item_arrow--disabled');
        $blockButtonPrev->display();
    }

    public function displayPaginationNext() {
        $blockButtonNext = new BlockButtonPlainIcon($this);
        $blockButtonNext->setUrl('#');
        $blockButtonNext->setIcon('ssi_16 ssi_16--paginatiorarrow');
        $blockButtonNext->setSmall();
        $blockButtonNext->setTabIndex(-1);
        $blockButtonNext->addAttribute('data-page', 'next');
        $blockButtonNext->addAttribute('class', 'n2_slider_manager__paginator_item n2_slider_manager__paginator_item_arrow n2_slider_manager__paginator_item_arrow--next n2_slider_manager__paginator_item_arrow--disabled');
        $blockButtonNext->display();
    }

    public function displayPaginationLimiters() {
        $blockLimiter = new BlockFloatingMenu($this);
        $blockButton  = new BlockButtonPlain($this);
        $limitText    = intval($this->paginationLimit) ? $this->paginationLimit : n2_('All');
        $blockButton->setLabel(n2_('Show') . " <span class='limitNumber'>" . $limitText . "</span>");
        $blockButton->setIcon('ssi_16 ssi_16--selectarrow');
        $blockButton->setSmall();
        $blockLimiter->setButton($blockButton);


        $limits = array(
            10,
            25,
            50,
            100
        );

        foreach ($limits as $limit) {
            $limitItem = new BlockFloatingMenuItem($this);
            $limitItem->setLabel($limit);
            $limitItem->setUrl('#');
            $limitItem->addAttribute('data-limit', $limit);
            $limitItem->addClass('n2_floating_menu__item-limiter');
            $limitItem->setIsActive($this->paginationLimit == $limit);
            $blockLimiter->addMenuItem($limitItem);
        }

        $limitAll = new BlockFloatingMenuItem($this);
        $limitAll->setLabel(n2_('All'));
        $limitAll->setUrl('#');
        $limitAll->addAttribute('data-limit', 'all');
        $limitAll->addClass('n2_floating_menu__item-limiter');
        $limitAll->setIsActive($this->paginationLimit == 'all');
        $blockLimiter->addMenuItem($limitAll);


        $blockLimiter->display();
    }

    public function displayPaginationLabel() {


        $actualSliderStart = $this->transformedPaginationLimit() * $this->sliderManager->getPaginationIndex();
        $actualSlidersEnd  = $actualSliderStart + $this->transformedPaginationLimit();
        $allSliders        = $this->sliderCount;

        echo sprintf(n2_("Showing %s to %s of %s projects"), "<span class='n2_slider_manager__paginator_label_item__from'>" . (($actualSliderStart === 0) ? 1 : esc_html($actualSliderStart)) . "</span>", "<span class='n2_slider_manager__paginator_label_item__to' > " . esc_html(($actualSlidersEnd < $this->sliderCount) ? $actualSlidersEnd : $this->sliderCount) . "</span > ", "<span class='n2_slider_manager__paginator_label_item__max' > " . esc_html($allSliders) . "</span > ");
    }

    public function displayNoSlidersLabel() {
        n2_e('No projects to show');
    }

}Admin/Layout/Block/Slider/SliderManager/Paginator/Paginator.php000064400000002026152356646020020434 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderManager\Paginator;

/**
 * @var BlockPaginator $this
 */

?>
<div class="n2_slider_manager__paginator_label <?php echo $this->sliderCount === 0 ? "n2_slider_manager__paginator_label--nosliders" : "" ?>">
    <p class="n2_slider_manager__paginator_label_item n2_slider_manager__paginator_label_item--active"><?php $this->displayPaginationLabel(); ?></p>
    <p class="n2_slider_manager__paginator_label_item n2_slider_manager__paginator_label_item--empty"><?php $this->displayNoSlidersLabel(); ?></p>
</div>
<div class=" n2_slider_manager__paginator_buttons">

    <?php
    $this->displayPaginationPrevious();
    ?>
    <div class="n2_slider_manager__paginator_buttons--numbers">
        <?php
        $this->displayPaginationButtons();
        ?>
    </div>
    <?php
    $this->displayPaginationNext();
    ?>
</div>
<div class="n2_slider_manager__paginator_limiter">
    <?php $this->displayPaginationLimiters() ?>
</div>




Admin/Layout/Block/Slider/SliderManager/ActionBar/ActionBar.php000064400000002454152356646020020275 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderManager\ActionBar;

/**
 * @var BlockActionBar $this
 */
?>
<div class="n2_slider_manager__action_bar">
    <div class="n2_slider_manager__action_bar_left">
        <?php

        $this->displayOrderBy();

        $this->displayCreateGroup();

        $this->displayTrash();

        $this->displayBulkActions();

        ?>
    </div>
    <div class="n2_slider_manager__action_bar_right">
        <?php if ($this->sliderManager->getGroupID() == 0) { ?>
            <div class="n2_slider_manager__search">
                <div class="n2_slider_manager__search_icon n2_slider_manager__search_icon--magnifier">
                    <i class="ssi_16 ssi_16--magnifier"></i>
                </div>
                <div class="n2_slider_manager__search_icon n2_slider_manager__search_icon--abort">
                    <i class="ssi_16 ssi_16--circularremove"></i>
                </div>
                <form class="n2_slider_manager__search_form" autocomplete="off">
                    <input type="text" name="kw" class="n2_slider_manager__search_input" value="" placeholder="<?php n2_e('Search Project'); ?>" tabindex="-1">
                </form>
            </div>
        <?php } ?>
    </div>

</div>
Admin/Layout/Block/Slider/SliderManager/ActionBar/BlockActionBar.php000064400000016716152356646020021256 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderManager\ActionBar;


use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonPlain;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\FloatingMenu\BlockFloatingMenu;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\FloatingMenu\BlockFloatingMenuItem;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderManager\BlockSliderManager;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;

class BlockActionBar extends AbstractBlock {

    use TraitAdminUrl;

    /**
     * @var BlockSliderManager
     */
    protected $sliderManager;

    public function display() {

        $this->renderTemplatePart('ActionBar');
    }

    /**
     * @param BlockSliderManager $sliderManager
     */
    public function setSliderManager($sliderManager) {
        $this->sliderManager = $sliderManager;
    }

    public function displayCreateGroup() {
        if ($this->sliderManager->getGroupID() == 0) {

            $blockButton = new BlockButtonPlain($this);
            $blockButton->setLabel(n2_('Create group'));
            $blockButton->addClass('n2_slider_create_group');
            $blockButton->setSmall();
            $blockButton->setIconBefore('ssi_16 ssi_16--group', 'n2_slider_icon--blue');
            $blockButton->setTabIndex(-1);
            $blockButton->display();

        }
    
    }

    public function displayTrash() {
        if ($this->sliderManager->getGroupID() == 0) {

            $blockButton = new BlockButtonPlain($this);
            $blockButton->setUrl($this->getUrlTrash());
            $blockButton->setLabel(n2_('View trash'));
            $blockButton->addClass('n2_slider_trash');
            $blockButton->setSmall();
            $blockButton->setIconBefore('ssi_16 ssi_16--delete', 'n2_slider_icon--blue');
            $blockButton->setTabIndex(-1);
            $blockButton->display();
        }
    }

    public function displayOrderBy() {
        if ($this->sliderManager->getGroupID() == 0) {

            $orderBy          = $this->sliderManager->getOrderBy();
            $orderByDirection = $this->sliderManager->getOrderByDirection();

            $blockOrderBy = new BlockFloatingMenu($this);

            $blockButton = new BlockButtonPlain($this);
            $blockButton->setLabel(n2_('Order by'));
            $blockButton->setIcon('ssi_16 ssi_16--selectarrow');
            $blockButton->setIconBefore('ssi_16 ssi_16--order', 'n2_slider_icon--blue');
            $blockButton->addClass('n2_slider_order');
            $blockButton->setSmall();
            $blockOrderBy->setButton($blockButton);

            $manualOrder = new BlockFloatingMenuItem($this);
            $manualOrder->setLabel(n2_('Manual order'));
            $manualOrder->setIsActive($orderBy == 'ordering' && $orderByDirection == 'ASC');
            $manualOrder->addAttribute('data-ordering', 'ordering');
            $manualOrder->addAttribute('data-orderdirection', 'ASC');
            $manualOrder->addClass('n2_floating_menu__item-order');
            $manualOrder->setUrl('#');
            $blockOrderBy->addMenuItem($manualOrder);

            $orderAZ = new BlockFloatingMenuItem($this);
            $orderAZ->setLabel(n2_('A-Z'));
            $orderAZ->setIsActive($orderBy == 'title' && $orderByDirection == 'ASC');
            $orderAZ->addAttribute('data-ordering', 'title');
            $orderAZ->addAttribute('data-orderdirection', 'ASC');
            $orderAZ->addClass('n2_floating_menu__item-order');
            $orderAZ->setUrl('#');
            $blockOrderBy->addMenuItem($orderAZ);

            $orderZA = new BlockFloatingMenuItem($this);
            $orderZA->setLabel(n2_('Z-A'));
            $orderZA->setIsActive($orderBy == 'title' && $orderByDirection == 'DESC');
            $orderZA->addAttribute('data-ordering', 'title');
            $orderZA->addAttribute('data-orderdirection', 'DESC');
            $orderZA->addClass('n2_floating_menu__item-order');
            $orderZA->setUrl('#');
            $blockOrderBy->addMenuItem($orderZA);

            $orderNewest = new BlockFloatingMenuItem($this);
            $orderNewest->setLabel(n2_('Newest first'));
            $orderNewest->setIsActive($orderBy == 'time' && $orderByDirection == 'DESC');
            $orderNewest->addAttribute('data-ordering', 'time');
            $orderNewest->addAttribute('data-orderdirection', 'DESC');
            $orderNewest->addClass('n2_floating_menu__item-order');
            $orderNewest->setUrl('#');
            $blockOrderBy->addMenuItem($orderNewest);

            $orderOldest = new BlockFloatingMenuItem($this);
            $orderOldest->setLabel(n2_('Oldest first'));
            $orderOldest->setIsActive($orderBy == 'time' && $orderByDirection == 'ASC');
            $orderOldest->addAttribute('data-ordering', 'time');
            $orderOldest->addAttribute('data-orderdirection', 'ASC');
            $orderOldest->addClass('n2_floating_menu__item-order');
            $orderOldest->setUrl('#');
            $blockOrderBy->addMenuItem($orderOldest);

            $blockOrderBy->display();
        }
    }

    public function displayBulkActions() {

        $blockBulkActions = new BlockFloatingMenu($this);
        $blockBulkActions->setRelatedClass('n2_slider_manager__action_bar_bulk_actions');
        $blockBulkActions->addClass('n2_slider_manager__action_bar_bulk_actions');
        $blockBulkActions->setContentID('n2_slider_manager_bulk_actions');

        $blockButton = new BlockButtonPlain($this);
        $blockButton->setLabel(n2_('Bulk actions'));
        $blockButton->setSmall();
        $blockButton->setIcon('ssi_16 ssi_16--selectarrow');
        $blockButton->setIconBefore('ssi_16 ssi_16--slides', 'n2_slider_icon--blue');

        $blockBulkActions->setButton($blockButton);

        $duplicate = new BlockFloatingMenuItem($this);
        $duplicate->addClass('n2_slider_manager__action_bar_bulk_action');
        $duplicate->setLabel(n2_('Duplicate'));
        $duplicate->addAttribute('data-action', 'duplicate');
        $blockBulkActions->addMenuItem($duplicate);

        $trash = new BlockFloatingMenuItem($this);
        $trash->setRed();
        $trash->addClass('n2_slider_manager__action_bar_bulk_action');
        $trash->setLabel(n2_('Move to trash'));
        $trash->addAttribute('data-action', 'trash');
        $blockBulkActions->addMenuItem($trash);

        $export = new BlockFloatingMenuItem($this);
        $export->addClass('n2_slider_manager__action_bar_bulk_action');
        $export->setLabel(n2_('Export'));
        $export->addAttribute('data-action', 'export');
        $blockBulkActions->addMenuItem($export);

        $blockBulkActions->addSeparator(array(
            'n2_slider_manager__action_bar_bulk_action'
        ));

        $selectAll = new BlockFloatingMenuItem($this);
        $selectAll->setLabel(n2_('Select all'));
        $selectAll->addAttribute('data-action', 'select-all');
        $selectAll->setStayOpen();
        $blockBulkActions->addMenuItem($selectAll);

        $selectNone = new BlockFloatingMenuItem($this);
        $selectNone->setLabel(n2_('Select none'));
        $selectNone->addAttribute('data-action', 'select-none');
        $blockBulkActions->addMenuItem($selectNone);

        $blockBulkActions->display();
    }

}Admin/Layout/Block/Slider/SliderBox/BlockSliderBox.php000064400000004501152356646020016610 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderBox;

use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;

class BlockSliderBox extends AbstractBlock {

    use TraitAdminUrl;

    protected $groupID = 0;

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

    public function display() {

        $this->renderTemplatePart('SliderBox');
    }

    /**
     * @return array
     */
    public function getSlider() {
        return $this->slider;
    }

    /**
     * @param array $slider
     */
    public function setSlider($slider) {
        $this->slider = $slider;
    }

    public function getEditUrl() {

        return $this->getUrlSliderEdit($this->slider['id'], $this->groupID);
    }

    public function getSimpleEditUrl() {

        return $this->getUrlSliderSimpleEdit($this->slider['id'], $this->groupID);
    }

    public function isGroup() {
        return $this->slider['type'] == 'group';
    }

    public function getSliderTitle() {

        return $this->slider['title'];
    }

    public function getSliderID() {
        return $this->slider['id'];
    }

    public function hasSliderAlias() {
        return !empty($this->slider['alias']);
    }

    public function getSliderAlias() {
        return $this->slider['alias'];
    }

    public function getThumbnail() {

        $thumbnail = $this->slider['thumbnail'];
        if (empty($thumbnail)) {
            return '';
        } else {
            return ResourceTranslator::toUrl($thumbnail);
        }
    }

    public function isThumbnailEmpty() {
        return empty($this->slider['thumbnail']);
    }

    public function getChildrenCount() {
        if ($this->slider['slides'] > 0) {

            return $this->slider['slides'];
        }

        return 0;
    }

    /**
     * @return int
     */

    public function getOrdering() {
        return $this->slider['ordering'];
    }

    /**
     * @return int
     */
    public function getGroupID() {
        return $this->groupID;
    }

    /**
     * @param int $groupID
     */
    public function setGroupID($groupID) {
        $this->groupID = $groupID;
    }

}Admin/Layout/Block/Slider/SliderBox/SliderBox.php000064400000007553152356646020015647 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\SliderBox;

use Nextend\Framework\Sanitize;

/**
 * @var BlockSliderBox $this
 */
?>

<div class="n2_slider_manager__box n2_slider_box<?php echo $this->isGroup() ? ' n2_slider_box--group' : ' n2_slider_box--slider'; ?>"
     data-group="<?php echo $this->isGroup() ? '1' : '0'; ?>"
     data-title="<?php echo esc_attr($this->getSliderTitle()); ?>"
     data-sliderid="<?php echo esc_attr($this->getSliderID()); ?>"
     data-ordering="<?php echo esc_attr($this->getOrdering()); ?>">

    <?php
    $thumbnailUrl   = esc_attr($this->getThumbnail());
    $thumbnailStyle = '';
    if (!empty($thumbnailUrl)) {
        $thumbnailStyle = "background-image: url('" . $thumbnailUrl . "');";
    }
    ?>

    <div class="n2_slider_box__content" style="<?php echo esc_attr($thumbnailStyle); ?>">
        <?php
        if ($this->isThumbnailEmpty()):
            $icon = "ssi_64 ssi_64--image";
            if ($this->isGroup()) {
                $icon = "ssi_64 ssi_64--folder";
            }
            ?>

            <div class="n2_slider_box__icon">
                <div class="n2_slider_box__icon_container">
                    <i class="<?php echo esc_attr($icon); ?>"></i>
                </div>
            </div>

        <?php
        endif;
        ?>

        <div class="n2_slider_box__slider_overlay">
            <a class="n2_slider_box__slider_overlay_link" href="<?php echo esc_url($this->getEditUrl()); ?>"></a>
            <a class="n2_slider_box__slider_overlay_edit_button n2_button n2_button--small n2_button--green" href="<?php echo esc_url($this->getEditUrl()); ?>">
                <?php
                n2_e('Edit');
                ?>
            </a>
            <div class="n2_slider_box__slider_select_tick">
                <i class="ssi_16 ssi_16--check"></i>
            </div>
        </div>

        <div class="n2_slider_box__slider_identifiers">
            <div class="n2_slider_box__slider_identifier">
                <?php
                echo '#' . esc_html($this->getSliderID());
                ?>
            </div>
            <?php
            if ($this->isGroup()):
                ?>
                <div class="n2_slider_box__slider_identifier">
                    <?php
                    n2_e('Group');
                    ?>
                </div>
            <?php
            endif;
            ?>
            <?php
            if ($this->hasSliderAlias()):
                ?>
                <div class="n2_slider_box__slider_identifier">
                    <?php
                    echo esc_html($this->getSliderAlias());
                    ?>
                </div>
            <?php
            endif;
            ?>
        </div>

        <div class="n2_slider_box__slider_actions">
            <a class="n2_slider_box__slider_action_more n2_button_icon n2_button_icon--small n2_button_icon--grey-dark" href="#"><i class="ssi_16 ssi_16--more"></i></a>
        </div>
    </div>

    <div class="n2_slider_box__footer">
        <?php
        if ($this->isGroup()):
            ?>
            <div class="n2_slider_box__footer_icon">
                <i class="ssi_16 ssi_16--folderclosed"></i>
            </div>
        <?php
        endif;
        ?>
        <div class="n2_slider_box__footer_title">
            <?php
            echo esc_html($this->getSliderTitle());
            ?>
        </div>
        <div class="n2_slider_box__footer_children_count">
            <?php
            echo esc_html($this->getChildrenCount());
            ?>
        </div>
    </div>
    <a class="n2_slide_box__screen_reader" href="<?php echo esc_url($this->getSimpleEditUrl()); ?>">
        <?php
        echo esc_html(n2_('Edit Slider') . ': ' . $this->getSliderTitle());
        ?>
    </a>
</div>
Admin/Layout/Block/Slider/DeviceZoom/BlockDeviceZoom.php000064400000000432152356646020017131 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\DeviceZoom;


use Nextend\Framework\View\AbstractBlock;

class BlockDeviceZoom extends AbstractBlock {

    public function display() {
        $this->renderTemplatePart('DeviceZoom');
    }
}Admin/Layout/Block/Slider/DeviceZoom/DeviceZoom.php000064400000002111152356646020016152 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slider\DeviceZoom;

/**
 * @var $this BlockDeviceZoom
 */

?>
<div class="n2_device_changer">
    <div class="n2_device_changer__button">
        <i class="ssi_24 ssi_24--desktop"></i>
    </div>
    <div class="n2_device_tester"></div>
</div>
<script>
    _N2.r(['$', 'documentReady'], function () {
        var $ = _N2.$;
        var timeout,
            $el = $('.n2_device_tester_hover')
                .on({
                    mouseenter: function () {
                        if (timeout) {
                            clearTimeout(timeout);
                            timeout = undefined
                        }
                        $el.addClass('n2_device_tester_hover--hover');
                    },
                    mouseleave: function () {
                        timeout = setTimeout(function () {
                            $el.removeClass('n2_device_tester_hover--hover');
                        }, 400);
                    }
                });
    });
</script>Admin/Layout/Block/Slide/SlideManager/BlockSlideManager.php000064400000002771152356646020017535 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\SlideManager;


use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Slider\Slider;

class BlockSlideManager extends AbstractBlock {

    use TraitAdminUrl;

    protected $groupID = 0;

    /** @var  integer */
    protected $sliderID;

    protected $breadcrumbOpener = false;

    protected $classes = array(
        'n2_slide_manager'
    );

    /**
     * @return Slider
     */
    public function getSliderObject() {

        $sliderObj = new Slider($this, $this->sliderID, array(), true);
        $sliderObj->initSlider();

        return $sliderObj;
    }

    public function setGroupID($groupID) {

        $this->groupID = $groupID;
    }

    public function setSliderID($sliderID) {

        $this->sliderID = $sliderID;
    }

    public function display() {
        $this->renderTemplatePart('SlideManager');
    }

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

    public function getClass() {
        return implode(' ', $this->classes);
    }

    /**
     * @return bool
     */
    public function hasBreadcrumbOpener() {
        return $this->breadcrumbOpener;
    }

    /**
     * @param bool $breadcrumbOpener
     */
    public function setBreadcrumbOpener($breadcrumbOpener) {
        $this->breadcrumbOpener = $breadcrumbOpener;
    }

}Admin/Layout/Block/Slide/SlideManager/SlideManager.php000064400000016130152356646020016554 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\SlideManager;

use Nextend\Framework\Asset\Js\Js;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\SlideBox\BlockSlideBox;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\SlideManager\ActionBar\BlockActionBar;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\SlideManager\AddSlide\BlockAddSlide;
use Nextend\SmartSlider3\Application\Model\ModelSlides;
use Nextend\SmartSlider3\Slider\Feature\Optimize;
use Nextend\SmartSlider3\Slider\Slide;
use Nextend\SmartSlider3\SmartSlider3Info;

/**
 * @var $this BlockSlideManager
 */

$sliderObj = $this->getSliderObject();

$sliderType = $sliderObj->data->get('type', 'simple');

SmartSlider3Info::initLicense();

$slidesModel = new ModelSlides($this);

$slides   = $slidesModel->getAll($sliderObj->sliderId);
$optimize = new Optimize($sliderObj);

$parameters = array();

$sliderEditUrl = $this->getUrlSliderEdit($sliderObj->sliderId, $this->groupID);

$options = array(
    'url'            => $this->getUrlSlidesUniversal($sliderObj->sliderId, $this->groupID),
    'ajaxUrl'        => $this->getAjaxUrlSlidesUniversal($sliderObj->sliderId, $this->groupID),
    'sliderUrl'      => $sliderEditUrl,
    'contentAjaxUrl' => $this->getAjaxUrlContentSearchContent()
);

Js::addInline('new _N2.SlidesManager(' . json_encode($options) . ', ' . json_encode($parameters) . ', ' . (defined('N2_IMAGE_UPLOAD_DISABLE') ? 1 : 0) . ", '" . $this->createAjaxUrl(array('browse/upload')) . "', 'slider" . $sliderObj->sliderId . "');");

$slideCount            = 0;
$hasPublishedGenerator = false;
foreach ($slides as $slide) {
    if ($slide['published']) {
        $slideCount++;
        if (!empty($slide['generator_id'])) {
            $hasPublishedGenerator = true;
        }
    }
}

Js::addGlobalInline('document.documentElement.setAttribute("data-slides", "' . count($slides) . '");');
Js::addGlobalInline('document.documentElement.setAttribute("data-published-regular-slides", "' . $slideCount . '");');
?>

<script>
    <?php
    if($this->hasBreadcrumbOpener()):
    ?>
    _N2.r(['$', 'documentReady'], function () {
        var $ = _N2.$;
        var isVisible = false,
            $editorOverLay = $('.n2_admin_editor_overlay'),
            toggle = function () {
                isVisible = !isVisible;
                $editorOverLay.toggleClass('n2_admin_editor_overlay--show-slides', isVisible);
            },
            hide = function () {
                isVisible = true;
                toggle();
            },
            $slideManager = $('.n2_slide_manager');

        $('.n2_nav_bar__breadcrumb_button_slides').on('click', toggle);
        $slideManager.find('.n2_slide_manager__exit').on('click', hide);
    });
    <?php
    endif;
    ?>
</script>

<div class="<?php echo esc_attr($this->getClass()); ?>" data-breadcrumbopener="<?php echo $this->hasBreadcrumbOpener() ? 1 : 0; ?>">
    <div class="n2_slide_manager__inner">
        <?php

        $addSlide = new BlockAddSlide($this);
        $addSlide->setGroupID($this->groupID);
        $addSlide->setSliderID($sliderObj->sliderId);
        $addSlide->display();

        $actionBar = new BlockActionBar($this);
        $actionBar->display();

        ?>
        <div class="n2_slide_manager__content">

            <div class="n2_slide_manager__box n2_slide_manager__add_slide">
                <i class="n2_slide_manager__add_slide_icon ssi_48 ssi_48--plus"></i>
                <div class="n2_slide_manager__add_slide_label n2_slide_manager__add_slide_label--add-slide">
                    <?php n2_e('Add slide'); ?>
                </div>
                <div class="n2_slide_manager__add_slide_label n2_slide_manager__add_slide_label--close">
                    <?php n2_e('Close'); ?>
                </div>
            </div>

            <?php

            if ($sliderType == 'block'):
                ?>
                <div class="n2_slide_manager__box n2_slide_manager__block_notice">
                    <div class="n2_slide_box__footer_title n2_slide_manager__block_notice_description">
                        <?php n2_e('Block must contain only one slide. Need more?'); ?>
                    </div>
                    <a class="n2_slide_manager__block_notice_button" href="<?php echo esc_url($sliderEditUrl); ?>#changeslidertype">
                        <?php n2_e('Convert to slider'); ?>
                    </a>
                </div>
            <?php
            elseif (!$hasPublishedGenerator):
                ?>
                <div class="n2_slide_manager__box n2_slide_manager__autoplay_notice n2_form_element--hidden" data-field="autoplay-single-slide-notice">
                    <div class="n2_slide_box__footer_title n2_slide_manager__autoplay_notice_description">
                        <?php n2_e('Single slides are duplicated while autoplay is used.'); ?>
                    </div>
                    <a class="n2_slide_manager__autoplay_notice_button" href="#n2_top_bar_main_1">
                        <?php n2_e('autoplay settings'); ?>
                    </a>
                </div>
            <?php
            endif;

            $slidesObj = array();
            foreach ($slides as $i => $slide) {
                $slidesObj[$i] = new Slide($sliderObj, $slide);
                $slidesObj[$i]->initGenerator();
            }

            foreach ($slidesObj as $slideObj) {
                $slideObj->fillSample();

                $blockSlideBox = new BlockSlideBox($this);

                $blockSlideBox->setGroupID($this->groupID);
                $blockSlideBox->setSlider($sliderObj);
                $blockSlideBox->setSlide($slideObj);
                $blockSlideBox->setOptimize($optimize);

                $blockSlideBox->display();
            }
            ?>
            <div class="n2_slide_manager__box n2_slide_manager__dummy_slide">
                <i class="n2_slide_manager__dummy_slide_icon ssi_48 ssi_48--image"></i>
                <div class="n2_slide_manager__dummy_slide_label">
                    <?php n2_e('Slide one'); ?>
                </div>
            </div>
            <?php if ($sliderType != 'block'): ?>
                <div class="n2_slide_manager__box n2_slide_manager__dummy_slide">
                    <i class="n2_slide_manager__dummy_slide_icon ssi_48 ssi_48--image"></i>
                    <div class="n2_slide_manager__dummy_slide_label">
                        <?php n2_e('Slide two'); ?>
                    </div>
                </div>
            <?php endif; ?>
            <div class="n2_slide_manager__box n2_slide_manager__dummy_slide">
                <i class="n2_slide_manager__dummy_slide_icon ssi_48 ssi_48--drop"></i>
                <div class="n2_slide_manager__dummy_slide_label">
                    <?php n2_e('Drop images here'); ?>
                </div>
            </div>
        </div>
    </div>
    <?php if ($this->hasBreadcrumbOpener()): ?>
        <div class="n2_slide_manager__exit"></div>
    <?php endif; ?>
</div>
Admin/Layout/Block/Slide/SlideManager/AddSlide/AddSlide.php000064400000004604152356646020017346 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\SlideManager\AddSlide;

use Nextend\Framework\Platform\Platform;

/**
 * @var $this BlockAddSlide
 */

?>
<div class="n2_slide_manager__add_slide_actions">
    <div class="n2_slide_manager__add_slide_actions_inner">

        <a href="#" class="n2_slide_manager__add_slide_action n2_slide_manager__add_slide_action--image" data-action="image">
            <div class="n2_slide_manager__add_slide_action_icon">
                <i class="ssi_48 ssi_48--image"></i>
            </div>
            <div class="n2_slide_manager__add_slide_action_label"><?php n2_e('Image'); ?></div>
        </a>

        <a href="#" class="n2_slide_manager__add_slide_action n2_slide_manager__add_slide_action--empty-slide" data-action="empty-slide">
            <div class="n2_slide_manager__add_slide_action_icon">
                <i class="ssi_48 ssi_48--empty"></i>
            </div>
            <div class="n2_slide_manager__add_slide_action_label"><?php n2_e('Blank'); ?></div>
        </a>

        <?php
        if (Platform::hasPosts()) :
            ?>
            <a href="#" class="n2_slide_manager__add_slide_action n2_slide_manager__add_slide_action--post" data-action="post">
                <div class="n2_slide_manager__add_slide_action_icon">
                    <i class="ssi_48 ssi_48--post"></i>
                </div>
                <div class="n2_slide_manager__add_slide_action_label"><?php n2_e('Post'); ?></div>
            </a>
        <?php
        endif;
        ?>

        <a href="#" class="n2_slide_manager__add_slide_action n2_slide_manager__add_slide_action--static" data-action="static-overlay">
            <div class="n2_slide_manager__add_slide_action_icon">
                <i class="ssi_48 ssi_48--static"></i>
            </div>
            <div class="n2_slide_manager__add_slide_action_label"><?php n2_e('Static overlay'); ?></div>
        </a>

        <a href="<?php echo esc_url($this->getDynamicSlidesUrl()); ?>" class="n2_slide_manager__add_slide_action n2_slide_manager__add_slide_action--dynamic">
            <div class="n2_slide_manager__add_slide_action_icon">
                <i class="ssi_48 ssi_48--dynamic"></i>
            </div>
            <div class="n2_slide_manager__add_slide_action_label"><?php n2_e('Dynamic slides'); ?></div>
        </a>

    </div>
</div>Admin/Layout/Block/Slide/SlideManager/AddSlide/BlockAddSlide.php000064400000001712152356646020020316 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\SlideManager\AddSlide;


use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;

class BlockAddSlide extends AbstractBlock {

    use TraitAdminUrl;

    protected $groupID = 0;

    protected $sliderID = 0;

    public function display() {
        $this->renderTemplatePart('AddSlide');
    }

    /**
     * @param int $groupID
     */
    public function setGroupID($groupID) {
        $this->groupID = $groupID;
    }

    /**
     * @return int
     */
    public function getSliderID() {
        return $this->sliderID;
    }

    /**
     * @param int $sliderID
     */
    public function setSliderID($sliderID) {
        $this->sliderID = $sliderID;
    }

    public function getDynamicSlidesUrl() {

        return $this->getUrlGeneratorCreate($this->getSliderID(), $this->groupID);
    }

}Admin/Layout/Block/Slide/SlideManager/ActionBar/ActionBar.php000064400000000401152356646020017717 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\SlideManager\ActionBar;

/**
 * @var BlockActionBar $this
 */
?>
<div class="n2_slide_manager__action_bar">
    <?php

    $this->displayBulkActions();

    ?>
</div>
Admin/Layout/Block/Slide/SlideManager/ActionBar/BlockActionBar.php000064400000005704152356646020020705 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\SlideManager\ActionBar;


use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonPlain;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\FloatingMenu\BlockFloatingMenu;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\FloatingMenu\BlockFloatingMenuItem;

class BlockActionBar extends AbstractBlock {

    /**
     * @var BlockFloatingMenu
     */
    protected $blockBulkActions;

    public function display() {

        $this->renderTemplatePart('ActionBar');
    }

    public function displayBulkActions() {

        $this->blockBulkActions = new BlockFloatingMenu($this);
        $this->blockBulkActions->setRelatedClass('n2_slide_manager__action_bar_bulk_actions');
        $this->blockBulkActions->addClass('n2_slide_manager__action_bar_bulk_actions');
        $this->blockBulkActions->setContentID('n2_slide_manager_bulk_actions');

        $blockButton = new BlockButtonPlain($this);
        $blockButton->setLabel(n2_('Bulk actions'));
        $blockButton->setIcon('ssi_16 ssi_16--selectarrow');
        $blockButton->setSmall();
        $this->blockBulkActions->setButton($blockButton);


        /**
         * Bulk actions
         */
        $class = 'n2_slide_manager__action_bar_bulk_action';

        $this->createAction(n2_('Duplicate'), 'duplicate', $class);
        $this->createAction(n2_('Copy'), 'copy', $class);
        $this->createAction(n2_('Delete'), 'delete', $class)
             ->setRed();
        $this->createAction(n2_('Publish'), 'publish', $class);
        $this->createAction(n2_('Unpublish'), 'unpublish', $class);


        $this->blockBulkActions->addSeparator(array(
            'n2_slide_manager__action_bar_bulk_action'
        ));

        /**
         * Quick selection
         */
        $this->createAction(n2_('Select all'), 'select-all', false, true);
        $this->createAction(n2_('Select none'), 'select-none', false);
        $this->createAction(n2_('Select published'), 'select-published', false, true);
        $this->createAction(n2_('Select unpublished'), 'select-unpublished', false, true);


        $this->blockBulkActions->display();
    }

    /**
     * @param             $label
     * @param             $action
     * @param bool|string $class
     * @param bool        $stayOpen
     *
     * @return BlockFloatingMenuItem
     */
    private function createAction($label, $action, $class = false, $stayOpen = false) {

        $item = new BlockFloatingMenuItem($this);
        $item->setLabel($label);
        $item->addAttribute('data-action', $action);

        if ($class) {
            $item->addClass($class);
        }

        if ($stayOpen) {
            $item->setStayOpen();
        }

        $this->blockBulkActions->addMenuItem($item);

        return $item;
    }
}Admin/Layout/Block/Slide/SlideBox/BlockSlideBox.php000064400000010454152356646020016066 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\SlideBox;


use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Slider\Feature\Optimize;
use Nextend\SmartSlider3\Slider\Slide;
use Nextend\SmartSlider3\Slider\Slider;

class BlockSlideBox extends AbstractBlock {

    use TraitAdminUrl;

    protected $groupID = 0;

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

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

    /** @var Optimize */
    protected $optimize;

    public function display() {

        $this->renderTemplatePart('SlideBox');
    }

    /**
     * @param int $groupID
     */
    public function setGroupID($groupID) {
        $this->groupID = $groupID;
    }

    /**
     * @param Slider $slider
     */
    public function setSlider($slider) {
        $this->slider = $slider;
    }

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

    /**
     * @param Optimize $optimize
     */
    public function setOptimize($optimize) {
        $this->optimize = $optimize;
    }

    public function getSlideId() {

        return $this->slide->id;
    }

    public function getSlideTitle() {

        return $this->slide->getTitle(true);
    }

    public function getEditUrl() {

        return $this->getUrlSlideEdit($this->slide->id, $this->slider->sliderId, $this->groupID);
    }

    public function getThumbnailOptimized() {
        $image = $this->slide->getThumbnailDynamic();
        if (empty($image)) {
            $image = ResourceTranslator::toUrl('$ss3-frontend$/images/placeholder/image.png');
        }

        return $this->optimize->adminOptimizeThumbnail($image);
    }

    public function getPublishUrl() {

        return $this->getUrlSlidePublish($this->slide->id, $this->slider->sliderId, $this->groupID);
    }

    public function getUnPublishUrl() {

        return $this->getUrlSlideUnPublish($this->slide->id, $this->slider->sliderId, $this->groupID);
    }

    public function getClasses() {
        $classes = array();

        if ($this->slide->isStatic()) {
            $classes[] = 'n2_slide_box--static-overlay';
        }

        if ($this->slide->isFirst()) {
            $classes[] = 'n2_slide_box--first-slide';
        }

        if ($this->slide->published) {
            $classes[] = 'n2_slide_box--published';
        }

        if ($this->slide->hasGenerator()) {
            $classes[] = 'n2_slide_box--has-generator';
        }

        if ($this->slide->isCurrentlyEdited()) {
            $classes[] = 'n2_slide_box--currently-edited';
        }

        return $classes;
    }

    public function isStaticSlide() {
        return !!$this->slide->parameters->get('static-slide', 0);
    }

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

    public function getGeneratorLabel() {
        return $this->slide->getGeneratorLabel() . ' [' . $this->slide->getSlideStat() . ']';
    }

    public function getGeneratorAttributeUrl() {
        return $this->getUrlGeneratorEdit($this->slide->generator_id, $this->groupID) . '"';
    }

    public function getHiddenDeviceText() {
        $hiddenViews = array();
        if (!$this->slide->isVisibleDesktopLandscape()) {
            $hiddenViews[] = n2_('Large desktop');
        }
    
        if (!$this->slide->isVisibleDesktopPortrait()) {
            $hiddenViews[] = n2_('Desktop');
        }
        if (!$this->slide->isVisibleTabletLandscape()) {
            $hiddenViews[] = n2_('Large tablet');
        }
    
        if (!$this->slide->isVisibleTabletPortrait()) {
            $hiddenViews[] = n2_('Tablet');
        }
        if (!$this->slide->isVisibleMobileLandscape()) {
            $hiddenViews[] = n2_('Large mobile');
        }
    
        if (!$this->slide->isVisibleMobilePortrait()) {
            $hiddenViews[] = n2_('Mobile');
        }

        if (!empty($hiddenViews)) {
            return sprintf(n2_('This slide is hidden on the following devices: %s'), implode(', ', $hiddenViews));
        }

        return '';
    }
}Admin/Layout/Block/Slide/SlideBox/SlideBox.php000064400000006163152356646020015115 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\SlideBox;

/**
 * @var BlockSlideBox $this
 */
?>

<div class="n2_slide_manager__box n2_slide_box <?php echo esc_attr(implode(' ', $this->getClasses())); ?>"
     data-slideid="<?php echo esc_attr($this->getSlideId()); ?>"
    <?php echo $this->hasGenerator() ? ' data-generator-edit="' . esc_url($this->getGeneratorAttributeUrl()) . '"' : ''; ?>>

    <div class="n2_slide_box__content" style="background-image: url('<?php echo esc_url($this->getThumbnailOptimized()); ?>');">

        <div class="n2_slide_box__slide_overlay">
            <a class="n2_slide_box__slide_overlay_link" href="<?php echo esc_url($this->getEditUrl()); ?>"></a>
            <a class="n2_slide_box__slide_overlay_edit_button" href="<?php echo esc_url($this->getEditUrl()); ?>">
                <?php
                n2_e('Edit');
                ?>
            </a>
            <div class="n2_slide_box__slide_select_tick">
                <i class="ssi_16 ssi_16--check"></i>
            </div>

            <div class="n2_slide_box__slide_actions">
                <a class="n2_slide_box__slide_action_more n2_button_icon n2_button_icon--small n2_button_icon--grey-dark" href="#"><i class="ssi_16 ssi_16--more"></i></a>
            </div>
        </div>

        <div class="n2_slide_box__details">
            <?php
            if ($this->isStaticSlide()):
                ?>
                <div class="n2_slide_box__details_static_slide"><?php n2_e('Static overlay'); ?></div>
            <?php
            endif;
            ?>
            <?php
            if ($this->hasGenerator()):
                ?>
                <div class="n2_slide_box__details_generator"><?php echo esc_html($this->getGeneratorLabel()); ?></div>
            <?php
            endif;
            ?>
        </div>
    </div>

    <div class="n2_slide_box__footer">
        <div class="n2_slide_box__footer_title">
            <?php
            echo esc_html($this->getSlideTitle());
            ?>
        </div>

        <div class="n2_slide_box__footer_status">

            <?php
            $hiddenViews = $this->getHiddenDeviceText();
            ?>
            <a class="n2_slide_box__footer_status_hidden" href="<?php echo esc_url($this->getEditUrl()); ?>" data-n2tip="<?php echo esc_attr($hiddenViews); ?>">
                <i class="ssi_16 ssi_16--hide"></i>
            </a>

            <div class="n2_slide_box__footer_status_first_slide" data-n2tip="<?php n2_e('First slide'); ?>">
                <i class="ssi_16 ssi_16--star"></i>
            </div>

            <a class="n2_slide_box__footer_status_published" href="<?php echo esc_url($this->getUnPublishUrl()); ?>" data-n2tip="<?php n2_e('Published'); ?>">
                <i class="ssi_16 ssi_16--filledcheck"></i>
            </a>

            <a class="n2_slide_box__footer_status_unpublished" href="<?php echo esc_url($this->getPublishUrl()); ?>" data-n2tip="<?php n2_e('Unpublished'); ?>">
                <i class="ssi_16 ssi_16--filledremove"></i>
            </a>
        </div>
    </div>
</div>Admin/Layout/Block/Slide/LayerWindow/BlockLayerWindow.php000064400000006362152356646020017357 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow;


use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings\AbstractLayerWindowSettings;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings\LayerWindowSettingsColumn;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings\LayerWindowSettingsCommon;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings\LayerWindowSettingsContent;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings\LayerWindowSettingsItem;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings\LayerWindowSettingsItemCommon;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings\LayerWindowSettingsRow;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings\LayerWindowSettingsSlide;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Tab\AbstractTab;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Tab\TabAnimation;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Tab\TabContent;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Tab\TabGoPro;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Tab\TabStyle;
use Nextend\SmartSlider3\Renderable\Item\ItemFactory;
use Nextend\SmartSlider3\Slider\Admin\AdminSlider;

class BlockLayerWindow extends AbstractBlock {

    /**
     * @var AdminSlider
     */
    protected $renderableAdminSlider;

    /**
     * @var AbstractTab[]
     */
    protected $tabs = array();

    /**
     * @var AbstractLayerWindowSettings[]
     */
    protected $settings = array();

    /**
     * @param AdminSlider $renderableAdminSlider
     */
    public function setRenderableAdminSlider($renderableAdminSlider) {
        $this->renderableAdminSlider = $renderableAdminSlider;
    }

    public function display() {


        $this->tabs['content'] = new TabContent($this);
        $this->tabs['style']   = new TabStyle($this);
        $this->tabs['animation'] = new TabAnimation($this);


        $this->settings[] = new LayerWindowSettingsSlide($this, $this->renderableAdminSlider);
        $this->settings[] = new LayerWindowSettingsContent($this);
        $this->settings[] = new LayerWindowSettingsRow($this);
        $this->settings[] = new LayerWindowSettingsColumn($this);

        foreach (ItemFactory::getItems() as $type => $item) {
            $this->settings[] = new LayerWindowSettingsItem($type, $item, $this, $this->renderableAdminSlider);
        }

        $this->settings[] = new LayerWindowSettingsItemCommon($this);

        $this->settings[] = new LayerWindowSettingsCommon($this);

        foreach ($this->settings as $setting) {
            $setting->extendForm($this->tabs['content']->getContainer(), $this->tabs['style']->getContainer());
        }

        $this->renderTemplatePart('LayerWindow');
    }

    /**
     * @return AbstractTab[]
     */
    public function getTabs() {

        return $this->tabs;
    }
}Admin/Layout/Block/Slide/LayerWindow/LayerWindow.php000064400000003612152356646020016377 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow;

/**
 * @var $this BlockLayerWindow
 */
?>

<div id="n2-ss-layer-window" class="n2_ss_layer_window  n2_form--dark">
    <div class="n2_ss_layer_window__crop">
        <div class="n2_ss_layer_window__title">

            <div class="n2_ss_layer_window__title_nav n2_ss_layer_window__title_nav_left">
            </div>

            <div class="n2_ss_layer_window__title_inner"></div>

            <div class="n2_ss_layer_window__title_nav n2_ss_layer_window__title_nav_right">
            </div>
        </div>

        <div class="n2_ss_layer_window__tab_buttons">
            <?php
            foreach ($this->getTabs() as $tab):
                ?>
                <div class="n2_ss_layer_window__tab_button" data-related-tab="<?php echo esc_attr($tab->getName()); ?>">
                    <div class="n2_ss_layer_window__tab_button_icon">
                        <i class="<?php echo esc_attr($tab->getIcon()); ?>"></i>
                    </div>
                    <div class="n2_ss_layer_window__tab_button_label">
                        <?php
                        echo esc_html($tab->getLabel());
                        ?>
                    </div>
                </div>
            <?php
            endforeach;
            ?>
        </div>

        <div class="n2_ss_layer_window__tab_container n2_container_scrollable">
            <?php
            foreach ($this->getTabs() as $tab):
                ?>
                <div class="n2_ss_layer_window__tab" data-tab="<?php echo esc_attr($tab->getName()); ?>">
                    <?php
                    $tab->display();
                    ?>
                </div>
            <?php
            endforeach;
            ?>
        </div>

        <?php
        //$this->renderForm();
        ?>
    </div>
</div>Admin/Layout/Block/Slide/LayerWindow/Tab/AbstractTab.php000064400000002302152356646020017026 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Tab;


use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\Form\Form;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\BlockLayerWindow;

abstract class AbstractTab {

    /**
     * @var BlockLayerWindow
     */
    protected $blockLayerWindow;

    /**
     * @var Form
     */
    protected $form;

    /**
     * AbstractTab constructor.
     *
     * @param BlockLayerWindow $blockLayerWindow
     */
    public function __construct($blockLayerWindow) {

        $this->blockLayerWindow = $blockLayerWindow;

        $this->form = new Form($blockLayerWindow, 'layer');
    }

    /**
     * @return ContainerInterface
     */
    public function getContainer() {
        return $this->form->getContainer();
    }

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

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

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

    public function display() {

        $this->form->render();
    }
}Admin/Layout/Block/Slide/LayerWindow/Tab/TabAnimation.php000064400000044232152356646020017212 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Tab;


use Nextend\Framework\Form\Container\LayerWindow\ContainerAnimation;
use Nextend\Framework\Form\Element\Grouping;
use Nextend\Framework\Form\Element\MixedField;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\Easing;
use Nextend\Framework\Form\Element\Text;
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\Text\NumberSlider;
use Nextend\Framework\Form\Element\Text\TextMultiAutoComplete;
use Nextend\Framework\Form\Fieldset\LayerWindow\FieldsetLayerWindow;
class TabAnimation extends AbstractTab {

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

    /**
     * @return string
     */
    public function getLabel() {
        return n2_('Animation');
    }

    /**
     * @return string
     */
    public function getIcon() {
        return 'ssi_24 ssi_24--animation';
    }

    public function display() {
        $containerAnimation = new ContainerAnimation($this->getContainer(), 'animation');

        $containerAnimation->createTab('in', n2_x('In', 'Layer animation'));
        $containerAnimation->createTab('loop', n2_('Loop'));
        $containerAnimation->createTab('out', n2_x('Out', 'Layer animation'));
        $tabEvents = $containerAnimation->createTab('events', n2_x('Events', 'Layer animation'));

        $events = new FieldsetLayerWindow($tabEvents, 'animations-events-events');

        $eventNames = array(
            'layerAnimationPlayIn',
            'layerAnimationPlayLoop',
            'LayerClick',
            'LayerMouseEnter',
            'LayerMouseLeave',
            'SlideClick',
            'SlideMouseEnter',
            'SlideMouseLeave',
            'SliderClick',
            'SliderMouseEnter',
            'SliderMouseLeave'
        );

        new TextMultiAutoComplete($events, 'in-play-event', n2_('Plays in when'), '', array(
            'options' => $eventNames,
            'style'   => 'width:260px;'
        ));

        new TextMultiAutoComplete($events, 'out-play-event', n2_('Plays out when'), '', array(
            'options' => array_merge($eventNames, array(
                'InstantOut',
                'OutForced'
            )),
            'style'   => 'width:260px;'
        ));

        new TextMultiAutoComplete($events, 'loop-play-event', n2_('Plays loop when'), '', array(
            'options' => $eventNames,
            'style'   => 'width:260px;'
        ));

        new TextMultiAutoComplete($events, 'loop-pause-event', n2_('Pauses loop when'), '', array(
            'options' => $eventNames,
            'style'   => 'width:260px;'
        ));

        new TextMultiAutoComplete($events, 'loop-stop-event', n2_('Stops loop when'), '', array(
            'options' => $eventNames,
            'style'   => 'width:260px;'
        ));

        new OnOff($events, 'repeatable', n2_('Repeatable'), 0, array(
            'relatedFieldsOn' => array(
                'layerstart-delay',
                'layerend-delay'
            ),
            'tipLabel'        => n2_('Repeatable'),
            'tipDescription'  => n2_('Allows the layer animations to play more than once.')
        ));

        new NumberAutoComplete($events, 'start-delay', n2_('Start delay'), 0, array(
            'min'    => 0,
            'values' => array(
                0,
                500,
                800,
                1000,
                1500,
                2000
            ),
            'unit'   => 'ms',
            'wide'   => 5
        ));

        new NumberAutoComplete($events, 'end-delay', n2_('End delay'), 0, array(
            'min'    => 0,
            'values' => array(
                0,
                500,
                800,
                1000,
                1500,
                2000
            ),
            'unit'   => 'ms',
            'wide'   => 5
        ));
        new OnOff($events, 'loop-repeat-self-only', n2_('Repeat loop only'), 0, array(
            'tipLabel'       => n2_('Repeat loop only'),
            'tipDescription' => n2_('Allows the stopped loop to start again.')
        ));

        $triggers = new FieldsetLayerWindow($tabEvents, 'animations-events-triggers', n2_('Trigger custom event on'));

        new Text($triggers, 'onclick', n2_('Click'), '', array(
            'style' => 'width:73px;'
        ));
        new Text($triggers, 'onmouseenter', n2_('Mouse enter'), '', array(
            'style' => 'width:73px;'
        ));
        new Text($triggers, 'onmouseleave', n2_('Mouse leave'), '', array(
            'style' => 'width:73px;'
        ));
        new Text($triggers, 'onplay', n2_('Media started'), '', array(
            'style' => 'width:73px;'
        ));
        new Text($triggers, 'onpause', n2_('Media paused'), '', array(
            'style' => 'width:73px;'
        ));
        new Text($triggers, 'onstop', n2_('Media stopped'), '', array(
            'style' => 'width:73px;'
        ));

        $this->formAnimationsBasic();
        $this->formAnimationsReveal();

        parent::display();
    }


    protected function formAnimationsBasic() {

        $basicForm = new FieldsetLayerWindow($this->getContainer(), 'layer-animation-basic-form');
        new NumberAutoComplete($basicForm, '-anim-duration', n2_('Duration'), 500, array(
            'min'    => 0,
            'values' => array(
                500,
                800,
                1000,
                1500,
                2000
            ),
            'unit'   => 'ms',
            'wide'   => 5
        ));
        new NumberAutoComplete($basicForm, '-anim-delay', n2_('Delay'), 0, array(
            'min'    => 0,
            'values' => array(
                0,
                500,
                800,
                1000,
                1500,
                2000
            ),
            'unit'   => 'ms',
            'wide'   => 5
        ));
        new Easing($basicForm, '-anim-ease', n2_('Easing'), 'easeOutCubic');


        new NumberSlider($basicForm, '-anim-opacity', n2_('Opacity'), 100, array(
            'wide' => 3,
            'min'  => 0,
            'max'  => 100,
            'unit' => '%'
        ));
        new NumberSlider($basicForm, '-anim-n2blur', n2_('Blur'), 0, array(
            'wide' => 3,
            'min'  => 0,
            'max'  => 100,
            'unit' => 'px'
        ));

        $offset = new Grouping($basicForm, 'animation-offset', n2_('Offset'), array(
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));
        new NumberAutoComplete($offset, '-anim-x', false, 0, array(
            'sublabel' => 'X',
            'values'   => array(
                -800,
                -400,
                -200,
                -100,
                -50,
                0,
                50,
                100,
                200,
                400,
                800
            ),
            'unit'     => 'px',
            'style'    => 'width:30px;'
        ));
        new NumberAutoComplete($offset, '-anim-y', false, 0, array(
            'sublabel' => 'Y',
            'values'   => array(
                -800,
                -400,
                -200,
                -100,
                -50,
                0,
                50,
                100,
                200,
                400,
                800
            ),
            'unit'     => 'px',
            'style'    => 'width:30px;'
        ));
        new Number($basicForm, '-anim-z', 'Z', 0, array(
            'wide'  => 4,
            'unit'  => 'px',
            'style' => 'width:30px;'
        ));


        $rotate = new Grouping($basicForm, 'animation-rotate', n2_('Rotate'));
        new NumberAutoComplete($rotate, '-anim-rotationX', false, 0, array(
            'wide'     => 4,
            'sublabel' => 'X',
            'values'   => array(
                0,
                90,
                180,
                -90,
                -180
            ),
            'unit'     => '°'
        ));
        new NumberAutoComplete($rotate, '-anim-rotationY', false, 0, array(
            'wide'     => 4,
            'sublabel' => 'Y',
            'values'   => array(
                0,
                90,
                180,
                -90,
                -180
            ),
            'unit'     => '°'
        ));
        new NumberAutoComplete($rotate, '-anim-rotationZ', false, 0, array(
            'wide'     => 4,
            'sublabel' => 'Z',
            'values'   => array(
                0,
                90,
                180,
                -90,
                -180
            ),
            'unit'     => '°'
        ));

        $scale = new Grouping($basicForm, 'animation-scale', n2_('Scale'));
        new NumberAutoComplete($scale, '-anim-scaleX', false, 0, array(
            'wide'     => 4,
            'sublabel' => 'X',
            'min'      => 0,
            'values'   => array(
                0,
                50,
                100,
                150
            ),
            'unit'     => '%'
        ));
        new NumberAutoComplete($scale, '-anim-scaleY', false, 0, array(
            'wide'     => 4,
            'sublabel' => 'Y',
            'min'      => 0,
            'values'   => array(
                0,
                50,
                100,
                150
            ),
            'unit'     => '%'
        ));


        new Number($basicForm, '-anim-skew', n2_('Skew'), 0, array(
            'wide' => 4,
            'unit' => '%'
        ));

        $layerAnimationBasicFormIn = new FieldsetLayerWindow($this->getContainer(), 'layer-animation-basic-form-in', false);

        $transformOrigin = new MixedField($layerAnimationBasicFormIn, 'basic-in-transformorigin', n2_('Transform origin'), '50|*|50|*|0');

        new NumberAutoComplete($transformOrigin, 'in-transformorigin-x', false, 50, array(
            'wide'     => 4,
            'sublabel' => 'X',
            'values'   => array(
                0,
                50,
                100
            ),
            'unit'     => '%'
        ));
        new NumberAutoComplete($transformOrigin, 'in-transformorigin-y', false, 50, array(
            'wide'     => 4,
            'sublabel' => 'Y',
            'values'   => array(
                0,
                50,
                100
            ),
            'unit'     => '%'
        ));
        new Number($transformOrigin, 'in-transformorigin-z', false, 0, array(
            'wide'     => 4,
            'sublabel' => 'Z',
            'unit'     => 'px'
        ));

        new OnOff($layerAnimationBasicFormIn, 'basic-in-special-zero', n2_('Special Zero'), 0, array(
            'tipLabel'       => n2_('Special Zero'),
            'tipDescription' => n2_('Makes the last keyframe to be the origin of the layer animation, instead of its canvas position.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1889-layer-animation'
        ));

        $layerAnimationBasicFormLoop = new FieldsetLayerWindow($this->getContainer(), 'layer-animation-basic-form-loop', false);

        new Number($layerAnimationBasicFormLoop, 'basic-loop-repeat-count', n2_('Repeat count'), 0, array(
            'wide'           => 3,
            'unit'           => n2_('loops'),
            'tipLabel'       => n2_('Repeat count'),
            'tipDescription' => n2_('You can restrict the loop to play only a certain amount of loops, instead of infinite.')
        ));
        new Number($layerAnimationBasicFormLoop, 'basic-loop-repeat-start-delay', n2_('Start delay'), 0, array(
            'wide' => 5,
            'unit' => 'ms'
        ));

        $transformOrigin = new MixedField($layerAnimationBasicFormLoop, 'basic-loop-transformorigin', n2_('Transform origin'), '50|*|50|*|0');

        new NumberAutoComplete($transformOrigin, 'loop-transformorigin-x', false, 50, array(
            'wide'     => 4,
            'sublabel' => 'X',
            'values'   => array(
                0,
                50,
                100
            ),
            'unit'     => '%'
        ));
        new NumberAutoComplete($transformOrigin, 'loop-transformorigin-y', false, 50, array(
            'wide'     => 4,
            'sublabel' => 'Y',
            'values'   => array(
                0,
                50,
                100
            ),
            'unit'     => '%'
        ));
        new Number($transformOrigin, 'loop-transformorigin-z', false, 0, array(
            'wide'     => 4,
            'sublabel' => 'Z',
            'unit'     => 'px'
        ));

        $layerAnimationBasicFormOut = new FieldsetLayerWindow($this->getContainer(), 'layer-animation-basic-form-out', false);

        $transformOrigin = new MixedField($layerAnimationBasicFormOut, 'basic-out-transformorigin', n2_('Transform origin'), '50|*|50|*|0');

        new NumberAutoComplete($transformOrigin, 'out-transformorigin-x', false, 50, array(
            'wide'     => 4,
            'sublabel' => 'X',
            'values'   => array(
                0,
                50,
                100
            ),
            'unit'     => '%'
        ));
        new NumberAutoComplete($transformOrigin, 'out-transformorigin-y', false, 50, array(
            'wide'     => 4,
            'sublabel' => 'Y',
            'values'   => array(
                0,
                50,
                100
            ),
            'unit'     => '%'
        ));
        new Number($transformOrigin, 'out-transformorigin-z', false, 0, array(
            'wide'     => 4,
            'sublabel' => 'Z',
            'unit'     => 'px'
        ));
    }

    protected function formAnimationsReveal() {
        $revealForm = new FieldsetLayerWindow($this->getContainer(), 'layer-animation-reveal-form', false);

        new Color($revealForm, '-reveal-color', n2_('Color'), 'ffffff');
        new NumberAutoComplete($revealForm, '-reveal-duration', n2_('Duration'), 500, array(
            'min'    => 0,
            'values' => array(
                500,
                800,
                1000,
                1500,
                2000
            ),
            'unit'   => 'ms',
            'wide'   => 5
        ));
        new NumberAutoComplete($revealForm, '-reveal-delay', n2_('Delay'), 0, array(
            'min'    => 0,
            'values' => array(
                0,
                500,
                800,
                1000,
                1500,
                2000
            ),
            'unit'   => 'ms',
            'wide'   => 5
        ));


        $options = array(
            'no'                   => n2_('No'),
            'top'                  => n2_x('Slide', 'Animation') . ' - ' . n2_('Top'),
            'right'                => n2_x('Slide', 'Animation') . ' - ' . n2_('Right'),
            'bottom'               => n2_x('Slide', 'Animation') . ' - ' . n2_('Bottom'),
            'left'                 => n2_x('Slide', 'Animation') . ' - ' . n2_('Left'),
            'skew-top'             => n2_('Skew') . ' - ' . n2_('Top'),
            'skew-right'           => n2_('Skew') . ' - ' . n2_('Right'),
            'skew-bottom'          => n2_('Skew') . ' - ' . n2_('Bottom'),
            'skew-left'            => n2_('Skew') . ' - ' . n2_('Left'),
            'curtains-horizontal'  => n2_('Curtains') . ' - ' . n2_('Horizontal'),
            'curtains-vertical'    => n2_('Curtains') . ' - ' . n2_('Vertical'),
            'curtains-diagonal-1'  => n2_('Curtains') . ' - ' . n2_('Diagonal') . ' 1',
            'curtains-diagonal-2'  => n2_('Curtains') . ' - ' . n2_('Diagonal') . ' 2',
            'rotate-top-left'      => n2_('Rotate') . ' - ' . n2_('Top') . ' ' . n2_('Left') . ' 1',
            'rotate-top-left-'     => n2_('Rotate') . ' - ' . n2_('Top') . ' ' . n2_('Left') . ' 2',
            'rotate-top-right'     => n2_('Rotate') . ' - ' . n2_('Top') . ' ' . n2_('Right') . ' 1',
            'rotate-top-right-'    => n2_('Rotate') . ' - ' . n2_('Top') . ' ' . n2_('Right') . ' 2',
            'rotate-bottom-right'  => n2_('Rotate') . ' - ' . n2_('Bottom') . ' ' . n2_('Right') . ' 1',
            'rotate-bottom-right-' => n2_('Rotate') . ' - ' . n2_('Bottom') . ' ' . n2_('Right') . ' 2',
            'rotate-bottom-left'   => n2_('Rotate') . ' - ' . n2_('Bottom') . ' ' . n2_('Left') . ' 1',
            'rotate-bottom-left-'  => n2_('Rotate') . ' - ' . n2_('Bottom') . ' ' . n2_('Left') . ' 2',
            'circle-top'           => n2_('Circle') . ' - ' . n2_('Top'),
            'circle-right'         => n2_('Circle') . ' - ' . n2_('Right'),
            'circle-bottom'        => n2_('Circle') . ' - ' . n2_('Bottom'),
            'circle-left'          => n2_('Circle') . ' - ' . n2_('Left'),
        );

        new Select($revealForm, '-reveal-from', n2_('From'), 'top', array(
            'options' => $options
        ));
        new Easing($revealForm, '-reveal-from-ease', n2_('Easing'), 'easeOutCubic');

        unset($options['no']);
        new Select($revealForm, '-reveal-to', n2_('To'), 'bottom', array(
            'options' => $options
        ));
        new Easing($revealForm, '-reveal-to-ease', n2_('Easing'), 'easeOutCubic');

        new Select($revealForm, '-reveal-content', n2_('Content'), '', array(
            'options' => array(
                ''           => n2_('Default'),
                'fade'       => n2_('Fade'),
                'scale-up'   => n2_('Scale up'),
                'scale-down' => n2_('Scale down'),
                'top'        => n2_('Top'),
                'right'      => n2_('Right'),
                'bottom'     => n2_('Bottom'),
                'left'       => n2_('Left')
            )
        ));
    }
}
Admin/Layout/Block/Slide/LayerWindow/Tab/TabContent.php000064400000000746152356646020016707 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Tab;

class TabContent extends AbstractTab {

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

    /**
     * @return string
     */
    public function getLabel() {
        return n2_('Content');
    }

    /**
     * @return string
     */
    public function getIcon() {
        return 'ssi_24 ssi_24--edit';
    }
}Admin/Layout/Block/Slide/LayerWindow/Tab/TabGoPro.php000064400000000275152356646020016320 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Tab;

use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\FreeNeedMore\BlockFreeNeedMore;Admin/Layout/Block/Slide/LayerWindow/Tab/TabStyle.php000064400000000745152356646020016374 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Tab;


class TabStyle extends AbstractTab {

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

    /**
     * @return string
     */
    public function getLabel() {
        return n2_('Style');
    }

    /**
     * @return string
     */
    public function getIcon() {
        return 'ssi_24 ssi_24--style';
    }
}Admin/Layout/Block/Slide/LayerWindow/Settings/AbstractLayerWindowSettings.php000064400000003512152356646020023403 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings;


use Nextend\Framework\Form\Container\LayerWindow\ContainerSettings;
use Nextend\Framework\Form\ContainerInterface;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\BlockLayerWindow;

abstract class AbstractLayerWindowSettings {

    /**
     * @var BlockLayerWindow
     */
    protected $blockLayerWindow;

    /**
     * @var ContainerSettings
     */
    protected $contentContainer;

    /**
     * @var ContainerSettings
     */
    protected $styleContainer;

    /**
     * AbstractLayerWindowSettings constructor.
     *
     * @param BlockLayerWindow $blockLayerWindow
     */
    public function __construct($blockLayerWindow) {

        $this->blockLayerWindow = $blockLayerWindow;
    }

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

    /**
     * @param ContainerInterface $contentContainer
     * @param ContainerInterface $styleContainer
     */
    public function extendForm($contentContainer, $styleContainer) {
        $this->createContentContainer($contentContainer);
        $this->createStyleContainer($styleContainer);

        $this->extendContent();
        $this->extendStyle();
    }

    /**
     * @param ContainerInterface $container
     */
    protected function createContentContainer($container) {
        $this->contentContainer = new ContainerSettings($container, $this->getName());
    }

    /**
     * @param ContainerInterface $container
     */
    protected function createStyleContainer($container) {
        $this->styleContainer = new ContainerSettings($container, $this->getName());
    }

    protected function extendContent() {

    }

    protected function extendStyle() {

    }
}Admin/Layout/Block/Slide/LayerWindow/Settings/LayerWindowSettingsColumn.php000064400000017561152356646020023106 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings;


use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\Form\Element\Hidden;
use Nextend\Framework\Form\Element\LayerWindowFocus;
use Nextend\Framework\Form\Element\MarginPadding;
use Nextend\Framework\Form\Element\MixedField\BoxShadow;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\Gradient;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\FieldImage;
use Nextend\Framework\Form\Element\Text\HiddenText;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;
use Nextend\Framework\Form\Element\Text\Url;
use Nextend\Framework\Form\Fieldset\LayerWindow\FieldsetLayerWindowLabelFields;
use Nextend\Framework\Form\Fieldset\LayerWindow\FieldsetLayerWindowStyleMode;
use Nextend\SmartSlider3\Form\Element\Radio\FlexAlign;
use Nextend\SmartSlider3\Form\Element\Radio\InnerAlign;

class LayerWindowSettingsColumn extends AbstractLayerWindowSettings {

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

    protected function extendContent() {

        $general = new FieldsetLayerWindowLabelFields($this->contentContainer, 'fields-col-general', n2_('General'));

        new Hidden($general, 'col-order', '0');
        new Hidden($general, 'col-opened', 1);
        new Hidden($general, 'col-colwidth', '');

        new InnerAlign($general, 'col-inneralign', n2_('Inner align'), 'inherit', array(
            'rowAttributes'  => array(
                'data-devicespecific' => ''
            ),
            'tipLabel'       => n2_('Inner align'),
            'tipDescription' => n2_('Positions the layers inside horizontally.')
        ));

        new FlexAlign($general, 'col-verticalalign', n2_('Vertical align'), 'center', array(
            'rowAttributes'  => array(
                'data-devicespecific' => ''
            ),
            'tipLabel'       => n2_('Vertical align'),
            'tipDescription' => n2_('Positions the layers inside vertically.')
        ));


        $link = new FieldsetLayerWindowLabelFields($this->contentContainer, 'fields-col-link', n2_('Link'));

        new Url($link, 'col-href', n2_('Link'), '', array(
            'relatedFields' => array(
                'layercol-href-target',
                'layercol-aria-label'
            ),
            'width'         => 248
        ));
        new LinkTarget($link, 'col-href-target', n2_('Target window'));

        new Text($link, 'col-aria-label', n2_('ARIA label'), '', array(
            'style'    => 'width:190px;',
            'tipLabel' => n2_('ARIA label')
        ));
    }

    protected function extendStyle() {

        $this->backgroundImage($this->styleContainer);
        $this->background($this->styleContainer);
        $this->border($this->styleContainer);
        $this->size($this->styleContainer);
    }

    /**
     * @param ContainerInterface $container
     */
    protected function backgroundImage($container) {

        $backgroundImage = new FieldsetLayerWindowLabelFields($container, 'fields-col-background-image', n2_('Background image'));
        $fieldImage      = new FieldImage($backgroundImage, 'col-background-image', n2_('Background image'), '', array(
            'width'         => 220,
            'relatedFields' => array(
                'layercol-background-focus'
            )
        ));

        $fieldFocusX = new HiddenText($backgroundImage, 'col-background-focus-x', 50);
        $fieldFocusY = new HiddenText($backgroundImage, 'col-background-focus-y', 50);

        $focusField = new LayerWindowFocus($backgroundImage, 'col-background-focus', n2_('Focus'), array(
            'tipLabel'       => n2_('Focus'),
            'tipDescription' => n2_('You can set the starting position of a background image. This makes sure that the selected part will always remain visible, so you should pick the most important part.')
        ));

        $focusField->setFields($fieldImage, $fieldFocusX, $fieldFocusY);

    }

    /**
     * @param ContainerInterface $container
     */
    protected function background($container) {

        $background = new FieldsetLayerWindowStyleMode($container, 'fields-col-background', n2_('Background'), array(
            ''       => 'Normal',
            '-hover' => 'Hover'
        ));

        new Color($background, 'col-background-color', n2_('Background color'), 'ffffff00', array(
            'alpha' => true
        ));

        new Gradient($background, 'col-background-gradient', n2_('Gradient'), 'off', array(
            'relatedFields' => array(
                'layercol-background-color-end'
            )
        ));

        new Color($background, 'col-background-color-end', n2_('Color end'), 'ffffff00', array(
            'alpha' => true
        ));

        new BoxShadow($background, 'col-boxshadow', n2_('Box shadow'), '0|*|0|*|0|*|0|*|00000080');

    }

    /**
     * @param ContainerInterface $container
     */
    protected function border($container) {

        $border = new FieldsetLayerWindowStyleMode($container, 'fields-col-border', n2_('Border'), array(
            ''       => 'Normal',
            '-hover' => 'Hover'
        ));

        $borderWidth = new MarginPadding($border, 'col-border-width', n2_('Border'), '0|*|0|*|0|*|0', array(
            'unit'          => 'px',
            'relatedFields' => array(
                'layercol-border-style',
                'layercol-border-color'
            )
        ));

        for ($i = 1; $i < 5; $i++) {
            new NumberAutoComplete($borderWidth, 'col-border-width-' . $i, false, '', array(
                'values' => array(
                    0,
                    1,
                    2,
                    3,
                    5
                ),
                'wide'   => 3
            ));
        }

        new Select($border, 'col-border-style', n2_('Style'), 'none', array(
            'options' => array(
                'none'   => n2_('None'),
                'solid'  => n2_('Solid'),
                'dashed' => n2_('Dashed'),
                'dotted' => n2_('Dotted'),
            )
        ));

        new Color($border, 'col-border-color', n2_('Color'), 'ffffffff', array(
            'alpha' => true
        ));

        new NumberAutoComplete($border, 'col-border-radius', n2_('Border radius'), 0, array(
            'values' => array(
                0,
                3,
                5,
                10,
                99
            ),
            'wide'   => 3,
            'unit'   => 'px'
        ));
    }

    /**
     * @param ContainerInterface $container
     */
    protected function size($container) {

        $size = new FieldsetLayerWindowLabelFields($container, 'fields-col-size', n2_('Size'));

        new Number($size, 'col-maxwidth', n2_('Max width'), 0, array(
            'rowAttributes' => array(
                'data-devicespecific' => ''
            ),
            'wide'          => 5,
            'unit'          => 'px'
        ));


        $padding = new MarginPadding($size, 'col-padding', n2_('Padding'), '5|*|5|*|5|*|5', array(
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));
        $padding->setUnit('px');

        for ($i = 1; $i < 5; $i++) {
            new NumberAutoComplete($padding, 'col-padding-' . $i, false, '', array(
                'values' => array(
                    0,
                    5,
                    10,
                    20,
                    30
                ),
                'wide'   => 3
            ));
        }
    }
}Admin/Layout/Block/Slide/LayerWindow/Settings/LayerWindowSettingsCommon.php000064400000027320152356646020023073 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings;


use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\Form\Element\Button;
use Nextend\Framework\Form\Element\Devices;
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\Select;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;
use Nextend\Framework\Form\Element\Text\NumberSlider;
use Nextend\Framework\Form\Fieldset\LayerWindow\FieldsetLayerWindowLabelFields;
use Nextend\SmartSlider3\Form\Element\Radio\HorizontalAlign;
use Nextend\SmartSlider3\Form\Element\Radio\VerticalAlign;
use Nextend\SmartSlider3Pro\Form\Element\CanvasLayerParentPicker;

class LayerWindowSettingsCommon extends AbstractLayerWindowSettings {

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

    protected function extendStyle() {

        $this->responsive($this->styleContainer);

        $this->effect($this->styleContainer);

        $this->normalPosition($this->styleContainer);

        $this->normalSize($this->styleContainer);

        $this->absolutePosition($this->styleContainer);

        $this->absoluteSize($this->styleContainer);

        $this->advanced($this->styleContainer);
    }

    /**
     * @param ContainerInterface $container
     */
    protected function normalPosition($container) {

        $position = new FieldsetLayerWindowLabelFields($container, 'fields-common-placement-content-position', n2_('Position'), array(
            'attributes' => array(
                'data-placement' => 'normal'
            )
        ));

        new Select($position, 'position-default', n2_('Position'), 'default', array(
            'options'        => array(
                'default'  => n2_('Default'),
                'absolute' => n2_('Absolute')
            ),
            'tipLabel'       => n2_('Position'),
            'tipDescription' => n2_('The editing mode the layer is positioned in.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1916-slide-editing-in-smart-slider-3'
        ));

        new HorizontalAlign($position, 'normal-selfalign', n2_('Align'), 'inherit', array(
            'inherit'        => true,
            'rowAttributes'  => array(
                'data-devicespecific' => ''
            ),
            'tipLabel'       => n2_('Align'),
            'tipDescription' => n2_('Positions the layer horizontally within its parent.')
        ));
    }

    /**
     * @param ContainerInterface $container
     */
    protected function normalSize($container) {

        $size = new FieldsetLayerWindowLabelFields($container, 'fields-common-placement-content-size', n2_('Size'), array(
            'attributes' => array(
                'data-placement' => 'normal'
            )
        ));

        new Number($size, 'normal-maxwidth', n2_('Max width'), 0, array(
            'wide'          => 4,
            'unit'          => 'px',
            'min'           => 0,
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));

        new Number($size, 'normal-height', n2_('Height'), 0, array(
            'wide'           => 4,
            'unit'           => 'px',
            'rowAttributes'  => array(
                'data-devicespecific' => ''
            ),
            'tipLabel'       => n2_('Height'),
            'tipDescription' => n2_('You can set a fix height for your layer.')
        ));

        $margin = new MarginPadding($size, 'normal-margin', n2_('Margin'), '0|*|0|*|0|*|0', array(
            'rowAttributes'  => array(
                'data-devicespecific' => ''
            ),
            'tipLabel'       => n2_('Margin'),
            'tipDescription' => n2_('With margins you can create distance between your layers.')
        )); // spacing

        $margin->setUnit('px');

        for ($i = 1; $i < 5; $i++) {
            new NumberAutoComplete($margin, 'normal-margin-' . $i, false, '', array(
                'values' => array(
                    0,
                    5,
                    10,
                    20,
                    30
                ),
                'wide'   => 3
            ));
        }
    }

    /**
     * @param ContainerInterface $container
     */
    protected function absolutePosition($container) {

        $position = new FieldsetLayerWindowLabelFields($container, 'fields-common-placement-absolute-position', n2_('Position'), array(
            'attributes' => array(
                'data-placement' => 'absolute'
            )
        ));

        new Hidden($position, 'adaptive-font', 1);

        new Select($position, 'position-absolute', n2_('Position'), 'absolute', array(
            'options' => array(
                'default'  => n2_('Default'),
                'absolute' => n2_('Absolute')
            )
        ));

        new HorizontalAlign($position, 'align', n2_('Align'), 'left', array(
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));

        new VerticalAlign($position, 'valign', n2_('Vertical align'), 'top', array(
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));

        $row2 = new Grouping($position, 'absolute-position-row2', false);

        new Number($row2, 'left', n2_('Left'), '', array(
            'unit'          => 'px',
            'wide'          => 4,
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));
        new Number($row2, 'top', n2_('Top'), '', array(
            'unit'          => 'px',
            'wide'          => 4,
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));
        new OnOff($row2, 'responsive-position', n2_('Responsive'), 1);
        $parentPicker = new Grouping($position, 'layer-parent-picker', false);
        new CanvasLayerParentPicker($parentPicker, 'parentid', n2_('Linked to'), '', array(
            'rowClass'       => 'n2-layer-picker-container',
            'relatedFields'  => array(
                'layerparentalign',
                'layerparentvalign'
            ),
            'tipLabel'       => n2_('Linked to'),
            'tipDescription' => n2_('You can link your layer to another layer on the same level. This way your layer won\'t be positioned to the slide, but the other layer.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1812-layer-style#linked-to'
        ));
        new HorizontalAlign($parentPicker, 'parentalign', n2_('Horizontal'), 'left', array(
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));
        new VerticalAlign($parentPicker, 'parentvalign', n2_('Vertical'), 'top', array(
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));
    
    }

    /**
     * @param ContainerInterface $container
     */
    protected function absoluteSize($container) {

        $size = new FieldsetLayerWindowLabelFields($container, 'fields-common-placement-absolute-size', n2_('Size'), array(
            'attributes' => array(
                'data-placement' => 'absolute'
            )
        ));
        new Text($size, 'width', n2_('Width'), '', array(
            'unit'          => 'px',
            'style'         => 'width:32px;',
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));
        new Text($size, 'height', n2_('Height'), '', array(
            'unit'          => 'px',
            'style'         => 'width:32px;',
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));
        new OnOff($size, 'responsive-size', n2_('Responsive'), 1);
    }

    /**
     * @param ContainerInterface $container
     */
    protected function responsive($container) {

        $responsive = new FieldsetLayerWindowLabelFields($container, 'fields-common-responsive', n2_('Responsive'));

        new Text($responsive, 'generator-visible', n2_('Hide when variable empty'), '', array(
            'rowAttributes' => array(
                'data-generator-related' => '1'
            ),
            'style'         => 'width:280px;'
        ));

        new Devices($responsive, 'show', n2_('Hide on'));

        new NumberSlider($responsive, 'font-size', n2_('Text scale'), 100, array(
            'min'           => 10,
            'max'           => 200,
            'step'          => 10,
            'unit'          => '%',
            'wide'          => 3,
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));

        new Button($responsive, '-clear-device-specific-changes', n2_('Device specific settings'), n2_('Clear'), array(
            'tipLabel'       => n2_('Clear device specific settings'),
            'tipDescription' => n2_('Erases all device specific changes you made on the current device.'),
        ));
    }

    /**
     * @param ContainerInterface $container
     */
    protected function effect($container) {

        $effect = new FieldsetLayerWindowLabelFields($container, 'fields-common-effect', n2_('Effect'));
        new Select($effect, 'parallax', n2_('Parallax'), 0, array(
            'tipLabel'       => n2_('Parallax'),
            'tipDescription' => n2_('More parallax options in slider settings -> Layer animations tab.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1812-layer-style#parallax',
            'options'        => array(
                '0'  => n2_('Off'),
                '1'  => 1,
                '2'  => 2,
                '3'  => 3,
                '4'  => 4,
                '5'  => 5,
                '6'  => 6,
                '7'  => 7,
                '8'  => 8,
                '9'  => 9,
                '10' => 10
            )
        ));
    

        new Select($effect, 'crop', n2_('Crop'), 'visible', array(
            'options'        => array(
                'visible' => n2_('Off'),
                'hidden'  => n2_('On'),
                'auto'    => n2_('Scroll'),
                'mask'    => n2_('Mask')
            ),
            'tipLabel'       => n2_('Crop'),
            'tipDescription' => n2_('If your content is larger than the layer, you can crop it to fit.')
        ));

        new Number($effect, 'rotation', n2_('Rotation'), 0, array(
            'wide' => 3,
            'unit' => '°'
        ));
    }

    /**
     * @param ContainerInterface $container
     */
    protected function advanced($container) {

        $advanced = new FieldsetLayerWindowLabelFields($container, 'fields-common-advanced', n2_('Advanced'));

        new Number($advanced, 'zindex', 'Z Index', 2, array(
            'wide' => 4
        ));

        new Text($advanced, 'class', n2_('CSS Class'), '', array(
            'style'          => 'width:220px;',
            'tipLabel'       => n2_('CSS Class'),
            'tipDescription' => n2_('You can add a custom CSS class on the layer container.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1812-layer-style#css-class',
        ));

        new Hidden($advanced, 'id');

        new Hidden($advanced, 'uniqueclass');
    }
}Admin/Layout/Block/Slide/LayerWindow/Settings/LayerWindowSettingsContent.php000064400000014024152356646020023252 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings;


use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\Form\Element\Hidden;
use Nextend\Framework\Form\Element\LayerWindowFocus;
use Nextend\Framework\Form\Element\MarginPadding;
use Nextend\Framework\Form\Element\Select\Gradient;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\FieldImage;
use Nextend\Framework\Form\Element\Text\HiddenText;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;
use Nextend\Framework\Form\Fieldset\LayerWindow\FieldsetLayerWindowLabelFields;
use Nextend\Framework\Form\Fieldset\LayerWindow\FieldsetLayerWindowStyleMode;
use Nextend\SmartSlider3\Form\Element\Radio\FlexAlign;
use Nextend\SmartSlider3\Form\Element\Radio\HorizontalAlign;
use Nextend\SmartSlider3\Form\Element\Radio\InnerAlign;

class LayerWindowSettingsContent extends AbstractLayerWindowSettings {

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

    protected function extendContent() {


        $general = new FieldsetLayerWindowLabelFields($this->contentContainer, 'fields-content-general', n2_('General'));

        new Hidden($general, 'content-opened', 1);

        new InnerAlign($general, 'content-inneralign', n2_('Inner align'), 'inherit', array(
            'rowAttributes'  => array(
                'data-devicespecific' => ''
            ),
            'tipLabel'       => n2_('Inner align'),
            'tipDescription' => n2_('Positions the layers inside horizontally.')
        ));
        new FlexAlign($general, 'content-verticalalign', n2_('Vertical align'), 'center', array(
            'rowAttributes'  => array(
                'data-devicespecific' => ''
            ),
            'tipLabel'       => n2_('Vertical align'),
            'tipDescription' => n2_('Positions the layers inside vertically.')
        ));
    }

    protected function extendStyle() {

        $this->backgroundImage($this->styleContainer);
        $this->background($this->styleContainer);
        $this->spacing($this->styleContainer);
        $this->position($this->styleContainer);
        $this->size($this->styleContainer);
    }

    /**
     * @param ContainerInterface $container
     */
    protected function backgroundImage($container) {

        $backgroundImage = new FieldsetLayerWindowLabelFields($container, 'fields-content-background-image', n2_('Background image'));

        $fieldImage = new FieldImage($backgroundImage, 'content-background-image', n2_('Background image'), '', array(
            'width'         => 220,
            'relatedFields' => array(
                'layercontent-background-focus'
            )
        ));

        $fieldFocusX = new HiddenText($backgroundImage, 'content-background-focus-x', 50);
        $fieldFocusY = new HiddenText($backgroundImage, 'content-background-focus-y', 50);

        $focusField = new LayerWindowFocus($backgroundImage, 'content-background-focus', n2_('Focus'), array(
            'tipLabel'       => n2_('Focus'),
            'tipDescription' => n2_('You can set the starting position of a background image. This makes sure that the selected part will always remain visible, so you should pick the most important part.')
        ));

        $focusField->setFields($fieldImage, $fieldFocusX, $fieldFocusY);
    }

    /**
     * @param ContainerInterface $container
     */
    protected function background($container) {

        $background = new FieldsetLayerWindowStyleMode($container, 'fields-content-background', n2_('Content background'), array(
            ''       => 'Normal',
            '-hover' => 'Hover'
        ));

        new Color($background, 'content-background-color', n2_('Background color'), 'ffffff00', array(
            'alpha' => true
        ));

        new Gradient($background, 'content-background-gradient', n2_('Gradient'), 'off', array(
            'relatedFields' => array(
                'layercontent-background-color-end'
            )
        ));

        new Color($background, 'content-background-color-end', n2_('Color end'), 'ffffff00', array(
            'alpha' => true
        ));

    }

    /**
     * @param ContainerInterface $container
     */
    protected function spacing($container) {

        $spacing = new FieldsetLayerWindowLabelFields($container, 'fields-content-spacing', n2_('Spacing'));

        $padding = new MarginPadding($spacing, 'content-padding', n2_('Padding'), '5|*|5|*|5|*|5', array(
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));
        $padding->setUnit('px');

        for ($i = 1; $i < 5; $i++) {
            new NumberAutoComplete($padding, 'content-padding-' . $i, false, '', array(
                'values' => array(
                    0,
                    5,
                    10,
                    20,
                    30
                ),
                'wide'   => 3
            ));
        }
    }

    /**
     * @param ContainerInterface $container
     */
    protected function position($container) {

        $position = new FieldsetLayerWindowLabelFields($container, 'fields-content-position', n2_('Position'));

        new HorizontalAlign($position, 'content-selfalign', n2_('Align'), 'center', array(
            'inherit'       => true,
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));
    }

    /**
     * @param ContainerInterface $container
     */
    protected function size($container) {

        $size = new FieldsetLayerWindowLabelFields($container, 'fields-content-size', n2_('Size'));

        new Number($size, 'content-maxwidth', n2_('Max width'), 0, array(
            'rowAttributes' => array(
                'data-devicespecific' => ''
            ),
            'unit'          => 'px',
            'wide'          => 5
        ));
    }
}Admin/Layout/Block/Slide/LayerWindow/Settings/LayerWindowSettingsItem.php000064400000003365152356646020022544 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings;


use Nextend\Framework\Asset\Js\Js;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\BlockLayerWindow;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;
use Nextend\SmartSlider3\Slider\Admin\AdminSlider;

class LayerWindowSettingsItem extends AbstractLayerWindowSettings {

    protected $type;

    /**
     * @var AbstractItem
     */
    protected $item;

    /**
     * LayerWindowSettingsItem constructor.
     *
     * @param string           $type
     * @param AbstractItem     $item
     * @param BlockLayerWindow $blockLayerWindow
     * @param AdminSlider      $renderableAdminSlider
     */
    public function __construct($type, $item, $blockLayerWindow, $renderableAdminSlider) {

        $this->type = $type;

        $this->item = $item;

        Js::addGlobalInline('window["itemValues/' . $this->type . '"]=' . json_encode($item->getValues()) . ';');

        $item->loadResources($renderableAdminSlider);

        parent::__construct($blockLayerWindow);
    }

    public function getName() {
        return 'item/' . $this->type;
    }

    protected function createContentContainer($container) {
        parent::createContentContainer($container);
        $this->contentContainer->setControlName('item_' . $this->type);
    }

    protected function createStyleContainer($container) {
        parent::createStyleContainer($container);
        $this->styleContainer->setControlName('item_' . $this->type);
    }

    protected function extendContent() {

        $this->item->renderFields($this->contentContainer);
    }

    protected function extendStyle() {

    }
}Admin/Layout/Block/Slide/LayerWindow/Settings/LayerWindowSettingsItemCommon.php000064400000016320152356646020023710 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings;


use Nextend\Framework\Form\Container\LayerWindow\ContainerDesign;
use Nextend\Framework\Form\Element\Button;
use Nextend\Framework\Form\Element\Decoration;
use Nextend\Framework\Form\Element\MarginPadding;
use Nextend\Framework\Form\Element\MixedField\Border;
use Nextend\Framework\Form\Element\MixedField\BoxShadow;
use Nextend\Framework\Form\Element\MixedField\FontSize;
use Nextend\Framework\Form\Element\MixedField\TextShadow;
use Nextend\Framework\Form\Element\Radio\TextAlign;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\FontWeight;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\Family;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;
use Nextend\Framework\Form\Element\Text\NumberSlider;
use Nextend\Framework\Form\Element\Text\TextAutoComplete;
use Nextend\Framework\Form\Element\Textarea;
use Nextend\Framework\Form\Element\Unit;
use Nextend\Framework\Form\Fieldset\LayerWindow\FieldsetDesign;

class LayerWindowSettingsItemCommon extends AbstractLayerWindowSettings {

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

    protected function extendStyle() {

        $designContainer = new ContainerDesign($this->styleContainer, 'layer_window_design');

        $this->font($designContainer);
        $this->style($designContainer);
    }

    /**
     * @param ContainerDesign $container
     */
    protected function font($container) {

        $font = new FieldsetDesign($container, 'basiccss-font', n2_('Typography'));

        new Family($font, '-font-family', n2_('Family'), 'Arial, Helvetica', array(
            'style'          => 'width:168px;',
            'tipLabel'       => n2_('Family'),
            'tipDescription' => n2_('You can select a font family from the preset, or type your custom family.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1828-using-your-own-fonts',
        ));
        new Color($font, '-font-color', n2_('Color'), '000000FF', array(
            'alpha' => true
        ));

        new FontSize($font, '-font-size', n2_('Size'), '14|*|px', array(
            'tipLabel'       => n2_('Size'),
            'tipDescription' => n2_('Need to change the font size device specifically? Use the Text scale option.')
        ));

        new FontWeight($font, '-font-weight', n2_('Font weight'), '');

        new TextAutoComplete($font, '-font-lineheight', n2_('Line height'), '18px', array(
            'values' => array(
                'normal',
                '1',
                '1.2',
                '1.5',
                '1.8',
                '2'
            ),
            'style'  => 'width:50px;'
        ));

        new TextAlign($font, '-font-textalign', n2_('Text align'), 'inherit');

        new Decoration($font, '-font-decoration', n2_('Decoration'));

        new Button\ButtonMoreLess($font, '-font-more', '', array(
            'relatedFields' => array(
                'layer-font-letterspacing',
                'layer-font-wordspacing',
                'layer-font-texttransform',
                'layer-font-tshadow',
                'layer-font-extracss'
            )
        ));

        new TextAutoComplete($font, '-font-letterspacing', n2_('Letter spacing'), 'normal', array(
            'values' => array(
                'normal',
                '1px',
                '2px',
                '5px',
                '10px',
                '15px'
            ),
            'style'  => 'width:73px;'
        ));

        new TextAutoComplete($font, '-font-wordspacing', n2_('Word spacing'), 'normal', array(
            'values' => array(
                'normal',
                '2px',
                '5px',
                '10px',
                '15px'
            ),
            'style'  => 'width:72px;'
        ));

        new Select($font, '-font-texttransform', n2_('Transform'), 'none', array(
            'options' => array(
                'none'       => n2_('None'),
                'capitalize' => n2_('Capitalize'),
                'uppercase'  => n2_('Uppercase'),
                'lowercase'  => n2_('Lowercase')
            )
        ));

        new TextShadow($font, '-font-tshadow', n2_('Text shadow'), '0|*|0|*|1|*|000000FF');

        new Textarea($font, '-font-extracss', 'CSS', '', array(
            'width'  => 314,
            'height' => 80
        ));
    }


    /**
     * @param ContainerDesign $container
     */
    protected function style($container) {

        $backgroundFieldset = new FieldsetDesign($container, 'basiccss-style', n2_('Background'));

        new Color($backgroundFieldset, '-style-backgroundcolor', n2_('Background color'), '000000FF', array(
            'alpha' => true
        ));

        new NumberSlider($backgroundFieldset, '-style-opacity', n2_('Opacity'), '100', array(
            'min'  => 0,
            'max'  => 100,
            'unit' => '%',
            'wide' => 3
        ));

        new Button\ButtonMoreLess($backgroundFieldset, '-style-more', '', array(
            'relatedFields' => array(
                'layer-style-extracss',
                'layer-style-boxshadow'
            )
        ));

        new BoxShadow($backgroundFieldset, '-style-boxshadow', n2_('Box shadow'), '0|*|0|*|0|*|0|*|000000ff');

        new Textarea($backgroundFieldset, '-style-extracss', 'CSS', '', array(
            'width'  => 314,
            'height' => 80
        ));


        $borderFieldset = new FieldsetDesign($container, 'basiccss-style-border', n2_('Border'));
        $borderFieldset->setParentDesign('fieldset-layer-window-basiccss-style');
        $borderFieldset->addAttribute('data-singular', 'style-border');

        new Border($borderFieldset, '-style-border', n2_('Border'), '0|*|solid|*|000000ff');

        new NumberAutoComplete($borderFieldset, '-style-borderradius', n2_('Border radius'), '0', array(
            'min'    => 0,
            'values' => array(
                0,
                3,
                5,
                10,
                99
            ),
            'unit'   => 'px',
            'wide'   => 3
        ));


        $spacingFieldset = new FieldsetDesign($container, 'basiccss-style-spacing', n2_('Spacing'));
        $spacingFieldset->setParentDesign('fieldset-layer-window-basiccss-style');
        $spacingFieldset->addAttribute('data-singular', 'style-spacing');

        $padding = new MarginPadding($spacingFieldset, '-style-padding', n2_('Padding'), '0|*|0|*|0|*|0|*|px');
        for ($i = 1; $i < 5; $i++) {
            new NumberAutoComplete($padding, 'padding-' . $i, false, '', array(
                'values' => array(
                    0,
                    5,
                    10,
                    20,
                    30
                ),
                'style'  => 'width: 22px;'
            ));
        }

        new Unit($padding, 'padding-5', '', '', array(
            'units' => array(
                'px',
                'em',
                '%'
            )
        ));
    }
}Admin/Layout/Block/Slide/LayerWindow/Settings/LayerWindowSettingsRow.php000064400000021542152356646020022412 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings;


use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\Form\Element\Hidden;
use Nextend\Framework\Form\Element\LayerWindowFocus;
use Nextend\Framework\Form\Element\MarginPadding;
use Nextend\Framework\Form\Element\MixedField\BoxShadow;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\Gradient;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\FieldImage;
use Nextend\Framework\Form\Element\Text\HiddenText;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;
use Nextend\Framework\Form\Element\Text\NumberSlider;
use Nextend\Framework\Form\Element\Text\Url;
use Nextend\Framework\Form\Fieldset\LayerWindow\FieldsetLayerWindowLabelFields;
use Nextend\Framework\Form\Fieldset\LayerWindow\FieldsetLayerWindowStyleMode;
use Nextend\SmartSlider3\Form\Element\Columns;
use Nextend\SmartSlider3\Form\Element\Radio\InnerAlign;

class LayerWindowSettingsRow extends AbstractLayerWindowSettings {

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

    protected function extendContent() {

        $structure = new FieldsetLayerWindowLabelFields($this->contentContainer, 'fields-row-structure', n2_('Columns'));

        new Columns($structure, 'row-columns', '1');

        new Hidden($structure, 'row-opened', 1);


        $rowGeneral = new FieldsetLayerWindowLabelFields($this->contentContainer, 'fields-row-general', n2_('General'));

        new InnerAlign($rowGeneral, 'row-inneralign', n2_('Inner align'), 'inherit', array(
            'rowAttributes'  => array(
                'data-devicespecific' => ''
            ),
            'tipLabel'       => n2_('Inner align'),
            'tipDescription' => n2_('Positions the layers inside horizontally.')
        ));

        new NumberSlider($rowGeneral, 'row-gutter', n2_('Gutter'), '', array(
            'min'            => 0,
            'max'            => 300,
            'sliderMax'      => 160,
            'unit'           => 'px',
            'rowAttributes'  => array(
                'data-devicespecific' => ''
            ),
            'style'          => 'width: 22px;',
            'tipLabel'       => n2_('Gutter'),
            'tipDescription' => n2_('Creates space between the columns')
        ));

        new NumberSlider($rowGeneral, 'row-wrap-after', n2_('Wrap after'), 0, array(
            'min'            => 0,
            'max'            => 10,
            'style'          => 'width:22px;',
            'unit'           => n2_('Column'),
            'rowAttributes'  => array(
                'data-devicespecific' => ''
            ),
            'tipLabel'       => n2_('Wrap after'),
            'tipDescription' => n2_('Breaks the columns to the given amount of rows.')
        ));

        new OnOff($rowGeneral, 'row-fullwidth', n2_('Full width'), 1, array(
            'relatedFieldsOn' => array(
                'layerrow-wrap-after'
            )
        ));

        new OnOff($rowGeneral, 'row-stretch', n2_('Stretch'), 0, array(
            'tipLabel'       => n2_('Stretch'),
            'tipDescription' => n2_('Makes the row fill the available vertical space')
        ));


        $link = new FieldsetLayerWindowLabelFields($this->contentContainer, 'fields-row-link', n2_('Link'));

        new Url($link, 'row-href', n2_('Link'), '', array(
            'relatedFields' => array(
                'layerrow-href-target',
                'layerrow-aria-label'
            ),
            'width'         => 248
        ));
        new LinkTarget($link, 'row-href-target', n2_('Target window'));

        new Text($link, 'row-aria-label', n2_('ARIA label'), '', array(
            'style'    => 'width:190px;',
            'tipLabel' => n2_('ARIA label')
        ));

    }

    protected function extendStyle() {

        $this->backgroundImage($this->styleContainer);
        $this->background($this->styleContainer);
        $this->border($this->styleContainer);
        $this->spacing($this->styleContainer);
    }

    /**
     * @param ContainerInterface $container
     */
    protected function backgroundImage($container) {

        $backgroundImage = new FieldsetLayerWindowLabelFields($container, 'fields-row-background-image', n2_('Background image'));
        $fieldImage      = new FieldImage($backgroundImage, 'row-background-image', n2_('Background image'), '', array(
            'width'         => 220,
            'relatedFields' => array(
                'layerrow-background-focus'
            )
        ));

        $fieldFocusX = new HiddenText($backgroundImage, 'row-background-focus-x', 50);
        $fieldFocusY = new HiddenText($backgroundImage, 'row-background-focus-y', 50);

        $focusField = new LayerWindowFocus($backgroundImage, 'row-background-focus', n2_('Focus'), array(
            'tipLabel'       => n2_('Focus'),
            'tipDescription' => n2_('You can set the starting position of a background image. This makes sure that the selected part will always remain visible, so you should pick the most important part.')
        ));

        $focusField->setFields($fieldImage, $fieldFocusX, $fieldFocusY);
    }

    /**
     * @param ContainerInterface $container
     */
    protected function background($container) {

        $background = new FieldsetLayerWindowStyleMode($container, 'fields-row-background', n2_('Background'), array(
            ''       => 'Normal',
            '-hover' => 'Hover'
        ));

        new Color($background, 'row-background-color', n2_('Background color'), 'ffffff00', array(
            'alpha' => true
        ));

        new Gradient($background, 'row-background-gradient', n2_('Gradient'), 'off', array(
            'relatedFields' => array(
                'layerrow-background-color-end'
            )
        ));

        new Color($background, 'row-background-color-end', n2_('Color end'), 'ffffff00', array(
            'alpha' => true
        ));

        new BoxShadow($background, 'row-boxshadow', n2_('Box shadow'), '0|*|0|*|0|*|0|*|00000080');
    }

    /**
     * @param ContainerInterface $container
     */
    protected function border($container) {

        $border = new FieldsetLayerWindowStyleMode($container, 'fields-row-border', n2_('Border'), array(
            ''       => 'Normal',
            '-hover' => 'Hover'
        ));


        $borderWidth = new MarginPadding($border, 'row-border-width', n2_('Border'), '0|*|0|*|0|*|0', array(
            'unit'          => 'px',
            'relatedFields' => array(
                'layerrow-border-style',
                'layerrow-border-color'
            )
        ));

        for ($i = 1; $i < 5; $i++) {
            new NumberAutoComplete($borderWidth, 'row-border-width-' . $i, false, '', array(
                'values' => array(
                    0,
                    1,
                    2,
                    3,
                    5
                ),
                'wide'   => 3
            ));
        }

        new Select($border, 'row-border-style', n2_('Style'), 'none', array(
            'options' => array(
                'none'   => n2_('None'),
                'solid'  => n2_('Solid'),
                'dashed' => n2_('Dashed'),
                'dotted' => n2_('Dotted'),
            )
        ));

        new Color($border, 'row-border-color', n2_('Color'), 'ffffffff', array(
            'alpha' => true
        ));

        new NumberAutoComplete($border, 'row-border-radius', n2_('Border radius'), 0, array(
            'values' => array(
                0,
                3,
                5,
                10,
                99
            ),
            'style'  => 'width: 22px;',
            'unit'   => 'px'
        ));
    }

    /**
     * @param ContainerInterface $container
     */
    protected function spacing($container) {

        $spacing = new FieldsetLayerWindowLabelFields($container, 'fields-row-spacing', n2_('Spacing'));

        $padding = new MarginPadding($spacing, 'row-padding', n2_('Padding'), '10|*|10|*|10|*|10', array(
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));
        $padding->setUnit('px');

        for ($i = 1; $i < 5; $i++) {
            new NumberAutoComplete($padding, 'row-padding-' . $i, false, '', array(
                'values' => array(
                    0,
                    5,
                    10,
                    20,
                    30
                ),
                'style'  => 'width: 22px;'
            ));
        }
    }
}Admin/Layout/Block/Slide/LayerWindow/Settings/LayerWindowSettingsSlide.php000064400000034402152356646020022702 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\LayerWindow\Settings;


use Nextend\Framework\Form\Element\Button;
use Nextend\Framework\Form\Element\Devices;
use Nextend\Framework\Form\Element\Grouping;
use Nextend\Framework\Form\Element\LayerWindowFocus;
use Nextend\Framework\Form\Element\MarginPadding;
use Nextend\Framework\Form\Element\Message\Warning;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\Gradient;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\FieldImage;
use Nextend\Framework\Form\Element\Text\FieldImageResponsive;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;
use Nextend\Framework\Form\Element\Text\NumberSlider;
use Nextend\Framework\Form\Element\Text\Url;
use Nextend\Framework\Form\Element\Text\Video;
use Nextend\Framework\Form\Element\Textarea;
use Nextend\Framework\Form\Fieldset\LayerWindow\FieldsetLayerWindow;
use Nextend\Framework\Form\Fieldset\LayerWindow\FieldsetLayerWindowLabelFields;
use Nextend\SmartSlider3\Form\Element\BackgroundImage;
use Nextend\SmartSlider3\Form\Element\DatePicker;
use Nextend\SmartSlider3\Slider\Admin\AdminSlider;
use Nextend\SmartSlider3\Slider\SliderType\SliderTypeFactory;

class LayerWindowSettingsSlide extends AbstractLayerWindowSettings {

    /** @var AdminSlider */
    protected $renderableAdminSlider;

    /**
     * LayerWindowSettingsSlide constructor.
     *
     * @param                    $blockLayerWindow
     * @param AdminSlider        $renderableAdminSlider
     */
    public function __construct($blockLayerWindow, $renderableAdminSlider) {
        $this->renderableAdminSlider = $renderableAdminSlider;
        parent::__construct($blockLayerWindow);
    }

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

    protected function extendContent() {

        $general = new FieldsetLayerWindow($this->contentContainer, 'fields-slide-general', n2_('General'));
        new Text($general, 'slide-title', n2_('Slide title'), n2_('Slide'), array(
            'style' => 'width:302px;',
        ));
        new Textarea($general, 'slide-description', n2_('Description'), '', array(
            'width' => 314
        ));

        new FieldImage($general, 'slide-thumbnail', n2_('Thumbnail'), '', array(
            'width'         => 220,
            'relatedFields' => array(
                'layerslide-thumbnailAlt'
            )
        ));
        new Text($general, 'slide-thumbnailAlt', n2_('Thumbnail alt') . ' [SEO]', '', array(
            'style' => "width:133px;"
        ));
        new Devices($general, 'slide-show', n2_('Hide on'));
    


        if (!$this->renderableAdminSlider->getEditedSlide()
                                         ->isStatic()) {
            $link = new FieldsetLayerWindow($this->contentContainer, 'fields-slide-link', n2_('Link'));

            new Url($link, 'slide-href', n2_('Link'), '', array(
                'relatedFields' => array(
                    'layerslide-href-target',
                    'layerslide-aria-label'
                ),
                'width'         => 248
            ));
            new LinkTarget($link, 'slide-href-target', n2_('Target window'));

            new Text($link, 'slide-aria-label', n2_('ARIA label'), '', array(
                'style'    => 'width:190px;',
                'tipLabel' => n2_('ARIA label')
            ));
        }


        if (!$this->renderableAdminSlider->getEditedSlide()
                                         ->isStatic()) {
            SliderTypeFactory::getType($this->renderableAdminSlider->data->get('type'))
                             ->createAdmin()
                             ->renderSlideFields($this->contentContainer);
        }

        if ($this->renderableAdminSlider->getEditedSlide()
                                        ->hasGenerator()) {
            $generator = new FieldsetLayerWindow($this->contentContainer, 'fields-slide-generator', n2_('Generator'));
            new Number($generator, 'slide-slide-generator-slides', n2_('Slides'), 5, array(
                'unit' => n2_x('slides', 'Unit'),
                'wide' => 3
            ));
        }


        $advanced = new FieldsetLayerWindow($this->contentContainer, 'fields-slide-advanced', n2_('Advanced'));

        if ($this->renderableAdminSlider->params->get('global-lightbox', 0)) {
            new FieldImageResponsive($advanced, 'slide-ligthboxImage', n2_('Custom lightbox image'), '', array(
                'width' => 180
            ));
        }

        new OnOff($advanced, 'slide-published', n2_('Published'), 1);

        if (!$this->renderableAdminSlider->getEditedSlide()
                                         ->isStatic() && $this->renderableAdminSlider->params->get('autoplay')) {
            new Number($advanced, 'slide-slide-duration', n2_('Slide duration'), 0, array(
                'unit' => 'ms',
                'wide' => 5
            ));
        }

        new DatePicker($advanced, 'slide-publish_up', n2_('Publish on'), '0000-00-00 00:00:00');
        new DatePicker($advanced, 'slide-publish_down', n2_('Unpublish on'), '0000-00-00 00:00:00');
    

        if (!$this->renderableAdminSlider->getEditedSlide()
                                         ->isStatic()) {
            new Select($advanced, 'slide-thumbnailType', n2_('Thumbnail type'), 'default', array(
                'options'        => array(
                    'default'   => n2_('Default'),
                    'videoDark' => n2_('Video')
                ),
                'tipLabel'       => n2_('Thumbnail type'),
                'tipDescription' => n2_('If you have a video on your slide, you can put a play icon on the thumbnail image to indicate that.'),
                'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1724-slide#thumbnail-type'
            ));
        }
    }

    protected function extendStyle() {
        if (!$this->renderableAdminSlider->getEditedSlide()
                                         ->isStatic()) {
            $this->background();
        }

        $spacing = new FieldsetLayerWindowLabelFields($this->styleContainer, 'fields-slide-spacing', n2_('Spacing'));

        $padding = new MarginPadding($spacing, 'slide-padding', n2_('Padding'), '10|*|10|*|10|*|10', array(
            'unit'          => 'px',
            'rowAttributes' => array(
                'data-devicespecific' => ''
            )
        ));

        for ($i = 1; $i < 5; $i++) {
            new NumberAutoComplete($padding, 'slide-padding-' . $i, false, '', array(
                'values' => array(
                    0,
                    5,
                    10,
                    20,
                    30
                ),
                'style'  => 'width: 22px;'
            ));
        }

        new Button($spacing, '-slide-clear-device-specific-changes', n2_('Device specific settings'), n2_('Clear'), array(
            'tipLabel'       => n2_('Clear device specific settings'),
            'tipDescription' => n2_('Erases all device specific changes you made on the current device.'),
        ));
    }

    private function background() {

        $background = new FieldsetLayerWindowLabelFields($this->styleContainer, 'fields-slide-background', n2_('Background'));
        new BackgroundImage($background->getFieldsetLabel(), 'slide-background-type', false, 'color', array(
            'relatedValueFields' => array(
                array(
                    'values' => array(
                        'image',
                        'video'
                    ),
                    'field'  => array(
                        'layer-slide-background-image',
                        'layerslide-backgroundColorOverlay',
                        'fieldset-layer-window-fields-slide-seo'
                    )
                ),
                array(
                    'values' => array(
                        'image'
                    ),
                    'field'  => array(
                        'layerslide-kenburns-animation'
                    )
                ),
                array(
                    'values' => array(
                        'video'
                    ),
                    'field'  => array(
                        'layer-slide-background-video'
                    )
                ),
            )
        ));

        $rowVideo = new Grouping($background, '-slide-background-video');

        new Warning($rowVideo, 'slide-background-notice', sprintf(n2_('Video autoplaying has a lot of limitations made by browsers. %1$sLearn about them.%2$s'), '<a href="https://smartslider.helpscoutdocs.com/article/1919-video-autoplay-handling" target="_blank">', '</a>'));

        new Video($rowVideo, 'slide-backgroundVideoMp4', n2_('Slide background video'), '', array(
            'post'  => 'break',
            'width' => 220
        ));

        new NumberSlider($rowVideo, 'slide-backgroundVideoOpacity', n2_('Opacity'), 100, array(
            'unit'  => '%',
            'min'   => 0,
            'max'   => 100,
            'style' => 'width:22px;'
        ));

        new OnOff($rowVideo, 'slide-backgroundVideoLoop', n2_x('Loop', 'Video/Audio play'), 1);
        new OnOff($rowVideo, 'slide-backgroundVideoReset', n2_('Restart on slide change'), 1, array(
            'tipLabel'       => n2_('Restart on slide change'),
            'tipDescription' => n2_('Starts the video from the beginning when the slide is viewed again.')
        ));

        new Select($rowVideo, 'slide-backgroundVideoMode', n2_('Fill mode'), 'fill', array(
            'options' => array(
                'fill'   => n2_('Fill'),
                'fit'    => n2_('Fit'),
                'center' => n2_('Center')
            )
        ));
    

        $rowImage = new Grouping($background, '-slide-background-image');

        $slideBackgroundAttr = array(
            'width'         => 180,
            'relatedFields' => array(
                'layerslide-background-focus',
                'layerslide-backgroundFocusX',
                'layerslide-backgroundFocusY',
                'layerslide-backgroundImageOpacity',
                'layerslide-backgroundImageBlur',
                'layerslide-backgroundMode',
                'layerslide-background-notice-image',
            )
        );
        $slideBackgroundAttr['tipLabel']       = n2_('Slide background');
        $slideBackgroundAttr['tipDescription'] = n2_('Select a background image for the slide. By clicking the small screen icon, you can pick different images for different devices.');
        $slideBackgroundAttr['tipLink']        = 'https://smartslider.helpscoutdocs.com/article/1724-slide#image';
    
        $fieldImage = new FieldImageResponsive($rowImage, 'slide-backgroundImage', n2_('Slide background'), '', $slideBackgroundAttr);

        $focusField = new LayerWindowFocus($rowImage, 'slide-background-focus', n2_('Focus'));

        $fieldFocusX = new Number($rowImage, 'slide-backgroundFocusX', false, 50, array(
            'wide'     => 3,
            'sublabel' => 'X',
            'unit'     => '%'
        ));
        $fieldFocusY = new Number($rowImage, 'slide-backgroundFocusY', false, 50, array(
            'wide'     => 3,
            'sublabel' => 'Y',
            'unit'     => '%'
        ));

        $focusField->setFields($fieldImage, $fieldFocusX, $fieldFocusY);

        new Warning($rowImage, 'slide-background-notice-image', sprintf(n2_('Please read %1$sour detailed guide%2$s about setting your own slide background correctly.'), '<a href="https://smartslider.helpscoutdocs.com/article/1922-how-to-set-your-background-image" target="_blank">', '</a>'));


        new Select\FillMode($rowImage, 'slide-backgroundMode', n2_('Fill mode'), 'default', array(
            'useGlobal'          => true,
            'relatedValueFields' => array(
                array(
                    'values' => array(
                        'blurfit'
                    ),
                    'field'  => array(
                        'layerslide-backgroundBlurFit'
                    )
                )
            )
        ));
        new NumberSlider($rowImage, 'slide-backgroundBlurFit', n2_('Background blur'), 7, array(
            'unit' => 'px',
            'min'  => 7,
            'max'  => 50,
            'wide' => 3
        ));

        new NumberSlider($rowImage, 'slide-backgroundImageOpacity', n2_('Opacity'), 100, array(
            'unit'  => '%',
            'min'   => 0,
            'max'   => 100,
            'style' => 'width:33px;'
        ));

        new NumberSlider($rowImage, 'slide-backgroundImageBlur', n2_('Blur'), 0, array(
            'unit'  => 'px',
            'min'   => 0,
            'max'   => 50,
            'style' => 'width:33px;'
        ));

        $rowColor = new Grouping($background, '-slide-background-color');

        new Color($rowColor, 'slide-backgroundColor', n2_('Color'), 'ffffff00', array(
            'alpha' => true
        ));

        new Gradient($rowColor, 'slide-backgroundGradient', n2_('Gradient'), 'off', array(
            'relatedFields' => array(
                'layerslide-backgroundColorEnd'
            )
        ));

        new Color($rowColor, 'slide-backgroundColorEnd', n2_('Color end'), 'ffffff00', array(
            'alpha' => true
        ));

        new OnOff($rowColor, 'slide-backgroundColorOverlay', n2_('Overlay'), 0, array(
            'tipLabel'       => n2_('Overlay'),
            'tipDescription' => n2_('Puts the color in front of the image.')
        ));


        $seo = new FieldsetLayerWindowLabelFields($this->styleContainer, 'fields-slide-seo', n2_('SEO'));
        new Text($seo, 'slide-backgroundAlt', n2_('Image alt') . ' [SEO]', '', array(
            'style' => "width:133px;"
        ));
        new Text($seo, 'slide-backgroundTitle', n2_('Image title') . ' [SEO]', '', array(
            'style' => "width:133px;"
        ));
    }
}Admin/Layout/Block/Slide/EditorOverlay/BlockEditorOverlay.php000064400000005115152356646020020222 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\EditorOverlay;

use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\BlockBreadCrumb\BlockBreadCrumb;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain\TopBarMainEditor\BlockTopBarMainEditor;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\AddLayer\BlockAddLayer;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\SlideManager\BlockSlideManager;

class BlockEditorOverlay extends AbstractBlock {

    /**
     * @var BlockTopBarMainEditor
     */
    protected $topBar;

    /**
     * @var BlockBreadCrumb
     */
    protected $blockBreadCrumb;

    /**
     * @var BlockSlideManager
     */
    protected $slideManager;

    /**
     * @var BlockAddLayer
     */
    protected $blockAddLayer;

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

    protected function init() {
        $this->topBar = new BlockTopBarMainEditor($this);

        $this->blockBreadCrumb = new BlockBreadCrumb($this);
        $this->topBar->addSecondaryBlock($this->blockBreadCrumb);
    }

    public function display() {

        $this->renderTemplatePart('EditorOverlay');
    }

    /**
     * @param BlockSlideManager $slideManager
     */
    public function setSlideManager($slideManager) {
        $this->slideManager = $slideManager;
        $slideManager->addClass('n2_admin_editor__ui_slide_manager');
    }

    public function displaySlideManager() {
        $this->slideManager->display();
    }

    /**
     * @return BlockTopBarMainEditor
     */
    public function getTopBar() {
        return $this->topBar;
    }

    public function displayTopBar() {
        $this->topBar->display();
    }

    /**
     * @return BlockBreadCrumb
     */
    public function getBlockBreadCrumb() {
        return $this->blockBreadCrumb;
    }

    /**
     * @param BlockAddLayer $blockAddLayer
     */
    public function setBlockAddLayer($blockAddLayer) {
        $this->blockAddLayer = $blockAddLayer;
    }

    public function displayBlockAddLayer() {
        $this->blockAddLayer->display();
    }

    /**
     * @param string $contentLayerWindow
     */
    public function setContentLayerWindow($contentLayerWindow) {
        $this->contentLayerWindow = $contentLayerWindow;
    }

    public function displayBlockLayerWindow() {
        echo wp_kses($this->contentLayerWindow, Sanitize::$adminFormTags);
    }

}Admin/Layout/Block/Slide/EditorOverlay/EditorOverlay.php000064400000001637152356646020017254 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\EditorOverlay;

/**
 * @var $this BlockEditorOverlay
 */
?>

<div class="n2_admin_editor_overlay">
    <div class="n2_admin_editor_overlay__top">
        <?php $this->displayTopBar(); ?>
    </div>

    <div class="n2_admin_editor_overlay__middle">
        <?php $this->displayBlockAddLayer(); ?>
        <div class="n2_admin_editor_overlay__middle_center">
            <div class="n2_ruler_corner"></div>
            <div class="n2_ruler n2_ruler--vertical">
                <div class="n2_ruler__inner">
                </div>
            </div>
            <div class="n2_ruler n2_ruler--horizontal">
                <div class="n2_ruler__inner">
                </div>
            </div>
        </div>
    </div>

    <?php $this->displayBlockLayerWindow(); ?>

    <?php $this->displaySlideManager(); ?>

</div>
Admin/Layout/Block/Slide/AddLayer/AddLayer.php000064400000014352152356646020015044 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\AddLayer;

use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\FreeNeedMore\BlockFreeNeedMore;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonIconCode;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonPlainIcon;

/**
 * @var $this BlockAddLayer
 */
?>
<div class="n2_add_layer">
    <div class="n2_add_layer__bar">

        <div class="n2_add_layer__bar_top">
            <?php
            $buttonAddLayer = new BlockButtonIconCode($this);
            $buttonAddLayer->addClass('n2_add_layer__bar_button');
            $buttonAddLayer->addClass('n2_add_layer__bar_button_add');
            $buttonAddLayer->setIcon('<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path fill="currentColor" d="M13 3a1 1 0 0 1 1 1v6h6a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-6v6a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1v-6H4a1 1 0 0 1-1-1v-2a1 1 0 0 1 1-1h6V4a1 1 0 0 1 1-1h2z"/></svg>');
            $buttonAddLayer->setGreen();
            $buttonAddLayer->addAttribute('data-n2tip', n2_('Add Layer'));
            $buttonAddLayer->display();

            $this->displayAddShortcut('heading', 'ssi_24 ssi_24--heading', n2_('Heading'));
            $this->displayAddShortcut('text', 'ssi_24 ssi_24--text', n2_('Text'));
            $this->displayAddShortcut('image', 'ssi_24 ssi_24--image', n2_('Image'));
            $this->displayAddShortcut('button', 'ssi_24 ssi_24--button', n2_('Button'));
            $this->displayAddShortcut('structure-2col', 'ssi_24 ssi_24--col2', n2_('Row'));
            ?>
        </div>
        <div class="n2_add_layer__bar_bottom">
            <?php
            $buttonPlay = new BlockButtonPlainIcon($this);
            $buttonPlay->addClass('n2_timeline_control_play_pause');
            $buttonPlay->addClass('n2_add_layer__bar_button');
            $buttonPlay->setIcon('ssi_24 ssi_24--play');
            $buttonPlay->addAttribute('data-n2tip', n2_('Play animations'));
            $buttonPlay->addAttribute('data-n2tipv', -20);
            $buttonPlay->display();

            $buttonTimeline = new BlockButtonPlainIcon($this);
            $buttonTimeline->addClass('n2_add_layer__bar_button');
            $buttonTimeline->addClass('n2_slide_editor_timeline_toggle n2_slide_editor_timeline_toggle--show');
            $buttonTimeline->setIcon('ssi_24 ssi_24--timeline');
            $buttonTimeline->addAttribute('data-n2tip', n2_('Timeline'));
            $buttonTimeline->addAttribute('data-n2tipv', -20);
            $buttonTimeline->display();
        
            ?>
        </div>
    </div>
    <div class="n2_add_layer__more n2_form--dark">
        <div class="n2_add_layer__more_tab_buttons">
            <div class="n2_add_layer__more_tab_button" data-related-tab="layers">
                <div class="n2_add_layer__more_tab_button_icon">
                    <i class="ssi_24 ssi_24--layers"></i>
                </div>
                <div class="n2_add_layer__more_tab_button_label">
                    <?php n2_e('Layers'); ?>
                </div>
            </div>
            <div class="n2_add_layer__more_tab_button" data-related-tab="library">
                <div class="n2_add_layer__more_tab_button_icon">
                    <i class="ssi_24 ssi_24--smart"></i>
                </div>
                <div class="n2_add_layer__more_tab_button_label">
                    <?php n2_e('Library'); ?>
                </div>
            </div>
        </div>
        <div class="n2_add_layer__more_tab" data-tab="layers">
            <div class="n2_add_layer__more_layers">
                <?php
                foreach ($this->getGroups() as $groupLabel => $boxes):
                    ?>
                    <div class="n2_add_layer_group">
                        <div class="n2_add_layer_group__label">
                            <?php echo esc_html($groupLabel); ?>
                        </div>
                        <div class="n2_add_layer_group__content">
                            <?php
                            foreach ($boxes as $box):
                                echo wp_kses(Html::openTag('div', array(
                                        'class' => 'n2_add_layer_box'
                                    ) + $box['attributes']), Sanitize::$adminTemplateTags);
                                ?>
                                <div class="n2_add_layer_box__icon">
                                    <i class="<?php echo esc_attr($box['icon']) ?>"></i>
                                </div>
                                <div class="n2_add_layer_box__label_wrap">
                                    <div class="n2_add_layer_box__label">
                                        <?php echo esc_html($box['label']); ?>
                                    </div>
                                </div>
                                <?php
                                echo wp_kses(Html::closeTag('div'), Sanitize::$basicTags);
                            endforeach;
                            ?>
                        </div>
                    </div>
                <?php
                endforeach;
                ?>
                <?php
                ?>
            </div>
            <div class="n2_add_layer__more_position n2_add_layer_position" data-position="default">
                <div class="n2_add_layer_position__label n2_add_layer_position__default_label">
                    <?php n2_e('Default'); ?>
                </div>
                <div class="n2_add_layer_position__switch_container">
                    <div class="n2_add_layer_position__switch">
                        <div class="n2_add_layer_position__switch_dot">

                        </div>
                    </div>
                </div>
                <div class=" n2_add_layer_position__label n2_add_layer_position__absolute_label">
                    <?php n2_e('Absolute'); ?>
                </div>
            </div>
        </div>
        <div class="n2_add_layer__more_tab n2_add_layer_library" data-tab="library">

        </div>
    </div>
</div>
Admin/Layout/Block/Slide/AddLayer/BlockAddLayer.php000064400000005657152356646020016027 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\AddLayer;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Plugin;
use Nextend\Framework\Style\ModelCss;
use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonPlainIcon;
use Nextend\SmartSlider3\Renderable\Item\ItemFactory;
use Nextend\SmartSlider3\Slider\SliderType\SliderTypeFactory;

class BlockAddLayer extends AbstractBlock {

    protected $groups = array();

    protected $sliderType = '';

    public function display() {

        $this->groups[n2_x('Basic', 'Layer group')] = array(
            array(
                'label'      => n2_('Row'),
                'icon'       => 'ssi_32 ssi_32--col2',
                'attributes' => array(
                    'data-item' => 'structure-2col'
                )
            )
        );


        $cssModel = new ModelCss($this);

        $itemDefaults = SliderTypeFactory::getType($this->sliderType)
                                         ->getItemDefaults();

        foreach (ItemFactory::getItemGroups() as $groupLabel => $group) {
            foreach ($group as $type => $item) {
                if (!$item->isLegacy()) {
                    if (!isset($this->groups[$groupLabel])) {
                        $this->groups[$groupLabel] = array();
                    }
                    $visualKey = 'ss3item' . $type;
                    $visuals   = $cssModel->getVisuals($visualKey);
                    Plugin::doAction($visualKey . 'Storage', array(
                        &$visuals
                    ));
                    Js::addInline('window["' . $visualKey . '"] = ' . json_encode($visuals) . ';');

                    $this->groups[$groupLabel][] = array(
                        'label'      => $item->getTitle(),
                        'icon'       => $item->getIcon(),
                        'attributes' => array(
                            'data-item'            => $type,
                            'data-layerproperties' => json_encode((object)array_merge($item->getLayerProperties(), $itemDefaults))
                        )
                    );
                }
            }
        }

        $this->renderTemplatePart('AddLayer');
    }

    /**
     * @return array
     */
    public function getGroups() {
        return $this->groups;
    }

    /**
     * @param string $sliderType
     */
    public function setSliderType($sliderType) {
        $this->sliderType = $sliderType;
    }

    public function displayAddShortcut($type, $icon, $label) {
        $button = new BlockButtonPlainIcon($this);
        $button->addClass('n2_add_layer__bar_button');
        $button->setIcon($icon);
        $button->addAttribute('data-add-layer-shortcut', $type);
        $button->addAttribute('data-n2tip', $label);
        $button->display();
    }
}Admin/Layout/Block/Generator/GeneratorBox/BlockGeneratorBox.php000064400000005012152356646020020522 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Generator\GeneratorBox;


use Nextend\Framework\View\AbstractBlock;

class BlockGeneratorBox extends AbstractBlock {


    protected $label = '';

    protected $buttonLink = '';

    protected $buttonLinkTarget = '';

    protected $buttonLabel = '';

    protected $description = '';

    protected $docsLink = '';

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

    public function display() {

        $this->renderTemplatePart('GeneratorBox');
    }

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

    /**
     * @param string $label
     */
    public function setLabel($label) {
        $this->label = $label;
    }

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

    /**
     * @param string $description
     */
    public function setDescription($description) {
        $this->description = $description;
    }

    /**
     * @param string
     */
    public function getDocsLink() {
        return $this->docsLink;
    }

    /**
     * @param string $link
     */
    public function setDocsLink($link) {
        $this->docsLink = $link;
    }

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

    /**
     * @param string $buttonLink
     */
    public function setButtonLink($buttonLink) {
        $this->buttonLink = $buttonLink;
    }

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

    /**
     * @param string $buttonLabel
     */
    public function setButtonLabel($buttonLabel) {
        $this->buttonLabel = $buttonLabel;
    }

    public function hasButtonLabel() {
        return !empty($this->buttonLabel);
    }

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

    /**
     * @param string $buttonLinkTarget
     */
    public function setButtonLinkTarget($buttonLinkTarget) {
        $this->buttonLinkTarget = $buttonLinkTarget;
    }

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

    /**
     * @param string $imageUrl
     */
    public function setImageUrl($imageUrl) {
        $this->imageUrl = $imageUrl;
    }
}Admin/Layout/Block/Generator/GeneratorBox/GeneratorBox.php000064400000002117152356646020017552 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Generator\GeneratorBox;

/**
 * @var $this BlockGeneratorBox
 */
?>
<div class="n2_slide_generator_box" style="background-image: url('<?php echo esc_url($this->getImageUrl()); ?>');">
    <div class="n2_slide_generator_box__title">
        <div class="n2_slide_generator_box__title_label">
            <div class="n2_slide_generator_box__title_label_inner">
                <?php
                $label = $this->getLabel();
                echo esc_html($label);
                ?>
            </div>
            <i class="ssi_16 ssi_16--info" data-tip-description="<?php echo esc_attr($this->getDescription()); ?>" data-tip-label="<?php echo esc_attr($label); ?>" data-tip-link="<?php echo esc_url($this->getDocsLink()); ?>"></i>
        </div>
        <a href="<?php echo esc_url($this->getButtonLink()); ?>" target="<?php echo esc_attr($this->getButtonLinkTarget()); ?>" class="n2_slide_generator_box__title_button">
            <?php echo esc_html($this->getButtonLabel()); ?>
        </a>
    </div>
</div>Admin/Layout/Block/Dashboard/DashboardManager/BlockDashboardManager.php000064400000000463152356646020022036 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Dashboard\DashboardManager;


use Nextend\Framework\View\AbstractBlock;

class BlockDashboardManager extends AbstractBlock {

    public function display() {

        $this->renderTemplatePart('DashboardManager');
    }

}Admin/Layout/Block/Dashboard/DashboardManager/DashboardManager.php000064400000001457152356646020021067 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Dashboard\DashboardManager;

use Nextend\SmartSlider3\Application\Admin\Layout\Block\Dashboard\DashboardManager\Boxes\BlockDashboardNewsletter;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Dashboard\DashboardManager\Boxes\BlockDashboardReview;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Dashboard\DashboardManager\Boxes\BlockDashboardUpgradePro;

/**
 * @var BlockDashboardManager $this
 */
?>
<div class="n2_dashboard_manager">
    <div class="n2_dashboard_manager__content">
        <?php
        $review = new BlockDashboardReview($this);
        $review->display();
    

        $newsletter = new BlockDashboardNewsletter($this);
        $newsletter->display();

        ?>
    </div>
</div>
Admin/Layout/Block/Dashboard/DashboardManager/Boxes/BlockDashboardNewsletter.php000064400000001074152356646020023677 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Dashboard\DashboardManager\Boxes;


use Nextend\Framework\Model\StorageSectionManager;
use Nextend\Framework\View\AbstractBlock;

class BlockDashboardNewsletter extends AbstractBlock {


    public function display() {
        $storage = StorageSectionManager::getStorage('smartslider');

        if (!$storage->get('free', 'subscribeOnImport') && !$storage->get('free', 'dismissNewsletterDashboard')) {
            $this->renderTemplatePart('DashboardNewsletter');
        }
    }
}Admin/Layout/Block/Dashboard/DashboardManager/Boxes/BlockDashboardReview.php000064400000001263152356646020023004 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Dashboard\DashboardManager\Boxes;


use Nextend\Framework\Model\StorageSectionManager;
use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Model\ModelSliders;

class BlockDashboardReview extends AbstractBlock {


    public function display() {
        if (!StorageSectionManager::getStorage('smartslider')
                                  ->get('free', 'rated')) {

            $modelSliders = new ModelSliders($this);
            if ($modelSliders->getSlidersCount() >= 3) {
                $this->renderTemplatePart('DashboardReview');
            }
        }
    }
}Admin/Layout/Block/Dashboard/DashboardManager/Boxes/BlockDashboardUpgradePro.php000064400000001627152356646020023617 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Dashboard\DashboardManager\Boxes;


use Nextend\Framework\Model\StorageSectionManager;
use Nextend\Framework\View\AbstractBlock;

class BlockDashboardUpgradePro extends AbstractBlock {

    protected $hasDismiss = false;

    protected $source = 'dashboard-why-upgrade';

    public function display() {
    }

    /**
     * @return bool
     */
    public function hasDismiss() {
        return $this->hasDismiss;
    }

    /**
     * @param bool $hasDismiss
     */
    public function setHasDismiss($hasDismiss) {
        $this->hasDismiss = $hasDismiss;
    }

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

    /**
     * @param string $source
     */
    public function setSource($source) {
        $this->source = $source;
    }

}Admin/Layout/Block/Dashboard/DashboardManager/Boxes/DashboardNewsletter.php000064400000005556152356646020022735 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Dashboard\DashboardManager\Boxes;

use Nextend\Framework\Platform\Platform;

/**
 * @var BlockDashboardNewsletter $this
 */
?>
<div class="n2_dashboard_manager_newsletter">

    <div class="n2_dashboard_manager_newsletter__logo">
        <i class="ssi_48 ssi_48--newsletter"></i>
    </div>

    <div class="n2_dashboard_manager_newsletter__heading">
        <?php n2_e('Don’t miss any update'); ?>
    </div>

    <div class="n2_dashboard_newsletter__paragraph">
        <?php n2_e('Join more than 120,000 subscribers and get access to the latest slider templates, tips, tutorials and other exclusive contents directly to your inbox.'); ?>
    </div>

    <form class="n2_dashboard_newsletter__form">
        <input type="hidden" name="<?php echo esc_attr(strtoupper(Platform::getName())); ?>" value="Yes">
        <input type="hidden" name="SOURCE" value="Smart Slider 3">
        <input type="email" name="EMAIL" value="<?php echo esc_attr(Platform::getUserEmail()); ?>" placeholder="Email" tabindex="-1">
    </form>

    <div class="n2_dashboard_manager_newsletter__button">
        <?php n2_e('Subscribe'); ?>
    </div>

    <div class="n2_dashboard_manager_newsletter__close">
        <i class="ssi_16 ssi_16--remove"></i>
    </div>
</div>

<script>
    _N2.r(['$', 'documentReady'], function () {
        var $ = _N2.$;
        var $box = $('.n2_dashboard_manager_newsletter'),
            close = function (e, action) {
                _N2.AjaxHelper
                    .ajax({
                        type: "POST",
                        url: _N2.AjaxHelper.makeAjaxUrl(_N2.AjaxHelper.getAdminUrl('ss3-admin'), {
                            nextendcontroller: 'settings',
                            nextendaction: action || 'dismissNewsletterDashboard'
                        }),
                        dataType: 'json'
                    });

                $box.remove();
            },
            $form = $('.n2_dashboard_newsletter__form')
                .on('submit', function (e) {
                    e.preventDefault();

                    _N2.AjaxHelper
                        .ajax({
                            type: "POST",
                            url: "https://secure.nextendweb.com/mailchimp/subscribe.php",
                            data: $form.serialize(),
                            dataType: 'json'
                        })
                        .done(function () {
                        });

                    close(e, 'subscribed');
                });

        $('.n2_dashboard_manager_newsletter__button')
            .on('click', function () {
                $form.trigger("submit");
            });

        $box.find('.n2_dashboard_manager_newsletter__close')
            .on('click', close);
    });
</script>Admin/Layout/Block/Dashboard/DashboardManager/Boxes/DashboardReview.php000064400000011665152356646020022040 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Dashboard\DashboardManager\Boxes;

use Nextend\Framework\Platform\Platform;
use Nextend\SmartSlider3\SmartSlider3Info;

/**
 * @var BlockDashboardReview $this
 */
?>

<div class="n2_dashboard_manager_review" data-star="0">

    <div class="n2_dashboard_manager_review__logo">
        <i class="ssi_48 ssi_48--review0"></i>
        <i class="ssi_48 ssi_48--review1"></i>
        <i class="ssi_48 ssi_48--review2"></i>
        <i class="ssi_48 ssi_48--review3"></i>
        <i class="ssi_48 ssi_48--review4"></i>
        <i class="ssi_48 ssi_48--review5"></i>
    </div>

    <div class="n2_dashboard_manager_review__heading">
        <?php n2_e('Let us know how we\'re doing'); ?>
    </div>

    <div class="n2_dashboard_manager_review__paragraph">
        <?php n2_e('If you are happy with Smart Slider 3 and can take a minute please leave a review. This will help to spread its popularity and to make this plugin a better one.'); ?>
    </div>

    <div class="n2_dashboard_manager_review__star_selector">

        <div class="n2_dashboard_manager_review__star" data-star="1" data-href="<?php echo esc_url('https://smartslider3.com/suggestion/?utm_campaign=' . SmartSlider3Info::$campaign . '&utm_source=dashboard-review-1&utm_medium=smartslider-' . Platform::getName() . '-' . SmartSlider3Info::$plan); ?>">
            <i class="ssi_24 ssi_24--star"></i>
        </div>
        <div class="n2_dashboard_manager_review__star" data-star="2" data-href="<?php echo esc_url('https://smartslider3.com/suggestion/?utm_campaign=' . SmartSlider3Info::$campaign . '&utm_source=dashboard-review-2&utm_medium=smartslider-' . Platform::getName() . '-' . SmartSlider3Info::$plan); ?>">
            <i class="ssi_24 ssi_24--star"></i>
        </div>
        <div class="n2_dashboard_manager_review__star" data-star="3" data-href="<?php echo esc_url('https://smartslider3.com/satisfied-customer/?utm_campaign=' . SmartSlider3Info::$campaign . '&utm_source=dashboard-review-3&utm_medium=smartslider-' . Platform::getName() . '-' . SmartSlider3Info::$plan); ?>">
            <i class="ssi_24 ssi_24--star"></i>
        </div>
        <div class="n2_dashboard_manager_review__star" data-star="4" data-href="<?php echo esc_url('https://smartslider3.com/satisfied-customer/?utm_campaign=' . SmartSlider3Info::$campaign . '&utm_source=dashboard-review-4&utm_medium=smartslider-' . Platform::getName() . '-' . SmartSlider3Info::$plan); ?>">
            <i class="ssi_24 ssi_24--star"></i>
        </div>

        <?php
        $reviewUrl = 'https://smartslider3.com/redirect/joomla-review.html?utm_campaign=' . SmartSlider3Info::$campaign . '&utm_source=dashboard-review-5&utm_medium=smartslider-' . Platform::getName() . '-' . SmartSlider3Info::$plan;
    
        ?>
        <div class="n2_dashboard_manager_review__star" data-star="5" data-href="<?php echo esc_url($reviewUrl); ?>">
            <i class="ssi_24 ssi_24--star"></i></div>

    </div>
    <div class="n2_dashboard_manager_review__label" data-star="0"><?php n2_e('Rate your experience'); ?></div>
    <div class="n2_dashboard_manager_review__label" data-star="1"><?php n2_e('Hated it'); ?></div>
    <div class="n2_dashboard_manager_review__label" data-star="2"><?php n2_e('Disliked it'); ?></div>
    <div class="n2_dashboard_manager_review__label" data-star="3"><?php n2_e('It was ok'); ?></div>
    <div class="n2_dashboard_manager_review__label" data-star="4"><?php n2_e('Liked it'); ?></div>
    <div class="n2_dashboard_manager_review__label" data-star="5"><?php n2_e('Loved it'); ?></div>

    <div class="n2_dashboard_manager_review__close">
        <i class="ssi_16 ssi_16--remove"></i>
    </div>
</div>

<script>
    _N2.r(['$', 'documentReady'], function () {
        var $ = _N2.$;
        var $box = $('.n2_dashboard_manager_review'),
            close = function () {
                _N2.AjaxHelper
                    .ajax({
                        type: "POST",
                        url: _N2.AjaxHelper.makeAjaxUrl(_N2.AjaxHelper.getAdminUrl('ss3-admin'), {
                            nextendcontroller: 'settings',
                            nextendaction: 'rated'
                        }),
                        dataType: 'json'
                    });

                $box.remove();
            };

        $('.n2_dashboard_manager_review__star')
            .on({
                mouseenter: function (e) {
                    $box.attr('data-star', $(e.currentTarget).data('star'));
                },
                mouseleave: function () {
                    $box.attr('data-star', 0);
                },
                click: function (e) {
                    window.open($(e.currentTarget).data('href'), '_blank');
                    close();
                }
            });

        $box.find('.n2_dashboard_manager_review__close')
            .on('click', close);
    });
</script>Admin/Layout/Block/Dashboard/DashboardManager/Boxes/DashboardUpgradePro.php000064400000011437152356646020022644 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Dashboard\DashboardManager\Boxes;

use Nextend\SmartSlider3\SmartSlider3Info;

/**
 * @var BlockDashboardUpgradePro $this
 */
?>
    <div class="n2_dashboard_manager_upgrade_pro">

        <div class="n2_dashboard_manager_upgrade_pro__logo">
            <i class="ssi_48 ssi_48--upgrade"></i>
        </div>

        <div class="n2_dashboard_manager_upgrade_pro__heading">
            <?php n2_e('Why upgrade to Smart Slider 3 Pro?'); ?>
        </div>

        <div class="n2_dashboard_manager_upgrade_pro__details">
            <a target="_blank" href="<?php echo esc_url(SmartSlider3Info::decorateExternalUrl('https://smartslider3.com/sample-sliders/', array('utm_source' => $this->getSource() . '-sample-sliders'))); ?>" class="n2_dashboard_manager_upgrade_pro__details_option">
                <i class="ssi_16 ssi_16--filledcheck"></i>
                <div class="n2_dashboard_manager_upgrade_pro__details_option_label"><?php echo sprintf(n2_('%d+ slider templates'), '120'); ?></div>
            </a>
            <a target="_blank" href="<?php echo esc_url(SmartSlider3Info::decorateExternalUrl('https://smartslider3.com/slide-library/', array('utm_source' => $this->getSource() . '-slide-library'))); ?>" class="n2_dashboard_manager_upgrade_pro__details_option">
                <i class="ssi_16 ssi_16--filledcheck"></i>
                <div class="n2_dashboard_manager_upgrade_pro__details_option_label"><?php n2_e('Full slide library access'); ?></div>
            </a>
            <a target="_blank" href="<?php echo esc_url(SmartSlider3Info::decorateExternalUrl('https://smartslider3.com/layers/', array('utm_source' => $this->getSource() . '-layers'))); ?>" class="n2_dashboard_manager_upgrade_pro__details_option">
                <i class="ssi_16 ssi_16--filledcheck"></i>
                <div class="n2_dashboard_manager_upgrade_pro__details_option_label"><?php echo sprintf(n2_('%d new layers'), '20'); ?></div>
            </a>
            <a target="_blank" href="<?php echo esc_url(SmartSlider3Info::decorateExternalUrl('https://smartslider3.com/features/', array('utm_source' => $this->getSource() . '-free-pro'))); ?>" class="n2_dashboard_manager_upgrade_pro__details_option">
                <i class="ssi_16 ssi_16--filledcheck"></i>
                <div class="n2_dashboard_manager_upgrade_pro__details_option_label"><?php n2_e('Extra advanced options'); ?></div>
            </a>
            <a target="_blank" href="<?php echo esc_url(SmartSlider3Info::decorateExternalUrl('https://smartslider3.com/animations-and-effects/', array('utm_source' => $this->getSource() . '-animations'))); ?>" class="n2_dashboard_manager_upgrade_pro__details_option">
                <i class="ssi_16 ssi_16--filledcheck"></i>
                <div class="n2_dashboard_manager_upgrade_pro__details_option_label"><?php n2_e('New animations & effects'); ?></div>
            </a>
            <a target="_blank" href="<?php echo esc_url(SmartSlider3Info::decorateExternalUrl('https://smartslider3.com/help/', array('utm_source' => $this->getSource() . '-support'))); ?>" class="n2_dashboard_manager_upgrade_pro__details_option">
                <i class="ssi_16 ssi_16--filledcheck"></i>
                <div class="n2_dashboard_manager_upgrade_pro__details_option_label"><?php n2_e('Lifetime update & support'); ?></div>
            </a>
        </div>

        <a href="<?php echo esc_url(SmartSlider3Info::getWhyProUrl(array('utm_source' => $this->getSource()))); ?>" target="_blank" class="n2_dashboard_manager_upgrade_pro__button">
            <?php n2_e('Upgrade to Pro'); ?>
        </a>

        <?php
        if ($this->hasDismiss()):
            ?>
            <div class="n2_dashboard_manager_upgrade_pro__close">
                <i class="ssi_16 ssi_16--remove"></i>
            </div>
        <?php
        endif;
        ?>
    </div>

    <?php
if ($this->hasDismiss()):
    ?>
    <script>
        _N2.r(['$', 'documentReady'], function () {
            var $ = _N2.$;
            var $box = $('.n2_dashboard_manager_upgrade_pro'),
                close = function () {
                    _N2.AjaxHelper
                        .ajax({
                            type: "POST",
                            url: _N2.AjaxHelper.makeAjaxUrl(_N2.AjaxHelper.getAdminUrl('ss3-admin'), {
                                nextendcontroller: 'settings',
                                nextendaction: 'dismissupgradepro'
                            }),
                            dataType: 'json'
                        });

                    $box.remove();
                };

            $box.find('.n2_dashboard_manager_upgrade_pro__close')
                .on('click', close);
        });
    </script>
<?php
endif;
?>Admin/Layout/Block/Dashboard/DashboardInfo/BlockDashboardInfo.php000064400000000575152356646020020704 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Dashboard\DashboardInfo;


use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;

class BlockDashboardInfo extends AbstractBlock {

    use TraitAdminUrl;

    public function display() {

        $this->renderTemplatePart('DashboardInfo');
    }
}Admin/Layout/Block/Dashboard/DashboardInfo/DashboardInfo.php000064400000006121152356646020017722 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Dashboard\DashboardInfo;

use Nextend\Framework\Asset\Js\Js;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonDashboardInfo;
use Nextend\SmartSlider3\SmartSlider3Info;

/**
 * @var $this BlockDashboardInfo
 */

Js::addInline('new _N2.DashboardInfo();');
?>

<div class="n2_dashboard_info">
    <?php
    $info = new BlockButtonDashboardInfo($this);
    $info->display();
    ?>
    <div class="n2_dashboard_info__content">

        <div class="n2_dashboard_info__row_icon n2_dashboard_info__row_icon_version">
            <i class="ssi_24 ssi_24--circularinfo"></i>
        </div>

        <div class="n2_dashboard_info__row_content n2_dashboard_info__row_content_version">
            Smart Slider
            <?php
            echo esc_html(SmartSlider3Info::$version . '-' . SmartSlider3Info::$plan);
            ?>
        </div>
        <div class="n2_dashboard_info__row_action n2_dashboard_info__row_action_version">
            <a target="_blank" href="https://smartslider.helpscoutdocs.com/article/1746-changelog"><?php n2_e('Changelog') ?></a>
        </div>

        <?php
        $this->getRouter()
             ->setMultiSite();
        $checkForUpdateUrl = $this->getUrlUpdateDownload();
        $this->getRouter()
             ->unSetMultiSite();
        ?>
        <div class="n2_dashboard_info__row_icon n2_dashboard_info__row_icon_check_update">
            <i class="ssi_24 ssi_24--refresh"></i>
        </div>

        <div class="n2_dashboard_info__row_content n2_dashboard_info__row_content_check_update">
            <?php n2_e('Check for update'); ?>
        </div>
        <div class="n2_dashboard_info__row_action n2_dashboard_info__row_action_check_update">
            <a target="_blank" href="<?php echo esc_url($checkForUpdateUrl); ?>"><?php n2_e('Check') ?></a>
        </div>

        <?php
        ?>
        <div class="n2_dashboard_info__row_icon n2_dashboard_info__row_icon_activated">
            <i class="ssi_24 ssi_24--active"></i>
        </div>

        <div class="n2_dashboard_info__row_content n2_dashboard_info__row_content_activated">
            <?php n2_e('Your license is active'); ?>
        </div>
        <div class="n2_dashboard_info__row_action n2_dashboard_info__row_action_activated">
            <a href="<?php echo esc_url($this->getUrlDeauthorizeLicense()); ?>"><?php n2_e('Deactivate license') ?></a>
        </div>

        <div class="n2_dashboard_info__row_icon n2_dashboard_info__row_icon_activate">
            <i class="ssi_24 ssi_24--attention"></i>
        </div>

        <div class="n2_dashboard_info__row_content n2_dashboard_info__row_content_activate">
            <?php n2_e('Activate your license'); ?>
        </div>
        <div class="n2_dashboard_info__row_action n2_dashboard_info__row_action_activate">
            <a onclick="_N2.License.get().startActivation();return false;" href="#"><?php n2_e('Activate') ?></a>
        </div>
        <?php
    
        ?>
    </div>
</div>
<?php
Admin/Layout/Block/Forms/FloatingMenu/BlockFloatingMenu.php000064400000005703152356646020017653 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\FloatingMenu;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractBlock;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\AbstractButton;

class BlockFloatingMenu extends AbstractBlock {

    /**
     * @var AbstractButton
     */
    protected $button;

    protected $classes = array(
        'n2_popover',
        'n2_floating_menu'
    );

    protected $attributes = array();

    /**
     * @var AbstractBlock[]
     */
    protected $menuItems = array();

    protected $contentID;

    public function display() {
        $this->renderTemplatePart('FloatingMenu');
    }

    public function displayButton() {
        $this->button->display();
    }

    /**
     * @param AbstractButton $button
     */
    public function setButton($button) {

        $button->setTabIndex(-1);
        $button->addClass('n2_floating_menu__button n2_popover__trigger');
        $this->button = $button;
    }

    /**
     * @param AbstractBlock $item
     */
    public function addMenuItem($item) {
        $this->menuItems[] = $item;
    }

    public function addSeparator($classes = array()) {

        $separator = new BlockFloatingMenuItemSeparator($this);
        $separator->setclasses($classes);
        $this->menuItems[] = $separator;
    }

    /**
     * @return AbstractBlock[]
     */
    public function getMenuItems() {
        return $this->menuItems;
    }

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

    public function getClasses() {

        return $this->classes;
    }

    /**
     * @return mixed
     */
    public function getContentID() {
        return $this->contentID;
    }

    /**
     * @param mixed $contentID
     */
    public function setContentID($contentID) {
        $this->contentID = $contentID;
    }

    public function renderAttributes() {

        echo wp_kses(Html::renderAttributes($this->attributes + array(
                'class' => implode(' ', $this->classes)
            )), Sanitize::$adminTemplateTags);
    }

    public function setAttribute($name, $value) {
        $this->attributes[$name] = $value;
    }

    public function setLeft() {
        $this->setAttribute('data-horizontal', 'left');
    }

    public function setRight() {
        $this->setAttribute('data-horizontal', 'right');
    }

    public function setAbove() {
        $this->setAttribute('data-vertical', 'above');
    }

    public function setBelow() {
        $this->setAttribute('data-vertical', 'below');
    }

    public function setRelatedClass($selector) {
        $this->setAttribute('data-relatedclass', $selector);
    }
}

Js::addInline('_N2.r(\'$\', function () {_N2.$(".n2_floating_menu").nextendPopover();});');Admin/Layout/Block/Forms/FloatingMenu/BlockFloatingMenuItem.php000064400000004616152356646020020474 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\FloatingMenu;


use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractBlock;
use Nextend\Framework\View\Html;

class BlockFloatingMenuItem extends AbstractBlock {

    protected $label = '';

    protected $url = '#';

    protected $icon = '';

    protected $isActive = false;

    protected $attributes = array();

    protected $classes = array(
        'n2_floating_menu__item'
    );

    protected $color = 'grey';

    public function display() {

        $label = '';
        if (!empty($this->icon)) {
            $label .= '<i class="' . $this->icon . '"></i>';
        }
        $label .= '<div class="n2_floating_menu__item_label">' . $this->label . '</div>';

        echo wp_kses(Html::link($label, $this->url, $this->attributes + array('class' => implode(' ', $this->getClasses()))), Sanitize::$adminTemplateTags);
    }

    /**
     * @param string $label
     */
    public function setLabel($label) {
        $this->label = $label;
    }

    /**
     * @param string $url
     */
    public function setUrl($url) {
        $this->url = $url;
    }

    /**
     * @param string $icon
     */
    public function setIcon($icon) {
        $this->icon = $icon;
    }

    /**
     * @param bool $isActive
     */
    public function setIsActive($isActive) {
        $this->isActive = $isActive;
    }

    public function addAttribute($name, $value) {
        $this->attributes[$name] = $value;
    }

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

    /**
     * @param string $target
     */
    public function setTarget($target) {
        $this->addAttribute('target', $target);
    }

    public function setRed() {
        $this->color = 'red';
    }

    public function setGrey() {
        $this->color = 'grey';
    }

    public function getClasses() {

        $classes = $this->classes;

        if ($this->isActive) {
            $classes[] = 'n2_floating_menu__item--active';
        }

        $classes[] = 'n2_floating_menu__item--' . $this->color;

        return $classes;
    }

    public function setState($state) {
        $this->attributes['data-state'] = $state;
    }

    public function setStayOpen() {
        $this->addAttribute('data-stay-open', 1);
    }
}Admin/Layout/Block/Forms/FloatingMenu/BlockFloatingMenuItemSeparator.php000064400000001124152356646020022344 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\FloatingMenu;

use Nextend\Framework\View\AbstractBlock;

class BlockFloatingMenuItemSeparator extends AbstractBlock {

    protected $classes = array();

    public function display() {

        echo '<div class="' . esc_attr(implode(' ', array_merge(array(
                'n2_floating_menu__item_separator'
            ), $this->classes))) . '"></div>';
    }

    /**
     * @param array $classes
     */
    public function setClasses($classes) {
        $this->classes = $classes;
    }


}Admin/Layout/Block/Forms/FloatingMenu/FloatingMenu.php000064400000001365152356646020016700 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\FloatingMenu;


/**
 * @var BlockFloatingMenu $this
 */
?>
<div <?php $this->renderAttributes(); ?>>
    <?php
    $this->displayButton();

    $contentID = $this->getContentID();
    ?>
    <div <?php if (!empty($contentID)): ?>id="<?php echo esc_attr($this->getContentID()); ?>"<?php endif; ?> class="n2_popover_content n2_floating_menu__items_container">
        <div class="n2_popover_content_exit"></div>
        <div class="n2_popover_content_inner n2_floating_menu__items">
            <?php
            foreach ($this->getMenuItems() as $menuItem) {
                $menuItem->display();
            }
            ?>
        </div>
    </div>
</div>Admin/Layout/Block/Forms/Button/AbstractButton.php000064400000004344152356646020016132 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button;


use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractBlock;
use Nextend\Framework\View\Html;

abstract class AbstractButton extends AbstractBlock {

    protected $url = '#';

    protected $attributes = array();

    protected $classes = array();

    protected $baseClass = '';

    protected $size = 'medium';

    protected $tabindex = 0;

    public function display() {

        echo wp_kses(Html::link($this->getContent(), $this->getUrl(), $this->getAttributes()), Sanitize::$adminTemplateTags);
    }

    abstract protected function getContent();

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

    /**
     * @param string $url
     */
    public function setUrl($url) {
        $this->url = $url;
    }

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

    public function addAttribute($name, $value) {
        $this->attributes[$name] = $value;
    }

    public function getAttributes() {

        $classes = array_merge(array($this->baseClass), $this->getClasses());

        return $this->attributes + array('class' => implode(' ', $classes));
    }

    /**
     * @param string $target
     */
    public function setTarget($target) {
        $this->addAttribute('target', $target);
    }

    /**
     * @return array
     */
    public function getClasses() {

        $classes   = $this->classes;
        $classes[] = $this->baseClass . '--' . $this->size;

        return $classes;
    }

    public function setSmall() {
        $this->size = 'small';
    }

    public function setMedium() {
        $this->size = 'medium';
    }

    public function setBig() {
        $this->size = 'big';
    }

    /**
     * @param integer $tabIndex
     */
    public function setTabIndex($tabIndex) {
        $this->tabindex = $tabIndex;

        if ($this->tabindex === 0) {
            unset($this->attributes['tabindex']);
        } else {
            $this->attributes['tabindex'] = $this->tabindex;
        }
    }
}Admin/Layout/Block/Forms/Button/AbstractButtonLabel.php000064400000002517152356646020017072 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button;


class AbstractButtonLabel extends AbstractButton {

    protected $label = '';

    protected $icon = '';

    protected $iconBefore = "";

    protected $iconBeforeClass = "";

    protected function getContent() {
        $content = '';

        if (!empty($this->iconBefore)) {
            $content .= '<i class="' . $this->iconBefore . ' ' . $this->iconBeforeClass . '"></i>';
        }

        $content .= '<span class="' . $this->baseClass . '__label">' . $this->getLabel() . '</span>';

        if (!empty($this->icon)) {
            $content .= '<i class="' . $this->icon . '"></i>';
        }

        return $content;
    }

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

    /**
     * @param string $label
     */
    public function setLabel($label) {
        $this->label = $label;
    }

    /**
     * @param string $icon
     */
    public function setIcon($icon) {
        $this->icon = $icon;
    }

    /**
     * @param string $icon
     * @param string $extraClass
     */
    public function setIconBefore($icon, $extraClass = "") {
        $this->iconBefore      = $icon;
        $this->iconBeforeClass = $extraClass;
    }

}Admin/Layout/Block/Forms/Button/BlockButton.php000064400000001411152356646020015411 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button;

class BlockButton extends AbstractButtonLabel {

    protected $baseClass = 'n2_button';

    protected $color = 'blue';

    public function setBlue() {
        $this->color = 'blue';
    }

    public function setGreen() {
        $this->color = 'green';
    }

    public function setRed() {
        $this->color = 'red';
    }

    public function setGrey() {
        $this->color = 'grey';
    }

    public function setGreyDark() {
        $this->color = 'grey-dark';
    }

    public function getClasses() {

        $classes = parent::getClasses();

        $classes[] = $this->baseClass . '--' . $this->color;

        return $classes;
    }
}Admin/Layout/Block/Forms/Button/BlockButtonApply.php000064400000000456152356646020016427 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button;


class BlockButtonApply extends BlockButton {

    protected function init() {
        parent::init();

        $this->setLabel(n2_('Apply'));
        $this->setBig();
        $this->setGreen();
    }
}Admin/Layout/Block/Forms/Button/BlockButtonBack.php000064400000000457152356646020016203 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button;


class BlockButtonBack extends BlockButton {

    protected function init() {
        parent::init();

        $this->setLabel(n2_('Back'));
        $this->setBig();
        $this->setGreyDark();
    }
}Admin/Layout/Block/Forms/Button/BlockButtonCancel.php000064400000000456152356646020016527 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button;


class BlockButtonCancel extends BlockButton {

    protected function init() {
        parent::init();

        $this->setLabel(n2_('Cancel'));
        $this->setBig();
        $this->setRed();
    }
}Admin/Layout/Block/Forms/Button/BlockButtonDashboardInfo.php000064400000001046152356646020020041 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button;


class BlockButtonDashboardInfo extends BlockButtonPlainIcon {

    protected $baseClass = 'n2_button_plain_icon';

    protected $icon = 'ssi_24 ssi_24--notification';

    protected $size = 'big';

    protected function init() {
        parent::init();

        $this->setTabIndex(-1);
    }

    protected function getContent() {

        return '<i class="' . $this->icon . '"></i><div class="n2_dashboard_info__marker"></div>';
    }
}Admin/Layout/Block/Forms/Button/BlockButtonIcon.php000064400000001425152356646020016227 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button;


class BlockButtonIcon extends BlockButtonPlainIcon {

    protected $baseClass = 'n2_button_icon';

    protected $color = 'grey';

    public function setBlue() {
        $this->color = 'blue';
    }

    public function setGreen() {
        $this->color = 'green';
    }

    public function setRed() {
        $this->color = 'red';
    }

    public function setGrey() {
        $this->color = 'grey';
    }

    public function setGreyDark() {
        $this->color = 'grey-dark';
    }

    public function getClasses() {

        $classes = parent::getClasses();

        $classes[] = $this->baseClass . '--' . $this->color;

        return $classes;
    }
}Admin/Layout/Block/Forms/Button/BlockButtonIconCode.php000064400000000341152356646020017016 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button;


class BlockButtonIconCode extends BlockButtonIcon {

    protected function getContent() {

        return $this->icon;
    }
}Admin/Layout/Block/Forms/Button/BlockButtonImport.php000064400000000460152356646020016607 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button;


class BlockButtonImport extends BlockButton {

    protected function init() {
        parent::init();

        $this->setLabel(n2_('Import'));
        $this->setBig();
        $this->setGreen();
    }
}Admin/Layout/Block/Forms/Button/BlockButtonPlain.php000064400000001110152356646020016371 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button;


class BlockButtonPlain extends AbstractButtonLabel {

    protected $baseClass = 'n2_button_plain';

    protected $color = '';

    public function setColorBlue() {
        $this->color = 'blue';
    }

    /**
     * @return array
     */
    public function getClasses() {

        $classes = parent::getClasses();

        if (!empty($this->color)) {
            $classes[] = $this->baseClass . '--color-' . $this->color;
        }

        return $classes;
    }
}Admin/Layout/Block/Forms/Button/BlockButtonPlainIcon.php000064400000000711152356646020017210 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button;


class BlockButtonPlainIcon extends AbstractButton {

    protected $baseClass = 'n2_button_plain_icon';

    protected $icon = '';

    protected function getContent() {

        return '<i class="' . $this->icon . '"></i>';
    }

    /**
     * @param string $icon
     */
    public function setIcon($icon) {
        $this->icon = $icon;
    }
}Admin/Layout/Block/Forms/Button/BlockButtonSave.php000064400000000454152356646020016236 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button;


class BlockButtonSave extends BlockButton {

    protected function init() {
        parent::init();

        $this->setLabel(n2_('Save'));
        $this->setBig();
        $this->setGreen();
    }
}Admin/Layout/Block/Forms/Button/BlockButtonSpacer.php000064400000001202152356646020016545 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button;


use Nextend\Framework\View\AbstractBlock;

class BlockButtonSpacer extends AbstractBlock {

    protected $isVisible = false;

    public function display() {

        $classes = array('n2_button_spacer');

        if ($this->isVisible) {
            $classes[] = 'n2_button_spacer--visible';
        }

        echo '<div class="' . esc_attr(implode(' ', $classes)) . '"></div>';
    }

    /**
     * @param bool $isVisible
     */
    public function setIsVisible($isVisible) {
        $this->isVisible = $isVisible;
    }
}Admin/Layout/Block/Core/TopBarMain/BlockTopBarMain.php000064400000002344152356646020016463 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain;


use Nextend\Framework\View\AbstractBlock;

class BlockTopBarMain extends AbstractBlock {

    private static $idCounter = 1;

    protected $id = 0;

    /**
     * @var AbstractBlock[]
     */
    protected $primaryBlocks = array();

    /**
     * @var AbstractBlock[]
     */
    protected $secondaryBlocks = array();

    protected $content = '';

    protected function init() {
        $this->id = self::$idCounter++;
        parent::init();
    }

    public function display() {

        $this->renderTemplatePart('TopBarMain');
    }

    public function addPrimaryBlock($block) {
        $this->primaryBlocks[] = $block;
    }

    public function displayPrimary() {

        foreach ($this->primaryBlocks as $block) {
            $block->display();
        }
    }

    public function addSecondaryBlock($block) {
        $this->secondaryBlocks[] = $block;
    }

    public function displaySecondary() {

        foreach ($this->secondaryBlocks as $block) {
            $block->display();
        }
    }

    public function getID() {
        return 'n2_top_bar_main_' . $this->id;
    }
}Admin/Layout/Block/Core/TopBarMain/TopBarMain.php000064400000001246152356646020015510 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain;

/**
 * @var $this BlockTopBarMain
 */
?>
<script>
    _N2.r(['$', 'documentReady'], function () {
        var $ = _N2.$;
        $('#<?php echo esc_html($this->getID()); ?>').css('top', _N2.Window.getTopOffset() + 'px');
    });
</script>
<div id="<?php echo esc_html($this->getID()); ?>" class="n2_admin__top_bar n2_top_bar_main">
    <div class="n2_top_bar_main__primary">
        <?php
        $this->displayPrimary();
        ?>
    </div>
    <div class="n2_top_bar_main__secondary">
        <?php
        $this->displaySecondary();
        ?>
    </div>
</div>Admin/Layout/Block/Core/TopBarMain/TopBarMainEditor/BlockTopBarMainEditor.php000064400000000675152356646020023002 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain\TopBarMainEditor;


use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain\BlockTopBarMain;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;

class BlockTopBarMainEditor extends BlockTopBarMain {

    use TraitAdminUrl;

    public function display() {

        $this->renderTemplatePart('TopBarMainEditor');
    }
}Admin/Layout/Block/Core/TopBarMain/TopBarMainEditor/TopBarMainEditor.php000064400000001524152356646020022021 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain\TopBarMainEditor;

use Nextend\Framework\Sanitize;

/**
 * @var $this BlockTopBarMainEditor
 */
?>
<div id="<?php echo esc_attr($this->getID()); ?>" class="n2_admin__top_bar n2_top_bar_main n2_admin_editor_overlay__top_bar_main">
    <div class="n2_top_bar_main__primary">
        <?php
        $this->displayPrimary();
        ?>
    </div>
    <div class="n2_top_bar_main__logo">
        <a href="<?php echo esc_url($this->getUrlDashboard()); ?>">
            <?php echo wp_kses($this->getApplicationType()
                                    ->getLogo(), Sanitize::$adminTemplateTags); ?>
        </a>
    </div>
    <div class="n2_top_bar_main__secondary">
        <?php
        $this->displaySecondary();
        ?>
    </div>
</div>
Admin/Layout/Block/Core/TopBarGroup/BlockTopBarGroup.php000064400000001624152356646020017103 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarGroup;


use Nextend\Framework\View\AbstractBlock;

class BlockTopBarGroup extends AbstractBlock {

    /**
     * @var AbstractBlock[]
     */
    protected $blocks = array();

    protected $classes = array('n2_top_bar_group');

    public function display() {

        $this->renderTemplatePart('TopBarGroup');
    }

    /**
     * @param AbstractBlock $block
     */
    public function addBlock($block) {
        $this->blocks[] = $block;
    }

    public function displayBlocks() {

        foreach ($this->blocks as $block) {
            $block->display();
        }
    }

    public function setNarrow() {
        $this->classes[] = 'n2_top_bar_group--narrow';
    }

    /**
     * @return array
     */
    public function getClasses() {
        return $this->classes;
    }
}Admin/Layout/Block/Core/TopBarGroup/TopBarGroup.php000064400000000521152356646020016123 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarGroup;

/**
 * @var $this BlockTopBarGroup
 */
?>

<div class="<?php echo esc_html(implode(' ', $this->getClasses())); ?>">
    <div class="n2_top_bar_group__inner">
        <?php
        $this->displayBlocks();
        ?>
    </div>
</div>
Admin/Layout/Block/Core/NavBar/BlockNavBar.php000064400000004051152356646020015012 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\NavBar;


use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\BlockBreadCrumb\BlockBreadCrumb;
use Nextend\SmartSlider3\Application\Admin\Layout\Helper\Breadcrumb;
use Nextend\SmartSlider3\Application\Admin\Layout\Helper\MenuItem;

class BlockNavBar extends AbstractBlock {

    protected $sidebarLink = '';

    protected $logo = '';

    /**
     * @var MenuItem[]
     */
    protected $menuItems = array();

    /**
     * @var BlockBreadCrumb
     */
    protected $blockBreadCrumb;

    public function display() {

        $this->renderTemplatePart('NavBar');
    }

    protected function init() {
        $this->blockBreadCrumb = new BlockBreadCrumb($this);
    }

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

    /**
     * @param string $sidebarLink
     */
    public function setSidebarLink($sidebarLink) {
        $this->sidebarLink = $sidebarLink;
    }

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

    /**
     * @param string $logo
     */
    public function setLogo($logo) {
        $this->logo = $logo;
    }

    /**
     * @return MenuItem[]
     */
    public function getMenuItems() {
        return $this->menuItems;
    }

    /**
     * @param string $menuItem
     * @param bool   $isActive
     */
    public function addMenuItem($menuItem, $isActive = false) {
        $this->menuItems[] = new MenuItem($menuItem, $isActive);
    }

    /**
     * @param        $label
     * @param        $icon
     * @param string $url
     *
     * @return Breadcrumb
     */
    public function addBreadcrumb($label, $icon, $url = '#') {

        return $this->blockBreadCrumb->addBreadcrumb($label, $icon, $url);
    }

    public function displayBreadCrumbs() {
        $this->blockBreadCrumb->display();
    }

}Admin/Layout/Block/Core/NavBar/NavBar.php000064400000001455152356646020014044 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\NavBar;

use Nextend\Framework\Sanitize;

/**
 * @var $this BlockNavBar
 */
?>
<div class="n2_nav_bar">

    <?php $this->displayBreadCrumbs(); ?>

    <div class="n2_nav_bar__logo">
        <a href="<?php echo esc_url($this->getSidebarLink()); ?>" tabindex="-1">
            <?php echo wp_kses($this->getLogo(), Sanitize::$adminTemplateTags); ?>
        </a>
    </div>
    <div class="n2_nav_bar__menu">
        <?php
        foreach ($this->getMenuItems() as $menuItem):
            ?>
            <div class="n2_nav_bar__menuitem<?php echo $menuItem->isActive() ? ' n2_nav_bar__menuitem--active' : ''; ?>"><?php $menuItem->display(); ?></div>
        <?php
        endforeach;
        ?>
    </div>
</div>
Admin/Layout/Block/Core/Header/BlockHeader.php000064400000003501152356646020015047 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header;


use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractBlock;

class BlockHeader extends AbstractBlock {

    protected $heading = '';

    protected $headingAfter = '';

    protected $actions = array();

    /**
     * @var MenuItem[]
     */
    protected $menuItems = array();

    public function display() {

        $this->renderTemplatePart('Header');
    }

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

    /**
     * @param string $heading
     */
    public function setHeading($heading) {
        $this->heading = Sanitize::esc_html($heading);
    }

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

    public function hasHeadingAfter() {
        return !empty($this->headingAfter);
    }

    /**
     * @param string $headingAfter
     */
    public function setHeadingAfter($headingAfter) {
        $this->headingAfter = $headingAfter;
    }

    /**
     * @return array
     */
    public function getActions() {
        return $this->actions;
    }

    public function hasActions() {
        return !empty($this->actions);
    }

    /**
     * @param string $action
     */
    public function addAction($action) {
        $this->actions[] = $action;
    }

    /**
     * @return MenuItem[]
     */
    public function getMenuItems() {
        return $this->menuItems;
    }

    public function hasMenuItems() {
        return !empty($this->menuItems);
    }

    /**
     * @param MenuItem $menuItem
     */
    public function addMenuItem($menuItem) {
        $this->menuItems[] = $menuItem;
    }


}Admin/Layout/Block/Core/Header/Header.php000064400000003125152356646020014076 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header;

use Nextend\Framework\Sanitize;

/**
 * @var $this BlockHeader
 */
?>
<div class="n2_header<?php echo $this->hasMenuItems() ? ' n2_header--has-menu-items' : ''; ?>">
    <div class="n2_header__content">
        <div class="n2_header__heading_container">
            <div class="n2_header__heading">
                <div class="n2_header__heading_primary">
                    <?php
                    echo esc_html($this->getHeading());
                    ?>
                </div>
                <?php
                if ($this->hasHeadingAfter()):
                    ?>
                    <div class="n2_header__heading_after">
                        <?php
                        echo esc_html($this->getHeadingAfter());
                        ?>
                    </div>
                <?php
                endif;
                ?>
            </div>
        </div>
        <?php
        if ($this->hasActions()):
            ?>
            <div class="n2_header__actions">
                <?php
                echo wp_kses(implode('', $this->getActions()), Sanitize::$adminTemplateTags);
                ?>
            </div>
        <?php
        endif;
        ?>
    </div>
    <?php
    if ($this->hasMenuItems()):
        ?>
        <div class="n2_header__menu">
            <?php
            foreach ($this->getMenuItems() as $menuItem) {
                $menuItem->display();
            }
            ?>
        </div>
    <?php
    endif;
    ?>
</div>
Admin/Layout/Block/Core/Header/MenuItem.php000064400000003555152356646020014440 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header;


use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;

class MenuItem {

    protected $isActive = false;

    protected $label = '';

    protected $url = '#';

    protected $classes = array(
        'n2_header__menu_item'
    );

    protected $attributes = array();

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

    public function getHtml() {
        $attributes = $this->attributes;

        if ($this->isActive) {
            $this->classes[] = 'n2_header__menu_item--active';
        }

        if (!empty($this->classes)) {
            $attributes['class'] = implode(' ', array_unique($this->classes));
        }

        return Html::link($this->label, $this->url, $attributes);
    }

    public function display() {
        echo wp_kses($this->getHtml(), Sanitize::$adminTemplateTags);
    }

    /**
     * @return bool
     */
    public function isActive() {
        return $this->isActive;
    }

    /**
     * @param bool $isActive
     */
    public function setActive($isActive) {
        $this->isActive = $isActive;
    }

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

    /**
     * @param string $label
     */
    public function setLabel($label) {
        $this->label = $label;
    }

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

    /**
     * @param string $url
     */
    public function setUrl($url) {
        $this->url = $url;
    }

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

    public function setAttribute($name, $value) {
        $this->attributes[$name] = $value;
    }
}Admin/Layout/Block/Core/ContentSidebar/BlockContentSidebar.php000064400000001552152356646020020303 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\ContentSidebar;


use Nextend\Framework\View\AbstractBlock;

class BlockContentSidebar extends AbstractBlock {

    protected $sidebar = '';

    protected $content = '';

    public function display() {

        $this->renderTemplatePart('ContentSidebar');
    }

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

    /**
     * @param string $sidebar
     */
    public function setSidebar($sidebar) {
        $this->sidebar = $sidebar;
    }

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

    /**
     * @param string $content
     */
    public function setContent($content) {
        $this->content = $content;
    }


}Admin/Layout/Block/Core/ContentSidebar/ContentSidebar.php000064400000001076152356646020017331 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\ContentSidebar;


use Nextend\Framework\Sanitize;

/**
 * @var $this BlockContentSidebar
 */
?>
<div class="n2-admin-content-with-sidebar">
    <div class="n2-admin-content-with-sidebar__sidebar">
        <?php
        echo wp_kses($this->getSidebar(), Sanitize::$adminTemplateTags);
        ?>
    </div>
    <div class="n2-admin-content-with-sidebar__content">
        <?php
        echo wp_kses($this->getContent(), Sanitize::$adminTemplateTags);
        ?>
    </div>
</div>Admin/Layout/Block/Core/BlockBreadCrumb/BreadCrumb.php000064400000001355152356646020016510 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\BlockBreadCrumb;

/**
 * @var $this BlockBreadCrumb
 */
?>

<div class="n2_breadcrumbs">
    <?php
    $breadcrumbs = $this->getBreadCrumbs();
    $length      = count($breadcrumbs);
    foreach ($breadcrumbs as $i => $breadcrumb):
        ?>
        <div class="n2_breadcrumbs__breadcrumb<?php echo $breadcrumb->isActive() ? ' n2_breadcrumbs__breadcrumb--active' : ''; ?>"><?php $breadcrumb->display(); ?></div>
        <?php
        if ($i < $length - 1):
            ?>
            <div class="n2_breadcrumbs__arrow"><i class="ssi_16 ssi_16--breadcrumb"></i></div>
        <?php
        endif;
        ?>
    <?php
    endforeach;
    ?>
</div>
Admin/Layout/Block/Core/BlockBreadCrumb/BlockBreadCrumb.php000064400000002633152356646020017463 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\BlockBreadCrumb;


use Nextend\Framework\View\AbstractBlock;
use Nextend\SmartSlider3\Application\Admin\Layout\Helper\Breadcrumb;

class BlockBreadCrumb extends AbstractBlock {

    /**
     * @var Breadcrumb[]
     */
    protected $breadCrumbs = array();

    public function display() {
        $this->renderTemplatePart('BreadCrumb');
    }

    /**
     * @return Breadcrumb[]
     */
    public function getBreadCrumbs() {

        /**
         * If there is no activate item in the menu or in the breadcrumb, mark the last breadcrumb as active.
         */
        if (!$this->hasActiveItem()) {
            $this->breadCrumbs[count($this->breadCrumbs) - 1]->setIsActive(true);
        }

        return $this->breadCrumbs;
    }

    /**
     * @param        $label
     * @param        $icon
     * @param string $url
     *
     * @return Breadcrumb
     */
    public function addBreadcrumb($label, $icon, $url = '#') {

        $breadCrumb          = new Breadcrumb($label, $icon, $url);
        $this->breadCrumbs[] = $breadCrumb;

        return $breadCrumb;
    }

    private function hasActiveItem() {

        foreach ($this->breadCrumbs as $breadCrumb) {
            if ($breadCrumb->isActive()) {
                return true;
            }
        }

        return false;
    }
}Admin/Layout/Block/Core/Banner/Banner.php000064400000003101152356646020014122 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Banner;

/**
 * @var $this BlockBanner
 */

$closeUrl = $this->getCloseUrl();
?>

<div id="<?php echo esc_attr($this->getID()); ?>" class="n2_admin__banner">
    <div class="n2_admin__banner_inner">
        <img src="<?php echo esc_url($this->getImage()); ?>" alt="">
        <div class="n2_admin__banner_inner_title"><?php echo esc_attr($this->getTitle()); ?></div>
        <div class="n2_admin__banner_inner_description"><?php echo esc_attr($this->getDescription()); ?></div>
        <a class="n2_admin__banner_inner_button n2_button n2_button--big n2_button--green"
           href="<?php echo esc_url($this->getButtonHref()); ?>"
           onclick="<?php echo esc_js($this->getButtonOnclick()); ?>"
           target="_blank">
            <?php echo esc_html($this->getButtonTitle()); ?>
        </a>
    </div>
    <?php if (!empty($closeUrl)): ?>
        <div class="n2_admin__banner_close">
            <i class="ssi_16 ssi_16--remove"></i>
        </div>

        <script>
            _N2.r(['$', 'documentReady'], function () {
                var $ = _N2.$;
                var $banner = $('#<?php echo esc_html($this->getID()); ?>');

                $banner.find('.n2_admin__banner_close').on('click', function (e) {
                    e.preventDefault();

                    _N2.AjaxHelper.ajax({url: <?php echo json_encode(esc_url($closeUrl)); ?>});
                    $banner.remove();
                });
            });
        </script>
    <?php endif; ?>
</div>Admin/Layout/Block/Core/Banner/BlockBanner.php000064400000004710152356646020015104 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Banner;


use Nextend\Framework\View\AbstractBlock;

class BlockBanner extends AbstractBlock {

    protected $id = '';

    protected $image = 'ssi_64 ssi_64--dummy';

    protected $title = '';

    protected $description = '';

    protected $buttonTitle = '';

    protected $buttonHref = '#';

    protected $buttonOnclick = '';

    protected $closeUrl = '';

    public function display() {

        $this->renderTemplatePart('Banner');
    }

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

    /**
     * @param $id
     */
    public function setID($id) {
        $this->id = $id;
    }

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

    /**
     * @param $image
     */
    public function setImage($image) {
        $this->image = $image;
    }

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

    /**
     * @param $title
     */
    public function setTitle($title) {
        $this->title = $title;
    }

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

    /**
     * @param $description
     */
    public function setDescription($description) {
        $this->description = $description;
    }

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

    /**
     * @param $closeUrl
     */
    public function setCloseUrl($closeUrl) {
        $this->closeUrl = $closeUrl;
    }

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

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

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

    /**
     * @param $button
     */
    public function setButton($button) {
        $this->buttonTitle = $button['title'];
        if (isset($button['href'])) {
            $this->buttonHref = $button['href'];
        }
        if (isset($button['onclick'])) {
            $this->buttonOnclick = $button['onclick'];
        }
    }

}Admin/Layout/Block/Core/Banner/BlockBannerActivate.php000064400000001470152356646020016565 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Banner;


use Nextend\Framework\ResourceTranslator\ResourceTranslator;

class BlockBannerActivate extends BlockBanner {

    protected function init() {
        $this->setID('n2-ss-activate-license-banner');
        $this->setImage(ResourceTranslator::toUrl('$ss3-admin$/images/activate.svg'));
        $this->setTitle(n2_('Activate Smart Slider 3 Pro'));
        $this->setDescription(n2_('Activation is required to unlock all features!') . ' ' . n2_('Register Smart Slider 3 Pro on this domain to enable auto update, slider templates and slide library.'));
        $this->setButton(array(
            'title'   => n2_('Activate'),
            'onclick' => '_N2.License.get().startActivation();return false;'
        ));
    }
}Admin/Layout/Block/Core/AdminIframe/AdminIframe.php000064400000001701152356646020016044 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\AdminIframe;


use Nextend\SmartSlider3\Settings;

/**
 * @var $this BlockAdminIframe
 */
if (intval(Settings::get('force-rtl-backend', 0))) {
    ?>
    <script>
        jQuery(document).ready(function () {
            jQuery("html").attr("dir", "rtl");
        });
    </script>
    <?php
}

?>
<div <?php $this->renderAttributes(); ?>>
    <div class="n2_iframe_application__nav_bar">
        <div class="n2_iframe_application__nav_bar_label">
            <?php echo esc_html($this->getLabel()); ?>
        </div>
        <div class="n2_iframe_application__nav_bar_actions">
            <?php
            foreach ($this->getActions() as $action) {
                $action->display();
            }
            ?>
        </div>
    </div>
    <div class="n2_iframe_application__content">
        <?php $this->displayContent(); ?>
    </div>
</div>Admin/Layout/Block/Core/AdminIframe/BlockAdminIframe.php000064400000004336152356646020017026 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\AdminIframe;


use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractBlock;
use Nextend\Framework\View\AbstractLayout;
use Nextend\Framework\View\Html;

class BlockAdminIframe extends AbstractBlock {

    /**
     * @var AbstractLayout
     */
    protected $layout;

    protected $id = 'n2-admin';

    protected $classes = array(
        'n2',
        'n2_admin',
        'n2_admin_ui',
        'n2_iframe_application',
        'fitvidsignore'
    );

    protected $attributes = array();

    protected $label = '';

    /**
     * @var AbstractBlock[]
     */
    protected $actions = array();

    /**
     * @param AbstractLayout $layout
     */
    public function setLayout($layout) {
        $this->layout = $layout;
    }

    public function displayContent() {
        $this->layout->displayContent();
    }

    public function display() {

        $this->renderTemplatePart('AdminIframe');
    }

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

    /**
     * @param string $label
     */
    public function setLabel($label) {
        $this->label = $label;
    }

    /**
     * @return AbstractBlock[]
     */
    public function getActions() {
        return $this->actions;
    }

    /**
     * @param AbstractBlock[] $actions
     */
    public function setActions($actions) {
        $this->actions = $actions;
    }


    /**
     * @return string
     */
    public function getClass() {

        $this->classes = array_unique($this->classes);

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

    /**
     * @param array $classes
     */
    public function addClasses($classes) {
        $this->classes += $classes;
    }

    public function setAttribute($name, $value) {
        $this->attributes[$name] = $value;
    }

    public function renderAttributes() {

        echo wp_kses(Html::renderAttributes($this->attributes + array(
                'id'    => $this->id,
                'class' => implode(' ', $this->classes)
            )), Sanitize::$adminTemplateTags);
    }
}Admin/Layout/Block/Core/AdminError/AdminError.php000064400000001637152356646020015630 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\AdminError;

/**
 * @var $this BlockAdminError
 */
?>
<div style="margin: 20px;width: 500px;border: 2px solid #1D81F9;background-color: #FFFFFF;border-radius: 5px;padding: 40px 50px;">
    <div style="font-size: 18px;line-height: 28px;font-weight: bold;color: #283F4D;">
        <?php
        echo esc_html($this->getTitle());
        ?>
    </div>
    <div style="font-size: 14px;line-height: 24px;color: #325C77;">
        <?php
        echo esc_html($this->getContent());
        ?>
    </div>
    <?php if ($this->hasUrl()): ?>
        <div style="margin-top: 10px;">
            <a href="<?php echo esc_url($this->getUrl()); ?>" target="_blank" style="font-size: 14px;line-height: 24px;color: #1375E9;text-decoration: none;text-transform: capitalize"><?php n2_e('Read more'); ?></a>
        </div>
    <?php endif; ?>
</div>Admin/Layout/Block/Core/AdminError/BlockAdminError.php000064400000002434152356646020016577 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\AdminError;


use Nextend\Framework\View\AbstractBlock;
use Nextend\Framework\View\AbstractLayout;

class BlockAdminError extends AbstractBlock {

    /**
     * @var AbstractLayout
     */
    protected $layout;

    protected $title, $content, $url = '';


    /**
     * @param AbstractLayout $layout
     */
    public function setLayout($layout) {
        $this->layout = $layout;
    }

    public function setError($title, $content, $url = '') {
        $this->title   = $title;
        $this->content = $content;
        $this->url     = $url;
    }

    public function displayContent() {
        $this->layout->displayContent();
    }

    public function display() {

        $this->renderTemplatePart('AdminError');
    }

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

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

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

    /**
     * @return string
     */
    public function getUrl() {
        return $this->url;
    }
}Admin/Layout/Block/Core/AdminEmpty/AdminEmpty.php000064400000000732152356646020015635 0ustar00<?php
namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\AdminEmpty;

use Nextend\SmartSlider3\Settings;

/**
 * @var $this BlockAdminEmpty
 */
if (intval(Settings::get('force-rtl-backend', 0))) {
    ?>
    <script>
        jQuery(document).ready(function () {
            jQuery("html").attr("dir", "rtl");
        });
    </script>
    <?php
}

?>
<div <?php $this->renderAttributes(); ?>>
    <?php $this->displayContent(); ?>
</div>Admin/Layout/Block/Core/AdminEmpty/BlockAdminEmpty.php000064400000002255152356646020016612 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\AdminEmpty;


use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractBlock;
use Nextend\Framework\View\AbstractLayout;
use Nextend\Framework\View\Html;

class BlockAdminEmpty extends AbstractBlock {

    /**
     * @var AbstractLayout
     */
    protected $layout;

    protected $id = 'n2-admin';

    protected $classes = array(
        'n2',
        'n2_admin',
        'n2_admin_ui',
        'n2_admin--empty',
        'fitvidsignore'
    );

    protected $attributes = array();

    /**
     * @param AbstractLayout $layout
     */
    public function setLayout($layout) {
        $this->layout = $layout;
    }

    public function displayContent() {
        $this->layout->displayContent();
    }

    public function display() {

        $this->renderTemplatePart('AdminEmpty');
    }

    public function renderAttributes() {

        echo wp_kses(Html::renderAttributes($this->attributes + array(
                'id'    => $this->id,
                'class' => implode(' ', $this->classes)
            )), Sanitize::$adminTemplateTags);
    }
}Admin/Layout/Block/Core/AdminEditor/AdminEditor.php000064400000001735152356646020016121 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\AdminEditor;

use Nextend\Framework\Notification\Notification;
use Nextend\Framework\Plugin;
use Nextend\SmartSlider3\Settings;
use Nextend\SmartSlider3\SmartSlider3Info;

/**
 * @var $this BlockAdminEditor
 */
SmartSlider3Info::initLicense();

if (intval(Settings::get('force-rtl-backend', 0))) {
    ?>
    <script>
        jQuery(document).ready(function () {
            jQuery("html").attr("dir", "rtl");
        });
    </script>
    <?php
}


?>

    <div <?php $this->renderAttributes(); ?>>

        <?php $this->displayEditorOverlay(); ?>

        <div class="n2_admin_editor__content">
            <div class="n2_admin_editor__content_inner" dir="ltr">

                <?php $this->displayContent(); ?>
            </div>
        </div>
        <?php
        Plugin::doAction('afterApplicationContent');
        ?>
    </div>

    <?php

Notification::show();Admin/Layout/Block/Core/AdminEditor/BlockAdminEditor.php000064400000003364152356646020017074 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\AdminEditor;


use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractBlock;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Slide\EditorOverlay\BlockEditorOverlay;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutEditor;

class BlockAdminEditor extends AbstractBlock {

    /**
     * @var LayoutEditor
     */
    protected $layout;


    protected $id = 'n2-admin';

    protected $classes = array(
        'n2',
        'n2_admin',
        'n2_admin_ui',
        'n2_admin_editor',
        'fitvidsignore'
    );

    protected $attributes = array();

    /**
     * @var BlockEditorOverlay
     */
    protected $editorOverlay;

    /**
     * @param LayoutEditor $layout
     */
    public function setLayout($layout) {
        $this->layout = $layout;
    }

    public function displayContent() {
        $this->layout->displayContent();
    }

    public function display() {

        $this->renderTemplatePart('AdminEditor');
    }

    public function setAttribute($name, $value) {
        $this->attributes[$name] = $value;
    }

    public function renderAttributes() {

        echo wp_kses(Html::renderAttributes($this->attributes + array(
                'id'    => $this->id,
                'class' => implode(' ', $this->classes)
            )), Sanitize::$adminTemplateTags);
    }

    public function displayEditorOverlay() {
        $this->editorOverlay->display();
    }

    /**
     * @param BlockEditorOverlay $editorOverlay
     */
    public function setEditorOverlay($editorOverlay) {
        $this->editorOverlay = $editorOverlay;
    }
}Admin/Layout/Block/Core/Admin/Admin.php000064400000002161152356646020013575 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Admin;

use Nextend\Framework\Notification\Notification;
use Nextend\Framework\Plugin;
use Nextend\Framework\Sanitize;
use Nextend\SmartSlider3\Settings;
use Nextend\SmartSlider3\SmartSlider3Info;

/**
 * @var $this BlockAdmin
 */
SmartSlider3Info::initLicense();

if (intval(Settings::get('force-rtl-backend', 0))) {
    ?>
    <script>
        jQuery(document).ready(function () {
            jQuery("html").attr("dir", "rtl");
        });
    </script>
    <?php
}

?>

    <div <?php $this->renderAttributes(); ?>>
        <div class="n2_admin__header">
            <?php echo wp_kses($this->getHeader(), Sanitize::$adminTemplateTags); ?>
        </div>
        <div class="n2_admin__content">
            <?php echo wp_kses($this->getSubNavigation(), Sanitize::$adminTemplateTags); ?>
            <?php $this->displayTopBar(); ?>

            <?php $this->displayContent(); ?>
        </div>
        <?php
        Plugin::doAction('afterApplicationContent');
        ?>
    </div>

    <?php

Notification::show();Admin/Layout/Block/Core/Admin/BlockAdmin.php000064400000005142152356646020014552 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Admin;


use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractBlock;
use Nextend\Framework\View\AbstractLayout;
use Nextend\Framework\View\Html;

class BlockAdmin extends AbstractBlock {

    /**
     * @var AbstractLayout
     */
    protected $layout;

    protected $id = 'n2-admin';

    protected $classes = array(
        'n2',
        'n2_admin',
        'n2_admin_ui',
        'fitvidsignore'
    );

    protected $attributes = array();

    protected $header = '';

    protected $subNavigation = '';

    /**
     * @var string
     */
    protected $topBar = '';

    /**
     * @param AbstractLayout $layout
     */
    public function setLayout($layout) {
        $this->layout = $layout;
    }

    public function displayContent() {
        $this->layout->displayContent();
    }

    public function display() {

        $this->renderTemplatePart('Admin');
    }

    /**
     * @return string
     */
    public function getClass() {

        $this->classes = array_unique($this->classes);

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

    /**
     * @param array $classes
     */
    public function addClasses($classes) {
        $this->classes += $classes;
    }

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

    /**
     * @param string $header
     */
    public function setHeader($header) {
        $this->header = $header;
    }

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

    /**
     * @param string $subNavigation
     */
    public function setSubNavigation($subNavigation) {
        $this->subNavigation = $subNavigation;
    }

    public function displayTopBar() {
        echo wp_kses($this->topBar, Sanitize::$adminTemplateTags);
    }

    /**
     * @param string $topBar
     */
    public function setTopBar($topBar) {
        $this->topBar = $topBar;
    }

    /**
     * @param string $content
     */
    public function setContent($content) {
        $this->content = $content;
    }

    public function setAttribute($name, $value) {
        $this->attributes[$name] = $value;
    }

    public function renderAttributes() {

        echo wp_kses(Html::renderAttributes($this->attributes + array(
                'id'    => $this->id,
                'class' => implode(' ', $this->classes)
            )), Sanitize::$adminTemplateTags);
    }
}Admin/Layout/Helper/Breadcrumb.php000064400000002722152356646020013063 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Helper;


use Nextend\Framework\Sanitize;

class Breadcrumb {

    protected $label = '';
    protected $icon = '';
    protected $url = '#';

    protected $isActive = false;

    protected $classes = array('n2_breadcrumbs__breadcrumb_button');

    public function __construct($label, $icon, $url = '#') {

        $this->label = $label;
        $this->icon  = $icon;
        $this->url   = $url;
    }

    /**
     * @param bool $isActive
     */
    public function setIsActive($isActive) {
        $this->isActive = $isActive;
    }

    /**
     * @return bool
     */
    public function isActive() {
        return $this->isActive;
    }

    public function display() {
        $html = '';
        if (!empty($this->icon)) {
            $html .= '<i class="' . $this->icon . '"></i>';
        }

        $html .= '<span>' . $this->label . '</span>';

        if ($this->url == '#') {
            echo wp_kses('<div class="' . $this->getClass() . '">' . $html . '</div>', Sanitize::$adminTemplateTags);
        } else {
            echo wp_kses('<a class="' . $this->getClass() . '" href="' . $this->url . '">' . $html . '</a>', Sanitize::$adminTemplateTags);
        }
    }

    protected function getClass() {

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

    public function addClass($className) {
        $this->classes[] = $className;
    }
}Admin/Layout/Helper/MenuItem.php000064400000001066152356646020012540 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Layout\Helper;


use Nextend\Framework\Sanitize;

class MenuItem {

    protected $html = '';

    protected $isActive = false;

    public function __construct($html, $isActive = false) {

        $this->html     = $html;
        $this->isActive = $isActive;
    }

    /**
     * @return bool
     */
    public function isActive() {
        return $this->isActive;
    }

    public function display() {
        echo wp_kses($this->html, Sanitize::$adminTemplateTags);
    }
}Admin/Help/ControllerHelp.php000064400000003673152356646020012153 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Help;


use Nextend\Framework\Api;
use Nextend\Framework\Model\StorageSectionManager;
use Nextend\Framework\Notification\Notification;
use Nextend\SmartSlider3\Application\Admin\AbstractControllerAdmin;
use WP_HTTP_Proxy;

class ControllerHelp extends AbstractControllerAdmin {

    public function actionIndex() {

        $view = new ViewHelpIndex($this);
        $view->display();

    }

    public function actionBrowserIncompatible() {

        $view = new ViewHelpBrowserIncompatible($this);
        $view->display();
    }

    public function actionTestApi() {

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, Api::getApiUrl());

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        $errorFile = dirname(__FILE__) . '/curl_error.txt';
        $out       = fopen($errorFile, "w");
        curl_setopt($ch, CURLOPT_VERBOSE, true);
        curl_setopt($ch, CURLOPT_STDERR, $out);

        $output = curl_exec($ch);

        curl_close($ch);
        fclose($out);
        $log   = array("API Connection Test");
        $log[] = htmlspecialchars(file_get_contents($errorFile));
        unlink($errorFile);

        if (!empty($output)) {
            $log[] = "RESPONSE: " . htmlspecialchars($output);
        }

        if (strpos($output, 'ACTION_MISSING') === false) {
            Notification::error(sprintf(n2_('Unable to connect to the API (%1$s). %2$s See %3$sDebug Information%4$s for more details!'), Api::getApiUrl(), '<br>', '<b>', '</b>'));
        } else {
            Notification::notice(n2_('Successful connection with the API.'));
        }

        $log[] = '------------------------------------------';
        $log[] = '';

        StorageSectionManager::getStorage('smartslider')
                             ->set('log', 'api', json_encode($log));

        $this->redirect($this->getUrlHelp());

    }
}Admin/Help/ViewHelpBrowserIncompatible.php000064400000001735152356646020014632 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Help;

use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutError;

class ViewHelpBrowserIncompatible extends AbstractView {

    public function display() {

        $this->layout = new LayoutError($this);

        $browsers = array(
            sprintf(n2_('%s or later'), 'Chrome 68'),
            sprintf(n2_('%s or later'), 'Firefox 52'),
            sprintf(n2_('%s or later'), 'Safari 10'),
            sprintf(n2_('%s or later'), 'Opera 55'),
            sprintf(n2_('%s or later'), 'Edge 18'),
        );

        $this->layout->setError(n2_('You are using an unsupported browser!'), sprintf(n2_('Smart Slider 3 does not support your current browser for editing. Supported browsers are the following: %s.'), implode(', ', $browsers)), 'https://smartslider.helpscoutdocs.com/article/1716-system-requirements');


        $this->layout->render();
    }
}Admin/Help/ViewHelpIndex.php000064400000010130152356646020011714 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Help;

use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Conflict\Conflict;

class ViewHelpIndex extends AbstractView {

    use TraitAdminUrl;

    /** @var Conflict */
    protected $conflict;

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

        $this->conflict = Conflict::getInstance();
    }

    public function display() {

        $this->layout = new LayoutDefault($this);

        $this->layout->addBreadcrumb(n2_('Help center'), '', $this->getUrlHelp());

        $this->layout->addContent($this->render('Index'));

        $this->layout->render();
    }

    public function getConflicts() {

        return $this->conflict->getConflicts();
    }

    public function getDebugConflicts() {

        return $this->conflict->getDebugConflicts();
    }

    public function getCurlLog() {

        return $this->conflict->getCurlLog();
    }

    /**
     * @return array
     */
    public function getArticles() {
        $arr = array(
            array(
                'url'   => 'https://smartslider.helpscoutdocs.com/article/1718-activation',
                'label' => 'How to activate Smart Slider 3?'
            ),
            array(
                'url'   => 'https://smartslider.helpscoutdocs.com/category/1709-layer-animations-events',
                'label' => 'Layer animation & Event tutorials'
            ),
            array(
                'url'   => 'https://smartslider.helpscoutdocs.com/article/1980-how-to-hide-the-slider-on-mobile',
                'label' => 'How to hide the slider on moble?'
            )
        );
    

        return array_merge($arr, array(
            array(
                'url'   => 'https://smartslider.helpscoutdocs.com/article/1916-slide-editing-in-smart-slider-3#why-is-the-slider-so-tall-on-mobile',
                'label' => 'Why is the slider tall on mobile?'
            ), 
            array(
                'url'   => 'https://smartslider.helpscoutdocs.com/article/1916-slide-editing-in-smart-slider-3',
                'label' => 'Slide editing in Smart Slider 3'
            ),
            array(
                'url'   => 'https://smartslider.helpscoutdocs.com/article/1922-how-to-set-your-background-image#cropped',
                'label' => 'Why are my images cropped?'
            ),
            array(
                'url'   => 'https://smartslider.helpscoutdocs.com/article/1924-how-to-add-a-video',
                'label' => 'How can I add a video?'
            ),
            array(
                'url'   => 'https://smartslider.helpscoutdocs.com/article/1807-slider-settings-autoplay',
                'label' => 'Where is the autoplay?'
            ),
            array(
                'url'   => 'https://smartslider.helpscoutdocs.com/article/1919-video-autoplay-handling',
                'label' => 'Why isn\'t my video autoplaying?'
            ),
            array(
                'url'   => 'https://smartslider.helpscoutdocs.com/article/1925-how-to-speed-up-your-site',
                'label' => 'How can I speed up my site?'
            ),
            array(
                'url'   => 'https://smartslider.helpscoutdocs.com/category/1699-publishing',
                'label' => 'How can I publish my sliders?'
            ),
            array(
                'url'   => 'https://smartslider.helpscoutdocs.com/article/1828-using-your-own-fonts',
                'label' => 'How to use different fonts in the slider?'
            ),
            array(
                'url'   => 'https://smartslider.helpscoutdocs.com/article/1725-dynamic-slide-basics',
                'label' => 'What is a dynamic slide?'
            ),
            array(
                'url'   => 'https://smartslider.helpscoutdocs.com/collection/1712-troubleshooting',
                'label' => 'Troubleshooting'
            )
        ));
    }
}Admin/Help/Template/Index.php000064400000030261152356646020012032 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Help;


use Nextend\Framework\Filesystem\Filesystem;
use Nextend\Framework\Platform\Platform;
use Nextend\Framework\Request\Request;
use Nextend\Framework\Sanitize;
use Nextend\Framework\Url\Url;
use Nextend\SmartSlider3\SmartSlider3Info;

/**
 * @var $this ViewHelpIndex
 */

$conflicts = $this->getConflicts();

?>
<div class="n2_help_center">

    <div class="n2_help_center__getting_started">
        <div class="n2_help_center__getting_started__heading">
            <?php n2_e('Welcome to Help Center'); ?>
        </div>
        <div class="n2_help_center__getting_started__subheading">
            <?php n2_e('To help you get started, we\'ve put together a super tutorial video that shows you the basic settings.'); ?>
        </div>
        <div class="n2_help_center__getting_started__video">
            <div class="n2_help_center__getting_started__video_placeholder"></div>
            <iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/videoseries?list=PLSawiBnEUNfvVeY7M8Yx7UdyOpBEmoH7Z&rel=0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
        </div>
    </div>


    <?php
    if (!empty($conflicts)) {
        ?>
        <div class="n2_help_center__conflicts" id="n2_help_center__possible_conflicts">
            <div class="n2_help_center__conflicts_icon"><i class="ssi_48 ssi_48--bug"></i></div>
            <div class="n2_help_center__conflicts_label"><?php n2_e('Possible conflicts'); ?></div>
            <div class="n2_help_center__conflicts_description">
                <div class="n2_help_center__conflicts_test_api">
                    <a href="<?php echo esc_url($this->getUrlHelpTestApi()); ?>">
                        <?php n2_e('Test connection'); ?>
                    </a>
                </div>
                <?php
                ?>
                <div class="n2_help_center__conflicts_test_api">
                    <a href="<?php echo esc_url($this->getUrlHelpRepairDatabase()); ?>">
                        <?php n2_e('Analyze & repair possible database issues'); ?>
                    </a>
                </div>
                <?php
            
                ?>
                <?php if (empty($conflicts)): ?>
                    <div class="n2_help_center__no_conflicts_detected"><?php n2_e('No conflicts detected.'); ?></div>
                <?php else: ?>
                    <?php foreach ($conflicts as $conflict): ?>
                        <div class="n2_help_center__conflicts_detected"><?php echo wp_kses($conflict, Sanitize::$basicTags); ?></div>
                    <?php endforeach; ?>
                <?php endif; ?>
            </div>
        </div>

        <?php
    }

    ?>


    <div class="n2_help_center__search">

        <div class="n2_help_center__search_heading">
            <?php n2_e('Hello! How can we help you today?'); ?>
        </div>

        <div class="n2_help_center__search_field">
            <form target="_blank" action="https://smartslider.helpscoutdocs.com/search" method="get">
                <input name="query" type="text" placeholder="<?php n2_e('Search in the knowledge base'); ?>">
                <button type="submit"><?php n2_e('Search'); ?></button>
            </form>
        </div>
    </div>

    <div class="n2_help_center__actions">
        <div class="n2_help_center__action">
            <a class="n2_help_center__action_link"
               href="<?php echo esc_url('https://smartslider.helpscoutdocs.com/?utm_campaign=' . SmartSlider3Info::$campaign . '&utm_source=dashboard-documentation&utm_medium=smartslider-' . Platform::getName() . '-' . SmartSlider3Info::$plan); ?>"
               target="_blank"></a>
            <div class="n2_help_center__action_icon"><i class="ssi_48 ssi_48--doc"></i></div>
            <div class="n2_help_center__action_label"><?php n2_e('Documentation'); ?></div>
            <div class="n2_help_center__action_description"><?php n2_e('To get started with Smart Slider 3, please refer to this guide for downloading, installing, and using.'); ?></div>
        </div>
        <div class="n2_help_center__action">
            <a class="n2_help_center__action_link" href="https://smartslider3.com/contact-us/support/"
               onclick="document.getElementById('n2_support_form').submit(); return false;"></a>
            <div class="n2_help_center__action_icon"><i class="ssi_48 ssi_48--help"></i></div>
            <div class="n2_help_center__action_label"><?php n2_e('Email support'); ?></div>
            <div class="n2_help_center__action_description"><?php n2_e('Need one-to-one assistance? Get in touch with our Support team! We\'d love the opportunity to help you.'); ?></div>
        </div>
        <div class="n2_help_center__action">
            <a class="n2_help_center__action_link"
               href="<?php echo esc_url('https://www.youtube.com/watch?v=3PPtkRU7D74&list=PLSawiBnEUNfvVeY7M8Yx7UdyOpBEmoH7Z&utm_campaign=' . SmartSlider3Info::$campaign . '&utm_source=dashboard-watch-videos&utm_medium=smartslider-' . Platform::getName() . '-' . SmartSlider3Info::$plan); ?>"
               target="_blank"></a>
            <div class="n2_help_center__action_icon"><i class="ssi_48 ssi_48--camera"></i></div>
            <div class="n2_help_center__action_label"><?php n2_e('Tutorial videos'); ?></div>
            <div class="n2_help_center__action_description"><?php n2_e('Check our video tutorials which cover everything you need to know about Smart Slider 3.'); ?></div>
        </div>
    </div>

    <div class="n2_help_center__articles_heading">
        <?php n2_e('Selected articles'); ?>
    </div>

    <div class="n2_help_center__articles">
        <?php
        foreach ($this->getArticles() as $article) {
            ?>
            <div class="n2_help_center__article">
                <a class="n2_help_center__article_link" href="<?php echo esc_url($article['url']); ?>" target="_blank"></a>
                <div class="n2_help_center__article_label"><?php echo esc_html($article['label']); ?></div>
                <i class="ssi_16 ssi_16--breadcrumb n2_help_center__article_icon"></i>
            </div>
            <?php
        }
        ?>
    </div>


    <?php
    if (empty($conflicts)) {
        ?>
        <div class="n2_help_center__conflicts" id="n2_help_center__possible_conflicts">
            <div class="n2_help_center__conflicts_icon"><i class="ssi_48 ssi_48--bug"></i></div>
            <div class="n2_help_center__conflicts_label"><?php n2_e('Possible conflicts'); ?></div>
            <div class="n2_help_center__conflicts_description">
                <div class="n2_help_center__conflicts_test_api">
                    <a href="<?php echo esc_url($this->getUrlHelpTestApi()); ?>">
                        <?php n2_e('Test connection'); ?>
                    </a>
                </div>
                <?php
                ?>
                <div class="n2_help_center__conflicts_test_api">
                    <a href="<?php echo esc_url($this->getUrlHelpRepairDatabase()); ?>">
                        <?php n2_e('Analyze & repair possible database issues'); ?>
                    </a>
                </div>
                <?php
            
                ?>

                <?php if (empty($conflicts)): ?>
                    <div class="n2_help_center__no_conflicts_detected"><?php n2_e('No conflicts detected.'); ?></div>
                <?php else: ?>
                    <?php foreach ($conflicts as $conflict): ?>
                        <div class="n2_help_center__conflicts_detected"><?php echo wp_kses($conflict, Sanitize::$basicTags); ?></div>
                    <?php endforeach; ?>
                <?php endif; ?>
            </div>
        </div>

        <?php
    }

    ?>


    <?php
    ?>

    <div class="n2_help_center__system_information">

        <div class="n2_help_center__system_information_label">
            <?php n2_e('Debug information'); ?>
        </div>

        <form id="n2_support_form" class="n2_help_center__system_information_form" method="post"
              action="https://smartslider3.com/contact-us/support/" target="_blank">
            <?php
            $debug = array(
                'Smart Slider 3 - version: ' . SmartSlider3Info::$completeVersion,
                'Plan: ' . SmartSlider3Info::$plan,
                'Platform: ' . Platform::getLabel() . ' - ' . Platform::getVersion(),
                'Site url: ' . Platform::getSiteUrl(),
                'Path: ' . Filesystem::getBasePath(),
                'Uri: ' . Url::getBaseUri(),
                'Browser: ' . Request::$SERVER->getVar('HTTP_USER_AGENT'),
                ''
            );

            $curlLog = $this->getCurlLog();
            if (!empty($curlLog)) {
                $debug   = array_merge($debug, $curlLog);
                $debug[] = '';
            }

            if (function_exists('ini_get')) {
                $debug[] = 'PHP: ' . phpversion();
                $debug[] = 'PHP - memory_limit: ' . ini_get('memory_limit');
                $debug[] = 'PHP - max_input_vars: ' . ini_get('max_input_vars');

                $opcache = ini_get('opcache.enable');
                $debug[] = 'PHP - opcache.enable: ' . intval($opcache);

                if ($opcache) {
                    $debug[] = 'PHP - opcache.revalidate_freq: ' . ini_get('opcache.revalidate_freq');
                }

                $debug[] = '';
            }

            if (extension_loaded('gd')) {
                $debug[] = 'GD modules status:';
                foreach (gd_info() as $module => $status) {
                    $debug[] = $module . ' : ' . (!empty($status) ? $status : "0");
                }
            }
            $debug[] = '';

            if (function_exists('get_loaded_extensions')) {

                $debug[] = 'Uncommon PHP extensions:';

                $debug[] = implode(" \t", array_diff(get_loaded_extensions(), array(
                    'Core',
                    'openssl',
                    'pcre',
                    'zlib',
                    'SPL',
                    'session',
                    'standard',
                    'cgi-fcgi',
                    'mysqlnd',
                    'PDO',
                    'bz2',
                    'calendar',
                    'filter',
                    'hash',
                    'Reflection',
                    'zip',
                    'Zend OPcache',
                    'shmop',
                    'sodium',
                    'date',
                    'dom',
                    'ctype',
                    'xml',
                    'libxml',
                    'fileinfo',
                    'ftp',
                    'gettext',
                    'iconv',
                    'intl',
                    'json',
                    'exif',
                    'mysqli',
                    'pdo_mysql',
                    'Phar',
                    'posix',
                    'readline',
                    'SimpleXML',
                    'soap',
                    'sockets',
                    'sysvmsg',
                    'sysvsem',
                    'sysvshm',
                    'tokenizer',
                    'wddx',
                    'xmlreader',
                    'xmlwriter',
                    'xsl'
                )));

                $debug[] = '';
            }


            $debugConflicts = $this->getDebugConflicts();
            if (empty($debugConflicts)) {
                $debug[] = 'No conflicts detected';
            } else {
                $debug[] = 'Conflicts:';
                foreach ($debugConflicts as $conflict) {
                    $debug[] = ' - ' . $conflict;
                }
                $debug[] = '';
            }

            $debug = array_merge($debug, Platform::getDebug());

            ?>
            <textarea readonly name="debug_information"
                      style="width:100%;height:800px;"><?php echo esc_html(implode("\n", $debug)); ?></textarea>
        </form>
    </div>
</div>
Admin/Generator/ControllerAjaxGenerator.php000064400000017311152356646020015045 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Generator;


use Exception;
use Nextend\Framework\Controller\Admin\AdminAjaxController;
use Nextend\Framework\Data\Data;
use Nextend\Framework\Notification\Notification;
use Nextend\Framework\Request\Request;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Application\Helper\HelperSliderChanged;
use Nextend\SmartSlider3\Application\Model\ModelGenerator;
use Nextend\SmartSlider3\Application\Model\ModelSlides;

class ControllerAjaxGenerator extends AdminAjaxController {

    use TraitAdminUrl;

    public function actionCheckConfiguration() {
        $this->validateToken();

        $this->validatePermission('smartslider_config');

        $group = Request::$REQUEST->getVar('group');
        $this->validateVariable($group, 'group');

        $sliderID = Request::$REQUEST->getVar('sliderid');
        $this->validateVariable($sliderID, 'sliderid');

        $groupID = Request::$REQUEST->getInt('groupID');

        $generatorModel = new ModelGenerator($this);

        $generatorGroup = $generatorModel->getGeneratorGroup($group);

        $configuration = $generatorGroup->getConfiguration();
        $configuration->addData(Request::$POST->getVar('generator'));

        if ($configuration->wellConfigured()) {
            $this->redirect($this->getUrlGeneratorCreateStep2($group, $sliderID, $groupID));
        } else {
            $this->response->redirect($this->getUrlGeneratorCheckConfiguration($group, $sliderID, $groupID));
        }
    }

    public function actionCreateSettings() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $group = Request::$REQUEST->getVar('group');
        $this->validateVariable($group, 'group');

        $type = Request::$REQUEST->getVar('type');
        $this->validateVariable($type, 'type');

        $sliderID = Request::$REQUEST->getVar('sliderid');
        $this->validateVariable($sliderID, 'sliderid');

        $groupID = Request::$REQUEST->getInt('groupID');

        $generatorModel = new ModelGenerator($this);
        $result         = $generatorModel->createGenerator($sliderID, Request::$REQUEST->getVar('generator'));

        Notification::success(n2_('Generator created.'));

        $this->response->redirect($this->getUrlSlideEdit($result['slideId'], $sliderID, $groupID));
    }

    public function actionEdit() {
        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $generatorId = Request::$REQUEST->getInt('generator_id');
        $this->validateVariable($generatorId, 'generatorId');

        $groupID = Request::$REQUEST->getInt('groupID');

        $generatorModel = new ModelGenerator($this);
        $generator      = $generatorModel->get($generatorId);
        $this->validateDatabase($generator);

        $slidesModel = new ModelSlides($this);
        $slides      = $slidesModel->getAll(-1, 'OR generator_id = ' . $generator['id'] . '');
        if (count($slides) > 0) {
            $slide = $slides[0];

            $request = new Data(Request::$REQUEST->getVar('generator'));

            $slideParams = new Data($slide['params'], true);
            $slideParams->set('record-slides', $request->get('record-slides', 1));
            $slidesModel->updateSlideParams($slide['id'], $slideParams->toArray());

            $request->un_set('record-slides');
            $generatorModel->save($generatorId, $request->toArray());

            $helper = new HelperSliderChanged($this);
            $helper->setSliderChanged($slide['slider'], 1);

            Notification::success(n2_('Generator updated and cache cleared.'));

            $this->response->respond();
        }
    }

    public function actionRecordsTable() {

        $this->validateToken();

        $this->validatePermission('smartslider_edit');

        $generatorID = Request::$REQUEST->getInt('generator_id');

        $generatorModel = new ModelGenerator($this);

        if ($generatorID > 0) {
            $generator = $generatorModel->get($generatorID);

            $this->validateDatabase($generator);
        } else {
            $info      = new Data(Request::$REQUEST->getVar('generator'));
            $generator = array(
                'group'  => $info->get('group'),
                'type'   => $info->get('type'),
                'params' => '{}'
            );
        }

        $generatorGroup = $generatorModel->getGeneratorGroup($generator['group']);

        if (!$generatorGroup) {
            Notification::notice(n2_('Generator group not found'));
            $this->response->error();
        }

        $generatorSource = $generatorGroup->getSource($generator['type']);

        if (!$generatorSource) {
            Notification::notice(n2_('Generator source not found'));
            $this->response->error();
        }

        $generator['params'] = new Data($generator['params'], true);

        $generator['params']->loadArray(Request::$REQUEST->getVar('generator'));

        $generatorSource->setData($generator['params']);

        $request = new Data(Request::$REQUEST->getVar('generator'));

        $group = max(intval($request->get('record-group', 1)), 1);

        $result = $generatorSource->getData(max($request->get('record-slides', 1), 1), max($request->get('record-start', 1), 1), $group);

        if (empty($result)) {
            Notification::notice(n2_('No records found for the filter'));
            $this->response->respond(null);

        }

        $view = new ViewAjaxGeneratorRecordsTable($this);
        $view->setRecordGroup($group);
        $view->setRecords($result);

        $this->response->respond($view->display());
    }

    public function actionGetAuthUrl() {
        $this->validateToken();
        $this->validatePermission('smartslider_config');
        $group = Request::$REQUEST->getVar('group');

        $generatorModel = new ModelGenerator($this);

        $generatorGroup = $generatorModel->getGeneratorGroup($group);

        try {
            $configuration = $generatorGroup->getConfiguration();
            $this->response->respond(array('authUrl' => $configuration->startAuth($this)));
        } catch (Exception $e) {
            Notification::error($e->getMessage());
            $this->response->error();
        }
    }

    public function actionGetRefresh() {
        $this->validateToken();
        $this->validatePermission('smartslider_config');
        $group = Request::$REQUEST->getVar('group');

        $generatorModel = new ModelGenerator($this);

        $generatorGroup = $generatorModel->getGeneratorGroup($group);

        try {
            $configuration = $generatorGroup->getConfiguration();
            $this->response->respond(array('authUrl' => $configuration->refreshToken($this)));
        } catch (Exception $e) {
            Notification::error($e->getMessage());
            $this->response->error();
        }
    }

    public function actionGetData() {
        $this->validateToken();
        $this->validatePermission('smartslider_edit');

        $group = Request::$REQUEST->getVar('group');

        $generatorModel = new ModelGenerator($this);

        $generatorGroup = $generatorModel->getGeneratorGroup($group);

        try {
            $configuration = $generatorGroup->getConfiguration();
            $this->response->respond(call_user_func(array(
                $configuration,
                Request::$REQUEST->getCmd('method')
            )));
        } catch (Exception $e) {
            Notification::error($e->getMessage());
            $this->response->error();
        }
    }
}Admin/Generator/ControllerGenerator.php000064400000021124152356646020014236 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Generator;


use Exception;
use Nextend\Framework\Notification\Notification;
use Nextend\Framework\PageFlow;
use Nextend\Framework\Request\Request;
use Nextend\SmartSlider3\Application\Admin\AbstractControllerAdmin;
use Nextend\SmartSlider3\Application\Model\ModelGenerator;
use Nextend\SmartSlider3\Application\Model\ModelSliders;
use Nextend\SmartSlider3\Application\Model\ModelSlides;
use Nextend\SmartSlider3\Generator\GeneratorFactory;

class ControllerGenerator extends AbstractControllerAdmin {

    public function actionCreate() {
        if ($this->validatePermission('smartslider_edit')) {

            $sliderID     = Request::$REQUEST->getInt("sliderid", 0);
            $slidersModel = new ModelSliders($this);
            $slider       = $slidersModel->get($sliderID);
            if ($this->validateDatabase($slider)) {

                $groupData = $this->getGroupData($sliderID);

                $view = new ViewGeneratorCreateStep1Groups($this);
                $view->setGroupData($groupData['group_id'], $groupData['title']);
                $view->setSlider($slider);
                $view->display();
            }
        }
    }

    public function actionCreateStep2() {
        if ($this->validatePermission('smartslider_edit')) {

            $sliderID     = Request::$REQUEST->getInt("sliderid", 0);
            $slidersModel = new ModelSliders($this);
            $slider       = $slidersModel->get($sliderID);
            if ($this->validateDatabase($slider)) {

                $groupData = $this->getGroupData($sliderID);

                $generatorGroup = GeneratorFactory::getGenerator(Request::$REQUEST->getCmd('group'));
                if (!$generatorGroup) {
                    $this->redirect($this->getUrlGeneratorCreate($sliderID, $groupData['group_id']));
                }

                $sources = $generatorGroup->getSources();
                if (empty($sources)) {
                    Notification::error($generatorGroup->getError());
                    $this->redirect($this->getUrlGeneratorCreate($sliderID, $groupData['group_id']));
                }

                if (count($sources) == 1) {

                    /**
                     * There is only one source in this generator. Skip to the next step.
                     */
                    reset($sources);

                    $this->redirect($this->getUrlGeneratorCreateSettings($generatorGroup->getName(), $sources[key($sources)]->getName(), $sliderID, $groupData['group_id']));
                }

                $view = new ViewGeneratorCreateStep3Sources($this);
                $view->setGroupData($groupData['group_id'], $groupData['title']);
                $view->setSlider($slider);
                $view->setGeneratorGroup($generatorGroup);

                $view->display();
            }
        }
    }

    public function actionEdit() {
        if ($this->validatePermission('smartslider_edit')) {

            $generatorId = Request::$REQUEST->getInt('generator_id');

            $generatorModel = new ModelGenerator($this);
            $generator      = $generatorModel->get($generatorId);
            if ($this->validateDatabase($generator)) {

                Request::$REQUEST->set('group', $generator['group']);
                Request::$REQUEST->set('type', $generator['type']);

                $slidesModel = new ModelSlides($this);
                $slides      = $slidesModel->getAll(-1, 'OR generator_id = ' . $generator['id'] . '');
                if (count($slides) > 0) {
                    $slide = $slides[0];

                    Request::$REQUEST->set('sliderid', $slide['slider']);

                    $slidersModel = new ModelSliders($this);
                    $slider       = $slidersModel->get($slide['slider']);

                    $groupData = $this->getGroupData($slider['id']);

                    $group = $generator['group'];
                    $type  = $generator['type'];

                    $generatorGroup = $generatorModel->getGeneratorGroup($group);
                    if (!$generatorGroup) {
                        $this->redirect($this->getUrlSlideEdit($slide['id'], $slider['id'], $groupData['group_id']));
                    }

                    $generatorSource = $generatorGroup->getSource($type);
                    if (!$generatorSource) {
                        $this->redirect($this->getUrlSlideEdit($slide['id'], $slider['id'], $groupData['group_id']));
                    }

                    $view = new ViewGeneratorEdit($this);
                    $view->setGroupData($groupData['group_id'], $groupData['title']);
                    $view->setSlider($slider);
                    $view->setSlide($slide);
                    $view->setGenerator($generator);
                    $view->setGeneratorGroup($generatorGroup);
                    $view->setGeneratorSource($generatorSource);

                    $view->display();

                } else {
                    $this->redirect($this->getUrlDashboard());
                }
            } else {
                $this->redirect($this->getUrlDashboard());

            }
        }
    }

    public function actionCreateSettings() {
        if ($this->validatePermission('smartslider_edit')) {

            $slidersModel = new ModelSliders($this);
            $sliderID     = Request::$REQUEST->getInt('sliderid');

            if (!($slider = $slidersModel->get($sliderID))) {
                $this->redirectToSliders();
            }

            $groupData = $this->getGroupData($slider['id']);

            $generatorGroup = GeneratorFactory::getGenerator(Request::$REQUEST->getCmd('group'));
            $source         = $generatorGroup->getSource(Request::$REQUEST->getVar('type'));
            if ($source) {

                $view = new ViewGeneratorCreateStep4Settings($this);

                $view->setGroupData($groupData['group_id'], $groupData['title']);
                $view->setSlider($slider);
                $view->setGeneratorGroup($generatorGroup);
                $view->setGeneratorSource($source);

                $view->display();

            } else {

                $this->redirect($this->getUrlSliderEdit($slider['id'], $groupData['group_id']));
            }
        }
    }

    public function actionCheckConfiguration() {
        if ($this->validatePermission('smartslider_config') && $this->validatePermission('smartslider_edit')) {

            $group = Request::$REQUEST->getVar('group');

            $generatorGroup = GeneratorFactory::getGenerator($group);

            $configuration = $generatorGroup->getConfiguration();

            $slidersModel = new ModelSliders($this);
            $sliderID     = Request::$REQUEST->getInt('sliderid');
            if (!($slider = $slidersModel->get($sliderID))) {
                $this->redirectToSliders();
            }

            $groupData = $this->getGroupData($sliderID);

            if ($configuration->wellConfigured()) {
                $this->redirect($this->getUrlGeneratorCreateStep2($group, $sliderID, $groupData['group_id']));
            }

            $view = new ViewGeneratorCreateStep2Configure($this);
            $view->setGroupData($groupData['group_id'], $groupData['title']);
            $view->setSlider($slider);
            $view->setGeneratorGroup($generatorGroup);
            $view->setConfiguration($configuration);

            $view->display();


        }
    }

    public function actionFinishAuth() {
        if ($this->validatePermission('smartslider_config')) {

            $generatorModel = new ModelGenerator($this);

            $group = Request::$REQUEST->getVar('group');

            $generatorGroup = $generatorModel->getGeneratorGroup($group);

            $configuration = $generatorGroup->getConfiguration();
            $result        = $configuration->finishAuth($this);
            if ($result === true) {
                Notification::success(n2_('Authentication successful.'));
                echo '<script>window.opener.location.reload();self.close();</script>';
            } else {
                if ($result instanceof Exception) {
                    $message = $result->getMessage();
                } else {
                    $message = 'Something wrong with the credentials';
                }
                echo '<script>window.opener._N2.Notification.error("' . esc_html($message) . '");self.close();</script>';
            }
            PageFlow::exitApplication();
        }
    }
}Admin/Generator/ViewAjaxGeneratorRecordsTable.php000064400000003555152356646020016133 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Generator;


use Nextend\Framework\View\AbstractViewAjax;

class ViewAjaxGeneratorRecordsTable extends AbstractViewAjax {

    /** @var integer */
    protected $recordGroup = 1;

    /** @var array */
    protected $records;

    public function display() {
        $records = $this->getRecords();

        $headings = array();

        for ($currentGroupIndex = 1; $currentGroupIndex <= $this->getRecordGroup(); $currentGroupIndex++) {
            $headings[] = '#';
            foreach ($records[0][0] as $recordKey => $v) {
                $headings[] = '{' . $recordKey . '/' . $currentGroupIndex . '}';
            }
        }

        $rows = array();

        $i = 0;
        foreach ($records as $recordGroup) {
            foreach ($recordGroup as $record) {
                $rows[$i][] = $i + 1;
                foreach ($record as $recordValue) {
                    if ($recordValue === null) {
                        $rows[$i][] = '';
                    } else {
                        $rows[$i][] = htmlspecialchars($recordValue, ENT_QUOTES, "UTF-8");
                    }
                }
            }
            $i++;
        }

        return array(
            'headings' => $headings,
            'rows'     => $rows
        );
    }

    /**
     * @return int
     */
    public function getRecordGroup() {
        return $this->recordGroup;
    }

    /**
     * @param int $recordGroup
     */
    public function setRecordGroup($recordGroup) {
        $this->recordGroup = $recordGroup;
    }

    /**
     * @return array
     */
    public function getRecords() {
        return $this->records;
    }

    /**
     * @param array $records
     */
    public function setRecords($records) {
        $this->records = $records;
    }
}Admin/Generator/ViewGeneratorCreateStep1Groups.php000064400000004327152356646020016274 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Generator;


use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header\BlockHeader;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Generator\AbstractGeneratorGroup;
use Nextend\SmartSlider3\Generator\GeneratorFactory;

class ViewGeneratorCreateStep1Groups extends AbstractView {

    use TraitAdminUrl;

    protected $groupID = 0;

    protected $groupTitle = '';

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

    public function display() {

        $this->layout = new LayoutDefault($this);

        if ($this->groupID) {
            $this->layout->addBreadcrumb(Sanitize::esc_html($this->groupTitle), 'ssi_16 ssi_16--folderclosed', $this->getUrlSliderEdit($this->groupID));
        }

        $this->layout->addBreadcrumb(Sanitize::esc_html($this->slider['title']), 'ssi_16 ssi_16--image', $this->getUrlSliderEdit($this->slider['id'], $this->groupID));

        $this->layout->addBreadcrumb(n2_('Add dynamic slides'), '');

        $blockHeader = new BlockHeader($this);
        $blockHeader->setHeading(n2_('Add dynamic slides'));

        $this->layout->addContentBlock($blockHeader);

        $this->layout->addContent($this->render('CreateStep1Groups'));

        $this->layout->render();
    }

    /**
     * @param int    $groupID
     * @param string $groupTitle
     */
    public function setGroupData($groupID, $groupTitle) {
        $this->groupID    = $groupID;
        $this->groupTitle = $groupTitle;
    }

    /**
     * @return array
     */
    public function getSlider() {
        return $this->slider;
    }

    /**
     * @param array $slider
     */
    public function setSlider($slider) {
        $this->slider = $slider;
    }

    /**
     * @return integer
     */
    public function getSliderID() {
        return $this->slider['id'];
    }

    /**
     * @return AbstractGeneratorGroup[]
     */
    public function getGeneratorGroups() {

        return GeneratorFactory::getGenerators();
    }

}Admin/Generator/ViewGeneratorCreateStep2Configure.php000064400000010472152356646020016735 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Generator;

use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header\BlockHeader;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain\BlockTopBarMain;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonCancel;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonSave;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Generator\AbstractGeneratorGroup;
use Nextend\SmartSlider3\Generator\AbstractGeneratorGroupConfiguration;

class ViewGeneratorCreateStep2Configure extends AbstractView {

    use TraitAdminUrl;

    protected $active = 'general';

    /** @var LayoutDefault */
    protected $layout;

    /**
     * @var BlockHeader
     */
    protected $blockHeader;

    protected $groupID;

    protected $groupTitle;

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

    /** @var AbstractGeneratorGroup */
    protected $generatorGroup;

    /** @var AbstractGeneratorGroupConfiguration */
    protected $configuration;

    /**
     * @param int    $groupID
     * @param string $groupTitle
     */
    public function setGroupData($groupID, $groupTitle) {
        $this->groupID    = $groupID;
        $this->groupTitle = $groupTitle;
    }

    /**
     * @return array
     */
    public function getSlider() {
        return $this->slider;
    }

    /**
     * @param array $slider
     */
    public function setSlider($slider) {
        $this->slider = $slider;
    }

    public function hasSlider() {

        return !is_null($this->slider);
    }

    public function getSliderID() {

        return $this->slider['id'];
    }

    /**
     * @return mixed
     */
    public function getGroupID() {
        return $this->groupID;
    }

    /**
     * @return AbstractGeneratorGroup
     */
    public function getGeneratorGroup() {
        return $this->generatorGroup;
    }

    /**
     * @param AbstractGeneratorGroup $generatorGroup
     */
    public function setGeneratorGroup($generatorGroup) {
        $this->generatorGroup = $generatorGroup;
    }

    /**
     * @return mixed
     */
    public function getConfiguration() {
        return $this->configuration;
    }

    /**
     * @param mixed $configuration
     */
    public function setConfiguration($configuration) {
        $this->configuration = $configuration;
    }

    public function renderForm() {

        $this->configuration->render($this);
    }

    public function display() {

        $this->layout = new LayoutDefault($this);

        if ($this->groupID) {
            $this->layout->addBreadcrumb(Sanitize::esc_html($this->groupTitle), 'ssi_16 ssi_16--folderclosed', $this->getUrlSliderEdit($this->groupID));
        }

        $this->layout->addBreadcrumb(Sanitize::esc_html($this->slider['title']), 'ssi_16 ssi_16--image', $this->getUrlSliderEdit($this->slider['id'], $this->groupID));

        $this->layout->addBreadcrumb(n2_('Add dynamic slides'), '', $this->getUrlGeneratorCreate($this->slider['id'], $this->groupID));


        $this->layout->addBreadcrumb(n2_('Configure') . ' - ' . $this->generatorGroup->getLabel(), '');


        $topBar = new BlockTopBarMain($this);

        $buttonSave = new BlockButtonSave($this);
        $buttonSave->addClass('n2_button--inactive');
        $buttonSave->addClass('n2_generator_configuration_save');
        $topBar->addPrimaryBlock($buttonSave);

        $buttonCancel = new BlockButtonCancel($this);
        $buttonCancel->addClass('n2_generator_configuration_cancel');
        $buttonCancel->setUrl($this->getUrlGeneratorCreate($this->slider['id'], $this->groupID));
        $topBar->addPrimaryBlock($buttonCancel);

        $this->layout->setTopBar($topBar->toHTML());

        $blockHeader = new BlockHeader($this);
        $blockHeader->setHeading(n2_('Configure') . ': ' . $this->generatorGroup->getLabel());

        $this->layout->addContentBlock($blockHeader);

        $this->layout->addContent($this->render('CreateStep2Configure'));

        $this->layout->render();
    }
}Admin/Generator/ViewGeneratorCreateStep3Sources.php000064400000005127152356646020016441 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Generator;


use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header\BlockHeader;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Generator\AbstractGeneratorGroup;

class ViewGeneratorCreateStep3Sources extends AbstractView {

    use TraitAdminUrl;

    protected $groupID = 0;

    protected $groupTitle = '';

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

    /** @var AbstractGeneratorGroup */
    protected $generatorGroup;

    public function display() {

        $this->layout = new LayoutDefault($this);

        if ($this->groupID) {
            $this->layout->addBreadcrumb(Sanitize::esc_html($this->groupTitle), 'ssi_16 ssi_16--folderclosed', $this->getUrlSliderEdit($this->groupID));
        }

        $this->layout->addBreadcrumb(Sanitize::esc_html($this->slider['title']), 'ssi_16 ssi_16--image', $this->getUrlSliderEdit($this->slider['id'], $this->groupID));

        $this->layout->addBreadcrumb(n2_('Add dynamic slides'), '', $this->getUrlGeneratorCreate($this->slider['id'], $this->groupID));

        $this->layout->addBreadcrumb($this->generatorGroup->getLabel(), '');


        $blockHeader = new BlockHeader($this);
        $blockHeader->setHeading(n2_('Add dynamic slides') . ': ' . $this->generatorGroup->getLabel());

        $this->layout->addContentBlock($blockHeader);

        $this->layout->addContent($this->render('CreateStep3Sources'));

        $this->layout->render();
    }

    /**
     * @param int    $groupID
     * @param string $groupTitle
     */
    public function setGroupData($groupID, $groupTitle) {
        $this->groupID    = $groupID;
        $this->groupTitle = $groupTitle;
    }

    /**
     * @return array
     */
    public function getSlider() {
        return $this->slider;
    }

    /**
     * @param array $slider
     */
    public function setSlider($slider) {
        $this->slider = $slider;
    }

    /**
     * @return int
     */
    public function getSliderID() {
        return $this->slider['id'];
    }

    /**
     * @return AbstractGeneratorGroup
     */
    public function getGeneratorGroup() {
        return $this->generatorGroup;
    }

    /**
     * @param AbstractGeneratorGroup $generatorGroup
     */
    public function setGeneratorGroup($generatorGroup) {
        $this->generatorGroup = $generatorGroup;
    }


}Admin/Generator/ViewGeneratorEdit.php000064400000013736152356646020013645 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Generator;


use Nextend\Framework\Data\Data;
use Nextend\Framework\Form\Element\Token;
use Nextend\Framework\Form\Form;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header\BlockHeader;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain\BlockTopBarMain;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonBack;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonPlainIcon;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonSave;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Application\Model\ModelGenerator;
use Nextend\SmartSlider3\Generator\AbstractGenerator;
use Nextend\SmartSlider3\Generator\AbstractGeneratorGroup;

class ViewGeneratorEdit extends AbstractView {

    use TraitAdminUrl;

    protected $groupID;

    protected $groupTitle;

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

    /** @var array */
    protected $slide;

    /** @var array */
    protected $generator;

    /** @var AbstractGeneratorGroup */
    protected $generatorGroup;

    /** @var AbstractGenerator */
    protected $generatorSource;

    public function display() {

        $this->layout = new LayoutDefault($this);

        if ($this->groupID) {
            $this->layout->addBreadcrumb(Sanitize::esc_html($this->groupTitle), 'ssi_16 ssi_16--folderclosed', $this->getUrlSliderEdit($this->groupID));
        }

        $this->layout->addBreadcrumb(Sanitize::esc_html($this->slider['title']), 'ssi_16 ssi_16--image', $this->getUrlSliderEdit($this->getSliderID(), $this->groupID));

        $this->layout->addBreadcrumb(n2_('Slide'), 'ssi_16 ssi_16--slides', $this->getUrlSlideEdit($this->slide['id'], $this->getSliderID(), $this->groupID));

        $this->layout->addBreadcrumb(n2_('Generator'), 'ssi_16 ssi_16--cog');

        $topBar = new BlockTopBarMain($this);

        $buttonSave = new BlockButtonSave($this);
        $buttonSave->addClass('n2_button--inactive');
        $buttonSave->addClass('n2_generator_settings_save');
        $topBar->addPrimaryBlock($buttonSave);

        $buttonBack = new BlockButtonBack($this);
        $buttonBack->setUrl($this->getUrlSlideEdit($this->slide['id'], $this->getSliderID(), $this->groupID));
        $buttonBack->addClass('n2_generator_settings_back');
        $topBar->addPrimaryBlock($buttonBack);

        $buttonPreview = new BlockButtonPlainIcon($this);
        $buttonPreview->addAttribute('id', 'n2-ss-preview');
        $buttonPreview->addClass('n2_top_bar_button_icon');
        $buttonPreview->addClass('n2_top_bar_main__preview');
        $buttonPreview->setIcon('ssi_24 ssi_24--preview');
        $buttonPreview->addAttribute('data-n2tip', n2_('Preview'));
        $buttonPreview->setUrl($this->getUrlPreviewIndex($this->slider['id']));
        $topBar->addPrimaryBlock($buttonPreview);

        $this->layout->setTopBar($topBar->toHTML());

        $blockHeader = new BlockHeader($this);
        $blockHeader->setHeading(n2_('Generator') . ': ' . $this->generatorGroup->getLabel() . ' - ' . $this->generatorSource->getLabel());

        $this->layout->addContentBlock($blockHeader);

        $this->layout->addContent($this->render('Edit'));

        $this->layout->render();
    }

    public function renderForm() {

        $params = new Data($this->generator['params'], true);

        $slideParams = new Data($this->slide['params'], true);
        $params->set('record-slides', $slideParams->get('record-slides', 1));

        $form = new Form($this, 'generator');
        new Token($form->getFieldsetHidden());

        $form->loadArray($params->toArray());

        $this->generatorSource->renderFields($form->getContainer());

        $generatorModel = new ModelGenerator($this);
        $generatorModel->renderFields($form->getContainer());

        $form->render();
    }

    /**
     * @param int    $groupID
     * @param string $groupTitle
     */
    public function setGroupData($groupID, $groupTitle) {
        $this->groupID    = $groupID;
        $this->groupTitle = $groupTitle;
    }

    /**
     * @return array
     */
    public function getSlider() {
        return $this->slider;
    }

    /**
     * @param array $slider
     */
    public function setSlider($slider) {
        $this->slider = $slider;
    }

    /**
     * @return integer
     */
    public function getSliderID() {

        return $this->slider['id'];
    }

    /**
     * @return mixed
     */
    public function getGroupID() {
        return $this->groupID;
    }

    /**
     * @return array
     */
    public function getSlide() {
        return $this->slide;
    }

    /**
     * @param array $slide
     */
    public function setSlide($slide) {
        $this->slide = $slide;
    }

    /**
     * @return array
     */
    public function getGenerator() {
        return $this->generator;
    }

    /**
     * @param array $generator
     */
    public function setGenerator($generator) {
        $this->generator = $generator;
    }

    /**
     * @return AbstractGeneratorGroup
     */
    public function getGeneratorGroup() {
        return $this->generatorGroup;
    }

    /**
     * @param AbstractGeneratorGroup $generatorGroup
     */
    public function setGeneratorGroup($generatorGroup) {
        $this->generatorGroup = $generatorGroup;
    }

    /**
     * @return AbstractGenerator
     */
    public function getGeneratorSource() {
        return $this->generatorSource;
    }

    /**
     * @param AbstractGenerator $generatorSource
     */
    public function setGeneratorSource($generatorSource) {
        $this->generatorSource = $generatorSource;
    }

}Admin/Generator/ViewGeneratorCreateStep4Settings.php000064400000011260152356646020016612 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\Generator;


use Nextend\Framework\Form\Element\Token;
use Nextend\Framework\Form\Form;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\AbstractView;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header\BlockHeader;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\TopBarMain\BlockTopBarMain;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonCancel;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Forms\Button\BlockButtonSave;
use Nextend\SmartSlider3\Application\Admin\Layout\LayoutDefault;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Application\Model\ModelGenerator;
use Nextend\SmartSlider3\Generator\AbstractGenerator;
use Nextend\SmartSlider3\Generator\AbstractGeneratorGroup;

class ViewGeneratorCreateStep4Settings extends AbstractView {

    use TraitAdminUrl;

    protected $groupID = 0;

    protected $groupTitle = '';

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

    /** @var AbstractGeneratorGroup */
    protected $generatorGroup;

    /** @var AbstractGenerator */
    protected $generatorSource;

    public function display() {

        $this->layout = new LayoutDefault($this);

        if ($this->groupID) {
            $this->layout->addBreadcrumb(Sanitize::esc_html($this->groupTitle), 'ssi_16 ssi_16--folderclosed', $this->getUrlSliderEdit($this->groupID));
        }

        $this->layout->addBreadcrumb(Sanitize::esc_html($this->slider['title']), 'ssi_16 ssi_16--image', $this->getUrlSliderEdit($this->slider['id'], $this->groupID));

        $this->layout->addBreadcrumb(n2_('Add dynamic slides'), '', $this->getUrlGeneratorCreate($this->slider['id'], $this->groupID));

        $this->layout->addBreadcrumb($this->generatorGroup->getLabel(), '', $this->getUrlGeneratorCreateStep2($this->generatorGroup->getName(), $this->slider['id'], $this->groupID));

        $this->layout->addBreadcrumb($this->generatorSource->getLabel(), '');


        $topBar = new BlockTopBarMain($this);

        $buttonSave = new BlockButtonSave($this);
        $buttonSave->addClass('n2_generator_add');
        $buttonSave->setLabel(n2_('Add'));
        $topBar->addPrimaryBlock($buttonSave);

        $buttonCancel = new BlockButtonCancel($this);
        $buttonCancel->addClass('n2_generator_add_cancel');
        $buttonCancel->setUrl($this->getUrlSliderEdit($this->slider['id'], $this->groupID));
        $topBar->addPrimaryBlock($buttonCancel);

        $this->layout->setTopBar($topBar->toHTML());

        $blockHeader = new BlockHeader($this);
        $blockHeader->setHeading(n2_('Add dynamic slides') . ': ' . $this->generatorGroup->getLabel() . ' - ' . $this->generatorSource->getLabel());

        $this->layout->addContentBlock($blockHeader);

        $this->layout->addContent($this->render('CreateStep4Settings'));

        $this->layout->render();
    }

    /**
     * @param int    $groupID
     * @param string $groupTitle
     */
    public function setGroupData($groupID, $groupTitle) {
        $this->groupID    = $groupID;
        $this->groupTitle = $groupTitle;
    }

    /**
     * @return array
     */
    public function getSlider() {
        return $this->slider;
    }

    /**
     * @return int
     */
    public function getGroupID() {
        return $this->groupID;
    }

    /**
     * @param array $slider
     */
    public function setSlider($slider) {
        $this->slider = $slider;
    }

    /**
     * @return integer
     */
    public function getSliderID() {

        return $this->slider['id'];
    }

    /**
     * @return AbstractGeneratorGroup
     */
    public function getGeneratorGroup() {
        return $this->generatorGroup;
    }

    /**
     * @param AbstractGeneratorGroup $generatorGroup
     */
    public function setGeneratorGroup($generatorGroup) {
        $this->generatorGroup = $generatorGroup;
    }

    /**
     * @return AbstractGenerator
     */
    public function getGeneratorSource() {
        return $this->generatorSource;
    }

    /**
     * @param AbstractGenerator $generatorSource
     */
    public function setGeneratorSource($generatorSource) {
        $this->generatorSource = $generatorSource;
    }

    public function displayForm() {
        $form = new Form($this, 'generator');
        new Token($form->getFieldsetHidden());

        $this->generatorSource->renderFields($form->getContainer());

        $generatorModel = new ModelGenerator($this);
        $generatorModel->renderFields($form->getContainer());
        $form->render();
    }

}Admin/Generator/Template/CreateStep1Groups.php000064400000005700152356646020015341 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Generator;


use Nextend\SmartSlider3\Application\Admin\Layout\Block\Generator\GeneratorBox\BlockGeneratorBox;
use Nextend\SmartSlider3\Generator\AbstractGeneratorGroup;

/**
 * @var ViewGeneratorCreateStep1Groups $this
 */

$generatorGroups = $this->getGeneratorGroups();

/** @var AbstractGeneratorGroup[] $installed */
$installed = array();

/** @var AbstractGeneratorGroup[] $notInstalled */
$notInstalled = array();

foreach ($generatorGroups as $generatorGroup) {

    if (!$generatorGroup->isDeprecated()) {
        if ($generatorGroup->isInstalled()) {
            $installed[] = $generatorGroup;
        } else {
            $notInstalled[] = $generatorGroup;
        }
    }
}

?>

<div class="n2_slide_generator_step1">
    <div class="n2_slide_generator_step1__installed_generators">
        <?php

        foreach ($installed as $generatorGroup) {

            $blockGeneratorBox = new BlockGeneratorBox($this);
            $blockGeneratorBox->setImageUrl($generatorGroup->getImageUrl());
            $blockGeneratorBox->setLabel($generatorGroup->getLabel());
            $blockGeneratorBox->setButtonLabel(n2_('Choose'));
            $blockGeneratorBox->setDescription($generatorGroup->getDescription());
            $blockGeneratorBox->setDocsLink($generatorGroup->getDocsLink());

            if ($generatorGroup->hasConfiguration()) {
                $url = $this->getUrlGeneratorCheckConfiguration($generatorGroup->getName(), $this->getSliderID(), $this->groupID);
            } else {
                $url = $this->getUrlGeneratorCreateStep2($generatorGroup->getName(), $this->getSliderID(), $this->groupID);
            }
            $blockGeneratorBox->setButtonLink($url);

            $blockGeneratorBox->display();
        }
        ?>
    </div>

    <?php if (!empty($notInstalled)): ?>
        <div class="n2_slide_generator_step1__not_installed">
            <div class="n2_slide_generator_step1__not_installed_label">
                <?php n2_e('Not installed'); ?>
            </div>
            <div class="n2_slide_generator_step1__not_installed_generators">
                <?php
                foreach ($notInstalled as $generatorGroup) {
                    $blockGeneratorBox = new BlockGeneratorBox($this);
                    $blockGeneratorBox->setImageUrl($generatorGroup->getImageUrl());
                    $blockGeneratorBox->setLabel($generatorGroup->getLabel());
                    $blockGeneratorBox->setButtonLabel(n2_('Visit'));
                    $blockGeneratorBox->setButtonLinkTarget('_blank');
                    $blockGeneratorBox->setButtonLink($generatorGroup->getUrl());
                    $blockGeneratorBox->setDescription($generatorGroup->getDescription());

                    $blockGeneratorBox->display();
                }
                ?>
            </div>
        </div>
    <?php endif; ?>
</div>Admin/Generator/Template/CreateStep2Configure.php000064400000001147152356646020016005 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Generator;

use Nextend\Framework\Asset\Js\Js;

/**
 * @var ViewGeneratorCreateStep2Configure $this
 */

JS::addInline('new _N2.GeneratorConfigure();');
?>
<form id="n2-ss-form-generator-configure" action="<?php echo esc_url($this->getAjaxUrlGeneratorCheckConfiguration($this->getGeneratorGroup()
                                                                                                                       ->getName(), $this->getSliderID(), $this->getGroupID())); ?>" method="post">
    <?php
    $this->renderForm();
    ?>
</form>Admin/Generator/Template/CreateStep3Sources.php000064400000001675152356646020015516 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Generator;

use Nextend\SmartSlider3\Application\Admin\Layout\Block\Generator\GeneratorBox\BlockGeneratorBox;

/**
 * @var ViewGeneratorCreateStep3Sources $this
 */

$generatorGroup = $this->getGeneratorGroup();

?>
<div class="n2_slide_generator_step3">
    <?php

    foreach ($generatorGroup->getSources() as $source) {

        $blockGeneratorBox = new BlockGeneratorBox($this);
        $blockGeneratorBox->setImageUrl($generatorGroup->getImageUrl());
        $blockGeneratorBox->setLabel($source->getLabel());
        $blockGeneratorBox->setButtonLink($this->getUrlGeneratorCreateSettings($generatorGroup->getName(), $source->getName(), $this->getSliderID(), $this->groupID));
        $blockGeneratorBox->setButtonLabel(n2_('Choose'));
        $blockGeneratorBox->setDescription($source->getDescription());

        $blockGeneratorBox->display();

    }
    ?>
</div>Admin/Generator/Template/CreateStep4Settings.php000064400000002235152356646020015665 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Generator;

use Nextend\Framework\Asset\Js\Js;

/**
 * @var ViewGeneratorCreateStep4Settings $this
 */

$generatorGroup  = $this->getGeneratorGroup();
$generatorSource = $this->getGeneratorSource();

JS::addInline('new _N2.GeneratorAdd();');
?>

<form id="n2-ss-form-generator-add" action="<?php echo esc_url($this->getAjaxUrlGeneratorCreateSettings($this->getGeneratorGroup()
                                                                                                             ->getName(), $this->getGeneratorSource()
                                                                                                                               ->getName(), $this->getSliderID(), $this->getGroupID())); ?>" method="post">
    <?php

    $this->displayForm();
    ?>
    <input name="generator[group]" value="<?php echo esc_attr($generatorGroup->getName()); ?>" type="hidden">
    <input name="generator[type]" value="<?php echo esc_attr($generatorSource->getName()); ?>" type="hidden">
    <input name="slider-id" value="<?php echo esc_attr($this->getSliderID()); ?>" type="hidden">
</form>Admin/Generator/Template/Edit.php000064400000002115152356646020012703 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\Generator;

use Nextend\Framework\Asset\Js\Js;
use Nextend\SmartSlider3\Settings;

/**
 * @var ViewGeneratorEdit $this
 */

$generator       = $this->getGenerator();
$generatorGroup  = $this->getGeneratorGroup();
$generatorSource = $this->getGeneratorSource();

JS::addInline('new _N2.GeneratorEdit(' . json_encode(array(
        'previewInNewWindow' => !!Settings::get('preview-new-window', 0),
        'previewUrl'         => $this->getUrlPreviewGenerator($generator['id'])
    )) . ');');

?>
<form id="n2-ss-form-generator-edit" action="<?php echo esc_url($this->getAjaxUrlGeneratorEdit($generator['id'], $this->getGroupID())); ?>" method="post">
    <?php
    $this->renderForm();
    ?>
    <input name="generator[group]" value="<?php echo esc_attr($generatorGroup->getName()); ?>" type="hidden">
    <input name="generator[type]" value="<?php echo esc_attr($generatorSource->getName()); ?>" type="hidden">
    <input name="slider-id" value="<?php echo esc_attr($this->getSliderID()); ?>" type="hidden">
</form>Admin/FormManager/FormManagerSlide.php000064400000003633152356646020013700 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\FormManager;


use Nextend\Framework\Form\AbstractFormManager;
use Nextend\Framework\Form\Element\Hidden;
use Nextend\Framework\Form\Form;
use Nextend\Framework\Pattern\MVCHelperTrait;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\Slider\Slider;

class FormManagerSlide extends AbstractFormManager {

    use TraitAdminUrl;

    protected $data;

    /**
     * @var int
     */
    protected $groupID;

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

    private $slide;

    /**
     * @var Form
     */
    protected $form;

    /**
     * FormManagerSlide constructor.
     *
     * @param MVCHelperTrait $MVCHelper
     * @param int            $groupID
     * @param Slider         $slider
     * @param                $slide
     */
    public function __construct($MVCHelper, $groupID, $slider, $slide) {

        $this->groupID = $groupID;
        $this->slider  = $slider;
        $this->slide   = $slide;

        parent::__construct($MVCHelper);

        $params = json_decode($slide['params'], true);
        if ($params == null) $params = array();
        $params                 += $slide;
        $params['sliderid']     = $slide['slider'];
        $params['generator_id'] = $slide['generator_id'];

        $params['first'] = isset($slide['first']) ? $slide['first'] : 0;

        $this->data = $params;

        $this->initForm();
    }

    public function render() {

        $this->form->render();
    }

    private function initForm() {

        $this->form = new Form($this, 'slide');

        if (!empty($this->data['guides'])) {
            $this->form->set('guides', $this->data['guides']);
        }

        $hidden = $this->form->getFieldsetHidden();

        new Hidden($hidden, 'slide', '');

        new Hidden($hidden, 'guides', '');
    }
}Admin/FormManager/FormManagerSlider.php000064400000012373152356646020014063 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\FormManager;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Font\FontManager;
use Nextend\Framework\Form\AbstractFormManager;
use Nextend\Framework\Form\Element\Hidden;
use Nextend\Framework\Form\FormTabbed;
use Nextend\Framework\Pattern\MVCHelperTrait;
use Nextend\Framework\Style\StyleManager;
use Nextend\SmartSlider3\Application\Admin\FormManager\Slider\SliderAnimations;
use Nextend\SmartSlider3\Application\Admin\FormManager\Slider\SliderAutoplay;
use Nextend\SmartSlider3\Application\Admin\FormManager\Slider\SliderControls;
use Nextend\SmartSlider3\Application\Admin\FormManager\Slider\SliderDeveloper;
use Nextend\SmartSlider3\Application\Admin\FormManager\Slider\SliderGeneral;
use Nextend\SmartSlider3\Application\Admin\FormManager\Slider\SliderOptimize;
use Nextend\SmartSlider3\Application\Admin\FormManager\Slider\SliderSize;
use Nextend\SmartSlider3\Application\Admin\FormManager\Slider\SliderSlides;
use Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header\BlockHeader;
use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
use Nextend\SmartSlider3\BackgroundAnimation\BackgroundAnimationManager;
use Nextend\SmartSlider3\Slider\SliderParams;
use Nextend\SmartSlider3\Slider\SliderType\AbstractSliderTypeAdmin;
use Nextend\SmartSlider3\Slider\SliderType\SliderTypeFactory;
use Nextend\SmartSlider3Pro\PostBackgroundAnimation\PostBackgroundAnimationManager;

class FormManagerSlider extends AbstractFormManager {

    use TraitAdminUrl;

    protected $slider;
    protected $data;

    /**
     * @var FormTabbed
     */
    protected $form;

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

    /**
     * FormManagerSlider constructor.
     *
     * @param MVCHelperTrait $MVCHelper
     * @param                $slider
     */
    public function __construct($MVCHelper, $slider) {

        parent::__construct($MVCHelper);

        $this->slider = $slider;

        $sliderParams = new SliderParams($slider['id'], $slider['type'], $slider['params'], true);

        $data              = $sliderParams->toArray();
        $data['title']     = $slider['title'];
        $data['type']      = $slider['type'];
        $data['thumbnail'] = $slider['thumbnail'];
        $data['alias']     = isset($slider['alias']) ? $slider['alias'] : '';
        $this->data        = $data;

        $this->initForm();
    }

    public function render() {

        $this->form->render();
    }

    /**
     * @return array|mixed|object
     */
    public function getData() {
        return $this->data;
    }

    /**
     * @param BlockHeader $blockHeader
     */
    public function addTabsToHeader($blockHeader) {
        $this->form->addTabsToHeader($blockHeader);
    }

    /**
     * @return AbstractSliderTypeAdmin
     */
    public function getSliderType() {
        return $this->sliderType;
    }

    private function initForm() {

        FontManager::enqueue($this);
        StyleManager::enqueue($this);

        // 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($this);
        PostBackgroundAnimationManager::enqueue($this);
    

        $this->form = new FormTabbed($this, 'slider');
        $this->form->setSessionID('slider-' . $this->slider['id']);
        $this->form->set('sliderID', $this->slider['id']);
        $this->form->set('class', 'nextend-smart-slider-admin');

        $this->form->loadArray($this->data);

        $this->initSliderType();

        new SliderGeneral($this, $this->form);

        new SliderSize($this->form);

        new SliderControls($this->form);

        new SliderAnimations($this->form);

        new SliderAutoplay($this->form);

        new SliderOptimize($this->form);

        new SliderSlides($this->form);

        new SliderDeveloper($this->form);

        $this->sliderType->prepareForm($this->form);
    }

    private function initSliderType() {

        new Hidden($this->form->getFieldsetHidden(), 'type', 'simple');

        $availableTypes = SliderTypeFactory::getAdminTypes();
        $sliderType     = $this->form->get('type', 'simple');
        if (!isset($availableTypes[$sliderType])) {
            $sliderType = 'simple';
        }

        $this->sliderType = $availableTypes[$sliderType];

        $types = array();
        foreach ($availableTypes as $type) {
            if (!$type->isDepreciated() || $type->getName() == $sliderType) {
                $types[$type->getName()] = array(
                    'icon'  => $type->getIcon(),
                    'label' => $type->getLabel()
                );
            }
        }

        JS::addInline('new _N2.SliderChangeType(' . json_encode(array(
                'types'       => $types,
                'currentType' => $sliderType,
                'ajaxUrl'     => $this->form->createAjaxUrl(array(
                    "slider/changeSliderType",
                    array(
                        'sliderID' => $this->form->get('sliderID')
                    )
                ))
            )) . ');');
    }
}Admin/FormManager/Slider/AbstractSliderTab.php000064400000001416152356646020015275 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\FormManager\Slider;


use Nextend\Framework\Form\Container\ContainerTab;
use Nextend\Framework\Form\FormTabbed;

abstract class AbstractSliderTab {

    /**
     * @var FormTabbed
     */
    protected $form;

    /**
     * @var ContainerTab
     */
    protected $tab;

    /**
     * AbstractSliderTab constructor.
     *
     * @param FormTabbed $form
     */
    public function __construct($form) {
        $this->form = $form;
        $this->tab  = $form->createTab($this->getName(), $this->getLabel());
    }

    /**
     * @return string
     */
    abstract protected function getName();

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

}Admin/FormManager/Slider/SliderAnimations.php000064400000011564152356646020015212 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\FormManager\Slider;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\FormTabbed;
use Nextend\SmartSlider3Pro\Form\Element\Particle;
use Nextend\SmartSlider3Pro\Form\Element\ShapeDivider;

class SliderAnimations extends AbstractSliderTab {

    /**
     * SliderAnimations constructor.
     *
     * @param FormTabbed $form
     */
    public function __construct($form) {
        parent::__construct($form);

        $this->effects();
        $this->layerAnimations();
        $this->layerParallax();
    
    }

    /**
     * @return string
     */
    protected function getName() {
        return 'animations';
    }

    /**
     * @return string
     */
    protected function getLabel() {
        return n2_('Animations');
    }

    protected function effects() {

        /**
         * Used for field injection: /animations/effects
         * Used for field removal: /animations/effects
         */
        $table = new ContainerTable($this->tab, 'effects', n2_('Effects'));

        /**
         * Used for field injection: /animations/effects/effects-row1
         */
        $row = $table->createRow('effects-row1');
        new ShapeDivider($row, 'shape-divider', n2_('Shape divider'));
        new Particle($row, 'particle', n2_('Particle effect'));
    
    }

    protected function layerAnimations() {
        
        /**
         * Used for field removal: /animations/layer-animations
         */
        $table = new ContainerTable($this->tab, 'layer-animations', n2_('Layer animations'));
        $row   = $table->createRow('layer-animations');

        new OnOff($row, 'playfirstlayer', n2_('Play on load'), 1, array(
            'tipLabel'       => n2_('Play on load'),
            'tipDescription' => n2_('Plays the layer animations on the first slide when it appears for the first time.')
        ));

        new OnOff($row, 'playonce', n2_('Play once'), 0, array(
            'tipLabel'       => n2_('Play once'),
            'tipDescription' => n2_('Plays the layer animations only during the first loop.')
        ));
        new Select($row, 'layer-animation-play-in', n2_('Play on'), 'end', array(
            'options' => array(
                'start' => n2_('Main animation start'),
                'end'   => n2_('Main animation end')
            )
        ));
        new Select($row, 'layer-animation-play-mode', n2_('Mode'), 'skippable', array(
            'options'        => array(
                'skippable' => n2_('Skippable'),
                'forced'    => n2_('Forced')
            ),
            'tipLabel'       => n2_('Mode'),
            'tipDescription' => n2_('You can make the outgoing layer animations, which don\'t have events, to play on slide switching.'),
        ));
    
    }

    protected function layerParallax() {
        /**
         * Used for field removal: /animations/layer-parallax
         */
        $table = new ContainerTable($this->tab, 'layer-parallax', n2_('Layer parallax'));

        new OnOff($table->getFieldsetLabel(), 'parallax-enabled', n2_('Enable'), 1, array(
            'relatedFieldsOn' => array(
                'table-rows-layer-parallax'
            )
        ));

        $row = $table->createRow('layer-parallax');
        new OnOff($row, 'parallax-enabled-mobile', n2_('Mobile'), 0);
        new OnOff($row, 'parallax-3d', '3D', 0);
        new OnOff($row, 'parallax-animate', n2_('Animate'), 1);
        new Select($row, 'parallax-horizontal', n2_('Horizontal'), 'mouse', array(
            'options' => array(
                '0'            => n2_('Off'),
                'mouse'        => n2_('Mouse'),
                'mouse-invert' => n2_('Mouse') . ' - ' . n2_('Invert')
            )
        ));
        new Select($row, 'parallax-vertical', n2_('Vertical'), 'mouse', array(
            'options' => array(
                '0'             => n2_('Off'),
                'scroll'        => n2_('Scroll'),
                'scroll-invert' => n2_('Scroll') . ' - ' . n2_('Invert'),
                'mouse'         => n2_('Mouse'),
                'mouse-invert'  => n2_('Mouse') . ' - ' . n2_('Invert')
            )
        ));
        new Select($row, 'parallax-mouse-origin', n2_('Mouse origin'), 'slider', array(
            'options' => array(
                'slider' => n2_('Slider center'),
                'enter'  => n2_('Mouse enter position')
            )
        ));
        new Select($row, 'parallax-scroll-move', n2_('Scroll move'), 'both', array(
            'options' => array(
                'both'   => n2_('Both'),
                'bottom' => n2_('To bottom'),
                'top'    => n2_('To top')
            )
        ));
    
    }
}Admin/FormManager/Slider/SliderAutoplay.php000064400000007530152356646020014704 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\FormManager\Slider;

use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Message\Warning;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\FormTabbed;
use Nextend\SmartSlider3\Widget\WidgetGroupFactory;
use Nextend\SmartSlider3Pro\Form\Element\AutoplayPicker;

class SliderAutoplay extends AbstractSliderTab {

    /**
     * SliderAutoplay constructor.
     *
     * @param FormTabbed $form
     */
    public function __construct($form) {
        parent::__construct($form);

        $this->autoplay();

        $plugins = WidgetGroupFactory::getGroups();

        if (isset($plugins['autoplay'])) {
            $plugins['autoplay']->renderFields($this->tab);
        }

        if (isset($plugins['indicator'])) {
            $plugins['indicator']->renderFields($this->tab);
        }
    }

    /**
     * @return string
     */
    protected function getName() {
        return 'autoplay';
    }

    /**
     * @return string
     */
    protected function getLabel() {
        return n2_('Autoplay');
    }

    protected function autoplay() {

        $table = new ContainerTable($this->tab, 'autoplay', n2_('Autoplay'));

        new OnOff($table->getFieldsetLabel(), 'autoplay', n2_('Enable'), 0, array(
            'relatedAttribute' => 'autoplay',
            'relatedFieldsOn'  => array(
                'table-rows-autoplay',
                'table-widget-autoplay',
                'table-widget-indicator',
                'autoplay-single-slide-notice'
            )
        ));

        $row2 = $table->createRow('row-2');
        new Number($row2, 'autoplayDuration', n2_('Slide duration'), 8000, array(
            'wide' => 5,
            'unit' => 'ms'
        ));
        new OnOff($row2, 'autoplayStart', n2_('Autostart'), 1);

        new OnOff($row2, 'autoplayAllowReStart', n2_('Allow restart'), 0, array(
            'tipLabel'       => n2_('Allow restart'),
            'tipDescription' => n2_('Keeps the autoplay control visible after the autoplay has finished to allow starting it again.')
        ));

        $rowFinish = $table->createRow('row-finish');

        new OnOff($rowFinish, 'autoplayLoop', n2_('Infinite loop'), 1, array(
            'relatedFieldsOff' => array(
                'sliderautoplayfinish',
                'sliderautoplayAllowReStart'
            )
        ));

        /**
         * Used for field injection: /autoplay/autoplay/row-finish/autoplayfinish
         */
        new AutoplayPicker($rowFinish, 'autoplayfinish', n2_('Finish autoplay'), '1|*|loop|*|current');

        new Warning($rowFinish, 'disabled-carousel-notice', n2_('The Carousel option is disabled, so the Autoplay will stop after the last slide appeared.'));

    

        $row3 = $table->createRow('row-3');
        new OnOff($row3, 'autoplayStopClick', n2_('Stop on click'), 1);
        new Select($row3, 'autoplayStopMouse', n2_('Stop on mouse'), 0, array(
            'options' => array(
                '0'     => n2_('Off'),
                'enter' => n2_('Enter'),
                'leave' => n2_('Leave')
            )
        ));
        new OnOff($row3, 'autoplayStopMedia', n2_('Stop on media'), 1);

        $row4 = $table->createRow('row-4');
        new OnOff($row4, 'autoplayResumeClick', n2_('Resume on click'), 0);
        new Select($row4, 'autoplayResumeMouse', n2_('Resume on mouse'), 0, array(
            'options' => array(
                '0'     => n2_('Off'),
                'leave' => n2_('Leave'),
                'enter' => n2_('Enter')
            )
        ));
        new OnOff($row4, 'autoplayResumeMedia', n2_('Resume on media'), 1);
    }
}Admin/FormManager/Slider/SliderControls.php000064400000005221152356646020014704 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\FormManager\Slider;

use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\FormTabbed;
use Nextend\Framework\Pattern\OrderableTrait;
use Nextend\SmartSlider3\Widget\WidgetGroupFactory;

class SliderControls extends AbstractSliderTab {

    use OrderableTrait;

    /**
     * SliderControls constructor.
     *
     * @param FormTabbed $form
     */
    public function __construct($form) {
        parent::__construct($form);

        $this->general();
        $this->controls();
    }

    /**
     * @return string
     */
    protected function getName() {
        return 'controls';
    }

    /**
     * @return string
     */
    protected function getLabel() {
        return n2_('Controls');
    }

    protected function general() {
        /**
         * Used for field removal: /controls/general
         */

        $table = new ContainerTable($this->tab, 'general', n2_('General'));
        $row1  = $table->createRow('general-1');

        new Select($row1, 'controlsTouch', n2_('Drag'), 'horizontal', array(
            'options'        => array(
                '0'          => n2_('Disabled'),
                'horizontal' => n2_('Horizontal'),
                'vertical'   => n2_('Vertical')
            ),
            'tipLabel'       => n2_('Drag'),
            'tipDescription' => n2_('Defines the drag (and touch) direction for your slider.')
        ));

        new Select($row1, 'controlsScroll', n2_('Mouse wheel'), '0', array(
            'options'        => array(
                '0' => n2_('Disabled'),
                '1' => n2_('Vertical'),
                '2' => n2_('Horizontal')
            ),
            'tipLabel'       => n2_('Mouse wheel'),
            'tipDescription' => n2_('Allows switching slides with the mouse wheel.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1778-slider-settings-controls#mouse-wheel'
        ));

        new OnOff($row1, 'controlsKeyboard', n2_('Keyboard'), 1, array(
            'tipLabel'       => n2_('Keyboard'),
            'tipDescription' => n2_('Allows switching slides with the keyboard.')
        ));
    }

    protected function controls() {

        $plugins = WidgetGroupFactory::getGroups();

        self::uasort($plugins);

        unset($plugins['autoplay']);
        unset($plugins['indicator']);

        foreach ($plugins as $name => $widgetGroup) {
            $widgetGroup->renderFields($this->tab);
        }
    }
}Admin/FormManager/Slider/SliderDeveloper.php000064400000014440152356646020015031 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\FormManager\Slider;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Message\Warning;
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\Element\Textarea;
use Nextend\Framework\Form\FormTabbed;

class SliderDeveloper extends AbstractSliderTab {

    /**
     * SliderDeveloper constructor.
     *
     * @param FormTabbed $form
     */
    public function __construct($form) {
        parent::__construct($form);

        $this->developer();
    }

    /**
     * @return string
     */
    protected function getName() {
        return 'developer';
    }

    /**
     * @return string
     */
    protected function getLabel() {
        return n2_('Developer');
    }

    protected function developer() {

        $table = new ContainerTable($this->tab, 'developer', n2_('Developer'));

        $row1 = $table->createRow('developer-1');
        new OnOff($row1, 'blockrightclick', n2_('Block right click'), 0);
    

        /**
         * Used for field removal: /developer/developer/developer-1/controlsBlockCarouselInteraction
         */
        new OnOff($row1, 'controlsBlockCarouselInteraction', n2_('Block carousel'), 1, array(
            'tipLabel'       => n2_('Block carousel'),
            'tipDescription' => n2_('Stops the carousel at the last slide when the source of interaction is vertical touch, vertical pointer, mouse wheel or vertical keyboard.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1806-slider-settings-developer#block-carousel'
        ));

        new OnOff($row1, 'clear-both', n2_('Clear before'), 1, array(
            'tipLabel'       => n2_('Clear before'),
            'tipDescription' => n2_('Closes the unclosed float CSS codes before the slider.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1806-slider-settings-developer#clear-before'
        ));
        new OnOff($row1, 'clear-both-after', n2_('Clear after'), 1, array(
            'tipLabel'       => n2_('Clear after'),
            'tipDescription' => n2_('Allows you to put your slider next to your text.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1806-slider-settings-developer#clear-after'
        ));

        $rowHideScrollbar = $table->createRow('developer-hide-scrollbar');
        new OnOff($rowHideScrollbar, 'overflow-hidden-page', n2_('Hide scrollbar'), 0, array(
            'relatedFieldsOn' => array(
                'slideroverflow-hidden-page-notice'
            )
        ));
        new Warning($rowHideScrollbar, 'overflow-hidden-page-notice', n2_('Your website won\'t be scrollable anymore! All out of screen elements will be hidden.'));

        $row2 = $table->createRow('developer-2');

        new OnOff($row2, 'responsiveFocusUser', n2_('Scroll to slider'), 1, array(
            'tipLabel'        => n2_('Scroll to slider'),
            'tipDescription'  => n2_('The page scrolls back to the slider when the user interacts with it.'),
            'relatedFieldsOn' => array(
                'sliderresponsiveFocusEdge'
            )
        ));

        new Select($row2, 'responsiveFocusEdge', n2_('Edge'), 'auto', array(
            'options' => array(
                'auto'         => n2_('Auto'),
                'top'          => n2_('Top - when needed'),
                'top-force'    => n2_('Top - always'),
                'bottom'       => n2_('Bottom - when needed'),
                'bottom-force' => n2_('Bottom - always'),
            )
        ));

        $row21 = $table->createRow('developer-21');

        new OnOff($row21, 'is-delayed', n2_('Delayed (for lightbox/tabs)'), 0, array(
            'tipLabel'       => n2_('Delayed (for lightbox/tabs)'),
            'tipDescription' => n2_('Delays the loading of the slider until its container gets visible. Useful when you display the slider in a lightbox or tab.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1801-slider-settings-optimize#delayed-for-lightboxtabs'
        ));

        $row211 = $table->createRow('developer-211');

        new OnOff($row211, 'legacy-font-scale', n2_('Legacy font scale'), 0, array(
            'relatedFieldsOn' => array(
                'sliderlegacy-font-scale-notice'
            )
        ));
        new Warning($row211, 'legacy-font-scale-notice', n2_('This feature brings back the non-adaptive font size for absolute layers which were made before version 3.5. Turning on can affect website performance, so we suggest to keep it disabled.
'));

        $row22 = $table->createRow('developer-22');

        new Text($row22, 'classes', n2_('Slider CSS classes'), '', array(
            'tipLabel'       => n2_('Slider CSS classes'),
            'tipDescription' => n2_('You can put custom CSS classes to the slider\'s container.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1806-slider-settings-developer#css'
        ));

        $row3 = $table->createRow('developer-3');
        new Textarea($row3, 'custom-css-codes', 'CSS', '', array(
            'height' => 26
        ));
        $row4 = $table->createRow('developer-4');
        new Textarea($row4, 'callbacks', n2_('JavaScript callbacks'), '', array(
            'height' => 26
        ));
    

        $row11 = $table->createRow('developer-11');
        new Number($row11, 'loading-time', n2_('Loading animation waiting time'), 2000, array(
            'wide' => 5,
            'unit' => 'ms',
        ));
        $row11 = $table->createRow('developer-11');
        new Text($row11, 'fallback-slider', n2_('Fallback slider') . ' (' . n2_('ID or Alias') . ')', '', array(
            'tipLabel'       => n2_('Fallback slider') . ' (' . n2_('ID or Alias') . ')',
            'tipDescription' => n2_('Select another slider by its ID or Alias that displays if your current slider has no published slides.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1806-slider-settings-developer#fallbackslider',
        ));
    

    }
}Admin/FormManager/Slider/SliderGeneral.php000064400000020145152356646020014460 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\FormManager\Slider;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\MarginPadding;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\FieldImage;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;
use Nextend\Framework\Form\Fieldset\FieldsetRowPlain;
use Nextend\Framework\Form\FormTabbed;
use Nextend\SmartSlider3\Application\Admin\FormManager\FormManagerSlider;
use Nextend\SmartSlider3\Form\Element\PublishSlider;

class SliderGeneral extends AbstractSliderTab {

    /**
     * @var FormManagerSlider
     */
    protected $manager;

    /**
     * SliderGeneral constructor.
     *
     * @param FormManagerSlider $manager
     * @param FormTabbed        $form
     */
    public function __construct($manager, $form) {

        $this->manager = $manager;

        parent::__construct($form);

        $this->publish();
        $this->general();
        $this->alias();
        $this->sliderDesign();
    }

    /**
     * @return string
     */
    protected function getName() {
        return 'general';
    }

    /**
     * @return string
     */
    protected function getLabel() {
        return n2_('General');
    }

    protected function publish() {

        $table = new ContainerTable($this->tab, 'publish', n2_('Publish'));
        $row   = new FieldsetRowPlain($table, 'publish');
        new PublishSlider($row);
    }

    protected function general() {

        $table = new ContainerTable($this->tab, 'general', n2_('General') . ' - ' . $this->manager->getSliderType()
                                                                                                  ->getLabelFull());

        $row1 = $table->createRow('general-1');

        new Text($row1, 'title', n2_('Name'), n2_('Slider'), array(
            'style' => 'width:300px;'
        ));
        new FieldImage($row1, 'thumbnail', n2_('Thumbnail'), '', array(
            'tipLabel'       => n2_('Thumbnail'),
            'tipDescription' => n2_('Slider thumbnail which appears in the slider list.')
        ));

        new Text($row1, 'aria-label', n2_('ARIA label'), '', array(
            'style'          => 'width:200px;',
            'tipLabel'       => n2_('ARIA label'),
            'tipDescription' => n2_('It allows you to label your slider for screen readers.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1722-slider-settings-general#aria-label'
        ));
    }


    protected function alias() {

        $table = new ContainerTable($this->tab, 'alias', n2_('Alias'));

        $row1 = $table->createRow('alias-1');

        new Text($row1, 'alias', n2_('Alias'), '', array(
            'style'          => 'width:200px;',
            'tipLabel'       => n2_('Alias'),
            'tipDescription' => n2_('You can use this alias in the slider\'s shortcode.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1722-slider-settings-general#alias'
        ));

        new OnOff($row1, 'alias-id', n2_('Use as anchor'), '', array(
            'tipLabel'        => n2_('Use as anchor'),
            'tipDescription'  => n2_('Creates an empty div before the slider, using the alias as the ID of this div. As a result, you can use #your-alias in the URL to make the page jump to the slider.'),
            'tipLink'         => 'https://smartslider.helpscoutdocs.com/article/1722-slider-settings-general#use-as-anchor',
            'relatedFieldsOn' => array(
                'slideralias-smoothscroll',
                'slideralias-slideswitch'
            )
        ));

        new OnOff($row1, 'alias-smoothscroll', n2_('Smooth scroll'), '', array(
            'tipLabel'       => n2_('Smooth scroll'),
            'tipDescription' => n2_('The #your-alias urls in links would be forced to smooth scroll to the slider.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1722-slider-settings-general#smooth-scroll-to-this-element'
        ));

        /**
         * Used for field removal: /general/alias/alias-1/alias-slideswitch
         */
        new OnOff($row1, 'alias-slideswitch', n2_('Switch slide'), '', array(
            'tipLabel'        => n2_('Switch slide'),
            'tipDescription'  => n2_('Use #your-alias-2 as an anchor to jump to the slider and switch to the 2nd slide immediately. Use #your-alias-3 for the 3rd slide and so on.'),
            'tipLink'         => 'https://smartslider.helpscoutdocs.com/article/1722-slider-settings-general#allow-slide-switching-for-anchor',
            'relatedFieldsOn' => array(
                'slideralias-slideswitch-scroll'
            )
        ));

        new OnOff($row1, 'alias-slideswitch-scroll', n2_('Scroll to slide'), 1, array(
            'tipLabel'       => n2_('Scroll to slide'),
            'tipDescription' => n2_('The "Switch slide" option won\'t scroll you to the slider. Only the slides will switch.')
        ));
    }

    protected function sliderDesign() {

        $table = new ContainerTable($this->tab, 'design', n2_('Slider design'));

        $rowBackground = $table->createRow('slider-type-simple-settings-background');

        new FieldImage($rowBackground, 'background', n2_('Slider background image'), '', array(
            'width'         => '200',
            'relatedFields' => array(
                'table-optimize-slider',
                'sliderbackground-fixed',
                'sliderbackground-size'
            )
        ));
        new OnOff($rowBackground, 'background-fixed', n2_('Fixed'), 0);
        new Text\TextAutoComplete($rowBackground, 'background-size', n2_('Size'), 'cover', array(
            'values' => array(
                'cover',
                'contain',
                'auto'
            )
        ));

        new Text\Color($rowBackground, 'background-color', n2_('Background color'), 'FFFFFF00', array(
            'alpha' => true
        ));

        new Text\Video($rowBackground, 'backgroundVideoMp4', n2_('Background video'), '', array(
            'relatedFields' => array(
                'sliderbackgroundVideoLoop',
                'sliderbackgroundVideoMode'
            )
        ));
        new OnOff($rowBackground, 'backgroundVideoLoop', n2_x('Loop', 'Video/Audio play'), 1);
        new Select($rowBackground, 'backgroundVideoMode', n2_('Fill mode'), 'fill', array(
            'options' => array(
                'fill'   => n2_('Fill'),
                'fit'    => n2_('Fit'),
                'center' => n2_('Center')
            )
        ));

    

        /**
         * Used for field injection: /general/design/design-1
         */
        $row1 = $table->createRow('design-1');

        new Select($row1, 'align', n2_('Align'), 'normal', array(
            'options' => array(
                'normal' => n2_('Normal'),
                'left'   => n2_('Left'),
                'center' => n2_('Center'),
                'right'  => n2_('Right')
            )
        ));

        /**
         * Used for field injection: /general/design/design-1/margin
         */
        $margin = new MarginPadding($row1, 'margin', n2_('Margin'), '0|*|0|*|0|*|0', array(
            'unit'           => 'px',
            'tipLabel'       => n2_('Margin'),
            'tipDescription' => n2_('Puts a fix margin around your slider.')
        ));

        for ($i = 1; $i < 5; $i++) {
            new Number($margin, 'col-border-width-' . $i, false, '', array(
                'wide' => 3
            ));
        }
        new NumberAutoComplete($row1, 'perspective', n2_('Perspective'), 1000, array(
            'wide'   => 5,
            'values' => array(
                0,
                500,
                1000,
                1500,
                2000,
                3000
            ),
            'unit'   => 'px'
        ));
    
    }
}Admin/FormManager/Slider/SliderSize.php000064400000052671152356646020014026 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\FormManager\Slider;


use Nextend\Framework\Form\Container\ContainerRowGroup;
use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Breakpoint;
use Nextend\Framework\Form\Element\CheckboxOnOff;
use Nextend\Framework\Form\Element\Group\GroupCheckboxOnOff;
use Nextend\Framework\Form\Element\Grouping;
use Nextend\Framework\Form\Element\Hidden\HiddenOnOff;
use Nextend\Framework\Form\Element\Message\Notice;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Text\HiddenText;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;
use Nextend\Framework\Form\FormTabbed;
use Nextend\SmartSlider3\Application\Admin\Settings\ViewSettingsGeneral;
use Nextend\SmartSlider3\Form\Element\Select\ResponsiveSubFormIcon;
use Nextend\SmartSlider3\Settings;

class SliderSize extends AbstractSliderTab {


    /**
     * SliderSize constructor.
     *
     * @param FormTabbed $form
     */
    public function __construct($form) {
        parent::__construct($form);

        $this->size();
        $this->breakpoints();
        $this->layout();
        $this->customSize();
    }

    /**
     * @return string
     */
    protected function getName() {
        return 'size';
    }

    /**
     * @return string
     */
    protected function getLabel() {
        return n2_('Size');
    }

    protected function size() {

        $table = new ContainerTable($this->tab, 'size', n2_('Slider size'));


        /**
         * Used for field injection: /size/size/size-1
         */
        $row1 = $table->createRow('size-1');

        new NumberAutoComplete($row1, 'width', n2_('Width'), 900, array(
            'wide'   => 5,
            'min'    => 10,
            'values' => array(
                1920,
                1400,
                1000,
                800,
                600,
                400
            ),
            'unit'   => 'px'
        ));
        new NumberAutoComplete($row1, 'height', n2_('Height'), 500, array(
            'wide'   => 5,
            'min'    => 10,
            'values' => array(
                800,
                600,
                500,
                400,
                300,
                200
            ),
            'unit'   => 'px'
        ));

        $groupShowOn = new GroupCheckboxOnOff($row1, 'show-on', n2_('Hide on'));
        new CheckboxOnOff($groupShowOn, 'mobileportrait', false, 'ssi_16 ssi_16--mobileportrait', 1, array(
            'invert'      => true,
            'checkboxTip' => n2_('Mobile')
        ));
        new CheckboxOnOff($groupShowOn, 'mobilelandscape', false, 'ssi_16 ssi_16--mobileportraitlarge', 1, array(
            'invert'      => true,
            'checkboxTip' => n2_('Large mobile'),
            'rowClass'    => 'n2-slider-settings-require--mobilelandscape'
        ));
        new CheckboxOnOff($groupShowOn, 'tabletportrait', false, 'ssi_16 ssi_16--tabletportrait', 1, array(
            'invert'      => true,
            'checkboxTip' => n2_('Tablet')
        ));
        new CheckboxOnOff($groupShowOn, 'tabletlandscape', false, 'ssi_16 ssi_16--tabletportraitlarge', 1, array(
            'invert'      => true,
            'checkboxTip' => n2_('Large tablet'),
            'rowClass'    => 'n2-slider-settings-require--tabletlandscape'
        ));
        new CheckboxOnOff($groupShowOn, 'desktopportrait', false, 'ssi_16 ssi_16--desktopportrait', 1, array(
            'invert'      => true,
            'checkboxTip' => n2_('Desktop')
        ));
        new CheckboxOnOff($groupShowOn, 'desktoplandscape', false, 'ssi_16 ssi_16--desktoplandscape', 1, array(
            'invert'      => true,
            'checkboxTip' => n2_('Large desktop'),
            'rowClass'    => 'n2-slider-settings-require--desktoplandscape'
        ));
    

        /**
         * Used for field removal: /size/size/size-2
         */
        $row2 = $table->createRow('size-2');

        new OnOff($row2, 'responsiveLimitSlideWidth', n2_('Limit slide width'), 1, array(
            'relatedFieldsOn' => array(
                'slidergrouping-responsive-slide-width'
            ),
            'tipLabel'        => n2_('Limit slide width'),
            'tipDescription'  => n2_('Limits the width of the slide and prevents the slider from getting too tall.'),
            'tipLink'         => 'https://smartslider.helpscoutdocs.com/article/1774-slider-settings-size#limit-slide-width'
        ));

        $slideMaxWidthGroup = new Grouping($row2, 'grouping-responsive-slide-width');
        $slideMaxWidthGroupDesktopLandscape = new Grouping($slideMaxWidthGroup, 'grouping-responsive-slide-width-desktop-landscape');

        new OnOff($slideMaxWidthGroupDesktopLandscape, 'responsiveSlideWidthDesktopLandscape', n2_('Large desktop'), 0, array(
            'relatedFieldsOn' => array(
                'sliderresponsiveSlideWidthMaxDesktopLandscape'
            )
        ));
        new NumberAutoComplete($slideMaxWidthGroupDesktopLandscape, 'responsiveSlideWidthMaxDesktopLandscape', n2_('Max'), 1600, array(
            'min'    => 0,
            'values' => array(
                3000,
                1600
            ),
            'unit'   => 'px',
            'wide'   => 5
        ));
    

        new OnOff($slideMaxWidthGroup, 'responsiveSlideWidth', n2_('Desktop'), 0, array(
            'relatedFieldsOn' => array(
                'sliderresponsiveSlideWidthMax'
            )
        ));
        new NumberAutoComplete($slideMaxWidthGroup, 'responsiveSlideWidthMax', n2_('Max'), 3000, array(
            'min'    => 0,
            'values' => array(
                3000,
                980
            ),
            'unit'   => 'px',
            'wide'   => 5
        ));
        $slideMaxWidthGroupTabletLandscape = new Grouping($slideMaxWidthGroup, 'grouping-responsive-slide-width-tablet-landscape');

        new OnOff($slideMaxWidthGroupTabletLandscape, 'responsiveSlideWidthTabletLandscape', n2_('Large tablet'), 0, array(
            'relatedFieldsOn' => array(
                'sliderresponsiveSlideWidthMaxTabletLandscape'
            )
        ));
        new NumberAutoComplete($slideMaxWidthGroupTabletLandscape, 'responsiveSlideWidthMaxTabletLandscape', n2_('Max'), 1200, array(
            'min'    => 0,
            'values' => array(
                3000,
                1200
            ),
            'unit'   => 'px',
            'wide'   => 5
        ));
    

        new OnOff($slideMaxWidthGroup, 'responsiveSlideWidthTablet', n2_('Tablet'), 0, array(
            'relatedFieldsOn' => array(
                'sliderresponsiveSlideWidthMaxTablet'
            )
        ));
        new NumberAutoComplete($slideMaxWidthGroup, 'responsiveSlideWidthMaxTablet', n2_('Max'), 3000, array(
            'min'    => 0,
            'values' => array(
                3000,
                980
            ),
            'unit'   => 'px',
            'wide'   => 5
        ));
        $slideMaxWidthGroupMobileLandscape = new Grouping($slideMaxWidthGroup, 'grouping-responsive-slide-width-mobile-landscape');

        new OnOff($slideMaxWidthGroupMobileLandscape, 'responsiveSlideWidthMobileLandscape', n2_('Large mobile'), 0, array(
            'relatedFieldsOn' => array(
                'sliderresponsiveSlideWidthMaxMobileLandscape'
            )
        ));

        new NumberAutoComplete($slideMaxWidthGroupMobileLandscape, 'responsiveSlideWidthMaxMobileLandscape', n2_('Max'), 740, array(
            'min'    => 0,
            'values' => array(
                3000,
                740
            ),
            'unit'   => 'px',
            'wide'   => 5
        ));
    

        new OnOff($slideMaxWidthGroup, 'responsiveSlideWidthMobile', n2_('Mobile'), 0, array(
            'relatedFieldsOn' => array(
                'sliderresponsiveSlideWidthMaxMobile'
            )
        ));
        new NumberAutoComplete($slideMaxWidthGroup, 'responsiveSlideWidthMaxMobile', n2_('Max'), 480, array(
            'min'    => 0,
            'values' => array(
                3000,
                480
            ),
            'unit'   => 'px',
            'wide'   => 5
        ));

    }

    protected function breakpoints() {

        $table = new ContainerTable($this->tab, 'breakpoints', n2_('Breakpoints'));

        $tableFieldset = $table->getFieldsetLabel();
        new HiddenText($tableFieldset, 'responsive-breakpoint-desktop-portrait', false, ViewSettingsGeneral::defaults['desktop-large-portrait']);
        new HiddenText($tableFieldset, 'responsive-breakpoint-desktop-portrait-landscape', false, ViewSettingsGeneral::defaults['desktop-large-landscape']);

        new HiddenText($tableFieldset, 'responsive-breakpoint-tablet-landscape', false, ViewSettingsGeneral::defaults['tablet-large-portrait']);
        new HiddenText($tableFieldset, 'responsive-breakpoint-tablet-landscape-landscape', false, ViewSettingsGeneral::defaults['tablet-large-landscape']);
    

        new HiddenText($tableFieldset, 'responsive-breakpoint-tablet-portrait', false, ViewSettingsGeneral::defaults['tablet-portrait']);
        new HiddenText($tableFieldset, 'responsive-breakpoint-tablet-portrait-landscape', false, ViewSettingsGeneral::defaults['tablet-landscape']);
        new HiddenText($tableFieldset, 'responsive-breakpoint-mobile-landscape', false, ViewSettingsGeneral::defaults['mobile-large-portrait']);
        new HiddenText($tableFieldset, 'responsive-breakpoint-mobile-landscape-landscape', false, ViewSettingsGeneral::defaults['mobile-large-landscape']);
    

        new HiddenText($tableFieldset, 'responsive-breakpoint-mobile-portrait', false, ViewSettingsGeneral::defaults['mobile-portrait']);
        new HiddenText($tableFieldset, 'responsive-breakpoint-mobile-portrait-landscape', false, ViewSettingsGeneral::defaults['mobile-landscape']);
        new HiddenOnOff($tableFieldset, 'responsive-breakpoint-desktop-landscape-enabled', n2_('Large desktop'), 0, array(
            'relatedFieldsOn' => array(
                'sliderresponsive-breakpoint-notice-desktop-landscape',
                'table-row-override-slider-size-desktop-landscape-row',
                'slidergrouping-responsive-slide-width-desktop-landscape'
            )
        ));
        new HiddenOnOff($tableFieldset, 'responsive-breakpoint-tablet-landscape-enabled', n2_('Large tablet'), 0, array(
            'relatedFieldsOn' => array(
                'sliderresponsive-breakpoint-notice-tablet-landscape',
                'table-row-override-slider-size-tablet-landscape-row',
                'slidergrouping-responsive-slide-width-tablet-landscape'
            )
        ));
    
        new HiddenOnOff($tableFieldset, 'responsive-breakpoint-tablet-portrait-enabled', n2_('Tablet'), 1, array(
            'relatedFieldsOn' => array(
                'sliderresponsive-breakpoint-notice-tablet-portrait',
                'table-row-override-slider-size-tablet-portrait-row'
            )
        ));
        new HiddenOnOff($tableFieldset, 'responsive-breakpoint-mobile-landscape-enabled', n2_('Large mobile'), 0, array(
            'relatedFieldsOn' => array(
                'sliderresponsive-breakpoint-notice-mobile-landscape',
                'table-row-override-slider-size-mobile-landscape-row',
                'slidergrouping-responsive-slide-width-mobile-landscape'
            )
        ));
    
        new HiddenOnOff($tableFieldset, 'responsive-breakpoint-mobile-portrait-enabled', n2_('Mobile'), 1, array(
            'relatedFieldsOn' => array(
                'sliderresponsive-breakpoint-notice-mobile-portrait',
                'table-row-override-slider-size-mobile-portrait-row'
            )
        ));

        $row1 = $table->createRow('breakpoints-row-1');

        $instructions = n2_('Breakpoints define the browser width in pixel when the slider switches to a different device.');

        new Notice($row1, 'breakpoints-instructions', n2_('Instruction'), $instructions);

        $row2 = $table->createRow('breakpoints-row-2');

        new OnOff($row2, 'responsive-breakpoint-global', n2_('Global breakpoints'), 0, array(
            'tipLabel'       => n2_('Global breakpoints'),
            'tipDescription' => sprintf(n2_('You can use the global breakpoints, or adjust them locally here. You can configure the Global breakpoints at %1$sGlobal settings%2$s > General > Breakpoints'), sprintf('<a href="%s" target="_blank">', $this->form->getMVCHelper()
                                                                                                                                                                                                                                                                 ->getUrlSettingsDefault()), '</a>')
        ));
        new Breakpoint($row2, 'breakpoints', array(
            'desktoplandscape-portrait'  => 'sliderresponsive-breakpoint-desktop-portrait',
            'desktoplandscape-landscape' => 'sliderresponsive-breakpoint-desktop-portrait-landscape',
            'tabletlandscape-portrait'   => 'sliderresponsive-breakpoint-tablet-landscape',
            'tabletlandscape-landscape'  => 'sliderresponsive-breakpoint-tablet-landscape-landscape',
            'tabletportrait-portrait'    => 'sliderresponsive-breakpoint-tablet-portrait',
            'tabletportrait-landscape'   => 'sliderresponsive-breakpoint-tablet-portrait-landscape',
            'mobilelandscape-portrait'   => 'sliderresponsive-breakpoint-mobile-landscape',
            'mobilelandscape-landscape'  => 'sliderresponsive-breakpoint-mobile-landscape-landscape',
            'mobileportrait-portrait'    => 'sliderresponsive-breakpoint-mobile-portrait',
            'mobileportrait-landscape'   => 'sliderresponsive-breakpoint-mobile-portrait-landscape'
        ), array(
            'desktoplandscape' => 'sliderresponsive-breakpoint-desktop-landscape-enabled',
            'tabletlandscape'  => 'sliderresponsive-breakpoint-tablet-landscape-enabled',
            'mobilelandscape'  => 'sliderresponsive-breakpoint-mobile-landscape-enabled'
        ), array(
            'field'  => 'sliderresponsive-breakpoint-global',
            'values' => array(
                'desktoplandscape-portrait'  => Settings::get('responsive-screen-width-desktop-portrait', ViewSettingsGeneral::defaults['desktop-large-portrait']),
                'desktoplandscape-landscape' => Settings::get('responsive-screen-width-desktop-portrait-landscape', ViewSettingsGeneral::defaults['desktop-large-landscape']),
                'tabletlandscape-portrait'   => Settings::get('responsive-screen-width-tablet-landscape', ViewSettingsGeneral::defaults['tablet-large-portrait']),
                'tabletlandscape-landscape'  => Settings::get('responsive-screen-width-tablet-landscape-landscape', ViewSettingsGeneral::defaults['tablet-large-landscape']),
                'tabletportrait-portrait'    => Settings::get('responsive-screen-width-tablet-portrait', ViewSettingsGeneral::defaults['tablet-portrait']),
                'tabletportrait-landscape'   => Settings::get('responsive-screen-width-tablet-portrait-landscape', ViewSettingsGeneral::defaults['tablet-landscape']),
                'mobilelandscape-portrait'   => Settings::get('responsive-screen-width-mobile-landscape', ViewSettingsGeneral::defaults['mobile-large-portrait']),
                'mobilelandscape-landscape'  => Settings::get('responsive-screen-width-mobile-landscape-landscape', ViewSettingsGeneral::defaults['mobile-large-landscape']),
                'mobileportrait-portrait'    => Settings::get('responsive-screen-width-mobile-portrait', ViewSettingsGeneral::defaults['mobile-portrait']),
                'mobileportrait-landscape'   => Settings::get('responsive-screen-width-mobile-portrait-landscape', ViewSettingsGeneral::defaults['mobile-landscape'])
            )
        ));
    }

    protected function layout() {

        $table = new ContainerTable($this->tab, 'responsive-mode', n2_('Layout'));

        $row1 = $table->createRow('responsive-mode-row-1');

        /**
         * Used for option removal: /size/responsive-mode/responsive-mode-row-1/responsive-mode
         */
        new ResponsiveSubFormIcon($row1, 'responsive-mode', $table, $this->form->createAjaxUrl(array("slider/renderresponsivetype")), 'auto');

    }

    protected function customSize() {

        /**
         * Used for field removal: /size/override-slider-size
         */
        $table = new ContainerTable($this->tab, 'override-slider-size', n2_('Custom size'));

        new OnOff($table->getFieldsetLabel(), 'slider-size-override', '', 0, array(
            'relatedFieldsOn' => array(
                'table-row-group-override-slider-size'
            )
        ));

        $row1         = $table->createRow('size-1');
        $instructions = sprintf(n2_('Use this option to customize the aspect ratio for each device. %1$s Read more in the documentation%2$s. %3$sBeware:%4$s This option is rarely needed and might be hard to set properly!'), '<a href="https://smartslider.helpscoutdocs.com/article/1774-slider-settings-size#custom-size" target="_blank">', '</a>', '<b>', '</b>');
        new Notice($row1, 'instructions', n2_('Instruction'), $instructions);

        $overrideEditorSize = $table->createRowGroup('override-slider-size', false);

        $this->mobilePortrait($overrideEditorSize);
        $this->mobileLandscape($overrideEditorSize);
        $this->tabletPortrait($overrideEditorSize);
        $this->tabletLandscape($overrideEditorSize);
        $this->desktopLandscape($overrideEditorSize);


    
    }

    /**
     * @param ContainerRowGroup $rowGroup
     */
    protected function desktopLandscape($rowGroup) {

        $row = $rowGroup->createRow('override-slider-size-desktop-landscape-row');

        new OnOff($row, 'slider-size-override-desktop-landscape', n2_('Large desktop'), 0, array(
            'relatedFieldsOn' => array(
                'sliderdesktop-landscape-width',
                'sliderdesktop-landscape-height'
            )
        ));

        new Number($row, 'desktop-landscape-width', n2_('Width'), 1440, array(
            'wide' => 5,
            'unit' => 'px'
        ));
        new Number($row, 'desktop-landscape-height', n2_('Height'), 900, array(
            'wide' => 5,
            'unit' => 'px'
        ));
    
    }

    /**
     * @param ContainerRowGroup $rowGroup
     */
    protected function tabletLandscape($rowGroup) {

        $row = $rowGroup->createRow('override-slider-size-tablet-landscape-row');

        new OnOff($row, 'slider-size-override-tablet-landscape', n2_('Large tablet'), 0, array(
            'relatedFieldsOn' => array(
                'slidertablet-landscape-width',
                'slidertablet-landscape-height'
            )
        ));

        new Number($row, 'tablet-landscape-width', n2_('Width'), 1024, array(
            'wide' => 5,
            'unit' => 'px'
        ));
        new Number($row, 'tablet-landscape-height', n2_('Height'), 768, array(
            'wide' => 5,
            'unit' => 'px'
        ));
    
    }

    /**
     * @param ContainerRowGroup $rowGroup
     */
    protected function tabletPortrait($rowGroup) {

        $row = $rowGroup->createRow('override-slider-size-tablet-portrait-row');

        new OnOff($row, 'slider-size-override-tablet-portrait', n2_('Tablet'), 0, array(
            'relatedFieldsOn' => array(
                'slidertablet-portrait-width',
                'slidertablet-portrait-height'
            )
        ));

        new Number($row, 'tablet-portrait-width', n2_('Width'), 768, array(
            'wide' => 5,
            'unit' => 'px'
        ));
        new Number($row, 'tablet-portrait-height', n2_('Height'), 1024, array(
            'wide' => 5,
            'unit' => 'px'
        ));
    }

    /**
     * @param ContainerRowGroup $rowGroup
     */
    protected function mobileLandscape($rowGroup) {

        $row = $rowGroup->createRow('override-slider-size-mobile-landscape-row');

        new OnOff($row, 'slider-size-override-mobile-landscape', n2_('Large mobile'), 0, array(
            'relatedFieldsOn' => array(
                'slidermobile-landscape-width',
                'slidermobile-landscape-height'
            )
        ));

        new Number($row, 'mobile-landscape-width', n2_('Width'), 568, array(
            'wide' => 5,
            'unit' => 'px'
        ));
        new Number($row, 'mobile-landscape-height', n2_('Height'), 320, array(
            'wide' => 5,
            'unit' => 'px'
        ));
    
    }

    /**
     * @param ContainerRowGroup $rowGroup
     */
    protected function mobilePortrait($rowGroup) {

        $row = $rowGroup->createRow('override-slider-size-mobile-portrait-row');

        new OnOff($row, 'slider-size-override-mobile-portrait', n2_('Mobile'), 0, array(
            'relatedFieldsOn' => array(
                'slidermobile-portrait-width',
                'slidermobile-portrait-height'
            )
        ));

        new Number($row, 'mobile-portrait-width', n2_('Width'), 320, array(
            'wide' => 5,
            'unit' => 'px'
        ));
        new Number($row, 'mobile-portrait-height', n2_('Height'), 568, array(
            'wide' => 5,
            'unit' => 'px'
        ));
    }
}Admin/FormManager/Slider/SliderOptimize.php000064400000032012152356646020014677 0ustar00<?php


namespace Nextend\SmartSlider3\Application\Admin\FormManager\Slider;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Grouping;
use Nextend\Framework\Form\Element\Message\Notice;
use Nextend\Framework\Form\Element\Message\Warning;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\FormTabbed;

class SliderOptimize extends AbstractSliderTab {

    /**
     * SliderOptimize constructor.
     *
     * @param FormTabbed $form
     */
    public function __construct($form) {
        parent::__construct($form);

        $this->loading();

        $this->optimizeSlide();
        $this->optimizeLayer();
    
        $this->optimizeSliderBackgroundImage();
    

        $this->other();
    }

    /**
     * @return string
     */
    protected function getName() {
        return 'optimize';
    }

    /**
     * @return string
     */
    protected function getLabel() {
        return n2_('Optimize');
    }

    protected function loading() {

        $table = new ContainerTable($this->tab, 'loading', n2_('Loading'));

        $row1 = $table->createRow('loading-1');

        new Select($row1, 'loading-type', n2_('Loading type'), '', array(
            'options'            => array(
                ''            => n2_('Instant'),
                'afterOnLoad' => n2_('After page loaded'),
                'afterDelay'  => n2_('After delay')
            ),
            'relatedValueFields' => array(
                array(
                    'values' => array(
                        'afterDelay'
                    ),
                    'field'  => array(
                        'sliderdelay'
                    )
                )
            ),
            'tipLabel'           => n2_('Loading type'),
            'tipDescription'     => n2_('If your slider is above the fold, you can load it immediately. Otherwise, you can load it only after the page has loaded.'),
            'tipLink'            => 'https://smartslider.helpscoutdocs.com/article/1801-slider-settings-optimize#loading-type'
        ));

        new Number($row1, 'delay', n2_('Load delay'), 0, array(
            'wide' => 5,
            'unit' => 'ms'
        ));

        new OnOff($row1, 'playWhenVisible', n2_('Play when visible'), 1, array(
            'relatedFieldsOn' => array(
                'sliderplayWhenVisibleAt'
            ),
            'tipLabel'        => n2_('Play when visible'),
            'tipDescription'  => n2_('Makes sure that the autoplay and layer animations only start when your slider is visible.')
        ));
        new Number($row1, 'playWhenVisibleAt', n2_('At'), 50, array(
            'unit' => '%',
            'wide' => 3
        ));
    }

    protected function optimizeSlide() {

        $table = new ContainerTable($this->tab, 'optimize-slide', n2_('Slide background images'));

        /**
         * Used for field injection: /optimize/optimize-slide/optimize-slide-loading-mode
         */
        $row1 = $table->createRow('optimize-slide-loading-mode');

        new Select($row1, 'imageload', n2_('Loading mode'), '0', array(
            'options'            => array(
                '0' => n2_('Normal'),
                '2' => n2_('Delayed loading'),
                '1' => n2_('Lazy loading')
            ),
            'relatedValueFields' => array(
                array(
                    'values' => array(
                        '1'
                    ),
                    'field'  => array(
                        'sliderimageloadNeighborSlides'
                    )
                )
            ),
            'tipLabel'           => n2_('Loading mode'),
            'tipDescription'     => n2_('You can speed up your site\'s loading by delaying the slide background images.'),
            'tipLink'            => 'https://smartslider.helpscoutdocs.com/article/1801-slider-settings-optimize#lazy-load'
        ));

        /**
         * Used for field injection: /optimize/optimize-slide/optimize-slide-loading-mode/imageloadNeighborSlides
         */
        new Number($row1, 'imageloadNeighborSlides', n2_('Load neighbor'), 0, array(
            'unit' => n2_x('slides', 'Unit'),
            'wide' => 3
        ));
    

        $row2 = $table->createRow('optimize-slide-2');

        $memoryLimitText = '';
        if (function_exists('ini_get')) {
            $memory_limit = ini_get('memory_limit');
            if (!empty($memory_limit)) {
                $memoryLimitText = ' (' . $memory_limit . ')';
            }
        }

        new Warning($row2, 'optimize-notice', sprintf(n2_('Convert to WebP and image resizing require a lot of memory. Lift the memory limit%s if you get a blank page.'), $memoryLimitText));

        $row3 = $table->createRow('optimize-slide-3');

        new OnOff($row3, 'optimize-webp', n2_('Convert to WebP'), '0', array(
            'relatedFieldsOn' => array(
                'slideroptimize-slide-webp',
                'slideroptimize-quality',
                'slideroptimize-slide-webp-2'
            )
        ));
    

        $optimizeWebp = new Grouping($row3, 'optimize-slide-webp');

        new Number($optimizeWebp, 'optimize-quality', n2_('Quality'), 70, array(
            'min'  => 0,
            'max'  => 100,
            'unit' => '%',
            'wide' => 3,
            'post' => 'break'
        ));
        new OnOff($optimizeWebp, 'optimize-scale', n2_('Resize'), '0', array(
            'relatedFieldsOn' => array(
                'slideroptimize-slide-width-normal',
                'slideroptimize-slide-width-tablet',
                'slideroptimize-slide-height-tablet',
                'slideroptimize-slide-width-mobile',
                'slideroptimize-slide-height-mobile',
                'slideroptimize-slide-width-retina',
                'slideroptimize-slide-scale-notice'
            )
        ));
    

        new Number($optimizeWebp, 'optimize-slide-width-normal', n2_('Default width'), 1920, array(
            'min'  => 0,
            'unit' => 'px',
            'wide' => 4
        ));
        new Number($optimizeWebp, 'optimize-slide-width-tablet', n2_('Medium width'), 1200, array(
            'min'  => 0,
            'unit' => 'px',
            'wide' => 4
        ));
        new Number($optimizeWebp, 'optimize-slide-height-tablet', n2_('Medium height'), 0, array(
            'min'  => 0,
            'unit' => 'px',
            'wide' => 4
        ));
        new Number($optimizeWebp, 'optimize-slide-width-mobile', n2_('Small width'), 500, array(
            'min'  => 0,
            'unit' => 'px',
            'wide' => 4
        ));
        new Number($optimizeWebp, 'optimize-slide-height-mobile', n2_('Small height'), 0, array(
            'min'  => 0,
            'unit' => 'px',
            'wide' => 4
        ));
        new OnOff($optimizeWebp, 'optimize-slide-width-retina', n2_('Retina'), 0);

        $resizeWarning = new Grouping($row3, 'optimize-slide-webp-2');
        new Notice($resizeWarning, 'optimize-slide-scale-notice', n2_('Instruction'), n2_('If your images look blurry on small screens, use the available height option to match the aspect ratio of the slider and image on that device.'));

    

        $row4 = $table->createRow('optimize-slide-4');

        new OnOff($row4, 'optimize-thumbnail-scale', n2_('Resize Thumbnail'), '0', array(
            'relatedFieldsOn' => array(
                'slideroptimize-thumbnail-quality',
                'slideroptimizeThumbnailWidth',
                'slideroptimizeThumbnailHeight'
            )
        ));

        new Number($row4, 'optimize-thumbnail-quality', n2_('Thumbnail Quality'), 70, array(
            'min'  => 0,
            'max'  => 100,
            'unit' => '%',
            'wide' => 3,
            'post' => 'break'
        ));

        new Number($row4, 'optimizeThumbnailWidth', n2_('Thumbnail width'), 100, array(
            'min'  => 0,
            'unit' => 'px',
            'wide' => 4
        ));
        new Number($row4, 'optimizeThumbnailHeight', n2_('Thumbnail height'), 60, array(
            'min'  => 0,
            'unit' => 'px',
            'wide' => 4
        ));

    }

    protected function optimizeLayer() {
        $table = new ContainerTable($this->tab, 'optimize-layer', n2_('Layer images'));

        $row1 = $table->createRow('optimize-layer-1');
        new OnOff($row1, 'layer-image-webp', n2_('Convert to WebP'), '0', array(
            'relatedFieldsOn' => array(
                'sliderlayer-image-optimize-webp'
            )
        ));

        $optimizeWebp = new Grouping($row1, 'layer-image-optimize-webp');

        new Number($optimizeWebp, 'layer-image-optimize-quality', n2_('Quality'), 70, array(
            'min'  => 0,
            'max'  => 100,
            'unit' => '%',
            'wide' => 3,
            'post' => 'break'
        ));

        new OnOff($optimizeWebp, 'layer-image-optimize', n2_('Resize'), '0', array(
            'relatedFieldsOn' => array(
                'sliderlayer-image-width-normal',
                'sliderlayer-image-width-tablet',
                'sliderlayer-image-width-mobile',
                'sliderlayer-image-width-retina'
            )
        ));

        new Number($optimizeWebp, 'layer-image-width-normal', n2_('Default width'), 1400, array(
            'unit' => 'px',
            'wide' => 4
        ));
        new Number($optimizeWebp, 'layer-image-width-tablet', n2_('Medium width'), 800, array(
            'unit' => 'px',
            'wide' => 4
        ));
        new Number($optimizeWebp, 'layer-image-width-mobile', n2_('Small width'), 425, array(
            'unit' => 'px',
            'wide' => 4
        ));
        new OnOff($optimizeWebp, 'layer-image-width-retina', n2_('Retina'), 0);

        $row2 = $table->createRow('optimize-layer-2');
        new OnOff($row2, 'layer-image-base64', n2_('Base64 embed'), '0', array(
            'relatedFieldsOn' => array(
                'sliderlayer-image-base64-size'
            ),
            'tipLabel'        => n2_('Base64 embed'),
            'tipDescription'  => n2_('Embeds the layer images to the page source, reducing the requests.')
        ));
        new Number($row2, 'layer-image-base64-size', n2_('Max file size'), 50, array(
            'min'  => 0,
            'unit' => 'kb',
            'wide' => 5
        ));
    
    }

    protected function optimizeSliderBackgroundImage() {
        $table = new ContainerTable($this->tab, 'optimize-slider', n2_('Slider background image'));

        $row1 = $table->createRow('optimize-slider-1');


        new OnOff($row1, 'optimize-slider-webp', n2_('Convert to WebP'), '0', array(
            'relatedFieldsOn' => array(
                'slideroptimize-slider-webp-group',
                'slideroptimize-slider-quality'
            )
        ));

        $optimizeWebp = new Grouping($row1, 'optimize-slider-webp-group');

        new Number($optimizeWebp, 'optimize-slider-quality', n2_('Quality'), 70, array(
            'min'  => 0,
            'max'  => 100,
            'unit' => '%',
            'wide' => 3,
            'post' => 'break'
        ));


        new OnOff($optimizeWebp, 'optimize-slider-scale', n2_('Resize'), '0', array(
            'relatedFieldsOn' => array(
                'slideroptimize-slider-width-normal',
                'slideroptimize-slider-width-tablet',
                'slideroptimize-slider-height-tablet',
                'slideroptimize-slider-width-mobile',
                'slideroptimize-slider-height-mobile',
            )
        ));

        new Number($optimizeWebp, 'optimize-slider-width-normal', n2_('Default width'), 1920, array(
            'min'  => 0,
            'unit' => 'px',
            'wide' => 4
        ));

        new Number($optimizeWebp, 'optimize-slider-width-tablet', n2_('Medium width'), 1200, array(
            'min'  => 0,
            'unit' => 'px',
            'wide' => 4
        ));
        new Number($optimizeWebp, 'optimize-slider-height-tablet', n2_('Medium height'), 0, array(
            'min'  => 0,
            'unit' => 'px',
            'wide' => 4
        ));
        new Number($optimizeWebp, 'optimize-slider-width-mobile', n2_('Small width'), 500, array(
            'min'  => 0,
            'unit' => 'px',
            'wide' => 4
        ));
        new Number($optimizeWebp, 'optimize-slider-height-mobile', n2_('Small height'), 0, array(
            'min'  => 0,
            'unit' => 'px',
            'wide' => 4
        ));
    
    }

    protected function other() {
        $table = new ContainerTable($this->tab, 'optimize-other', n2_('Other'));

        $row1 = $table->createRow('optimize-other-1');

        new OnOff($row1, 'slides-background-video-mobile', n2_('Background video on mobile'), 1);
    
    }
}Admin/FormManager/Slider/SliderSlides.php000064400000013570152356646020014332 0ustar00<?php

namespace Nextend\SmartSlider3\Application\Admin\FormManager\Slider;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Element\Text\NumberSlider;
use Nextend\Framework\Form\FormTabbed;

class SliderSlides extends AbstractSliderTab {

    /**
     * SliderSlides constructor.
     *
     * @param FormTabbed $form
     */
    public function __construct($form) {
        parent::__construct($form);

        $this->design();
        $this->slides();
        $this->parallax();
    
    }

    /**
     * @return string
     */
    protected function getName() {
        return 'slides';
    }

    /**
     * @return string
     */
    protected function getLabel() {
        return n2_('Slides');
    }

    protected function design() {
        $table = new ContainerTable($this->tab, 'slides-design', n2_('Slides design'));

        /**
         * Used for field injection: /slides/slides-design/slides-design-1
         */
        $row1 = $table->createRow('slides-design-1');

        /**
         * Used for field injection: /slides/slides-design/slides-design-1/backgroundMode
         */
        new Select\FillMode($row1, 'backgroundMode', n2_('Slide background image fill'), 'fill', array(
            'tipLabel'           => n2_('Slide background image fill'),
            'tipDescription'     => n2_('If the size of your image is not the same as your slider\'s, you can improve the result with the filling modes.'),
            'tipLink'            => 'https://smartslider.helpscoutdocs.com/article/1809-slider-settings-slides#slide-background-image-fill',
            'relatedValueFields' => array(
                array(
                    'values' => array(
                        'blurfit'
                    ),
                    'field'  => array(
                        'sliderbackgroundBlurFit'
                    )
                )
            )
        ));

        new NumberSlider($row1, 'backgroundBlurFit', n2_('Background Blur'), 7, array(
            'unit'  => 'px',
            'min'   => 7,
            'max'   => '50',
            'style' => 'width:22px;'
        ));
    }

    protected function slides() {

        /**
         * Used for field removal: /slides/slides-randomize
         */
        $table = new ContainerTable($this->tab, 'slides-randomize', n2_('Randomize'));

        $row1 = $table->createRow('slides-randomize-1');
        new OnOff($row1, 'randomize', n2_('Randomize slides'), 0);
        new OnOff($row1, 'randomizeFirst', n2_('Randomize first'), 0);
        new OnOff($row1, 'randomize-cache', n2_('Cache support'), 1);
        new Number($row1, 'variations', n2_('Cache variations'), 5, array(
            'wide' => 5
        ));

        /**
         * Used for field removal: /slides/other
         */
        $table = new ContainerTable($this->tab, 'other', n2_('Other'));

        $row2 = $table->createRow('other-1');

        new OnOff($row2, 'reverse-slides', n2_('Reverse'), 0, array(
            'tipLabel'       => n2_('Reverse'),
            'tipDescription' => n2_('You can make your slides appear in the slider in a reversed order.')
        ));

        new Number($row2, 'maximumslidecount', n2_('Max count'), 1000, array(
            'wide'           => 4,
            'tipLabel'       => n2_('Max count'),
            'tipDescription' => n2_('You can limit how many slides you want to show from your slider. It\'s best used with the Randomize feature, to improve the experience.')
        ));

        new OnOff($row2, 'maintain-session', n2_('Maintain session'), 0, array(
            'tipLabel'       => n2_('Maintain session'),
            'tipDescription' => n2_('The slider continues from the last viewed slide when the visitor comes back to the page.')
        ));

        $row3 = $table->createRow('slides-2');

        new OnOff($row3, 'global-lightbox', n2_('Backgrounds in lightbox'), 0, array(
            'tipLabel'        => n2_('Backgrounds in lightbox'),
            'tipDescription'  => n2_('Creates a lightbox from your slide background images. This feature only works if all slides have background images.'),
            'tipLink'         => 'https://smartslider.helpscoutdocs.com/article/1809-slider-settings-slides#backgrounds-in-lightbox',
            'relatedFieldsOn' => array(
                'sliderglobal-lightbox-label'
            )
        ));
        new Select($row3, 'global-lightbox-label', n2_('Show label'), '0', array(
            'options' => array(
                '0'        => n2_('No'),
                'name'     => n2_('Only slide name'),
                'namemore' => n2_('Slide name and description')
            )
        ));
    }

    protected function parallax() {


        /**
         * Used for field removal: /slides/slides-parallax
         */
        $table = new ContainerTable($this->tab, 'slides-parallax', n2_('Background parallax'));

        new OnOff($table->getFieldsetLabel(), 'slide-background-parallax', false, 0, array(
            'relatedFieldsOn' => array(
                'table-rows-slides-parallax'
            )
        ));

        $row1 = $table->createRow('slides-parallax-1');
        new Select($row1, 'slide-background-parallax-strength', n2_('Strength'), 50, array(
            'options' => array(
                10  => n2_('Super soft') . ' 10%',
                30  => n2_('Soft') . ' 30%',
                50  => n2_('Normal') . ' 50%',
                75  => n2_('Strong') . ' 75%',
                100 => n2_('Super strong') . ' 100%'
            )
        ));

        new OnOff($row1, 'bg-parallax-tablet', n2_('Tablet'), 0);
        new OnOff($row1, 'bg-parallax-mobile', n2_('Mobile'), 0);
    }
}