| Current Path : /proc/1908984/root/proc/self/root/proc/self/root/proc/2411249/cwd/ |
| Current File : //proc/1908984/root/proc/self/root/proc/self/root/proc/2411249/cwd/Platform.tar |
Base/Filesystem.php 0000644 00000007152 15234602046 0010262 0 ustar 00 <?php
/**
* @package FOF
* @copyright Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU GPL version 2 or later
*/
namespace FOF30\Platform\Base;
use FOF30\Container\Container;
use FOF30\Platform\FilesystemInterface;
defined('_JEXEC') or die;
abstract class Filesystem implements FilesystemInterface
{
/** @var Container The component container */
protected $container = null;
/**
* Public constructor.
*
* @param \FOF30\Container\Container $c The component container
*/
public function __construct(Container $c)
{
$this->container = $c;
}
/**
* The list of paths where platform class files will be looked for
*
* @var array
*/
protected static $paths = array();
/**
* This method will crawl a starting directory and get all the valid files that will be analyzed by getInstance.
* Then it organizes them into an associative array.
*
* @param string $path Folder where we should start looking
* @param array $ignoreFolders Folder ignore list
* @param array $ignoreFiles File ignore list
*
* @return array Associative array, where the `fullpath` key contains the path to the file,
* and the `classname` key contains the name of the class
*/
protected static function getFiles($path, array $ignoreFolders = array(), array $ignoreFiles = array())
{
$return = array();
$files = self::scanDirectory($path, $ignoreFolders, $ignoreFiles);
// Ok, I got the files, now I have to organize them
foreach($files as $file)
{
$clean = str_replace($path, '', $file);
$clean = trim(str_replace('\\', '/', $clean), '/');
$parts = explode('/', $clean);
// If I have less than 3 fragments, it means that the file was inside the generic folder
// (interface + abstract) so I have to skip it
if(count($parts) < 3)
{
continue;
}
$return[] = array(
'fullpath' => $file,
'classname' => 'F0FPlatform'.ucfirst($parts[0]).ucfirst(basename($parts[1], '.php'))
);
}
return $return;
}
/**
* Recursive function that will scan every directory unless it's in the ignore list. Files that aren't in the
* ignore list are returned.
*
* @param string $path Folder where we should start looking
* @param array $ignoreFolders Folder ignore list
* @param array $ignoreFiles File ignore list
*
* @return array List of all the files
*/
protected static function scanDirectory($path, array $ignoreFolders = array(), array $ignoreFiles = array())
{
$return = array();
$handle = @opendir($path);
if(!$handle)
{
return $return;
}
while (($file = readdir($handle)) !== false)
{
if($file == '.' || $file == '..')
{
continue;
}
$fullpath = $path . '/' . $file;
if((is_dir($fullpath) && in_array($file, $ignoreFolders)) || (is_file($fullpath) && in_array($file, $ignoreFiles)))
{
continue;
}
if(is_dir($fullpath))
{
$return = array_merge(self::scanDirectory($fullpath, $ignoreFolders, $ignoreFiles), $return);
}
else
{
$return[] = $path . '/' . $file;
}
}
return $return;
}
/**
* Gets the extension of a file name
*
* @param string $file The file name
*
* @return string The file extension
*/
public function getExt($file)
{
$dot = strrpos($file, '.') + 1;
return substr($file, $dot);
}
/**
* Strips the last extension off of a file name
*
* @param string $file The file name
*
* @return string The file name without the extension
*/
public function stripExt($file)
{
return preg_replace('#\.[^.]*$#', '', $file);
}
}
Base/Platform.php 0000644 00000022235 15234602046 0007721 0 ustar 00 <?php
/**
* @package FOF
* @copyright Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU GPL version 2 or later
*/
namespace FOF30\Platform\Base;
use Exception;
use FOF30\Container\Container;
use FOF30\Input\Input;
use FOF30\Platform\PlatformInterface;
defined('_JEXEC') or die;
/**
* Abstract implementation of the Platform integration
*
* @package FOF30\Platform\Base
*/
abstract class Platform implements PlatformInterface
{
/** @var Container The component container */
protected $container = null;
/**
* Public constructor.
*
* @param \FOF30\Container\Container $c The component container
*/
public function __construct(Container $c)
{
$this->container = $c;
}
/**
* Returns the base (root) directories for a given component.
*
* @param string $component The name of the component. For Joomla! this
* is something like "com_example"
*
* @see F0FPlatformInterface::getComponentBaseDirs()
*
* @return array A hash array with keys main, alt, site and admin.
*/
public function getComponentBaseDirs($component)
{
return array(
'main' => '',
'alt' => '',
'site' => '',
'admin' => '',
);
}
/**
* Returns the application's template name
*
* @param boolean|array $params An optional associative array of configuration settings
*
* @return string The template name. System is the fallback.
*/
public function getTemplate($params = false)
{
return 'system';
}
/**
* Get application-specific suffixes to use with template paths. This allows
* you to look for view template overrides based on the application version.
*
* @return array A plain array of suffixes to try in template names
*/
public function getTemplateSuffixes()
{
return array();
}
/**
* Return the absolute path to the application's template overrides
* directory for a specific component. We will use it to look for template
* files instead of the regular component directories. If the application
* does not have such a thing as template overrides return an empty string.
*
* @param string $component The name of the component for which to fetch the overrides
* @param boolean $absolute Should I return an absolute or relative path?
*
* @return string The path to the template overrides directory
*/
public function getTemplateOverridePath($component, $absolute = true)
{
return '';
}
/**
* Load the translation files for a given component.
*
* @param string $component The name of the component. For Joomla! this
* is something like "com_example"
*
* @see F0FPlatformInterface::loadTranslations()
*
* @return void
*/
public function loadTranslations($component)
{
return null;
}
/**
* Authorise access to the component in the back-end.
*
* @param string $component The name of the component.
*
* @see F0FPlatformInterface::authorizeAdmin()
*
* @return boolean True to allow loading the component, false to halt loading
*/
public function authorizeAdmin($component)
{
return true;
}
/**
* Returns the JUser object for the current user
*
* @param integer $id The ID of the user to fetch
*
* @see F0FPlatformInterface::getUser()
*
* @return \JDocument
*/
public function getUser($id = null)
{
return null;
}
/**
* Returns the JDocument object which handles this component's response.
*
* @see F0FPlatformInterface::getDocument()
*
* @return \JDocument
*/
public function getDocument()
{
return null;
}
/**
* This method will try retrieving a variable from the request (input) data.
*
* @param string $key The user state key for the variable
* @param string $request The request variable name for the variable
* @param Input $input The Input object with the request (input) data
* @param mixed $default The default value. Default: null
* @param string $type The filter type for the variable data. Default: none (no filtering)
* @param boolean $setUserState Should I set the user state with the fetched value?
*
* @see F0FPlatformInterface::getUserStateFromRequest()
*
* @return mixed The value of the variable
*/
public function getUserStateFromRequest($key, $request, $input, $default = null, $type = 'none', $setUserState = true)
{
return $input->get($request, $default, $type);
}
/**
* Load plugins of a specific type. Obviously this seems to only be required
* in the Joomla! CMS.
*
* @param string $type The type of the plugins to be loaded
*
* @see F0FPlatformInterface::importPlugin()
*
* @return void
*/
public function importPlugin($type)
{
}
/**
* Execute plugins (system-level triggers) and fetch back an array with
* their return values.
*
* @param string $event The event (trigger) name, e.g. onBeforeScratchMyEar
* @param array $data A hash array of data sent to the plugins as part of the trigger
*
* @see F0FPlatformInterface::runPlugins()
*
* @return array A simple array containing the results of the plugins triggered
*/
public function runPlugins($event, $data)
{
return array();
}
/**
* Perform an ACL check.
*
* @param string $action The ACL privilege to check, e.g. core.edit
* @param string $assetname The asset name to check, typically the component's name
*
* @see F0FPlatformInterface::authorise()
*
* @return boolean True if the user is allowed this action
*/
public function authorise($action, $assetname)
{
return true;
}
/**
* Is this the administrative section of the component?
*
* @see F0FPlatformInterface::isBackend()
*
* @return boolean
*/
public function isBackend()
{
return true;
}
/**
* Is this the public section of the component?
*
* @see F0FPlatformInterface::isFrontend()
*
* @return boolean
*/
public function isFrontend()
{
return true;
}
/**
* Is this a component running in a CLI application?
*
* @see F0FPlatformInterface::isCli()
*
* @return boolean
*/
public function isCli()
{
return true;
}
/**
* Is AJAX re-ordering supported? This is 100% Joomla!-CMS specific. All
* other platforms should return false and never ask why.
*
* @see F0FPlatformInterface::supportsAjaxOrdering()
*
* @return boolean
*/
public function supportsAjaxOrdering()
{
return true;
}
/**
* Saves something to the cache. This is supposed to be used for system-wide
* F0F data, not application data.
*
* @param string $key The key of the data to save
* @param string $content The actual data to save
*
* @return boolean True on success
*/
public function setCache($key, $content)
{
return false;
}
/**
* Retrieves data from the cache. This is supposed to be used for system-side
* F0F data, not application data.
*
* @param string $key The key of the data to retrieve
* @param string $default The default value to return if the key is not found or the cache is not populated
*
* @return string The cached value
*/
public function getCache($key, $default = null)
{
return false;
}
/**
* Is the global F0F cache enabled?
*
* @return boolean
*/
public function isGlobalFOFCacheEnabled()
{
return true;
}
/**
* Clears the cache of system-wide F0F data. You are supposed to call this in
* your components' installation script post-installation and post-upgrade
* methods or whenever you are modifying the structure of database tables
* accessed by F0F. Please note that F0F's cache never expires and is not
* purged by Joomla!. You MUST use this method to manually purge the cache.
*
* @return boolean True on success
*/
public function clearCache()
{
return false;
}
/**
* logs in a user
*
* @param array $authInfo authentification information
*
* @return boolean True on success
*/
public function loginUser($authInfo)
{
return true;
}
/**
* logs out a user
*
* @return boolean True on success
*/
public function logoutUser()
{
return true;
}
/**
* Logs a deprecated practice. In Joomla! this results in the $message being output in the
* deprecated log file, found in your site's log directory.
*
* @param string $message The deprecated practice log message
*
* @return void
*/
public function logDeprecated($message)
{
// The default implementation does nothing. Override this in your platform classes.
}
public function logUserAction($title, $logText, $extension)
{
// The default implementation does nothing. Override this in your platform classes.
}
/**
* Returns the version number string of the platform, e.g. "4.5.6". If
* implementation integrates with a CMS or a versioned foundation (e.g.
* a framework) it is advisable to return that version.
*
* @return string
*
* @since 2.1.2
*/
public function getPlatformVersion()
{
return '';
}
/**
* Handle an exception in a way that results to an error page.
*
* @param Exception $exception The exception to handle
*
* @throws Exception Possibly rethrown exception
*/
public function showErrorPage(Exception $exception)
{
throw $exception;
}
}
Joomla/Filesystem.php 0000644 00000014226 15234602046 0010631 0 ustar 00 <?php
/**
* @package FOF
* @copyright Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU GPL version 2 or later
*/
namespace FOF30\Platform\Joomla;
use FOF30\Container\Container;
use FOF30\Platform\Base\Filesystem as BaseFilesystem;
defined('_JEXEC') or die;
/**
* Abstraction for Joomla! filesystem API
*/
class Filesystem extends BaseFilesystem
{
/**
* Public constructor
*
* @param \FOF30\Container\Container $c
*/
public function __construct(Container $c)
{
if (class_exists('\\JLoader'))
{
\JLoader::import('joomla.filesystem.path');
\JLoader::import('joomla.filesystem.folder');
\JLoader::import('joomla.filesystem.file');
}
parent::__construct($c);
}
/**
* Does the file exists?
*
* @param $path string Path to the file to test
*
* @return bool
*/
public function fileExists($path)
{
return \JFile::exists($path);
}
/**
* Delete a file or array of files
*
* @param mixed $file The file name or an array of file names
*
* @return boolean True on success
*
*/
public function fileDelete($file)
{
return \JFile::delete($file);
}
/**
* Copies a file
*
* @param string $src The path to the source file
* @param string $dest The path to the destination file
* @param string $path An optional base path to prefix to the file names
* @param boolean $use_streams True to use streams
*
* @return boolean True on success
*/
public function fileCopy($src, $dest, $path = null, $use_streams = false)
{
return \JFile::copy($src, $dest, $path, $use_streams);
}
/**
* Write contents to a file
*
* @param string $file The full file path
* @param string &$buffer The buffer to write
* @param boolean $use_streams Use streams
*
* @return boolean True on success
*/
public function fileWrite($file, &$buffer, $use_streams = false)
{
return \JFile::write($file, $buffer, $use_streams);
}
/**
* Checks for snooping outside of the file system root.
*
* @param string $path A file system path to check.
*
* @return string A cleaned version of the path or exit on error.
*
* @throws \Exception
*/
public function pathCheck($path)
{
return \JPath::check($path);
}
/**
* Function to strip additional / or \ in a path name.
*
* @param string $path The path to clean.
* @param string $ds Directory separator (optional).
*
* @return string The cleaned path.
*
* @throws \UnexpectedValueException
*/
public function pathClean($path, $ds = DIRECTORY_SEPARATOR)
{
return \JPath::clean($path, $ds);
}
/**
* Searches the directory paths for a given file.
*
* @param mixed $paths An path string or array of path strings to search in
* @param string $file The file name to look for.
*
* @return mixed The full path and file name for the target file, or boolean false if the file is not found in any of the paths.
*/
public function pathFind($paths, $file)
{
return \JPath::find($paths, $file);
}
/**
* Wrapper for the standard file_exists function
*
* @param string $path Folder name relative to installation dir
*
* @return boolean True if path is a folder
*/
public function folderExists($path)
{
try
{
return \JFolder::exists($path);
}
catch (\Exception $e)
{
return false;
}
}
/**
* Utility function to read the files in a folder.
*
* @param string $path The path of the folder to read.
* @param string $filter A filter for file names.
* @param mixed $recurse True to recursively search into sub-folders, or an integer to specify the maximum depth.
* @param boolean $full True to return the full path to the file.
* @param array $exclude Array with names of files which should not be shown in the result.
* @param array $excludefilter Array of filter to exclude
* @param boolean $naturalSort False for asort, true for natsort
*
* @return array Files in the given folder.
*/
public function folderFiles($path, $filter = '.', $recurse = false, $full = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'),
$excludefilter = array('^\..*', '.*~'), $naturalSort = false)
{
// JFolder throws nonsense errors if the path is not a folder
try
{
$path = \JPath::clean($path);
}
catch (\Exception $e)
{
return array();
}
if (!@is_dir($path))
{
return array();
}
// Now call JFolder
return \JFolder::files($path, $filter, $recurse, $full, $exclude, $excludefilter, $naturalSort);
}
/**
* Utility function to read the folders in a folder.
*
* @param string $path The path of the folder to read.
* @param string $filter A filter for folder names.
* @param mixed $recurse True to recursively search into sub-folders, or an integer to specify the maximum depth.
* @param boolean $full True to return the full path to the folders.
* @param array $exclude Array with names of folders which should not be shown in the result.
* @param array $excludefilter Array with regular expressions matching folders which should not be shown in the result.
*
* @return array Folders in the given folder.
*/
public function folderFolders($path, $filter = '.', $recurse = false, $full = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'),
$excludefilter = array('^\..*'))
{
// JFolder throws idiotic errors if the path is not a folder
try
{
$path = \JPath::clean($path);
}
catch (\Exception $e)
{
return array();
}
if (!@is_dir($path))
{
return array();
}
// Now call JFolder
return \JFolder::folders($path, $filter, $recurse, $full, $exclude, $excludefilter);
}
/**
* Create a folder -- and all necessary parent folders.
*
* @param string $path A path to create from the base path.
* @param integer $mode Directory permissions to set for folders created. 0755 by default.
*
* @return boolean True if successful.
*/
public function folderCreate($path = '', $mode = 0755)
{
return \JFolder::create($path, $mode);
}
}
Joomla/Platform.php 0000644 00000074320 15234602046 0010272 0 ustar 00 <?php
/**
* @package FOF
* @copyright Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU GPL version 2 or later
*/
namespace FOF30\Platform\Joomla;
use Exception;
use FOF30\Container\Container;
use FOF30\Date\Date;
use FOF30\Date\DateDecorator;
use FOF30\Input\Input;
use FOF30\Platform\Base\Platform as BasePlatform;
use JApplicationCli;
use JApplicationCms;
use JApplicationWeb;
use JCache;
use JFactory;
use Joomla\Registry\Registry;
use JUri;
defined('_JEXEC') or die;
/**
* Part of the FOF Platform Abstraction Layer.
*
* This implements the platform class for Joomla! 3
*
* @since 2.1
*/
class Platform extends BasePlatform
{
/**
* Is this a CLI application?
*
* @var bool
*/
protected static $isCLI = null;
/**
* Is this an administrator application?
*
* @var bool
*/
protected static $isAdmin = null;
/**
* A fake session storage for CLI apps. Since CLI applications cannot have a session we are using a Registry object
* we manage internally.
*
* @var Registry
*/
protected static $fakeSession = null;
/**
* The table and table field cache object, used to speed up database access
*
* @var \JRegistry|Registry|null
*/
private $_cache = null;
/**
* Public constructor.
*
* Overridden to cater for CLI applications not having access to a session object.
*
* @param \FOF30\Container\Container $c The component container
*/
public function __construct(Container $c)
{
parent::__construct($c);
if ($this->isCli())
{
self::$fakeSession = new Registry();
}
}
/**
* Checks if the current script is run inside a valid CMS execution
*
* @see PlatformInterface::checkExecution()
*
* @return bool
*/
public function checkExecution()
{
return defined('_JEXEC');
}
/**
* Raises an error, using the logic requested by the CMS (PHP Exception or dedicated class)
*
* @param integer $code
* @param string $message
*
* @return void
*
* @throws \Exception
*/
public function raiseError($code, $message)
{
$this->showErrorPage(new \Exception($message, $code));
}
/**
* Main function to detect if we're running in a CLI environment and we're admin
*
* @return array isCLI and isAdmin. It's not an associative array, so we can use list().
*/
protected function isCliAdmin()
{
if (is_null(static::$isCLI) && is_null(static::$isAdmin))
{
static::$isCLI = false;
static::$isAdmin = false;
try
{
if (is_null(JFactory::$application))
{
static::$isCLI = true;
static::$isAdmin = false;
return [static::$isCLI, static::$isAdmin];
}
else
{
$app = JFactory::getApplication();
static::$isCLI = $app instanceof \Exception || $app instanceof JApplicationCli;
}
}
catch (\Exception $e)
{
static::$isCLI = true;
}
if (static::$isCLI)
{
return [static::$isCLI, static::$isAdmin];
}
try
{
$app = JFactory::getApplication();
}
catch (Exception $e)
{
return [static::$isCLI, static::$isAdmin];
}
if (method_exists($app, 'isAdmin'))
{
static::$isAdmin = $app->isAdmin();
}
elseif (method_exists($app, 'isClient'))
{
static::$isAdmin = $app->isClient('administrator');
}
}
return array(static::$isCLI, static::$isAdmin);
}
/**
* Returns absolute path to directories used by the CMS.
*
* @see PlatformInterface::getPlatformBaseDirs()
*
* @return array A hash array with keys root, public, admin, tmp and log.
*/
public function getPlatformBaseDirs()
{
return array(
'root' => JPATH_ROOT,
'public' => JPATH_SITE,
'media' => JPATH_SITE . '/media',
'admin' => JPATH_ADMINISTRATOR,
'tmp' => JFactory::getConfig()->get('tmp_path'),
'log' => JFactory::getConfig()->get('log_path')
);
}
/**
* Returns the base (root) directories for a given component.
*
* @param string $component The name of the component. For Joomla! this
* is something like "com_example"
*
* @see PlatformInterface::getComponentBaseDirs()
*
* @return array A hash array with keys main, alt, site and admin.
*/
public function getComponentBaseDirs($component)
{
if (!$this->isBackend())
{
$mainPath = JPATH_SITE . '/components/' . $component;
$altPath = JPATH_ADMINISTRATOR . '/components/' . $component;
}
else
{
$mainPath = JPATH_ADMINISTRATOR . '/components/' . $component;
$altPath = JPATH_SITE . '/components/' . $component;
}
return array(
'main' => $mainPath,
'alt' => $altPath,
'site' => JPATH_SITE . '/components/' . $component,
'admin' => JPATH_ADMINISTRATOR . '/components/' . $component,
);
}
/**
* Returns the application's template name
*
* @param boolean|array $params An optional associative array of configuration settings
*
* @return string The template name. System is the fallback.
*/
public function getTemplate($params = false)
{
return JFactory::getApplication()->getTemplate($params);
}
/**
* Get application-specific suffixes to use with template paths. This allows
* you to look for view template overrides based on the application version.
*
* @return array A plain array of suffixes to try in template names
*/
public function getTemplateSuffixes()
{
$jversion = new \JVersion;
$versionParts = explode('.', $jversion->getShortVersion());
$majorVersion = array_shift($versionParts);
$suffixes = array(
'.j' . str_replace('.', '', $jversion->getHelpVersion()),
'.j' . $majorVersion,
);
return $suffixes;
}
/**
* Return the absolute path to the application's template overrides
* directory for a specific component. We will use it to look for template
* files instead of the regular component directories. If the application
* does not have such a thing as template overrides return an empty string.
*
* @param string $component The name of the component for which to fetch the overrides
* @param boolean $absolute Should I return an absolute or relative path?
*
* @return string The path to the template overrides directory
*/
public function getTemplateOverridePath($component, $absolute = true)
{
list($isCli, $isAdmin) = $this->isCliAdmin();
if (!$isCli)
{
if ($absolute)
{
$path = JPATH_THEMES . '/';
}
else
{
$path = $isAdmin ? 'administrator/templates/' : 'templates/';
}
if (substr($component, 0, 7) == 'media:/')
{
$directory = 'media/' . substr($component, 7);
}
else
{
$directory = 'html/' . $component;
}
$path .= $this->getTemplate() .
'/' . $directory;
}
else
{
$path = '';
}
return $path;
}
/**
* Load the translation files for a given component.
*
* @param string $component The name of the component. For Joomla! this
* is something like "com_example"
*
* @see PlatformInterface::loadTranslations()
*
* @return void
*/
public function loadTranslations($component)
{
if ($this->isBackend())
{
$paths = array(JPATH_ROOT, JPATH_ADMINISTRATOR);
}
else
{
$paths = array(JPATH_ADMINISTRATOR, JPATH_ROOT);
}
$jlang = $this->getLanguage();
$jlang->load($component, $paths[0], 'en-GB', true);
$jlang->load($component, $paths[0], null, true);
$jlang->load($component, $paths[1], 'en-GB', true);
$jlang->load($component, $paths[1], null, true);
}
/**
* Authorise access to the component in the back-end.
*
* @param string $component The name of the component.
*
* @see PlatformInterface::authorizeAdmin()
*
* @return boolean True to allow loading the component, false to halt loading
*/
public function authorizeAdmin($component)
{
if ($this->isBackend())
{
// Master access check for the back-end, Joomla! 1.6 style.
$user = $this->getUser();
if (!$user->authorise('core.manage', $component)
&& !$user->authorise('core.admin', $component)
)
{
return false;
}
}
return true;
}
/**
* Return a user object.
*
* @param integer $id The user ID to load. Skip or use null to retrieve
* the object for the currently logged in user.
*
* @see PlatformInterface::getUser()
*
* @return \JUser The JUser object for the specified user
*/
public function getUser($id = null)
{
/**
* If I'm in CLI I need load the User directly, otherwise JFactory will check the session (which doesn't exist
* in CLI)
*/
if ($this->isCli())
{
if ($id)
{
return \JUser::getInstance($id);
}
return new \JUser();
}
return JFactory::getUser($id);
}
/**
* Returns the JDocument object which handles this component's response.
*
* @see PlatformInterface::getDocument()
*
* @return \JDocument
*/
public function getDocument()
{
$document = null;
if (!$this->isCli())
{
try
{
$document = JFactory::getDocument();
}
catch (\Exception $exc)
{
$document = null;
}
}
return $document;
}
/**
* Returns an object to handle dates
*
* @param mixed $time The initial time
* @param null $tzOffest The timezone offset
* @param bool $locale Should I try to load a specific class for current language?
*
* @return Date object
*/
public function getDate($time = 'now', $tzOffest = null, $locale = true)
{
if ($locale)
{
// Work around a bug in Joomla! 3.7.0.
if ($time == 'now')
{
$time = time();
}
$coreObject = JFactory::getDate($time, $tzOffest);
return new DateDecorator($coreObject);
}
else
{
return new Date($time, $tzOffest);
}
}
/**
* Return the \JLanguage instance of the CMS/application
*
* @return \JLanguage
*/
public function getLanguage()
{
return JFactory::getLanguage();
}
/**
* Returns the database driver object of the CMS/application
*
* @return \JDatabaseDriver
*/
public function getDbo()
{
return JFactory::getDbo();
}
/**
* This method will try retrieving a variable from the request (input) data.
*
* @param string $key The user state key for the variable
* @param string $request The request variable name for the variable
* @param Input $input The Input object with the request (input) data
* @param mixed $default The default value. Default: null
* @param string $type The filter type for the variable data. Default: none (no filtering)
* @param boolean $setUserState Should I set the user state with the fetched value?
*
* @see PlatformInterface::getUserStateFromRequest()
*
* @return mixed The value of the variable
*/
public function getUserStateFromRequest($key, $request, $input, $default = null, $type = 'none', $setUserState = true)
{
list($isCLI, $isAdmin) = $this->isCliAdmin();
unset($isAdmin); // Just to make phpStorm happy
if ($isCLI)
{
$ret = $input->get($request, $default, $type);
if ($ret === $default)
{
$input->set($request, $ret);
}
return $ret;
}
$app = JFactory::getApplication();
if (method_exists($app, 'getUserState'))
{
$old_state = $app->getUserState($key, $default);
}
else
{
$old_state = null;
}
$cur_state = (!is_null($old_state)) ? $old_state : $default;
$new_state = $input->get($request, null, $type);
// Save the new value only if it was set in this request
if ($setUserState)
{
if ($new_state !== null)
{
$app->setUserState($key, $new_state);
}
else
{
$new_state = $cur_state;
}
}
elseif (is_null($new_state))
{
$new_state = $cur_state;
}
return $new_state;
}
/**
* Load plugins of a specific type. Obviously this seems to only be required
* in the Joomla! CMS.
*
* @param string $type The type of the plugins to be loaded
*
* @see PlatformInterface::importPlugin()
*
* @return void
*
* @codeCoverageIgnore
*/
public function importPlugin($type)
{
if (!$this->isCli())
{
\JLoader::import('joomla.plugin.helper');
\JPluginHelper::importPlugin($type);
}
}
/**
* Execute plugins (system-level triggers) and fetch back an array with
* their return values.
*
* @param string $event The event (trigger) name, e.g. onBeforeScratchMyEar
* @param array $data A hash array of data sent to the plugins as part of the trigger
*
* @see PlatformInterface::runPlugins()
*
* @return array A simple array containing the results of the plugins triggered
*
* @codeCoverageIgnore
*/
public function runPlugins($event, $data)
{
if (!$this->isCli())
{
if (class_exists('JEventDispatcher'))
{
return \JEventDispatcher::getInstance()->trigger($event, $data);
}
return JFactory::getApplication()->triggerEvent($event, $data);
}
else
{
return array();
}
}
/**
* Perform an ACL check.
*
* @param string $action The ACL privilege to check, e.g. core.edit
* @param string $assetname The asset name to check, typically the component's name
*
* @see PlatformInterface::authorise()
*
* @return boolean True if the user is allowed this action
*/
public function authorise($action, $assetname)
{
if ($this->isCli())
{
return true;
}
$ret = JFactory::getUser()->authorise($action, $assetname);
// Work around Joomla returning null instead of false in some cases.
return $ret ? true : false;
}
/**
* Is this the administrative section of the component?
*
* @see PlatformInterface::isBackend()
*
* @return boolean
*/
public function isBackend()
{
list ($isCli, $isAdmin) = $this->isCliAdmin();
return $isAdmin && !$isCli;
}
/**
* Is this the public section of the component?
*
* @see PlatformInterface::isFrontend()
*
* @return boolean
*/
public function isFrontend()
{
list ($isCli, $isAdmin) = $this->isCliAdmin();
return !$isAdmin && !$isCli;
}
/**
* Is this a component running in a CLI application?
*
* @see PlatformInterface::isCli()
*
* @return boolean
*/
public function isCli()
{
list ($isCli, $isAdmin) = $this->isCliAdmin();
return !$isAdmin && $isCli;
}
/**
* Is AJAX re-ordering supported? This is 100% Joomla!-CMS specific. All
* other platforms should return false and never ask why.
*
* @see PlatformInterface::supportsAjaxOrdering()
*
* @return boolean
*
* @codeCoverageIgnore
*/
public function supportsAjaxOrdering()
{
return true;
}
/**
* Is the global F0F cache enabled?
*
* @return boolean
*
* @codeCoverageIgnore
*/
public function isGlobalF0FCacheEnabled()
{
return !(defined('JDEBUG') && JDEBUG);
}
/**
* Saves something to the cache. This is supposed to be used for system-wide
* F0F data, not application data.
*
* @param string $key The key of the data to save
* @param string $content The actual data to save
*
* @return boolean True on success
*/
public function setCache($key, $content)
{
$registry = $this->getCacheObject();
$registry->set($key, $content);
return $this->saveCache();
}
/**
* Retrieves data from the cache. This is supposed to be used for system-side
* F0F data, not application data.
*
* @param string $key The key of the data to retrieve
* @param string $default The default value to return if the key is not found or the cache is not populated
*
* @return string The cached value
*/
public function getCache($key, $default = null)
{
$registry = $this->getCacheObject();
return $registry->get($key, $default);
}
/**
* Gets a reference to the cache object, loading it from the disk if
* needed.
*
* @param boolean $force Should I forcibly reload the registry?
*
* @return \JRegistry|Registry
*/
private function &getCacheObject($force = false)
{
// Check if we have to load the cache file or we are forced to do that
if (is_null($this->_cache) || $force)
{
// Try to get data from Joomla!'s cache
$cache = JFactory::getCache('fof', '');
$this->_cache = $cache->get('cache', 'fof');
\JLoader::import('joomla.registry.registry');
$isRegistry = is_object($this->_cache);
if ($isRegistry)
{
$isRegistry = class_exists('JRegistry') ? ($this->_cache instanceof \JRegistry) : ($this->_cache instanceof Registry);
}
if (!$isRegistry)
{
// Create a new Registry object
$this->_cache = class_exists('JRegistry') ? new \JRegistry() : new Registry();
}
}
return $this->_cache;
}
/**
* Save the cache object back to disk
*
* @return boolean True on success
*/
private function saveCache()
{
// Get the Registry object of our cached data
$registry = $this->getCacheObject();
$cache = JFactory::getCache('fof', '');
return $cache->store($registry, 'cache', 'fof');
}
/**
* Clears the cache of system-wide F0F data. You are supposed to call this in
* your components' installation script post-installation and post-upgrade
* methods or whenever you are modifying the structure of database tables
* accessed by F0F. Please note that F0F's cache never expires and is not
* purged by Joomla!. You MUST use this method to manually purge the cache.
*
* @return boolean True on success
*/
public function clearCache()
{
$false = false;
$cache = JFactory::getCache('fof', '');
$cache->store($false, 'cache', 'fof');
}
/**
* Returns an object that holds the configuration of the current site.
*
* @return \JRegistry|Registry
*
* @codeCoverageIgnore
*/
public function getConfig()
{
return JFactory::getConfig();
}
/**
* logs in a user
*
* @param array $authInfo authentification information
*
* @return boolean True on success
*/
public function loginUser($authInfo)
{
\JLoader::import('joomla.user.authentication');
$options = array('remember' => false);
$authenticate = \JAuthentication::getInstance();
$response = $authenticate->authenticate($authInfo, $options);
// User failed to authenticate: maybe he enabled two factor authentication?
// Let's try again "manually", skipping the check vs two factor auth
// Due the big mess with encryption algorithms and libraries, we are doing this extra check only
// if we're in Joomla 2.5.18+ or 3.2.1+
if ($response->status != \JAuthentication::STATUS_SUCCESS && method_exists('JUserHelper', 'verifyPassword'))
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('id, password')
->from('#__users')
->where('username=' . $db->quote($authInfo['username']));
$result = $db->setQuery($query)->loadObject();
if ($result)
{
$match = \JUserHelper::verifyPassword($authInfo['password'], $result->password, $result->id);
if ($match === true)
{
// Bring this in line with the rest of the system
$user = \JUser::getInstance($result->id);
$response->email = $user->email;
$response->fullname = $user->name;
list($isCli, $isAdmin) = $this->isCliAdmin();
if ($isAdmin)
{
$response->language = $user->getParam('admin_language');
}
else
{
$response->language = $user->getParam('language');
}
$response->status = \JAuthentication::STATUS_SUCCESS;
$response->error_message = '';
}
}
}
if ($response->status == \JAuthentication::STATUS_SUCCESS)
{
$this->importPlugin('user');
$results = $this->runPlugins('onLoginUser', array((array)$response, $options));
unset($results); // Just to make phpStorm happy
\JLoader::import('joomla.user.helper');
$userid = \JUserHelper::getUserId($response->username);
$user = $this->getUser($userid);
$session = $this->container->session;
$session->set('user', $user);
return true;
}
return false;
}
/**
* logs out a user
*
* @return boolean True on success
*/
public function logoutUser()
{
\JLoader::import('joomla.user.authentication');
$app = JFactory::getApplication();
$user = $this->getUser();
$options = array('remember' => false);
$parameters = array(
'username' => $user->username,
'id' => $user->id
);
// Set clientid in the options array if it hasn't been set already and shared sessions are not enabled.
if (!$app->get('shared_session', '0'))
{
$options['clientid'] = $app->getClientId();
}
$ret = $app->triggerEvent('onUserLogout', array($parameters, $options));
return !in_array(false, $ret, true);
}
/**
* Add a log file for FOF
*
* @param string $file
*
* @return void
*
* @codeCoverageIgnore
*/
public function logAddLogger($file)
{
\JLog::addLogger(array('text_file' => $file), \JLog::ALL, array('fof'));
}
/**
* Logs a deprecated practice. In Joomla! this results in the $message being output in the
* deprecated log file, found in your site's log directory.
*
* @param string $message The deprecated practice log message
*
* @return void
*
* @codeCoverageIgnore
*/
public function logDeprecated($message)
{
\JLog::add($message, \JLog::WARNING, 'deprecated');
}
/**
* Adds a message to the application's debug log
*
* @param string $message
*
* @return void
*
* @codeCoverageIgnore
*/
public function logDebug($message)
{
\JLog::add($message, \JLog::DEBUG, 'fof');
}
public function logUserAction($title, $logText, $extension)
{
static $joomlaModelAdded = false;
// User Actions Log is available only under Joomla 3.9+
if (version_compare(JVERSION, '3.9', 'lt'))
{
return;
}
// Do not perform logging if we're under CLI. Even if we _could_ have a logged user in CLI, ActionlogsModelActionlog
// model always uses JFactory to fetch the current user, fetching data from the session. This means that under the CLI
// (where there is no session) such session is started, causing warnings because usually output was already started before
if ($this->isCli())
{
return;
}
// Include required Joomla Model
if (!$joomlaModelAdded)
{
\JModelLegacy::addIncludePath(JPATH_ROOT . '/administrator/components/com_actionlogs/models', 'ActionlogsModel');
$joomlaModelAdded = true;
}
$user = $this->getUser();
// No log for guest users
if ($user->guest)
{
return;
}
$message = array(
'title' => $title,
'username' => $user->username,
'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id
);
/** @var \ActionlogsModelActionlog $model **/
try
{
$model = \JModelLegacy::getInstance('Actionlog', 'ActionlogsModel');
$model->addLog(array($message), $logText, $extension, $user->id);
}
catch (\Exception $e)
{
// Ignore any error
}
}
/**
* Returns the root URI for the request.
*
* @param boolean $pathonly If false, prepend the scheme, host and port information. Default is false.
* @param string $path The path
*
* @return string The root URI string.
*
* @codeCoverageIgnore
*/
public function URIroot($pathonly = false, $path = null)
{
\JLoader::import('joomla.environment.uri');
return \JUri::root($pathonly, $path);
}
/**
* Returns the base URI for the request.
*
* @param boolean $pathonly If false, prepend the scheme, host and port information. Default is false.
*
* @return string The base URI string
*
* @codeCoverageIgnore
*/
public function URIbase($pathonly = false)
{
\JLoader::import('joomla.environment.uri');
return \JUri::base($pathonly);
}
/**
* 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 (only if the current platform supports header caching)
*
* @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 void
*
* @codeCoverageIgnore
*/
public function setHeader($name, $value, $replace = false)
{
JFactory::getApplication()->setHeader($name, $value, $replace);
}
/**
* In platforms that perform header caching, send all headers.
*
* @return void
*
* @codeCoverageIgnore
*/
public function sendHeaders()
{
JFactory::getApplication()->sendHeaders();
}
/**
* Immediately terminate the containing application's execution
*
* @param int $code The result code which should be returned by the application
*
* @return void
*/
public function closeApplication($code = 0)
{
// Necessary workaround for broken System - Page Cache plugin in Joomla! 3.7.0
$this->bugfixJoomlaCachePlugin();
JFactory::getApplication()->close($code);
}
/**
* Perform a redirection to a different page, optionally enqueuing a message for the user.
*
* @param string $url The URL to redirect to
* @param int $status (optional) The HTTP redirection status code, default 303 (See Other)
* @param string $msg (optional) A message to enqueue
* @param string $type (optional) The message type, e.g. 'message' (default), 'warning' or 'error'.
*
* @return void
*
* @throws \Exception
*/
public function redirect($url, $status = 303, $msg = '', $type = 'message')
{
// Necessary workaround for broken System - Page Cache plugin in Joomla! 3.7.0
$this->bugfixJoomlaCachePlugin();
$app = JFactory::getApplication();
if (class_exists('JApplicationCms') && class_exists('JApplicationWeb')
&& ($app instanceof JApplicationCms)
&& ($app instanceof JApplicationWeb))
{
// In modern Joomla! versions we have versatility on setting the message and the redirection HTTP code
if (!empty($msg))
{
if (empty($type))
{
$type = 'message';
}
$app->enqueueMessage($msg, $type);
}
$app->redirect($url, $status);
}
/**
* If you're here, you have an ancient Joomla version and we have to use the legacy four parameter method...
* Note that we can't set a custom HTTP code, we can only tell it if it's a permanent redirection or not.
*/
$app->redirect($url, $msg, $type, $status == 301);
}
/**
* Handle an exception in a way that results to an error page. We use this under Joomla! to work around a bug in
* Joomla! 3.7 which results in error pages leading to white pages because Joomla's System - Page Cache plugin is
* broken.
*
* @param Exception $exception The exception to handle
*
* @throws Exception We rethrow the exception
*/
public function showErrorPage(Exception $exception)
{
// Necessary workaround for broken System - Page Cache plugin in Joomla! 3.7.0
$this->bugfixJoomlaCachePlugin();
throw $exception;
}
/**
* Set a variable in the user session
*
* @param string $name The name of the variable to set
* @param string $value (optional) The value to set it to, default is null
* @param string $namespace (optional) The variable's namespace e.g. the component name. Default: 'default'
*
* @return void
*/
public function setSessionVar($name, $value = null, $namespace = 'default')
{
if ($this->isCli())
{
self::$fakeSession->set("$namespace.$name", $value);
return;
}
$this->container->session->set($name, $value, $namespace);
}
/**
* Get a variable from the user session
*
* @param string $name The name of the variable to set
* @param string $default (optional) The default value to return if the variable does not exit, default: null
* @param string $namespace (optional) The variable's namespace e.g. the component name. Default: 'default'
*
* @return mixed
*/
public function getSessionVar($name, $default = null, $namespace = 'default')
{
if ($this->isCli())
{
return self::$fakeSession->get("$namespace.$name", $default);
}
return $this->container->session->get($name, $default, $namespace);
}
/**
* Unset a variable from the user session
*
* @param string $name The name of the variable to unset
* @param string $namespace (optional) The variable's namespace e.g. the component name. Default: 'default'
*
* @return void
*/
public function unsetSessionVar($name, $namespace = 'default')
{
$this->setSessionVar($name, null, $namespace);
}
/**
* Return the session token. Two types of tokens can be returned:
*
* Session token ($formToken == false): Used for anti-spam protection of forms. This is specific to a session
* object.
*
* Form token ($formToken == true): A secure hash of the user ID with the session token. Both the session and the
* user are fetched from the application container. They are interpolated with the site's secret and passed
* through MD5, making this harder to spoof than the plain old session token.
*
* @param bool $formToken Should I return a form token?
* @param bool $forceNew Should I force the creation of a new token?
*
* @return mixed
*/
public function getToken($formToken = false, $forceNew = false)
{
// For CLI apps we implement our own fake token system
if ($this->isCli())
{
$token = $this->getSessionVar('session.token');
// Create a token
if (is_null($token) || $forceNew)
{
$token = \JUserHelper::genRandomPassword(32);
$this->setSessionVar('session.token', $token);
}
if (!$formToken)
{
return $token;
}
$user = $this->getUser();
return \JApplicationHelper::getHash($user->id . $token);
}
// Web application, go through the regular Joomla! API.
if ($formToken)
{
return \JSession::getFormToken($forceNew);
}
return $this->container->session->getToken($forceNew);
}
/**
* Joomla! 3.7 has a broken System - Page Cache plugin. When this plugin is enabled it FORCES the caching of all
* pages as soon as Joomla! starts loading, before the plugin has a chance to request to not be cached. Event worse,
* in case of a redirection, it doesn't try to remove the cache lock. This means that the next request will be
* treated as though the result of the page should be cached. Since there is NO cache content for the page Joomla!
* returns an empty response with a 200 OK header. This will, of course, get in the way of every single attempt to
* perform a redirection in the frontend of the site.
*/
private function bugfixJoomlaCachePlugin()
{
// Only Joomla! 3.7 and later is broken.
if (version_compare(JVERSION, '3.6.999', 'le'))
{
return;
}
// Only do something when the System - Cache plugin is activated
if (!class_exists('PlgSystemCache'))
{
return;
}
// Forcibly uncache the current request
$options = array(
'defaultgroup' => 'page',
'browsercache' => false,
'caching' => false,
);
$cache_key = JUri::getInstance()->toString();
JCache::getInstance('page', $options)->cache->remove($cache_key, 'page');
}
}
FilesystemInterface.php 0000644 00000011424 15234602046 0011226 0 ustar 00 <?php
/**
* @package FOF
* @copyright Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU GPL version 2 or later
*/
namespace FOF30\Platform;
use FOF30\Container\Container;
defined('_JEXEC') or die;
interface FilesystemInterface
{
/**
* Public constructor.
*
* @param \FOF30\Container\Container $c The component container
*/
public function __construct(Container $c);
/**
* Does the file exists?
*
* @param $path string Path to the file to test
*
* @return bool
*/
public function fileExists($path);
/**
* Delete a file or array of files
*
* @param mixed $file The file name or an array of file names
*
* @return boolean True on success
*
*/
public function fileDelete($file);
/**
* Copies a file
*
* @param string $src The path to the source file
* @param string $dest The path to the destination file
*
* @return boolean True on success
*/
public function fileCopy($src, $dest);
/**
* Write contents to a file
*
* @param string $file The full file path
* @param string &$buffer The buffer to write
*
* @return boolean True on success
*/
public function fileWrite($file, &$buffer);
/**
* Checks for snooping outside of the file system root.
*
* @param string $path A file system path to check.
*
* @return string A cleaned version of the path or exit on error.
*
* @throws \Exception
*/
public function pathCheck($path);
/**
* Function to strip additional / or \ in a path name.
*
* @param string $path The path to clean.
* @param string $ds Directory separator (optional).
*
* @return string The cleaned path.
*
* @throws \UnexpectedValueException
*/
public function pathClean($path, $ds = DIRECTORY_SEPARATOR);
/**
* Searches the directory paths for a given file.
*
* @param mixed $paths An path string or array of path strings to search in
* @param string $file The file name to look for.
*
* @return mixed The full path and file name for the target file, or boolean false if the file is not found in any of the paths.
*/
public function pathFind($paths, $file);
/**
* Wrapper for the standard file_exists function
*
* @param string $path Folder name relative to installation dir
*
* @return boolean True if path is a folder
*/
public function folderExists($path);
/**
* Utility function to read the files in a folder.
*
* @param string $path The path of the folder to read.
* @param string $filter A filter for file names.
* @param mixed $recurse True to recursively search into sub-folders, or an integer to specify the maximum depth.
* @param boolean $full True to return the full path to the file.
* @param array $exclude Array with names of files which should not be shown in the result.
* @param array $excludefilter Array of filter to exclude
*
* @return array Files in the given folder.
*/
public function folderFiles($path, $filter = '.', $recurse = false, $full = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'),
$excludefilter = array('^\..*', '.*~'));
/**
* Utility function to read the folders in a folder.
*
* @param string $path The path of the folder to read.
* @param string $filter A filter for folder names.
* @param mixed $recurse True to recursively search into sub-folders, or an integer to specify the maximum depth.
* @param boolean $full True to return the full path to the folders.
* @param array $exclude Array with names of folders which should not be shown in the result.
* @param array $excludefilter Array with regular expressions matching folders which should not be shown in the result.
*
* @return array Folders in the given folder.
*/
public function folderFolders($path, $filter = '.', $recurse = false, $full = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'),
$excludefilter = array('^\..*'));
/**
* Create a folder -- and all necessary parent folders.
*
* @param string $path A path to create from the base path.
* @param integer $mode Directory permissions to set for folders created. 0755 by default.
*
* @return boolean True if successful.
*/
public function folderCreate($path = '', $mode = 0755);
/**
* Gets the extension of a file name
*
* @param string $file The file name
*
* @return string The file extension
*/
public function getExt($file);
/**
* Strips the last extension off of a file name
*
* @param string $file The file name
*
* @return string The file name without the extension
*/
public function stripExt($file);
}
PlatformInterface.php 0000644 00000037001 15234602046 0010665 0 ustar 00 <?php
/**
* @package FOF
* @copyright Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU GPL version 2 or later
*/
namespace FOF30\Platform;
use Exception;
use FOF30\Container\Container;
use FOF30\Date\Date;
use FOF30\Input\Input;
use Joomla\Registry\Registry;
defined('_JEXEC') or die;
/**
* Part of the F0F Platform Abstraction Layer. It implements everything that
* depends on the platform F0F is running under, e.g. the Joomla! CMS front-end,
* the Joomla! CMS back-end, a CLI Joomla! Platform app, a bespoke Joomla!
* Platform / Framework web application and so on.
*/
interface PlatformInterface
{
/**
* Public constructor.
*
* @param \FOF30\Container\Container $c The component container
*/
public function __construct(Container $c);
/**
* Checks if the current script is run inside a valid CMS execution
*
* @return bool
*/
public function checkExecution();
/**
* Raises an error, using the logic requested by the CMS (PHP Exception or dedicated class)
*
* @param integer $code
* @param string $message
*
* @return mixed
*/
public function raiseError($code, $message);
/**
* Returns the version number string of the CMS/application we're running in
*
* @return string
*
* @since 2.1.2
*/
public function getPlatformVersion();
/**
* Returns absolute path to directories used by the containing CMS/application.
*
* The return is a table with the following key:
* * root Path to the site root
* * public Path to the public area of the site
* * admin Path to the administrative area of the site
* * tmp Path to the temp directory
* * log Path to the log directory
*
* @return array A hash array with keys root, public, admin, tmp and log.
*/
public function getPlatformBaseDirs();
/**
* Returns the base (root) directories for a given component, i.e the application
* which is running inside our main application (CMS, web app).
*
* The return is a table with the following keys:
* * main The normal location of component files. For a back-end Joomla!
* component this is the administrator/components/com_example
* directory.
* * alt The alternate location of component files. For a back-end
* Joomla! component this is the front-end directory, e.g.
* components/com_example
* * site The location of the component files serving the public part of
* the application.
* * admin The location of the component files serving the administrative
* part of the application.
*
* All paths MUST be absolute. All four paths MAY be the same if the
* platform doesn't make a distinction between public and private parts,
* or when the component does not provide both a public and private part.
* All of the directories MUST be defined and non-empty.
*
* @param string $component The name of the component. For Joomla! this
* is something like "com_example"
*
* @return array A hash array with keys main, alt, site and admin.
*/
public function getComponentBaseDirs($component);
/**
* Returns the application's template name
*
* @param boolean|array $params An optional associative array of configuration settings
*
* @return string The template name. System is the fallback.
*/
public function getTemplate($params = false);
/**
* Get application-specific suffixes to use with template paths. This allows
* you to look for view template overrides based on the application version.
*
* @return array A plain array of suffixes to try in template names
*/
public function getTemplateSuffixes();
/**
* Return the absolute path to the application's template overrides
* directory for a specific component. We will use it to look for template
* files instead of the regular component directories. If the application
* does not have such a thing as template overrides return an empty string.
*
* @param string $component The name of the component for which to fetch the overrides
* @param boolean $absolute Should I return an absolute or relative path?
*
* @return string The path to the template overrides directory
*/
public function getTemplateOverridePath($component, $absolute = true);
/**
* Load the translation files for a given component.
*
* @param string $component The name of the component. For Joomla! this
* is something like "com_example"
*
* @return void
*/
public function loadTranslations($component);
/**
* By default FOF will only use the Controller's onBefore* methods to
* perform user authorisation. In some cases, like the Joomla! back-end,
* you also need to perform component-wide user authorisation in the
* Dispatcher. This method MUST implement this authorisation check. If you
* do not need this in your platform, please always return true.
*
* @param string $component The name of the component.
*
* @return boolean True to allow loading the component, false to halt loading
*/
public function authorizeAdmin($component);
/**
* This method will try retrieving a variable from the request (input) data.
* If it doesn't exist it will be loaded from the user state, typically
* stored in the session. If it doesn't exist there either, the $default
* value will be used. If $setUserState is set to true, the retrieved
* variable will be stored in the user session.
*
* @param string $key The user state key for the variable
* @param string $request The request variable name for the variable
* @param Input $input The Input object with the request (input) data
* @param mixed $default The default value. Default: null
* @param string $type The filter type for the variable data. Default: none (no filtering)
* @param boolean $setUserState Should I set the user state with the fetched value?
*
* @return mixed The value of the variable
*/
public function getUserStateFromRequest($key, $request, $input, $default = null, $type = 'none', $setUserState = true);
/**
* Load plugins of a specific type. Obviously this seems to only be required
* in the Joomla! CMS itself.
*
* @param string $type The type of the plugins to be loaded
*
* @return void
*/
public function importPlugin($type);
/**
* Execute plugins (system-level triggers) and fetch back an array with
* their return values.
*
* @param string $event The event (trigger) name, e.g. onBeforeScratchMyEar
* @param array $data A hash array of data sent to the plugins as part of the trigger
*
* @return array A simple array containing the results of the plugins triggered
*/
public function runPlugins($event, $data);
/**
* Perform an ACL check. Please note that FOF uses by default the Joomla!
* CMS convention for ACL privileges, e.g core.edit for the edit privilege.
* If your platform uses different conventions you'll have to override the
* F0F defaults using fof.xml or by specialising the controller.
*
* @param string $action The ACL privilege to check, e.g. core.edit
* @param string $assetname The asset name to check, typically the component's name
*
* @return boolean True if the user is allowed this action
*/
public function authorise($action, $assetname);
/**
* Returns a user object.
*
* @param integer $id The user ID to load. Skip or use null to retrieve
* the object for the currently logged in user.
*
* @return \JUser The \JUser object for the specified user
*/
public function getUser($id = null);
/**
* Returns the \JDocument object which handles this component's response. You
* may also return null and FOF will a. try to figure out the output type by
* examining the "format" input parameter (or fall back to "html") and b.
* FOF will not attempt to load CSS and Javascript files (as it doesn't make
* sense if there's no \JDocument to handle them).
*
* @return \JDocument
*/
public function getDocument();
/**
* Returns an object to handle dates
*
* @param mixed $time The initial time
* @param null $tzOffest The timezone offset
* @param bool $locale Should I try to load a specific class for current language?
*
* @return Date object
*/
public function getDate($time = 'now', $tzOffest = null, $locale = true);
/**
* Return the \JLanguage instance of the CMS/application
*
* @return \JLanguage
*/
public function getLanguage();
/**
* Returns the database driver object of the CMS/application
*
* @return \JDatabaseDriver
*/
public function getDbo();
/**
* Is this the administrative section of the component?
*
* @return boolean
*/
public function isBackend();
/**
* Is this the public section of the component?
*
* @return boolean
*/
public function isFrontend();
/**
* Is this a component running in a CLI application?
*
* @return boolean
*/
public function isCli();
/**
* Is AJAX re-ordering supported? This is 100% Joomla! CMS (version 3+) specific.
*
* @return boolean
*/
public function supportsAjaxOrdering();
/**
* Saves something to the cache. This is supposed to be used for system-wide
* FOF data, not application data.
*
* @param string $key The key of the data to save
* @param string $content The actual data to save
*
* @return boolean True on success
*/
public function setCache($key, $content);
/**
* Retrieves data from the cache. This is supposed to be used for system-side
* FOF data, not application data.
*
* @param string $key The key of the data to retrieve
* @param string $default The default value to return if the key is not found or the cache is not populated
*
* @return string The cached value
*/
public function getCache($key, $default = null);
/**
* Clears the cache of system-wide FOF data. You are supposed to call this in
* your components' installation script post-installation and post-upgrade
* methods or whenever you are modifying the structure of database tables
* accessed by F0F. Please note that FOF's cache never expires and is not
* purged by Joomla!. You MUST use this method to manually purge the cache.
*
* @return boolean True on success
*/
public function clearCache();
/**
* Returns an object that holds the configuration of the current site.
*
* @return Registry
*/
public function getConfig();
/**
* Is the global FOF cache enabled?
*
* @return boolean
*/
public function isGlobalFOFCacheEnabled();
/**
* logs in a user
*
* @param array $authInfo authentification information
*
* @return boolean True on success
*/
public function loginUser($authInfo);
/**
* logs out a user
*
* @return boolean True on success
*/
public function logoutUser();
/**
* Add a log file for FOF
*
* @param string $file
*
* @return void
*/
public function logAddLogger($file);
/**
* Logs a deprecated practice. In Joomla! this results in the $message being output in the
* deprecated log file, found in your site's log directory.
*
* @param string $message The deprecated practice log message
*
* @return void
*/
public function logDeprecated($message);
/**
* Adds a message to the application's debug log
*
* @param string $message
*
* @return void
*/
public function logDebug($message);
/**
* Adds a message
*
* @param string $title
* @param string $logText
* @param string $extension
*
* @return void
*/
public function logUserAction($title, $logText, $extension);
/**
* Returns the root URI for the request.
*
* @param boolean $pathonly If false, prepend the scheme, host and port information. Default is false.
* @param string $path The path
*
* @return string The root URI string.
*/
public function URIroot($pathonly = false, $path = null);
/**
* Returns the base URI for the request.
*
* @param boolean $pathonly If false, prepend the scheme, host and port information. Default is false.
* |
* @return string The base URI string
*/
public function URIbase($pathonly = false);
/**
* 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 (only if the current platform supports header caching)
*
* @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 void
*/
public function setHeader($name, $value, $replace = false);
/**
* In platforms that perform header caching, send all headers.
*
* @return void
*/
public function sendHeaders();
/**
* Immediately terminate the containing application's execution
*
* @param int $code The result code which should be returned by the application
*
* @return void
*/
public function closeApplication($code = 0);
/**
* Perform a redirection to a different page, optionally enqueuing a message for the user.
*
* @param string $url The URL to redirect to
* @param int $status (optional) The HTTP redirection status code, default 301
* @param string $msg (optional) A message to enqueue
* @param string $type (optional) The message type, e.g. 'message' (default), 'warning' or 'error'.
*
* @return void
*
* @throws \Exception
*/
public function redirect($url, $status = 301, $msg = null, $type = 'message');
/**
* Handle an exception in a way that results to an error page.
*
* @param Exception $exception The exception to handle
*
* @throws Exception Possibly rethrown exception
*/
public function showErrorPage(Exception $exception);
/**
* Set a variable in the user session
*
* @param string $name The name of the variable to set
* @param string $value (optional) The value to set it to, default is null
* @param string $namespace (optional) The variable's namespace e.g. the component name. Default: 'default'
*
* @return void
*/
public function setSessionVar($name, $value = null, $namespace = 'default');
/**
* Get a variable from the user session
*
* @param string $name The name of the variable to set
* @param string $default (optional) The default value to return if the variable does not exit, default: null
* @param string $namespace (optional) The variable's namespace e.g. the component name. Default: 'default'
*
* @return mixed
*/
public function getSessionVar($name, $default = null, $namespace = 'default');
/**
* Unset a variable from the user session
*
* @param string $name The name of the variable to unset
* @param string $namespace (optional) The variable's namespace e.g. the component name. Default: 'default'
*
* @return void
*/
public function unsetSessionVar($name, $namespace = 'default');
/**
* Return the session token. Two types of tokens can be returned:
*
* Session token ($formToken == false): Used for anti-spam protection of forms. This is specific to a session
* object.
*
* Form token ($formToken == true): A secure hash of the user ID with the session token. Both the session and the
* user are fetched from the application container.
*
* @param bool $formToken Should I return a form token?
* @param bool $forceNew Should I force the creation of a new token?
*
* @return mixed
*/
public function getToken($formToken = false, $forceNew = false);
}
AbstractSmartSlider3Platform.php 0000644 00000001137 15235664472 0013002 0 ustar 00 <?php
namespace Nextend\SmartSlider3\Platform;
use Nextend\Framework\Pattern\GetAssetsPathTrait;
use Nextend\Framework\Pattern\SingletonTrait;
abstract class AbstractSmartSlider3Platform {
use SingletonTrait, GetAssetsPathTrait;
public abstract function start();
/**
* @return string
*/
public abstract function getAdminUrl();
/**
* @return string
*/
public abstract function getAdminAjaxUrl();
/**
* @return string
*/
public function getNetworkAdminUrl() {
return $this->getAdminUrl();
}
} SmartSlider3Platform.php 0000644 00000001356 15235664472 0011321 0 ustar 00 <?php
namespace Nextend\SmartSlider3\Platform;
use Nextend\Framework\Pattern\SingletonTrait;
class SmartSlider3Platform {
use SingletonTrait;
/**
* @var AbstractSmartSlider3Platform
*/
private static $platform;
public function __construct() {
self::$platform = Joomla\SmartSlider3PlatformJoomla::getInstance();
self::$platform->start();
}
public static function getAdminUrl() {
return self::$platform->getAdminUrl();
}
public static function getAdminAjaxUrl() {
return self::$platform->getAdminAjaxUrl();
}
public static function getNetworkAdminUrl() {
return self::$platform->getNetworkAdminUrl();
}
} Joomla/AdministratorComponent.php 0000644 00000005433 15235664472 0013224 0 ustar 00 <?php
namespace Nextend\SmartSlider3\Platform\Joomla;
use Joomla\CMS\Access\Exception\NotAllowed;
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Uri\Uri;
use Nextend\Framework\PageFlow;
use Nextend\Framework\Request\Request;
use Nextend\SmartSlider3\Application\ApplicationSmartSlider3;
use Nextend\SmartSlider3\Install\Install;
use Nextend\SmartSlider3\Install\Tables;
use Nextend\SmartSlider3\Platform\SmartSlider3Platform;
use Nextend\SmartSlider3\Settings;
use Nextend\SmartSlider3\SmartSlider3Info;
use plgSystemSmartSlider3;
class AdministratorComponent {
public function __construct() {
$this->checkAcl();
if (!Request::$GET->getInt('keepalive')) {
/**
* Required for the license activation to work.
*/
Factory::getApplication()
->setHeader('cross-origin-opener-policy', 'unsafe-none', true);
$this->loadSystemPlugins();
if (Settings::get('n2_ss3_version') != SmartSlider3Info::$completeVersion) {
Install::install();
} else if (Request::$REQUEST->getInt('repairss3')) {
Install::install();
Tables::repair();
header('LOCATION: ' . SmartSlider3Platform::getAdminUrl());
exit;
}
$applicationType = ApplicationSmartSlider3::getInstance()
->getApplicationTypeAdmin();
$isAjax = Request::$GET->getInt('nextendajax');
$applicationType->processRequest('sliders', 'gettingstarted', $isAjax);
?>
<script>
_N2.r('$', function () {
var $ = _N2.$;
var __keepAlive = function () {
$.get('<?php echo esc_url(Uri::current() . '?option=com_smartslider3&keepalive=1');?>', function () {
setTimeout(__keepAlive, 300000);
});
};
setTimeout(__keepAlive, 300000);
});
</script>
<?php
PageFlow::markApplicationEnd();
}
}
protected function checkAcl() {
if (!Factory::getUser()
->authorise('core.manage', 'com_smartslider3')) {
throw new NotAllowed(Text::_('JERROR_ALERTNOAUTHOR'), 403);
}
}
protected function loadSystemPlugins() {
if (!class_exists('plgSystemSmartSlider3')) {
$plugin = PluginHelper::getPlugin('system', 'smartslider3');
new plgSystemSmartSlider3(JoomlaShim::getDispatcher(), (array)($plugin));
}
}
} Joomla/compat.php 0000644 00000000704 15235664472 0010000 0 ustar 00 <?php
use Nextend\SmartSlider3\Application\ApplicationSmartSlider3;
function nextend_smartslider3($sliderId, $usage = 'Used in PHP') {
$applicationTypeFrontend = ApplicationSmartSlider3::getInstance()
->getApplicationTypeFrontend();
$applicationTypeFrontend->process('slider', 'display', false, array(
'sliderID' => $sliderId,
'usage' => $usage
));
} Joomla/ImageFallback.php 0000644 00000007121 15235664472 0011157 0 ustar 00 <?php
namespace Nextend\SmartSlider3\Platform\Joomla;
use Joomla\CMS\Uri\Uri;
use Nextend\Framework\Filesystem\Filesystem;
use Nextend\Framework\Request\Request;
class ImageFallback {
static public function fallback($imageVars, $textVars = array(), $root = '') {
$root = self::fixRoot($root);
$return = '';
foreach ($imageVars as $image) {
if (!empty($image)) {
if (strpos($image, '#') !== false) {
$imageHelper = explode('#', $image);
$realImage = $imageHelper[0];
} else {
$realImage = $image;
}
$return = self::getImage($realImage, $root);
if (!empty($return)) {
break;
}
}
}
if ($return == '' && !empty($textVars)) {
foreach ($textVars as $text) {
$imageInText = self::findImage($text);
if (!empty($imageInText)) {
$return = self::getImage($imageInText, $root);
if ($return != '$/') {
break;
} else {
$return = '';
}
}
}
}
return $return;
}
static public function fixRoot($root) {
if (substr($root, 0, 5) != 'http:' && substr($root, 0, 6) != 'https:') {
$root = self::siteURL();
}
return self::removeSlashes($root);
}
static public function getImage($image, $root) {
$imageUrl = self::httpLink($image, $root);
if (self::isExternal($imageUrl) || self::imageUrlExists($imageUrl)) {
return $imageUrl;
} else {
return '';
}
}
static public function findImage($s) {
preg_match_all('/(<img.*?src=[\'"](.*?)[\'"][^>]*>)|(background(-image)??\s*?:.*?url\((["|\']?)?(.+?)(["|\']?)?\))/i', $s, $r);
if (isset($r[2]) && !empty($r[2][0])) {
$s = $r[2][0];
} else if (isset($r[6]) && !empty($r[6][0])) {
$s = trim($r[6][0], "'\" \t\n\r\0\x0B");
} else {
$s = '';
}
return $s;
}
static public function removeSlashes($text, $right = true) {
if ($right) {
return rtrim($text, '/\\');
} else {
return ltrim($text, '/\\');
}
}
static public function siteURL() {
return Uri::root(false);
}
static public function isExternal($url) {
$url = str_replace(array(
'http:',
'https:',
'//',
'\\\\'
), '', $url);
$domain = Request::$SERVER->getVar('HTTP_HOST');
return !(substr($url, 0, strlen($domain)) === $domain);
}
static public function httpLink($image, $root) {
if (substr($image, 0, 5) != 'http:' && substr($image, 0, 6) != 'https:' && substr($image, 0, 2) != '//' && substr($image, 0, 2) != '\\\\') {
return $root . '/' . self::removeSlashes($image, false);
} else {
return $image;
}
}
static public function imageUrlExists($imageUrl) {
if (substr($imageUrl, 0, 2) == '//' || substr($imageUrl, 0, 2) == '\\\\') {
$imageUrl = (strtolower(Request::$SERVER->getCmd('HTTPS', 'off')) != 'off' ? "https:" : "http:") . $imageUrl;
}
return Filesystem::existsFile(Filesystem::absoluteURLToPath(urldecode($imageUrl)));
}
} Joomla/Joomla3Assets.php 0000644 00000025030 15235664472 0011203 0 ustar 00 <?php
namespace Nextend\SmartSlider3\Platform\Joomla;
use Joomla\CMS\Document\HtmlDocument;
use Joomla\CMS\Factory;
class Joomla3Assets {
/**
* @var HtmlDocument
*/
private $document;
private $original = array();
private $updates = array();
public function __construct() {
$this->document = Factory::getDocument();
$this->original['_styleSheets'] = $this->document->_styleSheets;
$this->original['_style'] = $this->document->_style;
$this->original['_scripts'] = $this->document->_scripts;
$this->original['_script'] = $this->document->_script;
$this->document->_style = array();
$this->document->_script = array();
}
public function process() {
$this->updates['_styleSheets'] = array_diff_key($this->document->_styleSheets, $this->original['_styleSheets']);
$this->updates['_style'] = $this->document->_style;
$this->updates['_scripts'] = array_diff_key($this->document->_scripts, $this->original['_scripts']);
$this->updates['_script'] = $this->document->_script;
$this->document->_style = $this->original['_style'];
$this->document->_script = $this->original['_script'];
}
/**
* Based on Joomla\CMS\Document\DocumentRendererHead
*
* @return string
*/
public function renderHead() {
if (get_class($this->document) === 'Joomla\CMS\Document\HtmlDocument') {
$lnEnd = $this->document->_getLineEnd();
$tab = $this->document->_getTab();
$tagEnd = ' >';
$buffer = '';
$mediaVersion = $this->document->getMediaVersion();
$defaultCssMimes = array('text/css');
// Generate stylesheet links
foreach ($this->updates['_styleSheets'] as $src => $attribs) {
// Check if stylesheet uses IE conditional statements.
$conditional = isset($attribs['options']) && isset($attribs['options']['conditional']) ? $attribs['options']['conditional'] : null;
// Check if script uses media version.
if (isset($attribs['options']['version']) && $attribs['options']['version'] && strpos($src, '?') === false && ($mediaVersion || $attribs['options']['version'] !== 'auto')) {
$src .= '?' . ($attribs['options']['version'] === 'auto' ? $mediaVersion : $attribs['options']['version']);
}
$buffer .= $tab;
// This is for IE conditional statements support.
if (!is_null($conditional)) {
$buffer .= '<!--[if ' . $conditional . ']>';
}
$buffer .= '<link href="' . $src . '" rel="stylesheet"';
// Add script tag attributes.
foreach ($attribs as $attrib => $value) {
// Don't add the 'options' attribute. This attribute is for internal use (version, conditional, etc).
if ($attrib === 'options') {
continue;
}
// Don't add type attribute if document is HTML5 and it's a default mime type. 'mime' is for B/C.
if (in_array($attrib, array(
'type',
'mime'
)) && $this->document->isHtml5() && in_array($value, $defaultCssMimes)) {
continue;
}
// Don't add type attribute if document is HTML5 and it's a default mime type. 'mime' is for B/C.
if ($attrib === 'mime') {
$attrib = 'type';
}
// Add attribute to script tag output.
$buffer .= ' ' . htmlspecialchars($attrib, ENT_COMPAT, 'UTF-8');
// Json encode value if it's an array.
$value = !is_scalar($value) ? json_encode($value) : $value;
$buffer .= '="' . htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '"';
}
$buffer .= $tagEnd;
// This is for IE conditional statements support.
if (!is_null($conditional)) {
$buffer .= '<![endif]-->';
}
$buffer .= $lnEnd;
}
// Generate stylesheet declarations
foreach ($this->updates['_style'] as $type => $content) {
$buffer .= $tab . '<style';
if (!is_null($type) && (!$this->document->isHtml5() || !in_array($type, $defaultCssMimes))) {
$buffer .= ' type="' . $type . '"';
}
$buffer .= '>' . $lnEnd;
// This is for full XHTML support.
if ($this->document->_mime != 'text/html') {
$buffer .= $tab . $tab . '/*<![CDATA[*/' . $lnEnd;
}
$buffer .= $content . $lnEnd;
// See above note
if ($this->document->_mime != 'text/html') {
$buffer .= $tab . $tab . '/*]]>*/' . $lnEnd;
}
$buffer .= $tab . '</style>' . $lnEnd;
}
// Generate scripts options
$scriptOptions = $this->document->getScriptOptions();
if (!empty($scriptOptions)) {
$buffer .= $tab . '<script type="application/json" class="joomla-script-options new">';
$prettyPrint = (JDEBUG && defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : false);
$jsonOptions = json_encode($scriptOptions, $prettyPrint);
$jsonOptions = $jsonOptions ? $jsonOptions : '{}';
$buffer .= $jsonOptions;
$buffer .= '</script>' . $lnEnd;
}
$defaultJsMimes = array(
'text/javascript',
'application/javascript',
'text/x-javascript',
'application/x-javascript'
);
$html5NoValueAttributes = array(
'defer',
'async'
);
foreach ($this->updates['_scripts'] as $src => $attribs) {
// Check if script uses IE conditional statements.
$conditional = isset($attribs['options']) && isset($attribs['options']['conditional']) ? $attribs['options']['conditional'] : null;
// Check if script uses media version.
if (isset($attribs['options']['version']) && $attribs['options']['version'] && strpos($src, '?') === false && ($mediaVersion || $attribs['options']['version'] !== 'auto')) {
$src .= '?' . ($attribs['options']['version'] === 'auto' ? $mediaVersion : $attribs['options']['version']);
}
$buffer .= $tab;
// This is for IE conditional statements support.
if (!is_null($conditional)) {
$buffer .= '<!--[if ' . $conditional . ']>';
}
$buffer .= '<script src="' . $src . '"';
// Add script tag attributes.
foreach ($attribs as $attrib => $value) {
// Don't add the 'options' attribute. This attribute is for internal use (version, conditional, etc).
if ($attrib === 'options') {
continue;
}
// Don't add type attribute if document is HTML5 and it's a default mime type. 'mime' is for B/C.
if (in_array($attrib, array(
'type',
'mime'
)) && $this->document->isHtml5() && in_array($value, $defaultJsMimes)) {
continue;
}
// B/C: If defer and async is false or empty don't render the attribute.
if (in_array($attrib, array(
'defer',
'async'
)) && !$value) {
continue;
}
// Don't add type attribute if document is HTML5 and it's a default mime type. 'mime' is for B/C.
if ($attrib === 'mime') {
$attrib = 'type';
} // B/C defer and async can be set to yes when using the old method.
else if (in_array($attrib, array(
'defer',
'async'
)) && $value === true) {
$value = $attrib;
}
// Add attribute to script tag output.
$buffer .= ' ' . htmlspecialchars($attrib, ENT_COMPAT, 'UTF-8');
if (!($this->document->isHtml5() && in_array($attrib, $html5NoValueAttributes))) {
// Json encode value if it's an array.
$value = !is_scalar($value) ? json_encode($value) : $value;
$buffer .= '="' . htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '"';
}
}
$buffer .= '></script>';
// This is for IE conditional statements support.
if (!is_null($conditional)) {
$buffer .= '<![endif]-->';
}
$buffer .= $lnEnd;
}
foreach ($this->updates['_script'] as $type => $content) {
$buffer .= $tab . '<script';
if (!is_null($type) && (!$this->document->isHtml5() || !in_array($type, $defaultJsMimes))) {
$buffer .= ' type="' . $type . '"';
}
$buffer .= '>' . $lnEnd;
// This is for full XHTML support.
if ($this->document->_mime != 'text/html') {
$buffer .= $tab . $tab . '//<![CDATA[' . $lnEnd;
}
$buffer .= $content . $lnEnd;
// See above note
if ($this->document->_mime != 'text/html') {
$buffer .= $tab . $tab . '//]]>' . $lnEnd;
}
$buffer .= $tab . '</script>' . $lnEnd;
}
return $buffer;
} else {
return null;
}
}
} Joomla/JoomlaModule.php 0000644 00000000775 15235664472 0011114 0 ustar 00 <?php
namespace Nextend\SmartSlider3\Platform\Joomla;
use Joomla\Registry\Registry;
class JoomlaModule {
/**
* JoomlaModule constructor.
*
* @param Registry $params
*/
public function __construct($params) {
$sliderId = intval($params->get('slider'));
if (defined('LITESPEED_ESI_SUPPORT')) {
nextend_smartslider3($sliderId);
} else {
echo 'smartslider3[' . esc_html($sliderId) . ']';
}
}
} Joomla/JoomlaShim.php 0000644 00000020572 15235664472 0010564 0 ustar 00 <?php
namespace Nextend\SmartSlider3\Platform\Joomla;
use Exception;
use JEventDispatcher;
use Joomla\CMS\Factory;
use Joomla\Event\Event;
use Joomla\CMS\Plugin\PluginHelper;
use Nextend\Framework\Pattern\SingletonTrait;
use Nextend\Security\Joomla\JoomlaSecurity;
use Nextend\SmartSlider3\Settings;
use ReflectionFunction;
class JoomlaShim {
use SingletonTrait;
public static $isJoomla4 = 0;
protected function init() {
self::$isJoomla4 = version_compare(JVERSION, '4', '>=') ? 1 : 0;
JoomlaSecurity::getInstance();
}
public static function getDispatcher() {
if (!self::$isJoomla4) {
return JEventDispatcher::getInstance();
}
return Factory::getApplication()
->getDispatcher();
}
private static function getExcludedContentPlugins() {
static $excludedPlugins;
if ($excludedPlugins === null) {
$excludedPlugins = explode('||', Settings::get('joomla-plugins-content-excluded', ''));
$excludedPlugins[] = 'plgcontentemailcloak';
$excludedPlugins[] = 'plgcontentdropeditor';
$excludedPlugins[] = 'plgcontentshortcode_ultimate';
$excludedPlugins[] = 'plgcontentarkcontent';
$excludedPlugins[] = 'plgcontentosyoutube';
$excludedPlugins[] = 'plgsystemt4';
$excludedPlugins[] = 'plgcontentfields';
}
return $excludedPlugins;
}
public static function triggerOnContentPrepare($data) {
static $contentPluginsEnabled, $pluginsToRun = array();
PluginHelper::importPlugin('content');
if (!self::$isJoomla4) {
if ($contentPluginsEnabled === null) {
$contentPluginsEnabled = intval(Settings::get('joomla-plugins-content-enabled', 1));
if ($contentPluginsEnabled) {
$classNames = array();
foreach (PluginHelper::getPlugin('content') as $plugin) {
$classNames[] = strtolower('Plg' . $plugin->type . $plugin->name);
}
$classNames = array_diff($classNames, self::getExcludedContentPlugins());
$dispatcher = JEventDispatcher::getInstance();
$observers = $dispatcher->get('_observers');
foreach ($observers as $observer) {
if (is_object($observer)) {
$className = strtolower(get_class($observer));
if (in_array($className, $classNames)) {
$pluginsToRun[] = $observer;
} else if (method_exists($observer, 'onContentPrepare') && !in_array($className, self::getExcludedContentPlugins())) {
$pluginsToRun[] = $observer;
}
}
}
}
}
if ($contentPluginsEnabled && !empty($pluginsToRun)) {
foreach ($pluginsToRun as $observer) {
// Joomla removes it in every update
$data['event'] = 'oncontentprepare';
$observer->update($data);
}
}
return true;
}
if ($contentPluginsEnabled === null) {
$contentPluginsEnabled = intval(Settings::get('joomla-plugins-content-enabled', 1));
if ($contentPluginsEnabled) {
$classNames = array();
foreach (PluginHelper::getPlugin('content') as $plugin) {
$classNames[] = strtolower('Plg' . $plugin->type . $plugin->name);
}
$classNames = array_diff($classNames, self::getExcludedContentPlugins());
$dispatcher = Factory::getApplication()
->getDispatcher();
$listeners = $dispatcher->getListeners('onContentPrepare');
foreach ($listeners as $listener) {
if (is_array($listener)) {
if (is_callable($listener) && is_object($listener[0])) {
$className = strtolower(get_class($listener[0]));
if (in_array($className, $classNames)) {
$pluginsToRun[] = $listener;
}
}
} else {
$fn = new ReflectionFunction($listener);
$fnClosure = $fn->getClosureThis();
if (is_object($fnClosure)) {
$className = strtolower(get_class($fnClosure));
if (in_array($className, $classNames)) {
$pluginsToRun[] = $listener;
}
}
}
}
}
}
if ($contentPluginsEnabled && !empty($pluginsToRun)) {
$event = new Event('onContentPrepare', $data);
foreach ($pluginsToRun as $callable) {
try {
call_user_func($callable, $event);
} catch (Exception $e) {
}
}
}
return true;
}
public static function getOnContentPreparePluginsList() {
if (!self::$isJoomla4) {
PluginHelper::importPlugin('content');
$dispatcher = JEventDispatcher::getInstance();
$classNames = array();
foreach ($dispatcher->get('_observers') as $observer) {
if ((is_object($observer) || (is_string($observer) && class_exists($observer))) && method_exists($observer, 'onContentPrepare')) {
$className = strtolower(get_class($observer));
$classNames[$className] = $className;
}
}
foreach (PluginHelper::getPlugin('content') as $plugin) {
$className = strtolower('Plg' . $plugin->type . $plugin->name);
$classNames[$className] = ucfirst($plugin->name);
}
return $classNames;
}
PluginHelper::importPlugin('content');
$dispatcher = Factory::getApplication()
->getDispatcher();
$classNames = array();
foreach ($dispatcher->getListeners('onContentPrepare') as $listener) {
if (is_array($listener)) {
if (is_callable($listener) && is_object($listener[0])) {
$className = strtolower(get_class($listener[0]));
$classNames[$className] = $className;
}
} else {
$fn = new ReflectionFunction($listener);
$fnClosure = $fn->getClosureThis();
if (is_object($fnClosure)) {
$className = strtolower(get_class($fnClosure));
$classNames[$className] = $className;
}
}
}
foreach (PluginHelper::getPlugin('content') as $plugin) {
$className = strtolower('Plg' . $plugin->type . $plugin->name);
$classNames[$className] = ucfirst($plugin->name);
}
return $classNames;
}
public static function triggerEvent($eventName, $args = array()) {
if (!self::$isJoomla4) {
$dispatcher = JEventDispatcher::getInstance();
return $dispatcher->trigger('onInitN2Library', $args);
}
return Factory::getApplication()
->triggerEvent($eventName, $args);
}
public static function loadComContentRoute() {
if (!self::$isJoomla4) {
require_once JPATH_ROOT . '/components/com_content/helpers/route.php';
}
}
public static function mediaLibraryUrl() {
if (!self::$isJoomla4) {
return 'index.php?option=com_media&view=images&tmpl=component&asset=com_content&author=&fieldid=notused&folder=';
}
return 'index.php?option=com_media&tmpl=component&asset=86&author=584&fieldid={field-media-id}&path=local-0:/';
}
}
JoomlaShim::getInstance(); Joomla/SmartSlider3PlatformJoomla.php 0000644 00000001372 15235664472 0013702 0 ustar 00 <?php
namespace Nextend\SmartSlider3\Platform\Joomla;
use Joomla\CMS\Uri\Uri;
use Nextend\Framework\Sanitize;
use Nextend\SmartSlider3\Platform\AbstractSmartSlider3Platform;
class SmartSlider3PlatformJoomla extends AbstractSmartSlider3Platform {
public function start() {
require_once(dirname(__FILE__) . '/compat.php');
$this->initSanitize();
}
public function getAdminUrl() {
return Uri::root() . 'administrator/index.php?option=com_smartslider3';
}
public function getAdminAjaxUrl() {
return Uri::root() . 'administrator/index.php?option=com_smartslider3&nextendajax=1';
}
private function initSanitize() {
Sanitize::set_allowed_tags();
}
} Joomla/Module/Field/FieldEditSlider.php 0000644 00000001337 15235664472 0013764 0 ustar 00 <?php
namespace Nextend\SmartSlider3\Platform\Joomla\Module\Field;
use Joomla\CMS\Form\FormField;
use Joomla\CMS\Uri\Uri;
jimport('joomla.form.formfield');
class FieldEditSlider extends FormField {
protected $type = 'EditSlider';
public function getInput() {
$style = '<style>#jform_params_slider_chzn{width:100% !important;max-width:500px;}</style>';
return $style . '<a href="#" onclick="window.open(\'' . Uri::root() . 'administrator/index.php?option=com_smartslider3&nextendcontroller=slider&nextendaction=edit&sliderid=\' + jQuery(\'#jform_params_slider\').val(), \'_blank\'); return false;" class="btn btn-small btn-success" target="_blank"> Edit selected slider</a>';
}
} Joomla/Plugin/PluginInstallerSmartSlider3.php 0000644 00000002352 15235664472 0015325 0 ustar 00 <?php
namespace Nextend\SmartSlider3\Platform\Joomla\Plugin;
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\CMSPlugin;
use Nextend\SmartSlider3\Application\Model\ModelLicense;
use Nextend\SmartSlider3\SmartSlider3Info;
class PluginInstallerSmartSlider3 extends CMSPlugin {
public function onInstallerBeforePackageDownload(&$url, &$headers) {
if (in_array(parse_url($url, PHP_URL_HOST), array(
'secure.nextendweb.com',
'api.nextendweb.com'
)) && strpos($url, 'smartslider3')) {
$license = ModelLicense::getInstance();
$isActive = $license->isActive() == 'OK';
if (!$isActive) {
Factory::getApplication()
->enqueueMessage('Update error: Smart Slider 3 Pro is not activated on your site!', 'error');
$url = SmartSlider3Info::api(array(
'action' => 'joomla_fail'
), true);
return false;
}
$url = SmartSlider3Info::api(array(
'action' => 'joomla_update',
'channel' => SmartSlider3Info::$channel
), true);
}
return true;
}
} Joomla/Plugin/PluginSmartSlider3.php 0000644 00000013130 15235664472 0013443 0 ustar 00 <?php
namespace Nextend\SmartSlider3\Platform\Joomla\Plugin;
use Artx;
use ArtxPage;
use EshopHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Application\SiteApplication;
use Joomla\CMS\Plugin\CMSPlugin;
use Nextend\Framework\Asset\AssetManager;
use Nextend\SmartSlider3\Platform\Joomla\Joomla3Assets;
use Nextend\SmartSlider3\Platform\Joomla\JoomlaShim;
jimport('joomla.plugin.plugin');
/**
* Class PluginSmartSlider3
*
* Used in Joomla -> Plugin -> System -> Nextend2
*/
class PluginSmartSlider3 extends CMSPlugin {
private $hadError = false;
/*
Artisteer jQuery fix
*/
public function onAfterDispatch() {
if (class_exists('Artx', true)) {
Artx::load("Artx_Page");
if (isset(ArtxPage::$inlineScripts)) {
ArtxPage::$inlineScripts[] = '<script>if(typeof jQuery != "undefined") window.artxJQuery = jQuery;</script>';
}
}
}
private function isRenderAllowed() {
static $isAllowed;
if ($isAllowed === null) {
/**
* @var SiteApplication $application
*/
$application = Factory::getApplication();
if ($application->isClient('site')) {
$request = $application->input->request;
$isAllowed = true;
if (!Factory::getUser()->guest) {
if ($request->get('view') == 'form' && $request->get('layout') == 'edit' && $application->input->getInt('a_id') > 0) {
//Joomla frontend article editing
$isAllowed = false;
} else if ($request->get('option') == 'com_quix' && $request->get('layout') == 'edit' || $request->get('builder') == 'frontend') {
//Quix Visual Builder
$isAllowed = false;
} else if ($application->input->get('option') == 'com_sppagebuilder' && $application->input->get('layout') == 'edit') {
//SP Page Builder - @see SSDEV-3640
$isAllowed = false;
}
}
if ($request->get('type') == 'rss') {
//RSS feed
$isAllowed = false;
}
} else {
$isAllowed = false;
}
}
return $isAllowed;
}
private function displaySliders($output) {
if (strpos($output, 'smartslider3[') !== false) {
if (class_exists('\\EshopHelper', false) && EshopHelper::getConfigValue('rich_snippets') == '1') {
$output = preg_replace_callback('/(<.*?>)?smartslider3\[([0-9]+)\]/', array(
self::class,
'cleanEshop'
), $output);
}
$output = preg_replace_callback('/smartslider3\[([0-9]+)\]/', array(
self::class,
'prepare'
), $output);
}
return $output;
}
private function onNextendBeforeCompileHead() {
if ($this->isRenderAllowed()) {
/**
* @var SiteApplication $application
*/
$application = Factory::getApplication();
$body = $application->getBody();
// Simple performance check to determine whether bot should process further
if (strpos($body, 'smartslider3[') !== false) {
$bodyParts = explode('</head>', $body);
/**
* Last part is not the head
*/
$lastPart = count($bodyParts) - 1;
$bodyParts[$lastPart] = $this->displaySliders($bodyParts[$lastPart]);
$application->setBody(implode('</head>', $bodyParts));
}
}
}
public function onAfterRender() {
if (!JoomlaShim::$isJoomla4) {
$joomla3Assets = new Joomla3Assets();
$this->onNextendBeforeCompileHead();
$joomla3Assets->process();
} else {
$this->onNextendBeforeCompileHead();
}
ob_start();
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
}
$head = ob_get_clean();
if (!empty($head)) {
$application = Factory::getApplication();
$body = $application->getBody();
$parts = preg_split('/<\/head>/', $body, 2);
if (!JoomlaShim::$isJoomla4) {
$head .= $joomla3Assets->renderHead();
}
$body = implode($head . '</head>', $parts);
$application->setBody($body);
}
}
public function onError() {
$this->hadError = true;
}
public function onBeforeRespond() {
if ($this->hadError) {
$this->onAfterRender();
}
}
public static function prepare($matches) {
ob_start();
nextend_smartslider3($matches[1]);
return ob_get_clean();
}
public static function cleanEshop($matches) {
if (strpos($matches[1], 'itemprop') !== false) {
return $matches[1];
}
return $matches[0];
}
}