| Current Path : /home/cbequiperp/www/components/com_flexicontent/classes/helpers/ |
| Current File : /home/cbequiperp/www/components/com_flexicontent/classes/helpers/html.php |
<?php
defined( '_JEXEC' ) or die( 'Restricted access' );
use Joomla\String\StringHelper;
use Joomla\Utilities\ArrayHelper;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Router\Router;
class flexicontent_html
{
static $use_bootstrap = true;
static $icon_classes = null;
static $option = 'com_flexicontent';
static $inline_links = array();
static function getInlineLinkOnce($link, $options)
{
// Check if already added
if ( isset(self::$inline_links[$link]) )
{
foreach(self::$inline_links[$link]['options'] as $i => $v)
{
if ( isset($options[$i]) && $options[$i] == $v )
{
return '';
}
}
return '';
}
// Check if link already added to head object
if( isset(JFactory::getDocument()->_styleSheets[$link]) )
{
$headlink = JFactory::getDocument()->_styleSheets[$link];
if (isset($headlink['options']))
{
foreach($headlink['options'] as $i => $v)
{
if ( isset($options[$i]) && $options[$i] == $v )
{
return '';
}
}
}
}
// return an inline link
self::$inline_links[$link]['options'] = $options;
$ops = array();
foreach($options as $i => $v)
{
$ops[] = $i . '=' . $v;
}
if ($ops) $link .= '?' . implode('&', $ops);
return '<link rel="stylesheet" href="'.$link.'">';
}
static function load_class_config()
{
$cparams = JComponentHelper::getParams('com_flexicontent');
$icon_classes = $cparams->get('font_icon_classes');
$icon_classes = $icon_classes
? preg_split("/[\s]*,[\s]*/", $icon_classes)
: array();
self::$icon_classes = array();
foreach ($icon_classes as $d)
{
$data = preg_split("/[\s]*:[\s]*/", $d);
if (count($data) !== 2)
{
echo "Misconfigured parameter 'Icon classes': " . $d;
continue;
}
self::$icon_classes[$data[0]] = $data[1];
}
}
static function get_system_messages_html($add_containers=false)
{
$msgsByType = array(); // Initialise variables.
$messages = JFactory::getApplication()->getMessageQueue(); // Get the message queue
// Build the sorted message list
if (is_array($messages) && !empty($messages)) {
foreach ($messages as $msg) {
if (isset($msg['type']) && isset($msg['message'])) $msgsByType[$msg['type']][] = $msg['message'];
}
}
$alert_class = array('error' => 'alert-error', 'warning' => 'alert-warning', 'notice' => 'alert-info', 'message' => 'alert-success');
ob_start();
?>
<?php if ($add_containers) : ?>
<div class="row-fluid">
<div class="span12">
<div id="system-message-container">
<?php endif; ?>
<div id="fc_ajax_system_messages">
<?php if (is_array($msgsByType) && $msgsByType) : ?>
<?php foreach ($msgsByType as $type => $msgs) : ?>
<div class="alert <?php echo $alert_class[$type]; ?>">
<button type="button" class="close" data-dismiss="alert">×</button>
<h4 class="alert-heading"><?php echo JText::_($type); ?></h4>
<?php if ($msgs) : ?>
<?php foreach ($msgs as $msg) : ?>
<div class="alert-<?php echo $type; ?>"><?php echo $msg; ?></div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<?php if ($add_containers) : ?>
</div>
</div>
</div>
<?php endif; ?>
<?php
$msgs_html = ob_get_contents();
ob_end_clean();
return $msgs_html;
}
static function & checkPHPLimits($required=null, $recommended=null)
{
if (!$required) $required=array('max_input_vars'=>1000, 'suhosin.post.max_vars'=>1000, 'suhosin.request.max_vars'=>1000);
if (!$recommended) $recommended=array('max_input_vars'=>2000, 'suhosin.post.max_vars'=>2000, 'suhosin.request.max_vars'=>2000);
$suhosin_loaded = extension_loaded('suhosin');
$result = array();
foreach($required as $varname => $req_value)
{
if ( substr( $varname, 0, strlen('suhosin.') ) === 'suhosin.' && !$suhosin_loaded ) continue;
$sys_value = flexicontent_upload::parseByteLimit(ini_get($varname));
$required_ok = $sys_value >= $required[$varname];
$recommended_ok = $sys_value >= $recommended[$varname];
$conf_limit_class = $recommended_ok ? 'badge-success' : ($required_ok ? 'badge-warning' : 'badge-important');
$result[ $recommended_ok ? 'message' : ($required_ok ? 'notice' : 'warning') ][] = '
<span class="fc-php-limits-box">
<span class="label text-white bg-info label-info">'.$varname.'</span>
<span class="badge '.$conf_limit_class.'">'.$sys_value.'</span>
<span class="fc-php-limits-box">
<span class="label">'.JText::_('FLEXI_REQUIRED').'</span>
<b class="">'.$required[$varname].'</b>
<span class="label">'.JText::_('FLEXI_RECOMMENDED').'</span>
<b class="">'.$recommended[$varname].'</b>
</span>
</span>';
}
return $result;
}
/* Returns true if any LESS file has changed in the LESS include folders */
static function dirty_less_incPath_exists($inc_paths, $check_global = true)
{
static $_dirty_arr = array();
static $less_folders = null;
$app = JFactory::getApplication();
static $print_logging_info = null;
$print_logging_info = $print_logging_info !== null ? $print_logging_info : JComponentHelper::getParams('com_flexicontent')->get('print_logging_info');
$debug = JDEBUG || $print_logging_info;
if (!is_array($inc_paths)) $inc_paths = array($inc_paths);
// Get global include folders
if ($check_global) {
if ($less_folders===null) {
$JTEMPLATE_SITE = flexicontent_html::getSiteTemplate(true);
$less_folders = JComponentHelper::getParams('com_flexicontent')->get('less_folders', 'JPATH_COMPONENT_SITE/assets/less/ :: JTEMPLATE_SITE/less/com_flexicontent/ ::');
$_reps = array(
'JPATH_COMPONENT_SITE' => JPATH_SITE.DS.'components'.DS.'com_flexicontent', 'JPATH_COMPONENT_ADMINISTRATOR' => JPATH_ADMINISTRATOR.DS.'components'.DS.'com_flexicontent',
'JPATH_SITE' => JPATH_SITE, 'JPATH_ADMINISTRATOR' => JPATH_ADMINISTRATOR,
'JTEMPLATE_SITE' => $JTEMPLATE_SITE
);
$less_folders = str_replace(array_keys($_reps), $_reps, $less_folders);
$less_folders = preg_split("/[\s]*::[\s]*/", $less_folders);
foreach($less_folders as $k => $v)
{
if (!empty($v)) {
$v = JPath::clean($v);
$v .= $v[strlen($v) - 1] == DS ? '' : DS;
$less_folders[$k] = $v;
} else
unset($less_folders[$k]);
}
}
$inc_paths_all = array_merge($inc_paths, $less_folders);
}
//echo "<pre>"; debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); echo "</pre>";
//echo "<pre>"; print_r( $inc_paths_all); echo "</pre>";
$_dirty_any = false; // This FLAG is set in flag for all folders
foreach ($inc_paths_all as $inc_path)
{
// Find if any "include" file has changed and set FLAG
if ( !$inc_path )
$_dirty = false;
else if ( !JFolder::exists($inc_path) )
$_dirty_arr[$inc_path] = $_dirty = false;
else
$_dirty = isset($_dirty_arr[$inc_path]) ? $_dirty_arr[$inc_path] : null;
// Examine folder if not already examined
if ($_dirty===null)
{
$_dirty = false;
$inc_files = glob($inc_path.'*.{less}', GLOB_BRACE); //print_r($inc_files);
if (!is_array($inc_files) && $debug) JFactory::getApplication()->enqueueMessage('Reading LESS folder failed: '.$inc_path, 'notice');
if (is_array($inc_files)) foreach ($inc_files as $confFile) {
//echo $confFile . " time: ".filemtime($confFile) ."<br/>";
if (!JFile::exists($inc_path.'_config_fc_ts') || filemtime($confFile) > filemtime($inc_path.'_config_fc_ts')) {
touch($inc_path.'_config_fc_ts');
$_dirty = true;
break;
}
}
}
$_dirty_arr[$inc_path] = $_dirty;
$_dirty_any = $_dirty_any || $_dirty;
}
return $_dirty_any;
}
/**
* Checks and if needed compiles LESS files to CSS files
*/
static function checkedLessCompile($files, $path, $inc_paths=null, $force=false, $check_global_inc = true)
{
static $print_logging_info = null;
$print_logging_info = $print_logging_info !== null ? $print_logging_info : JComponentHelper::getParams('com_flexicontent')->get('print_logging_info');
$debug = JDEBUG || $print_logging_info;
static $initialized;
if ($initialized===null)
{
jimport('joomla.filesystem.path' );
jimport('joomla.filesystem.folder');
jimport('joomla.filesystem.file');
$initialized = 1;
}
// Validate paths
$path = JPath::clean($path);
if (!is_array($inc_paths)) $inc_paths = $inc_paths ? array($inc_paths) : array();
foreach($inc_paths as $k => $v)
{
$v = JPath::clean($v);
$v .= $v[strlen($v) - 1] == DS ? '' : DS;
$inc_paths[$k] = $v;
}
// Check if LESS include paths have modified less files
$_dirty = flexicontent_html::dirty_less_incPath_exists($inc_paths, $check_global_inc);
// Find which LESS files have changed
$stale = array();
foreach ($files as & $inFile)
{
$inFile = JPath::clean($inFile);
$inFilename = basename($inFile);
$nameOnly = basename($inFilename, '.less');
$outFile = 'css' .DS. $nameOnly . '.css';
if (!JFile::exists($path.$inFile)) {
if ($debug) JFactory::getApplication()->enqueueMessage('Path not found: '.$path.$inFile, 'warning');
} else if ( $_dirty || $force || !is_file($path.$outFile) || filemtime($path.$inFile) > filemtime($path.$outFile) || (filesize($path.$outFile)===0 && is_writable($path.$outFile)) ) {
$stale[$inFile] = $outFile;
}
}
unset($inFile);
//echo '<pre>'; print_r($stale); echo '</pre>';
// We are done if no CSS files need to be updated
if (empty($stale)) return array();
static $prev_path = null;
if ( $prev_path != $path && $debug ) JFactory::getApplication()->enqueueMessage('Compiling LESS files in: ' .$path, 'message');
require_once (JPATH_SITE.DS.'components'.DS.'com_flexicontent'.DS.'librairies'.DS.'lessphp'.DS.'lessc.inc.php');
$compiled = array();
$msg = ''; $error = false;
foreach ($stale as $in => $out)
{
// *** WARNING: Always create new object on every call, otherwise files needed more than one place, will may NOT be include
$less = new \FLEXIcontent\lessc(); // JLess($fname = null, new JLessFormatterJoomla);
$formater = new \FLEXIcontent\lessc_formatter_classic();
$formater->disableSingle = true;
$formater->breakSelectors = true;
$formater->assignSeparator = ": ";
$formater->selectorSeparator = ",";
$formater->indentChar="\t";
$less->setFormatter($formater);
try
{
$wasCompiled = $less->compileFile($path.$in, $path.$out); // $less->checkedCompile($path.$in, $path.$out); // consider modification times
if ($wasCompiled) $compiled[$in] = $out;
}
catch (Exception $e)
{
$error = true;
if ($debug || JFactory::getApplication()->isClient('administrator')) JFactory::getApplication()->enqueueMessage(
'- LESS to CSS halted ... CSS file was not changed ... please edit LESS file(s) find offending <b>lines</b> and fix or remove<br/>'. str_replace($path.$in, '<br/><b>'.$path.$in.'</b>', $e->getMessage()), 'notice'
);
continue;
}
}
if ( count($compiled) && $debug ) {
foreach($compiled as $inPath => $outPath) $msg .= '<span class="row" style="display:block; margin:0;"><span class="span4">' . $inPath . '</span><span class="span4">' .$outPath . '</span></span>';
JFactory::getApplication()->enqueueMessage(($prev_path != $path ? '<span class="row" style="display:block; margin:0;"><span class="span4">LESS</span><span class="span4">CSS</span></span>' : '').$msg, 'message');
}
$prev_path = $path;
return !$error ? $stale : false;
}
/* Creates Joomla default canonical URL and also finds the configured SEF domain */
static function getDefaultCanonical(&$_domain=null)
{
$app = JFactory::getApplication();
$doc = JFactory::getDocument();
if ($app->getName() != 'site' || $doc->getType() !== 'html') return;
static $link = null;
static $domain = null;
$_domain = $domain; // pass it back by reference
if ($link !== null) return $link;
// Get SEF plugin configuration
$plugin = JPluginHelper::getPlugin('system', 'sef');
$pluginParams = new JRegistry($plugin ? $plugin->params : null);
$domain = $pluginParams->get('domain');
$jversion = new JVersion;
$is_j35ge = version_compare( $jversion->getShortVersion(), '3.4.999', 'ge' ); // includes 3.5.0-beta* too
if ( ($is_j35ge && $domain === false) || (!$is_j35ge && $domain === null) || $domain === '')
{
$domain = JUri::getInstance()->toString(array('scheme', 'host', 'port'));
}
$_domain = $domain; // pass it back by reference
$link = $domain . JRoute::_('index.php?' . http_build_query($app->getRouter()->getVars()), false);
return $link;
}
/* Sets the given URL as rel canonical URL, also clearing any already set rel canonical URL */
static function setRelCanonical($ucanonical)
{
$uri = JUri::getInstance();
$doc = JFactory::getDocument();
// Get canonical URL that SEF plugin adds, also $domain passed by reference, to get the domain configured in SEF plugin (multi-domain website)
$domain = null;
$defaultCanonical = flexicontent_html::getDefaultCanonical($domain);
$domain = $domain ? $domain : $uri->toString(array('scheme', 'host', 'port'));
// Remove trailing slash for home page without subfolder'
if ($ucanonical === '/')
{
$ucanonical = '';
}
// Add scheme, domain, port
$ucanonical = $domain . $ucanonical;
// Encode the canonical URL
$ucanonical_encoded = htmlspecialchars($ucanonical);
// Get head object
$head_obj = $doc->mergeHeadData(array(1=>1));
// Remove canonical inserted by SEF plugin, unsetting default directly may not be reliable, instead we will search for it
//unset($head_obj->_links[htmlspecialchars($defaultCanonical)]);
$addRel = true;
foreach($head_obj->_links as $link => $data)
{
if (strtolower($data['relation']) === 'canonical' && strtolower($data['relType']) === 'rel')
{
if($link == $ucanonical_encoded)
{
$addRel = false;
}
else
{
// Remove current rel canonical ... which is wrong ...
unset($head_obj->_links[$link]);
// Set add flag in case we found multiple canonicals ... and it was cleared by if statement ...
$addRel = true;
}
}
}
// Add REL canonical only if different than current URL
// * J3.5.1+ * Always add canonical, otherwise Joomla SEF plugin will add the default
if ($addRel /*&& rawurldecode($uri->toString()) != $ucanonical*/)
{
$doc->addHeadLink( $ucanonical, 'canonical', 'rel' );
}
}
/**
* Get visibility of table columns from Posted Form or from Browser Cookie
*/
static function getVisibleColumns($data_tbl_id)
{
$app = JFactory::getApplication();
$jinput = $app->input;
static $columnchoose = false;
if ($columnchoose === false)
{
// First try to find POSTED data
$columnchoose = $jinput->post->get('columnchoose_'.$data_tbl_id, null, 'array');
if ($columnchoose !== null)
{
$columnchoose = array_keys($columnchoose);
}
// Otherwise try to find COOKIE data
else
{
$fc_columnchooser = $jinput->cookie->get('fc_columnchooser', '{}', 'string');
// Parse the COLUMNS cookie
try
{
$fc_columnchooser = json_decode($fc_columnchooser);
// Reset cookie if it is not a class, or if the version hash does not matches (reset column chooser on every version upgrade)
if (!is_object($fc_columnchooser) || !isset($fc_columnchooser->vhash) || $fc_columnchooser->vhash !== FLEXI_VHASH)
{
$fc_columnchooser = new stdClass();
$fc_columnchooser->vhash = FLEXI_VHASH;
$jinput->cookie->set('fc_columnchooser', json_encode($fc_columnchooser), time()+60*60*24*30, JUri::base(true), '');
}
// Get specific table data
elseif (isset($fc_columnchooser->$data_tbl_id))
{
$columnchoose = preg_split("/[\s]*,[\s]*/", $fc_columnchooser->$data_tbl_id);
foreach($columnchoose as $i => $id)
{
$columnchoose[$i] = (int) $id;
}
}
}
catch (Exception $e)
{
$fc_columnchooser = new stdClass();
$fc_columnchooser->vhash = FLEXI_VHASH;
$jinput->cookie->set('fc_columnchooser', json_encode($fc_columnchooser), time()+60*60*24*30, JUri::base(true), '');
$columnchoose = null;
}
}
}
return $columnchoose;
}
/**
* Output the JavaScript to dynamically hide/show columns of a table
*/
static function jscode_to_showhide_table($container_div_id, $data_tbl_id, $start_html = '', $end_html = '', $toggle_on_init = 1)
{
$document = JFactory::getDocument();
$app = JFactory::getApplication();
$jinput = $app->input;
// Clear legacy cookie
$legacy_cookie = $jinput->cookie->get('columnchoose_'.$data_tbl_id, null);
if ($legacy_cookie) $jinput->cookie->set('columnchoose_'.$data_tbl_id, null, 1, '', '');
$js = "
var show_col_${data_tbl_id} = Array();
jQuery(document).ready(function() {
";
// Get visibility of table columns from Posted Form or from Browser Cookie
$columnchoose = self::getVisibleColumns($data_tbl_id);
if ($columnchoose) foreach ($columnchoose as $colnum)
{
$colnum = (int) $colnum;
$js .= "show_col_${data_tbl_id}[".$colnum."]=1; \n";
}
$firstload = $columnchoose !== null ? "false" : "true";
$js .= "
create_column_choosers('$container_div_id', '$data_tbl_id', $firstload, '".$start_html."', '".$end_html."', " . (int) $toggle_on_init . ");
});
";
$document->addScriptDeclaration($js);
}
/**
* Function to create the tooltip text regardless of Joomla version
*
* @return string : the HTML of the tooltip for usage in the title paramter of the HTML tag
* @since 1.5
*/
static function getToolTip($title = '', $content = '', $translate = 1, $escape = 1)
{
return JHtml::tooltipText($title ?? '', $content ?? '', $translate, $escape);
}
static function escape($str)
{
return htmlspecialchars($str, ENT_COMPAT, 'UTF-8');
}
static function get_basedomain($url)
{
$pieces = parse_url($url);
$domain = isset($pieces['host']) ? $pieces['host'] : '';
if (preg_match('/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs))
{
return $regs['domain'];
}
return false;
}
static function is_safe_url($url, $baseonly=false)
{
$cparams = JComponentHelper::getParams( 'com_flexicontent' );
$allowed_redirecturls = $cparams->get('allowed_redirecturls', 'internal_base'); // Parameter does not exist YET
// prefix the URL if needed so that parse_url will work
$has_prefix = preg_match("#^http|^https|^ftp|^ftps#i", $url);
if (!$has_prefix)
{
$is_abs_noproto = strpos($url, "//") === 0;
$is_abs_urlpath = strpos($url, "/") === 0;
if ($is_abs_noproto)
{
$url = 'http:' . $url;
}
elseif (!$is_abs_urlpath)
{
$url = JUri::base() . $url;
}
else
{
$url = 'http://' . $url;
}
}
// Require baseonly internal url: (HOST only)
if ( $baseonly || $allowed_redirecturls == 'internal_base' )
return flexicontent_html::get_basedomain($url) == flexicontent_html::get_basedomain(JUri::base());
// Require full internal url: (HOST + this JOOMLA folder)
else // if ( $allowed_redirecturls == 'internal_full' )
return parse_url($url, PHP_URL_HOST) == parse_url(JUri::base(), PHP_URL_HOST);
// Allow any URL, (external too) this may be considered a vulnerability for unlogged/logged users, since
// users may be redirected to an offsite URL despite clicking an internal site URL received e.g. by an email
//else
// return true;
}
static function make_absolute_url($link)
{
static $domain = null;
if ($domain === null)
{
$uri = JUri::getInstance('SERVER');
$domain = $uri->gethost();
}
// Is absolute with protocol, NOTHING TO DO
if ( parse_url($link, PHP_URL_SCHEME) ) $prefix = '';
// Is absolute without protocol, NOTHING TO DO
else if (strpos($link, '//') === 0) $prefix = '';
// Has current domain but no protocol, ADD '//' (so that it is treated as absolute URL)
else if (strpos($link, $domain) === 0) $prefix = '//';
// Is absolute without protocol - host - port, NOTHING TO DO
else if (strpos($link, '/') === 0) $prefix = '';
// Anything else is relative, prepend full joomla root uri
else
{
$prefix = JUri::root();
}
$link = empty($link) ? '' : $prefix . $link;
return $link;
}
/**
* Function to render the item view of a given item id
*
* @param int $item_id
* @return string : the HTML of the item view, also the CSS / JS file would have been loaded
* @since 1.5
*/
function renderItem($item_id, $view=FLEXI_ITEMVIEW, $ilayout = '')
{
JTable::addIncludePath(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_flexicontent'.DS.'tables');
require_once (JPATH_SITE.DS.'components'.DS.'com_flexicontent'.DS.'classes'.DS.'flexicontent.fields.php');
//require_once (JPATH_SITE.DS.'components'.DS.'com_flexicontent'.DS.'classes'.DS.'flexicontent.helper.php');
require_once (JPATH_SITE.DS.'components'.DS.'com_flexicontent'.DS.'helpers'.DS.'permission.php');
require_once (JPATH_SITE.DS.'components'.DS.'com_flexicontent'.DS.'models'.DS.FLEXI_ITEMVIEW.'.php');
$app = JFactory::getApplication();
$user = JFactory::getUser();
$itemmodel = new FlexicontentModelItem();
$item = $itemmodel->getItem($item_id, $check_view_access=false);
$aid = JAccess::getAuthorisedViewLevels($user->id);
// Get Item's specific ilayout
if (!$ilayout)
{
$ilayout = $item->parameters->get('ilayout');
}
// Get type's ilayout
if (!$ilayout)
{
$type = JTable::getInstance('flexicontent_types', '');
$type->id = $item->type_id;
$type->load();
$type->params = new JRegistry($type->attribs);
$ilayout = $type->params->get('ilayout') ?: 'default';
}
// Get cached template data, re-parsing XML/LESS files, also loading any template language files of a specific template
$themes = flexicontent_tmpl::getTemplates(array($ilayout));
// Get Fields
list($item) = FlexicontentFields::getFields($item, $view, $item->parameters, $aid);
// WE WILL NOT LOAD CSS/JS of the item as it may have undesired effects !
// TODO add parameter for this
// WE DO NOT TRIGGER CONTENT PLUGINS, as it may have undesired effects ?
// TODO add parameter for this
$this->item = $item;
$this->params_saved = @$this->params;
$this->params = $item->parameters;
$this->tmpl = '.item.'.$ilayout;
$this->print_link = JRoute::_('index.php?view='.FLEXI_ITEMVIEW.'&id='.$item->slug.'&pop=1&tmpl=component&print=1');
$this->pageclass_sfx = '';
if (!isset($this->item->event))
{
$this->item->event = new stdClass();
}
$this->item->event->beforeDisplayContent = '';
$this->item->event->afterDisplayTitle = '';
$this->item->event->afterDisplayContent = '';
$this->fields = & $this->item->fields;
// start capturing output into a buffer
ob_start();
// Include the requested template filename in the local scope (this will execute the view logic).
if (file_exists(JPATH_SITE.DS.'templates'.DS.$app->getTemplate().DS.'html'.DS.'com_flexicontent'.DS.'templates'.DS.$ilayout))
{
include JPATH_SITE.DS.'templates'.DS.$app->getTemplate().DS.'html'.DS.'com_flexicontent'.DS.'templates'.DS.$ilayout.DS.'item.php';
}
elseif (file_exists(JPATH_COMPONENT.DS.'templates'.DS.$ilayout))
{
include JPATH_SITE.DS.'components'.DS.'com_flexicontent'.DS.'templates'.DS.$ilayout.DS.'item.php';
}
else
{
include JPATH_SITE.DS.'components'.DS.'com_flexicontent'.DS.'templates'.DS.'default'.DS.'item.php';
}
// done with the requested template; get the buffer and clear it.
$item_html = ob_get_contents();
ob_end_clean();
$this->params = $this->params_saved;
return $item_html;
}
static function listall_selector(&$params, $formname='adminForm', $autosubmit=1)
{
if (flexicontent_html::initial_list_limited($params))
{
$tooltip_class = 'hasTooltip';
return '
<input type="checkbox" id="listall" name="listall" value="1" form="'.$formname.'"/>
<label id="listall-lbl" for="listall" class="btn '.$tooltip_class.'" style="width:100%; margin:8px 0; box-sizing:border-box;" title="'.JText::_('FLEXI_LISTING_ONLY_FEATURED_CLICK_TO_LIST_ALL_DESC', true).'">
'.JText::_('FLEXI_LIST_ALL_ITEMS').'
</label>
';
}
}
static function initial_list_limited(&$params)
{
$use_limit_before = (int) $params->get('use_limit_before_search_filt', 0);
if ($use_limit_before < 2)
{
return false;
}
$use_limit_before_search_filt = JFactory::getApplication()->getUserState('use_limit_before_search_filt');
if ($use_limit_before_search_filt < 2)
{
return false;
}
return true;
}
static function limit_selector(&$params, $formname='adminForm', $autosubmit=1)
{
if (!$params->get('limit_override'))
{
return '';
}
$app = JFactory::getApplication();
$default_limit = (int) ($app->getUserState('use_limit_before_search_filt') ? $params->get('limit_before_search_filt') : $params->get('limit'));
$limit_given = strlen( $app->input->get('limit', '', 'string') );
$limit = $limit_given ? $app->input->get('limit', 0, 'int') : $default_limit;
flexicontent_html::loadFramework('select2');
$classes = "fc_field_filter use_select2_lib";
$attribs = array(
'id' => 'limit', // HTML id for select field
'list.attr' => array( // additional HTML attributes for select field
),
'list.translate'=>false, // true to translate
'option.key'=>'value', // key name for value in data array
'option.text'=>'text', // key name for text in data array
'option.attr'=>'attr', // key name for attr in data array
'list.select'=>$limit // value of the SELECTED field
);
$attribs['list.attr']['onchange'] = $autosubmit ? "adminFormPrepare(this.form, 2);" : null;
$attribs['list.attr']['class'] = $classes;
$attribs['list.attr']['form'] = $formname;
$limit_options = $params->get('limit_options', '5,10,20,30,50,100,150,200');
$limit_options = preg_split("/[\s]*,[\s]*/", $limit_options);
$limit_options = ArrayHelper::toInteger($limit_options);
if (!in_array($default_limit, $limit_options))
{
$limit_options[] = $default_limit;
}
$limiting = array();
$limit_override_label = $params->get('limit_override_label', 2);
$inside_label = $limit_override_label==2 ? ' '.JText::_('FLEXI_PER_PAGE') : '';
if ($app->getUserState('use_limit_before_search_filt'))
{
$attribs['list.attr']['disabled'] = 'disabled';
$limiting[] = array(
'value' => $default_limit,
'text' => $default_limit . $inside_label,
'attr' => array('data-is-default-value' => '1')
);
}
else foreach($limit_options as $limit_option)
{
$attr_arr = $default_limit == $limit_option ? array('data-is-default-value' => '1') : array();
$limiting[] = array(
'value' => $limit_option,
'text' => $limit_option . $inside_label,
'attr' => $attr_arr
);
}
// Outside label
$outside_label = '';
if ($limit_override_label==1) {
$outside_label = '<span class="flexi label limit_override_label">'.JText::_('FLEXI_PER_PAGE').'</span>';
}
return $outside_label.JHtml::_('select.genericlist', $limiting, 'limit', $attribs);
}
static function orderby_selector(&$params, $formname='adminForm', $autosubmit=1, $extra_order_types=array(), $sfx='')
{
if ( !$params->get('orderby_override'.$sfx, 0) ) return '';
$app = JFactory::getApplication();
$default_orderby = $params->get( 'orderby'.$sfx );
$orderby = $app->input->get('orderby'.$sfx, '', 'string');
$orderby = $orderby ? $orderby : $default_orderby;
flexicontent_html::loadFramework('select2');
$classes = "fc_field_filter use_select2_lib";
$attribs = array(
'id' => 'orderby'.$sfx, // HTML id for select field
'list.attr' => array( // additional HTML attributes for select field
),
'list.translate'=>false, // true to translate
'option.key'=>'value', // key name for value in data array
'option.text'=>'text', // key name for text in data array
'option.attr'=>'attr', // key name for attr in data array
'list.select'=>$orderby // value of the SELECTED field
);
$attribs['list.attr']['onchange'] = $autosubmit ? "adminFormPrepare(this.form, 2);" : null;
$attribs['list.attr']['class'] = $classes;
$attribs['list.attr']['form'] = $formname;
$orderby_options = $params->get(
'orderby_options'.$sfx,
array('_preconfigured_','date','rdate','modified','alpha','ralpha','author','rauthor','hits','rhits','id','rid','order','jorder')
);
$orderby_options = FLEXIUtilities::paramToArray($orderby_options);
$orderby_names = array(
'_preconfigured_'=>'FLEXI_ORDER_DEFAULT_INITIAL',
'date'=>'FLEXI_ORDER_OLDEST_FIRST',
'rdate'=>'FLEXI_ORDER_MOST_RECENT_FIRST',
'modified'=>'FLEXI_ORDER_LAST_MODIFIED_FIRST',
'published'=>'FLEXI_ORDER_RECENTLY_PUBLISHED_FIRST',
'published_oldest'=>'FLEXI_ORDER_OLDEST_PUBLISHED_FIRST',
'alpha'=>'FLEXI_ORDER_TITLE_ALPHABETICAL',
'ralpha'=>'FLEXI_ORDER_TITLE_ALPHABETICAL_REVERSE',
'author'=>'FLEXI_ORDER_AUTHOR_ALPHABETICAL',
'rauthor'=>'FLEXI_ORDER_AUTHOR_ALPHABETICAL_REVERSE',
'hits'=>'FLEXI_ORDER_MOST_HITS',
'rhits'=>'FLEXI_ORDER_LEAST_HITS',
'id'=>'FLEXI_ORDER_HIGHEST_ITEM_ID',
'rid'=>'FLEXI_ORDER_LOWEST_ITEM_ID',
'commented'=>'FLEXI_ORDER_MOST_COMMENTED',
'rated'=>'FLEXI_ORDER_BEST_RATED',
'order'=>'FLEXI_ORDER_CONFIGURED_ORDER',
'jorder'=>'FLEXI_ORDER_CONFIGURED_ORDER_JOOMLA',
'random'=>'FLEXI_ORDER_RANDOM',
'alias'=>'FLEXI_ORDER_ALIAS',
'ralias'=>'FLEXI_ORDER_ALIAS_REVERSE'
);
$ordering = array();
foreach ($extra_order_types as $value => $text)
{
$text = JText::_( $text );
//$ordering[] = JHtml::_('select.option', $value, $text);
$attr_arr = $default_orderby == $value ? array('data-is-default-value' => '1') : array();
$ordering[] = array(
'value' => $value,
'text' => $text,
'attr' => $attr_arr
);
}
foreach ($orderby_options as $orderby_option)
{
if ($orderby_option=='__SAVED__') continue;
$value = ($orderby_option!='_preconfigured_') ? $orderby_option : '';
$text = JText::_( $orderby_names[$orderby_option] );
//$ordering[] = JHtml::_('select.option', $value, $text);
$attr_arr = $default_orderby == $value ? array('data-is-default-value' => '1') : array();
$ordering[] = array(
'value' => $value,
'text' => $text,
'attr' => $attr_arr
);
}
// Add custom field orderings
$orderby_custom = $params->get('orderby_custom'.$sfx, '');
$orderby_custom = preg_split("/\s*,\s*/u", $orderby_custom);
$custom_order_types = array('int'=>1, 'decimal'=>1, 'date'=>1, 'file_hits'=>1);
$field_ids = array();
$custom_ops = array();
$n = 0;
foreach ($orderby_custom as $custom_option)
{
$order_parts = preg_split("/:/", $custom_option);
if (count($order_parts)!=3 && count($order_parts)!=4) continue; // ignore order with wrong number parts
$_field_id = (int) @ $order_parts[0];
if (!$_field_id) continue; // ignore order with bad fieldid
if (!isset($custom_order_types[@ $order_parts[1]])) continue; // ignore order with bad type
$field_ids[$_field_id] = 1;
$custom_ops[$n] = $order_parts;
$n++;
}
$fields = FlexicontentFields::getFieldsByIds(array_keys($field_ids));
foreach($custom_ops as $op)
{
$field_id = $op[0];
$field = $fields[$field_id];
$value = 'custom:'.$op[0].':'.$op[1].':'.$op[2];
if (count($op)==4) {
$text = JText::_( $op[3] );
} else {
$text = JText::_( $field->label ) .' '. JText::_(strtolower($op[2])=='asc' ? 'FLEXI_INCREASING' : 'FLEXI_DECREASING');
}
//$ordering[] = JHtml::_('select.option', $value, $text);
$attr_arr = $default_orderby == $value ? array('data-is-default-value' => '1') : array();
$ordering[] = array(
'value' => $value,
'text' => $text,
'attr' => $attr_arr
);
}
return JHtml::_('select.genericlist', $ordering, 'orderby'.$sfx, $attribs);
}
static function ordery_selector(&$params, $formname='adminForm', $autosubmit=1, $extra_order_types=array(), $sfx='')
{
return //'Please search and replace (in your template files): flexicontent_html::ordery_selector with flexicontent_html::orderby_selector'.
flexicontent_html::orderby_selector($params, $formname, $autosubmit, $extra_order_types, $sfx);
}
static function layout_selector(&$params, $formname='adminForm', $autosubmit=1, $layout_type='clayout')
{
if ( !$params->get($layout_type.'_switcher') ) return '';
$default_layout = $params->get($layout_type.'_default', $layout_type=='clayout' ? 'blog' : 'default');
if ($layout_type=='clayout')
{
$displayed_tmpls = $params->get('displayed_'.$layout_type.'s');
if ( empty($displayed_tmpls) ) $displayed_tmpls = array();
else if ( ! is_array($displayed_tmpls) ) $displayed_tmpls = explode("|", $displayed_tmpls);
$current_layout = $params->get('clayout');
if (count($displayed_tmpls) && $current_layout && !in_array($current_layout, $displayed_tmpls)) $displayed_tmpls[] = $current_layout;
}
$allowed_tmpls = $params->get('allowed_'.$layout_type.'s');
if ( empty($allowed_tmpls) ) $allowed_tmpls = array();
else if ( ! is_array($allowed_tmpls) ) $allowed_tmpls = explode("|", $allowed_tmpls);
// Return if none allowed layout(s) were configured / allowed
$layout_names = $layout_type=='clayout' ? $displayed_tmpls : $allowed_tmpls;
if (!count($layout_names)) return false;
$app = JFactory::getApplication();
$jinput = $app->input;
$option = $jinput->get('option', '', 'cmd');
$layout = $jinput->get('layout', '', 'cmd');
$svar = $layout ? '.'.$layout : '.category';
$layout_typename = $layout_type=='clayout' ? 'category' : 'items';
/*if (!$layout) $svar .= $jinput->get('cid', 0, 'INT');
else if ($layout=='tags') $svar .= $jinput->get('tagid', 0, 'INT');
else if ($layout=='author') $svar .= $jinput->get('authorid', 0, 'INT');
if ($layout) $svar .= '.category'.$jinput->get('cid', 0, 'INT');*/
//$layout = $app->getUserStateFromRequest( $option.$svar.'.'.$layout_type, $layout_type, $default_layout, 'cmd' );
$layout = $jinput->get($layout_type, $default_layout, 'cmd') ;
$_switcher_label = $params->get($layout_type.'_switcher_label', 0);
$inside_label = $_switcher_label==2 ? ' '.JText::_('FLEXI_LAYOUT') : '';
$outside_label = $_switcher_label==1 ? '<span class="flexi label limit_override_label">'.JText::_('FLEXI_LAYOUT').'</span>' : '';
// Get layout titles
$layout_texts = flexicontent_tmpl::getLayoutTexts($layout_typename);
if ( $params->get('clayout_switcher_display_mode', 1) == 0 )
{
flexicontent_html::loadFramework('select2');
$classes = "fc_field_filter use_select2_lib";
//$onchange = !$autosubmit ? '' : ' onchange="adminFormPrepare(this.form, 2);" ';
//$attribs = ' class="'.$classes.'" ' . $onchange . ' form="'.$formname.'" ';
$attribs = array(
'id' => $layout_type, // HTML id for select field
'list.attr' => array( // additional HTML attributes for select field
),
'list.translate'=>false, // true to translate
'option.key'=>'value', // key name for value in data array
'option.text'=>'text', // key name for text in data array
'option.attr'=>'attr', // key name for attr in data array
'list.select'=>$layout // value of the SELECTED field
);
$attribs['list.attr']['onchange'] = $autosubmit ? "adminFormPrepare(this.form, 2);" : null;
$attribs['list.attr']['class'] = $classes;
$attribs['list.attr']['form'] = $formname;
$options = array();
foreach($layout_names as $layout_name)
{
$layout_title = !empty($layout_texts->$layout_name->title) ? $layout_texts->$layout_name->title : $layout_name;
//$options[] = JHtml::_('select.option', $layout_name, $layout_title .$inside_label);
$attr_arr = $default_layout == $layout_name ? array('data-is-default-value' => '1') : array();
$options[] = array(
'value' => $layout_name,
'text' => $layout_title .$inside_label,
'attr' => $attr_arr
);
}
$html = JHtml::_('select.genericlist', $options, $layout_type, $attribs);
}
else
{
$tmplurl = 'components/com_flexicontent/templates/';
$tooltip_class = ' hasTooltip';
$n = 0;
$options = array();
foreach($layout_names as $layout_name)
{
$layout_title = !empty($layout_texts->$layout_name->title) ? $layout_texts->$layout_name->title : '';
$checked_attr = $layout==$layout_name ? ' checked=checked ' : '';
$is_default_attr = $default_layout == $layout_name ? ' data-is-default-value="1" ' : '';
$options[] =
'<input form="'.$formname.'" type="radio" name="'.$layout_type.'" value="'.$layout_name.'" id="'.$layout_type.$n.'" onchange="adminFormPrepare(this.form, 2); return true;" '.$checked_attr.$is_default_attr.'>'.
'<label for="'.$layout_type.$n.'" class="btn '.$tooltip_class.'" title="'.$layout_title.'"><img alt="'.$layout_name.'" src="'.$tmplurl.$layout_name.'/clayout.png"></label>'
;
$n++;
}
$html = '
<fieldset class="radio btn-group group-fcinfo">
'.implode('', $options).'
</fieldset>
';
JFactory::getDocument()->addScriptDeclaration('jQuery(document).ready(function(){ jQuery(\'input[name="'.$layout_type.'"]\').click( function() { adminFormPrepare(this.form, 2); }); });');
}
return $outside_label.$html;
}
static function searchphrase_selector(&$params, $formname='adminForm')
{
$show_searchphrase = $params->get('show_searchphrase', 1);
if (!$show_searchphrase)
{
return '';
}
$app = JFactory::getApplication();
$default_searchphrase = $params->get('default_searchphrase', 'all');
$p = $app->input->getWord('searchphrase', $app->input->getWord('p', $default_searchphrase));
$searchphrase_names = array(
'all'=>'FLEXI_ALL_WORDS',
'any'=>'FLEXI_ANY_WORDS',
'natural'=>'FLEXI_NATURAL_PHRASE',
'natural_expanded'=>'FLEXI_NATURAL_PHRASE_MORE_RESULTS',
'exact'=>'FLEXI_EXACT_PHRASE',
);
$searchphrases = array();
foreach ($searchphrase_names as $searchphrase_value => $searchphrase_name)
{
$searchphrases[] = array(
'value' => $searchphrase_value,
'text' => $searchphrase_name,
'attr' => $default_searchphrase === $searchphrase_value ? array('data-is-default-value' => '1') : array()
);
}
$attribs = array(
'id' => 'searchphrase', // HTML id for select field
'group.id' => 'id',
'list.attr' => array('class' => 'fc_field_filter use_select2_lib'),
'list.translate' => true, // true to translate
'option.key' => 'value', // key name for value in data array
'option.text' => 'text', // key name for text in data array
'option.attr' => 'attr', // key name for attr in data array
'list.select' => $p, // value of the SELECTED field
);
return JHtml::_('select.genericlist', $searchphrases, 'p', $attribs);
}
/**
* Utility function to add JQuery to current Document
*
* @param string $text
* @param int $nb
* @return string
* @since 1.5
*/
static function loadJQuery( $add_jquery = 1, $add_jquery_ui = 1, $add_jquery_ui_css = 1, $add_remote = 1, $params = null )
{
static $jquery_added = false;
static $jquery_ui_added = false;
static $jquery_ui_css_added = false;
$document = JFactory::getDocument();
$flexiparams = JComponentHelper::getParams('com_flexicontent');
$lib_path = '/components/com_flexicontent/librairies';
$add_remote_forced_jquery = $add_remote === 2;
$add_remote_forced_jquery_ui = $add_remote === 2;
if (!$params)
{
$params = new JRegistry;
}
// Set jQuery to load in views that use it
$JQUERY_VER = FLEXI_J40GE ? '3.3.1' : $params->get('jquery_ver', $flexiparams->get('jquery_ver', '1.8.3'));
$JQUERY_VER_URL_ATTRS = FLEXI_J40GE ? array(
'integrity' => 'sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=',
'crossorigin' => 'anonymous',
) : null;
$JQUERY_UI_VER = FLEXI_J40GE ? '1.13.1' : $params->get('jquery_ui_ver', $flexiparams->get('jquery_ui_ver', '1.9.2'));
$JQUERY_UI_THEME = $params->get('jquery_ui_theme', $flexiparams->get('jquery_ui_theme', 'ui-lightness')); // FLEXI_JQUERY_UI_CSS_STYLE: 'ui-lightness', 'smoothness'
if (!in_array($JQUERY_UI_THEME, array('ui-lightness', 'smoothness')))
{
$JQUERY_UI_THEME = 'ui-lightness';
}
JText::script("FLEXI_FORM_IS_BEING_SUBMITTED", true);
JText::script("FLEXI_LOADING", true);
/*
* jQuery library
*/
if ( $add_jquery && !$jquery_added && !JPluginHelper::isEnabled('system', 'jquerysupport') )
{
if ($add_remote_forced_jquery)
{
JHtml::_('jquery.framework'); // add and "override" it
$document->addScript('//code.jquery.com/jquery-'.$JQUERY_VER.'.min.js', null, $JQUERY_VER_URL_ATTRS);
}
else
{
FLEXI_J30GE
? JHtml::_('jquery.framework')
: $document->addScript(JUri::root(true).$lib_path.'/jquery/js/jquery-'.$JQUERY_VER.'.min.js');
}
// The 'noConflict()' statement must be inside a js file, to make sure it executed immediately
if (!FLEXI_J30GE)
{
$document->addScript(JUri::root(true).$lib_path.'/jquery/js/jquery-no-conflict.js');
}
//$document->addCustomTag('<script>jQuery.noConflict();</script>'); // not placed in proper place
$jquery_added = 1;
}
/*
* jQuery-UI library (and its CSS)
*/
if ($add_jquery_ui && !$jquery_ui_added)
{
// Load all components of jQuery-UI (add and "override" it)
if ($add_remote_forced_jquery_ui)
{
!FLEXI_J40GE
? JHtml::_('jquery.ui', array())
: false;
$document->addScript('//code.jquery.com/ui/'.$JQUERY_UI_VER.'/jquery-ui.min.js');
}
else
{
if (FLEXI_J40GE)
{
$document->addScript(JUri::root(true).$lib_path.'/jquery/js/jquery-ui-'.$JQUERY_UI_VER.'/jquery-ui.min.js');
}
elseif (FLEXI_J30GE)
{
JHtml::_('jquery.ui', array('core', 'sortable')); // 'core' in J3+ includes all parts of jQuery-UI CORE component: Core, Widget, Mouse, Position
if ( !$params || $params->get('load-ui-dialog', 1) ) $document->addScript(JUri::root(true).$lib_path.'/jquery/js/jquery-ui/jquery.ui.dialog.min.js');
if ( !$params || $params->get('load-ui-menu', 1) ) $document->addScript(JUri::root(true).$lib_path.'/jquery/js/jquery-ui/jquery.ui.menu.min.js');
if ( !$params || $params->get('load-ui-autocomplete', 1) ) $document->addScript(JUri::root(true).$lib_path.'/jquery/js/jquery-ui/jquery.ui.autocomplete.min.js');
if ( !$params || $params->get('load-ui-progressbar', 1) ) $document->addScript(JUri::root(true).$lib_path.'/jquery/js/jquery-ui/jquery.ui.progressbar.min.js');
}
else
{
$document->addScript(JUri::root(true).$lib_path.'/jquery/js/jquery-ui-'.$JQUERY_UI_VER.'.js');
}
}
$jquery_ui_added = 1;
}
// Add jQuery UI theme, this is included in J3+ when executing jQuery-UI framework is called
if ( $add_jquery_ui_css && !$jquery_ui_css_added )
{
// FLEXI_JQUERY_UI_CSS_STYLE: 'ui-lightness', 'smoothness', ...
$add_remote_forced_jquery_ui
? $document->addStyleSheet('//code.jquery.com/ui/'.$JQUERY_UI_VER.'/themes/'.$JQUERY_UI_THEME.'/jquery-ui.css')
: $document->addStyleSheet(JUri::root(true).$lib_path.'/jquery/css/'.$JQUERY_UI_THEME.'/jquery-ui-'.$JQUERY_UI_VER.'.css');
$jquery_ui_css_added = 1;
}
}
/**
* Utility function to get the Mobile Detector Object
*
* @param string $text
* @param int $nb
* @return string
* @since 1.5
*/
static function getMobileDetector()
{
static $mobileDetector = null;
if ( $mobileDetector===null ) {
require_once (JPATH_SITE.DS.'components'.DS.'com_flexicontent'.DS.'librairies'.DS.'mobiledetect'.DS.'Mobile_Detect.php');
$mobileDetector = new Mobile_Detect_FC();
}
return $mobileDetector;
}
/**
* Utility function to load each JS Frameworks once
*
* @param string $text
* @param int $nb
* @return string
* @since 1.5
*/
static function loadFramework( $framework, $mode='', $params=null )
{
// Detect already loaded framework
static $_loaded = array();
if ( isset($_loaded[$framework]) ) return $_loaded[$framework];
$_loaded[$framework] = false;
// Get frameworks that are configured to be loaded manually in frontend (e.g. via the Joomla template)
$app = JFactory::getApplication();
$cparams = JComponentHelper::getParams('com_flexicontent');
static $load_frameworks = null;
static $load_jquery = null;
if (!isset($load_frameworks[$framework]))
{
if ($load_jquery === null)
{
$load_jquery = (int) $cparams->get('loadfw_jquery', 1) === 1 || !$app->isClient('site');
}
$loadfw_param = 'loadfw_' . strtolower(str_replace('-', '_', $framework));
$load_framework = (int) $cparams->get($loadfw_param, 1);
$load_frameworks[$framework] = $load_framework === 1 || ($load_framework === 2 && !$app->isClient('site'));
}
// Set loaded flag
$_loaded[$framework] = $load_frameworks[$framework];
// Do not progress further if it is disabled
if ( !$load_frameworks[$framework] ) return false;
// Load Framework
$document = JFactory::getDocument();
$lib_path = '/components/com_flexicontent/librairies';
$js = "";
$css = "";
static $specific_browser_support = null;
if ( $specific_browser_support === null )
{
if ( method_exists($document, 'addCustomTag') ) $document->addCustomTag('
<!--[if IE 8]>
<link href="'.JUri::root(true).'/components/com_flexicontent/assets/css/ie8.css?' . FLEXI_VHASH . '" rel="stylesheet" />
<![endif]-->
');
$specific_browser_support = true;
}
static $shared_js_added = null;
if ( $shared_js_added === null )
{
$js .= "
var jbase_url_fc = ".json_encode(JUri::base()).";
var jroot_url_fc = ".json_encode(JUri::root()).";
var jclient_path_fc = ".json_encode(JUri::base(true)).";
";
$shared_js_added = true;
}
switch ( $framework )
{
case 'jQuery':
if ($load_jquery) flexicontent_html::loadJQuery(1, 1, 1, 1, $params);
break;
case 'bootstrap-toggle':
if ($load_jquery) flexicontent_html::loadJQuery();
$framework_path = JUri::root(true).$lib_path.'/bootstrap-toggle';
$document->addScript($framework_path.'/js/bootstrap2-toggle.min.js');
$document->addStyleSheet($framework_path.'/css/bootstrap2-toggle.min.css');
$js .= "
jQuery(document).ready(function(){
jQuery('input.fc_checkboxtoggle').bootstrapToggle();
});
";
break;
case 'touch-punch':
$mobileDetector = flexicontent_html::getMobileDetector();
$isMobile = $mobileDetector->isMobile() || $mobileDetector->isTablet();
if ($isMobile)
{
if ($load_jquery) flexicontent_html::loadJQuery();
$document->addScript(JUri::root(true).$lib_path.'/jquery/js/jquery-ui/jquery.ui.touch-punch.min.js');
}
break;
case 'grapejs':
$framework_path = JUri::root(true).$lib_path.'/grapesjs';
$grapjs_vers = '0.16.22'; // need to update
$url_grapjs_css = 'https://unpkg.com/grapesjs@' . $grapjs_vers . '/dist/css/grapes.min.css';
$url_grapjs_js = 'https://unpkg.com/grapesjs@' . $grapjs_vers . '/dist/grapes.min.js';
$document->addStyleSheet($framework_path.'/stylesheets/toastr.min.css');
$document->addStyleSheet($url_grapjs_css);
$document->addStyleSheet($framework_path.'/stylesheets/grapesjs-preset-webpage.min.css?0.1.10');
$document->addStyleSheet($framework_path.'/stylesheets/tooltip.css');
$document->addStyleSheet($framework_path.'/stylesheets/grapesjs-plugin-filestack.css');
$document->addStyleSheet($framework_path.'/stylesheets/demos.css');
$document->addScript('https://static.filestackapi.com/v3/filestack.js');
$document->addScript($framework_path.'/js/toastr.min.js');
$document->addScript($url_grapjs_js);
// GrapesJS Plugins
//$document->addScript('https://unpkg.com/grapesjs-blocks-basic');
$document->addScript($framework_path.'/js/grapesjs-preset-webpage.min.js?0.1.10');
$document->addScript($framework_path.'/js/grapesjs-lory-slider.min.js?0.1.5');
$document->addScript($framework_path.'/js/grapesjs-tabs.min.js?0.1.1');
$document->addScript($framework_path.'/js/grapesjs-custom-code.min.js?0.1.1');
$document->addScript($framework_path.'/js/grapesjs-touch.min.js?0.1.1');
$document->addScript($framework_path.'/js/grapesjs-parser-postcss.min.js?0.1.1');
$document->addScript($framework_path.'/js/grapesjs-tooltip.min.js?0.1.1');
//shapedivider module
//$document->addScript('https://unpkg.com/grapesjs-shape-divider');
//ckeditor for graps
$document->addScript($framework_path.'/js/grapesjs-plugin-ckeditor.min.js?0.0.9');
$document->addScript('https://cdn.ckeditor.com/4.14.1/standard-all/ckeditor.js');
//bs4
$document->addScript($framework_path.'/js/grapesjs-blocks-bootstrap4.min');
break;
case 'grapesjs_view':
$js .= "
jQuery(document).ready(function(){
jQuery('.tab-container').click(function(e)
{
e.preventDefault();
return true;
});
});
";
break;
case 'sabberworm':
$framework_folder = JPATH_ROOT.$lib_path.'/php_css_parser';
require_once(JPath::clean($framework_folder . '/autoload.php'));
break;
case 'mousewheel':
if ($load_jquery) flexicontent_html::loadJQuery();
$framework_path = JUri::root(true).$lib_path.'/mousewheel';
$document->addScript($framework_path.'/jquery.mousewheel.min.js');
break;
case 'mCSB':
if ($load_jquery) flexicontent_html::loadJQuery();
$framework_path = JUri::root(true).$lib_path.'/mCSB';
// Load jQuery mouse wheel as this JS can make use of it
flexicontent_html::loadFramework('mousewheel');
// Add mousewheel plugin (this is optional)
//$document->addScript($framework_path.'/jquery.mousewheel.min.js');
$document->addScript($framework_path.'/jquery.mCustomScrollbar.min.js');
$document->addStyleSheet($framework_path.'/jquery.mCustomScrollbar.min.css');
$js .= "
jQuery(document).ready(function(){
jQuery('.fc_add_scroller').mCustomScrollbar({
theme:'dark-thick',
advanced:{updateOnContentResize: true}
});
jQuery('.fc_add_scroller_horizontal').mCustomScrollbar({
theme:'dark-thick',
horizontalScroll:true,
advanced:{updateOnContentResize: true}
});
});
";
break;
case 'image-picker':
if ($load_jquery) flexicontent_html::loadJQuery();
$framework_path = JUri::root(true).$lib_path.'/image-picker';
$document->addScript($framework_path.'/image-picker.min.js');
$document->addStyleSheet($framework_path.'/image-picker.css');
break;
case 'masonry':
$framework_path = JUri::root(true).$lib_path.'/masonry';
$document->addScript($framework_path.'/masonry.pkgd.min.js');
break;
case 'google-maps':
//$force_language = $mode == 'form' ? '&language=' . flexicontent_html::getUserCurrentLang() : '';
$force_language = '&language=' . flexicontent_html::getUserCurrentLang();
$apikey = trim($params->get('google_maps_js_api_key', $params->get('apikey')));
// Key is not empty
if ($apikey)
{
// Get head object
$head_obj = $document->mergeHeadData(array(1=>1));
// Unset any previous URL that had no KEY
unset($head_obj->_links['https://maps.google.com/maps/api/js?libraries=geometry,places' . $force_language]);
}
// Key is empty
else
{
// Unset framework-added Flag, to allow retry with other module or field configuration, that may have configured a KEY
unset($load_frameworks[$framework]);
}
// Add map link
$document->addScript('https://maps.google.com/maps/api/js?libraries=geometry,places' . ($apikey ? '&key=' . $apikey : '') . $force_language);
break;
case 'openstreetmap' :
$framework_path = JUri::root(true).$lib_path.'/leaflet';
$document->addStyleSheet($framework_path.'/leaflet.css');
$document->addStyleSheet($framework_path.'/MarkerCluster.css');
$document->addStyleSheet($framework_path.'/MarkerCluster.Default.css');
$document->addScript($framework_path.'/leaflet.js');
$document->addScript($framework_path.'/leaflet.markercluster.js');
break;
case 'pannellum' :
$document->addStyleSheet('https://cdn.jsdelivr.net/npm/pannellum@2.5.6/build/pannellum.css');
$document->addScript('https://cdn.jsdelivr.net/npm/pannellum@2.5.6/build/pannellum.js');
break;
case 'select2':
if ($load_jquery) flexicontent_html::loadJQuery();
// Load flexi-lib, as it contains the select2 attach function: fc_attachSelect2()
flexicontent_html::loadFramework('flexi-lib');
// Load jQuery mouse wheel as this JS can make use of it
flexicontent_html::loadFramework('mousewheel');
// Disable select2 JS in mobile devices and instead use chosen JS ...
$mobileDetector = flexicontent_html::getMobileDetector();
$isMobile = $mobileDetector->isMobile() || $mobileDetector->isTablet();
// Load chosen function (if not loaded already) and target specific selector
if ($isMobile)
{
JHtml::_('formbehavior.chosen', '.use_chosen_lib');
}
// Regardless if we loaded chosen JS or some other code loaded it, prevent it from ... attaching to elements meant for select2
$js .= "
if (typeof jQuery.fn.chosen == 'function') {
jQuery.fn.chosen_fc = jQuery.fn.chosen;
jQuery.fn.chosen = function(){
var args = arguments;
var result;
jQuery(this).each(function() {
if (jQuery(this).hasClass('use_select2_lib') || jQuery(this).hasClass('fc_no_js_attach')) return;
result = jQuery(this).chosen_fc(args);
});
return result;
};
}
";
$ver = '3.5.4';
$framework_path = JUri::root(true).$lib_path.'/select2';
$framework_folder = JPATH_SITE.DS.'components'.DS.'com_flexicontent'.DS.'librairies'.DS.'select2';
$document->addScript($framework_path.'/select2.min.js', array('version' => $ver));
$document->addScript($framework_path.'/select2.sortable.js', array('version' => $ver));
$document->addStyleSheet($framework_path.'/select2.css', array('version' => $ver));
$lang_code = flexicontent_html::getUserCurrentLang();
if ( $lang_code && $lang_code!='en' )
{
// Try language shortcode
if ( file_exists($framework_folder.DS.'select2_locale_'.$lang_code.'.js') ) {
$document->addScript($framework_path.'/select2_locale_'.$lang_code.'.js', array('version' => $ver));
}
// select2 JS 4.0.0+
/*if ( file_exists($framework_folder.DS.'select2'.DS.'i18n'.DS.$lang_code.'.js') ) {
$document->addScript($framework_path.'/select2/i18n/'.$lang_code.'.js', array('version' => $ver));
}*/
// Try country language code
else {
$country_code = flexicontent_html::getUserCurrentLang($short_tag=false);
if ( $country_code && file_exists($framework_folder.DS.'select2_locale_'.$country_code.'.js') ) {
$document->addScript($framework_path.'/select2_locale_'.$country_code.'.js', array('version' => $ver));
}
// select2 JS 4.0.0+
/*if ( $country_code && file_exists($framework_folder.DS.'select2'.DS.'i18n'.DS.$country_code.'.js') ) {
$document->addScript($framework_path.'/select2/i18n/'.$country_code.'.js', array('version' => $ver));
}*/
}
}
// Attach select2 JS but skip it in mobiles and use chosen instead
$js .= "
jQuery(document).ready(function()
{
window.skip_select2_js = ".($isMobile ? 1 : 0).";
fc_attachSelect2('body');
});
";
break;
case 'inputmask':
if ($load_jquery) flexicontent_html::loadJQuery();
$framework_path = JUri::root(true).$lib_path.'/inputmask';
$document->addScript($framework_path.'/jquery.inputmask.bundle.min.js');
// Extra inputmask declarations definitions, e.g. ...
$js .= "";
// Attach inputmask to all input fields that have appropriate tag parameters
$js .= "
jQuery(document).ready(function(){
Inputmask.extendAliases({
decimal: {
alias: 'numeric',
autoGroup: true,
radixPoint: '.',
groupSeparator: ',',
clearMaskOnLostFocus: true,
removeMaskOnSubmit: true,
unmaskAsNumber: false
},
decimal_comma: {
alias: 'numeric',
autoGroup: true,
radixPoint: ',',
groupSeparator: '.',
clearMaskOnLostFocus: true,
removeMaskOnSubmit: true,
unmaskAsNumber: false
},
currency: {
alias: 'numeric',
prefix: '$ ',
groupSeparator: ',',
autoGroup: true,
digits: 2,
digitsOptional: false,
clearMaskOnLostFocus: true,
removeMaskOnSubmit: true,
unmaskAsNumber: false
},
currency_euro: {
alias: 'currency',
prefix: '\u20ac ',
groupSeparator: ',',
autoGroup: true,
digits: 2,
digitsOptional: false,
clearMaskOnLostFocus: false,
removeMaskOnSubmit: true,
unmaskAsNumber: false
},
percentage_zero_nolimit: {
alias: 'percentage',
digits: 2,
radixPoint: '.',
autoGroup: true,
min: 0,
max: '',
suffix: ' %',
allowPlus: false,
allowMinus: false,
clearMaskOnLostFocus: true,
removeMaskOnSubmit: true,
unmaskAsNumber: false
},
percentage_nolimit_nolimit: {
alias: 'percentage',
digits: 2,
radixPoint: '.',
autoGroup: true,
min: '',
max: '',
suffix: ' %',
allowPlus: false,
allowMinus: true,
clearMaskOnLostFocus: true,
removeMaskOnSubmit: true,
unmaskAsNumber: false
},
integer: {
alias: 'numeric',
digits: 0,
radixPoint: '',
clearMaskOnLostFocus: true,
removeMaskOnSubmit: true,
unmaskAsNumber: false
},
unsigned: {
alias: 'numeric',
digits: 0,
radixPoint: '',
allowPlus: false,
allowMinus: false,
clearMaskOnLostFocus: true,
removeMaskOnSubmit: true,
unmaskAsNumber: false
},
'mobile': {
'mask': '9999 999 999',
'autounmask': true,
'insertMode': true,
clearMaskOnLostFocus: true,
removeMaskOnSubmit: true,
unmaskAsNumber: false
}
});
jQuery('input.has_inputmask').each(function() {
jQuery(this).inputmask();
});
jQuery('input.inputmask-regex').each(function() {
jQuery(this).inputmask('Regex');
});
});
";
break;
case 'prettyCheckable':
if ($load_jquery) flexicontent_html::loadJQuery();
$framework_path = JUri::root(true).$lib_path.'/prettyCheckable';
$document->addScript($framework_path.'/dev/prettyCheckable.js');
$document->addStyleSheet($framework_path.'/dist/prettyCheckable.css');
$js .= "
jQuery(document).ready(function(){
jQuery('input.use_prettycheckable').each(function() {
var elem = jQuery(this);
var lbl = elem.next('label');
var lbl_html = elem.next('label').html();
lbl.remove();
elem.prettyCheckable({
color: 'blue',
label: lbl_html
});
});
});
";
break;
case 'multibox':
case 'jmultibox':
if ($load_jquery) flexicontent_html::loadJQuery();
$framework_path = JUri::root(true).$lib_path.'/jmultibox';
// Add JS
$document->addScript($framework_path.'/js/jmultibox.js');
$document->addScript($framework_path.'/js/jquery.vegas.js');
// Add CSS
$document->addStyleSheet($framework_path.'/styles/multibox.css');
$document->addStyleSheet($framework_path.'/styles/jquery.vegas.css');
if (substr($_SERVER['HTTP_USER_AGENT'],0,34)=="Mozilla/4.0 (compatible; MSIE 6.0;") {
$document->addStyleSheet($framework_path.'/styles/multibox-ie6.css');
}
// Attach multibox to ... this will be left to the caller so that it will create a multibox object with custom options
$js .= "";
break;
case 'fancybox':
if ($load_jquery) flexicontent_html::loadJQuery();
$document->addScript(JUri::root(true).'/components/com_flexicontent/assets/js/jquery-easing.js');
$framework_path = JUri::root(true).$lib_path.'/fancybox';
// Load jQuery mouse wheel as this JS can make use of it
flexicontent_html::loadFramework('mousewheel');
// Add fancyBox CSS / JS
$document->addStyleSheet($framework_path.'/dist/jquery.fancybox.min.css');
$document->addScript($framework_path.'/dist/jquery.fancybox.min.js');
// Attach fancybox to all elements having a specific CSS class
$js .= "
jQuery(document).ready(function(){
jQuery('.fancybox').fancybox({
'openEffect' : 'elastic',
'closeEffect' : 'elastic',
'openEasing' : 'easeOutCubic',
'closeEasing' : 'easeInCubic',
'idleTime' : 0
});
});
";
break;
case 'galleriffic':
if ($load_jquery) flexicontent_html::loadJQuery();
$framework_path = JUri::root(true).$lib_path.'/galleriffic';
$document->addStyleSheet($framework_path.'/css/basic.css');
$document->addScript($framework_path.'/js/jquery.galleriffic.js');
break;
case 'elastislide':
if ($load_jquery) flexicontent_html::loadJQuery();
$framework_path = JUri::root(true).$lib_path.'/elastislide';
$document->addStyleSheet($framework_path.'/css/gallery.css');
$document->addScript($framework_path.'/js/jquery.tmpl.min.js');
$document->addScript(JUri::root(true).'/components/com_flexicontent/assets/js/jquery-easing.js', array('version' => FLEXI_VHASH));
$document->addScript($framework_path.'/js/jquery.elastislide.js');
$document->addScript($framework_path.'/js/gallery.js');
break;
case 'photoswipe':
if ($load_jquery) flexicontent_html::loadJQuery();
$framework_path = JUri::root(true).$lib_path.'/photoswipe';
//$document->addStyleSheet($framework_path.'/lib/jquery.mobile/jquery.mobile.css');
$document->addStyleSheet($framework_path.'/photoswipe.css');
//$document->addScript($framework_path.'/lib/jquery.mobile/jquery.mobile.js');
$document->addScript($framework_path.'/lib/simple-inheritance.min.js');
//$document->addScript($framework_path.'/lib/jquery.animate-enhanced.min.js');
$document->addScript($framework_path.'/code.photoswipe.min.js');
$js .= "
jQuery(document).ready(function() {
var myPhotoSwipe = jQuery('.photoswipe_fccontainer a').photoSwipe();
});
";
break;
case 'fcxSlide':
if ($load_jquery) flexicontent_html::loadJQuery();
$framework_path = JUri::root(true).$lib_path.'/fcxSlide';
$document->addScript($framework_path.'/class.fcxSlide.js', array('version' => FLEXI_VHASH));
$document->addStyleSheet($framework_path.'/fcxSlide.css', array('version' => FLEXI_VHASH));
//$document->addScript($framework_path.'/class.fcxSlide.packed.js', array('version' => FLEXI_VHASH));
break;
case 'imagesLoaded':
$framework_path = JUri::root(true).$lib_path.'/imagesLoaded';
$document->addScript($framework_path.'/imagesloaded.pkgd.min.js');
break;
case 'zTree':
if ($load_jquery) flexicontent_html::loadJQuery();
$framework_path = JUri::root(true).$lib_path.'/zTree';
$document->addStyleSheet($framework_path.'/css/flexi_ztree.css');
$document->addStyleSheet($framework_path.'/css/zTreeStyle/zTreeStyle.css');
$document->addScript($framework_path.'/js/jquery.ztree.all-3.5.min.js');
//$document->addScript($framework_path.'/js/jquery.ztree.core-3.5.js');
//$document->addScript($framework_path.'/js/jquery.ztree.excheck-3.5.js');
//$document->addScript($framework_path.'/js/jquery.ztree.exedit-3.5.js');
break;
case 'plupload':
if ($load_jquery) flexicontent_html::loadJQuery();
$framework_path = JUri::root(true).$lib_path.'/plupload';
$framework_folder = JPATH_SITE.DS.'components'.DS.'com_flexicontent'.DS.'librairies'.DS.'plupload';
$document->addScript($framework_path.'/js/plupload.full.min.js');
if ($mode=='ui') {
$document->addStyleSheet($framework_path.'/js/jquery.ui.plupload/css/jquery.ui.plupload.css');
$document->addScript($framework_path.'/js/jquery.ui.plupload/jquery.ui.plupload.min.js');
//$document->addScript($framework_path.'/js/themeswitcher.js');
} else {
$document->addStyleSheet($framework_path.'/js/jquery.plupload.queue/css/jquery.plupload.queue.css');
$document->addScript($framework_path.'/js/jquery.plupload.queue/jquery.plupload.queue.js');
}
$lang_code = flexicontent_html::getUserCurrentLang();
if ( $lang_code && $lang_code!='en' )
{
// Try language shortcode
if ( file_exists($framework_folder.DS.'js'.DS.'i18n'.DS.$lang_code.'.js') ) {
$document->addScript($framework_path.'/js/i18n/'.$lang_code.'.js');
}
// Try country language code
else {
$country_code = flexicontent_html::getUserCurrentLang($short_tag=false);
$country_code = str_replace('-', '_', $country_code); // Files for this library use underscore ...
if ( $country_code && file_exists($framework_folder.DS.'js'.DS.'i18n'.DS.$country_code.'.js') ) {
$document->addScript($framework_path.'/js/i18n/'.$country_code.'.js');
}
}
}
// For debugging
//$document->addScript($framework_path.'/js/moxie.min.js');
//$document->addScript($framework_path.'/js/plupload.dev.js');
break;
case 'nouislider':
$framework_path = JUri::root(true).$lib_path.'/nouislider';
$document->addStyleSheet($framework_path.'/nouislider.min.css');
$document->addScript($framework_path.'/nouislider.min.js');
break;
case 'flexi_js_common':
$site_languages = FLEXIUtilities::getLanguages();
$default_lang_code = flexicontent_html::getSiteDefaultLang();
$sef_lang_code = isset($site_languages->{$default_lang_code}) ? $site_languages->{$default_lang_code}->sef : '';
$needed_vars = array('cid', 'cids', 'cc');
$FC_URL_VARS = array();
foreach($needed_vars as $nv)
{
!isset($_GET[$nv]) ?: $FC_URL_VARS[$nv] = $_GET[$nv];
}
$js .= "
var fc_sef_lang = '" . $sef_lang_code . "';
var fc_root_uri = '" . JUri::root(true) . "';
var fc_base_uri = '" . JUri::base(true) . "';
var FC_URL_VARS = " . json_encode($FC_URL_VARS) . ";
";
break;
case 'flexi_tmpl_common':
if ($load_jquery) flexicontent_html::loadJQuery();
flexicontent_html::loadFramework('flexi_js_common');
flexicontent_html::loadFramework('select2'); // make sure select2 is loaded
// Make sure user cookie is set
$jcookie = $app->input->cookie;
$fc_uid = $jcookie->get( 'fc_uid', null);
$hashedUA = JFactory::getUser()->id
? JUserHelper::getShortHashedUserAgent()
: 'p';
if ($fc_uid != $hashedUA)
{
$jcookie->set( 'fc_uid', $hashedUA, 0);
}
$document->addScript(JUri::root(true).'/components/com_flexicontent/assets/js/tmpl-common.js', array('version' => FLEXI_VHASH));
$document->addScript(JUri::root(true).'/components/com_flexicontent/assets/js/jquery-easing.js', array('version' => FLEXI_VHASH));
JText::script("FLEXI_APPLYING_FILTERING", true);
JText::script("FLEXI_TYPE_TO_LIST", true);
JText::script("FLEXI_TYPE_TO_FILTER", true);
JText::script("FLEXI_UPDATING_CONTENTS", true);
break;
case 'flexi-lib':
if ($load_jquery) flexicontent_html::loadJQuery();
flexicontent_html::loadFramework('flexi_js_common');
// For J3.7.0+ , load polyfills for older IE browsers: < IE11
if (FLEXI_J37GE)
{
JHtml::_('behavior.polyfill', array('event', 'classlist', 'map'), 'lte IE 11');
}
$js .= "";
$document->addScript(JUri::root(true).'/components/com_flexicontent/assets/js/flexi-lib.js', array('version' => FLEXI_VHASH));
JText::script("FLEXI_NOT_AN_IMAGE_FILE", true);
JText::script("FLEXI_IMAGE", true);
JText::script('FLEXI_LOADING_IMAGES',true);
JText::script('FLEXI_THUMBNAILS',true);
JText::script("FLEXI_NO_ITEMS_SELECTED", true);
JText::script("FLEXI_ARE_YOU_SURE", true);
JText::script("FLEXI_APPLYING_FILTERING");
/**
* MANAGE FILTERING MESSAGE DISPLAY
*/
// Content Box
$content_color = $cparams->get('page_reloading_content_color', 'rgba(0, 0, 0, 1)');
$content_bg_color = $cparams->get('page_reloading_content_bg_color', 'rgba(255, 255, 255, 1)');
// Logo ... in Content Box
$logo_imgsrc = $cparams->get('page_reloading_logo_imgsrc', '');
$logo_imgsrc = $logo_imgsrc ? JUri::root() . $logo_imgsrc : '';
$logo_opacity = $cparams->get('page_reloading_logo_opacity', 100);
$logo_opacity = number_format(($logo_opacity / 100.0), 2, '.', '');
// Text Message ... in Content Box
$mssg_display = $cparams->get('page_reloading_mssg_display', 1);
$mssg_text = $cparams->get('page_reloading_mssg_text', 'FLEXI_APPLYING_FILTERING');
// Progress Bar ... in Content Box
$pbar_display = $cparams->get('page_reloading_pbar_display', 1);
$pbar_color = $cparams->get('page_reloading_pbar_color', 'rgba(0, 153, 255, 1)');
// Overlay Box
$overlay_bg_color = $cparams->get('page_reloading_overlay_bg_color', 'rgba(0, 0, 0, 0.3)');
// Get other CSS
// Create CSS style as an array, we will implode it using '; '
$styles = (object) array(
'content_box' => 'background-color: ' . $content_bg_color . '; color: ' . $content_color . ';' ,
'logo_box' => 'opacity: ' . $logo_opacity . ';',
'mssg_box' => '',
'progress_bar' => 'background-color: ' . $pbar_color . ';' ,
'overlay_box' => 'background-color: ' . $overlay_bg_color . ';',
);
$js .= '
jQuery( document ).ready(function() {
jQuery("body").prepend(\'\\
<div id="fc_filter_form_blocker" style="display: none;">\\
<div class="fc_blocker_overlay" style="' . $styles->overlay_box . '"></div>\\
<div class="fc_blocker_content" style="' . $styles->content_box . '">\\
' . ($logo_imgsrc ? '<div class="fc_blocker_logo" style="' . $styles->logo_box . '" ><img src="' . $logo_imgsrc . '" alt="' . $mssg_text . '"></div>' : '') . '\\
' . ($mssg_display ? '<div class="fc_blocker_mssg" style="' . $styles->mssg_box . '" >' . JText::_($mssg_text, true) . '</div>' : '') . '\\
' . ($pbar_display ? '<div class="fc_blocker_bar"><div style="' . $styles->progress_bar . '"></div></div>' : '') . '\\
</div>\\
</div>\\
\');
});
';
break;
// Used only by content / configuration forms, that have form elements needing this
case 'flexi-lib-form':
if ($load_jquery) flexicontent_html::loadJQuery();
$document->addScript(JUri::root(true).'/components/com_flexicontent/assets/js/flexi-lib-form.js', array('version' => FLEXI_VHASH));
JText::script("FLEXI_EDIT", true);
JText::script("FLEXI_ADD", true);
JText::script("FLEXI_NA", true);
JText::script("FLEXI_PUBLISHED", true);
JText::script("FLEXI_UNPUBLISHED", true);
JText::script("FLEXI_EXPIRED", true);
JText::script("FLEXI_ARCHIVED", true);
JText::script("FLEXI_TRASHED", true);
JText::script("FLEXI_REMOVE", true);
JText::script("FLEXI_ORDER", true);
JText::script("FLEXI_INDEXED_FIELD_UNUSED_COL_DISABLED", true);
JText::script("FLEXI_INDEXED_FIELD_VALGRP_COL_DISABLED", true);
JText::script("FLEXI_INDEXED_FIELD_STATE_COL_DISABLED", true);
JText::script('FLEXI_REQUIRED',true);
JText::script('FLEXI_INVALID',true);
JText::script('FLEXI_AUTO',true);
JText::script('FLEXI_FIELD_SELECT_AT_LEAST_PROMPT',true);
JText::script('FLEXI_FIELD_SELECT_UP_TO_PROMPT',true);
JText::script('FLEXI_FIELD_SELECT_EXACTLY_PROMPT',true);
break;
default:
JFactory::getApplication()->enqueueMessage(__FUNCTION__.' Cannot load unknown Framework: '.$framework, 'error');
break;
}
// Add custom JS & CSS code
if ($js) $document->addScriptDeclaration($js);
if ($css) $document->addStyleDeclaration($css);
return $_loaded[$framework];
}
/**
* Escape an HTML string so that it can be used directly by JS source code
*
* @param string $text
* @param int $nb
* @return string
* @since 1.5
*/
static function encodeHTML($string, $no_quote='s')
{
$string = trim(json_encode($string, FLEXI_PHP_54GE ? JSON_UNESCAPED_UNICODE : 0), '"');
if ($no_quote === 1)
{
}
else if ($no_quote === 2)
{
$string = str_replace("\\'", "\\\\\\'", addslashes($string));
}
else if ($no_quote === 'd')
{
$string = str_replace('\\"', '"', $string);
$string = str_replace("'", "\\'", $string);
}
return $string;
}
// DEPRECATED, instead use: encodeHTML()
static function escapeJsText($string, $no_quote='s')
{
return flexicontent_html::encodeHTML($string, $no_quote);
}
/**
* Trims whitespace from an array of strings
*
* @param string array $arr_str
* @return string array
* @since 1.5
*/
static function arrayTrim($arr_str) {
if(!is_array($arr_str)) return false;
foreach($arr_str as $k=>$a) {
$arr_str[$k] = trim($a);
}
return $arr_str;
}
// Server-Side validation
static function dataFilter( $v, $maxlength=0, $validation='string', $check_callable=0 )
{
// validation: Strip HTML and cut the text
if ($validation=='-1') return flexicontent_html::striptagsandcut( $v, $maxlength );
// validation: via function call
$v = $maxlength ? substr($v, 0, $maxlength) : $v;
if ($check_callable)
{
if (strpos($validation, '::') !== false && is_callable(explode('::', $validation)))
{
return call_user_func(explode('::', $validation), $v); // A callback class method
}
elseif (function_exists($validation))
{
return $validation($v);
}
}
// Map integer validation code to custom validation types
$_map = array('1'=>'safehtml_decode_first', '2'=>'joomla_text_filters', '3'=>'safehtml_allow_encoded');
$validation = isset($_map[$validation]) ? $_map[$validation] : $validation;
// Create a safe-HTML or a no-HTML filter
if ($validation=='safehtml_decode_first' || $validation=='safehtml_allow_encoded')
{
$safeHtmlFilter = JFilterInput::getInstance(null, null, 1, 1);
}
else if ($validation!='joomla_ug_text_filters')
{
$noHtmlFilter = JFilterInput::getInstance();
}
// Do the filtering
$validation = strtoupper($validation);
switch ($validation)
{
case 'SAFEHTML_DECODE_FIRST':
// Allow safe HTML ... but also decode HTML special characters before filtering
// Decoding allows removal of e.g. <badtag> ... </badtag>
$v = $safeHtmlFilter->clean($v, 'string');
break;
case 'SAFEHTML_ALLOW_ENCODED':
// Allow safe HTML ... and allow ANY HTML if encoded, e.g. allows <i> ... </i>
$v = $safeHtmlFilter->clean($v, 'html');
break;
case 'JOOMLA_TEXT_FILTERS':
// Filter according to user group Text Filters
$v = JComponentHelper::filterText($v);
break;
case 'ACCESSLEVEL':
// Filter using known access levels
if ( ((int) $v) != $v )
{
$v = 1; // Public
break;
}
$v = (int) $v;
$options = JHtml::_('access.assetgroups');
$found = false;
foreach ($options as $o)
{
if ($o->value== $v)
{
$found = true;
break;
}
}
if (!$found) $v = 1;
break;
case 'URL':
// This cleans some of the more dangerous characters but leaves special characters that are valid.
$v = trim($noHtmlFilter->clean($v, 'HTML'));
// <>" are never valid in a uri see http://www.ietf.org/rfc/rfc1738.txt.
$v = str_replace(array('<', '>', '"'), '', $v);
// Convert to Punycode string
$v = JStringPunycode::urlToPunycode( $v );
break;
case 'EMAIL':
// Use the Joomla mail helper to validate emails
jimport('joomla.mail.helper');
if ( !JMailHelper::isEmailAddress($v) ) $v = '';
break;
default:
// Filter using JFilterInput
$v = $noHtmlFilter->clean($v, $validation);
break;
}
$v = trim($v);
return $v;
}
/**
* Strip html tags and cut after x characters, optionally adding a toggler button to show the trimmed text
*
* @param string $text
* @param int $nb
* @return string
* @since 1.5
*/
static function striptagsandcut( $text, $chars=null, &$uncut_length=0, $options = null)
{
$options = $options ?: array(
'cut_at_word' => false,
'more_box_id' => '',
'more_toggler' => 0,
'more_icon' => 'icon-paragraph-center',
'more_txt' => '...',
'modal_title'=>'...',
'keep_jplugins_code' => false
);
// Convert html entities to characters so that they will not be removed ... by strip_tags
$cleantext = html_entity_decode ($text, ENT_NOQUOTES, 'UTF-8');
// Add whitespaces at start/end of tags so that words will not be joined,
//$cleantext = preg_replace('/(<\/[^>]+>((?!\P{L})|(?=[0-9])))|(<[^>\/][^>]*>)/u', ' $1', $cleantext);
//$cleantext = preg_replace('/(<\/[^>]+>(?![\:|\.|,|:|"|\']))|(<[^>\/][^>]*>)/u', ' $1', $cleantext);
// Add whitespaces at start/end of BLOCK AND LINE BREAKING TAGS so that words will not be joined,
$cleantext = preg_replace('/(<|<\/)('.
'address|article|aside|blockquote|br|canvas|dd|div|dl|dt|'.
'fieldset|figcaption|figure|footer|form|h1|h2|h3|h4|h5|h6|header|hgroup|hr|li|'.
'main|nav|noscript|ol|output|p|pre|section|table|tfoot|ul|video'.
')\b/i',
' $1$2', $cleantext);
// Strip javascript
$cleantext = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $cleantext);
// Strip html tags
$cleantext = strip_tags($cleantext);
// Strip SCRIPT tags already done above
//$cleantext = preg_replace( '#<script\b[^>]*>(.*?)<\/script>#is', '', $cleantext );
// Clean Joomla Plugin code
if ( empty($options['keep_jplugins_code']) )
{
$patterns = array();
$patterns[] = '#\[(.*?)\]#';
$patterns[] = '#{(.*?)}#';
$patterns[] = '#&(.*?);#';
foreach ($patterns as $pattern)
{
$cleantext = preg_replace( $pattern, '', $cleantext );
}
}
// Replace multiple spaces, tabs, newlines, etc with a SINGLE whitespace so that text length will be calculated correctly
$cleantext = preg_replace('/[\p{Z}\s]{2,}/u', ' ', $cleantext); // Unicode safe whitespace replacing
// Calculate length according to UTF-8 encoding
$uncut_length = StringHelper::strlen($cleantext);
// Cut off the text if required
if ($chars && $uncut_length > $chars)
{
// If not cutting at middle of word, then find closest whitespace, that is previous to the word
if (!$options['cut_at_word'])
{
$chars = StringHelper::strrpos(StringHelper::substr($cleantext, 0, $chars), ' ');
}
// Cut the text
$text1 = StringHelper::substr($cleantext, 0, $chars);
// Add a toggle of the full text
switch ($options['more_toggler'])
{
case 2:
$box_js = !empty($options['more_box_id'])
? ' var box = document.getElementById(\'' . $options['more_box_id'] . '\'); '
: ' var box = this.parentElement.previousElementSibling; ';
$text2 = (empty($options['more_box_id']) ? '
<div style="display:none;">
'. $text . '
</div>' : '') . '
<span class="readmore">
<span style="cursor: pointer;" class="btn btn-mini" onclick="' . $box_js . ' fc_file_props_handle = fc_showAsDialog(box, 800, 600, null, { title: \'' . JText::_($options['modal_title']) . '\'}); return false;">
<span class="'.$options['more_icon'].'"></span>
'.JText::_($options['more_txt']).'
</span>
</span>';
break;
case 1:
$text2 = '
<span style="cursor: pointer;" class="btn btn-mini" onclick="var box = this.nextElementSibling; box.style.display = box.style.display == \'none\' ? \'block\' : \'none\'; return false;">
<span class="'.$options['more_icon'].'"></span>
'.JText::_($options['more_txt']).'
</span>
<span class="fc_cutted_text" style="display: none;">
' . htmlspecialchars(StringHelper::substr($cleantext, $chars), ENT_COMPAT, 'UTF-8') . '
</span>';
break;
default:
$text2 = ' ' . JText::_($options['more_txt']);
break;
}
}
else
{
$text1 = $cleantext;
$text2 = '';
}
// Reencode HTML special characters, (but do not encode UTF8 characters)
// and RETURN cutted text, optionally adding a show all text button
return htmlspecialchars($text1, ENT_COMPAT, 'UTF-8') . $text2;
}
/**
* Make image tag from field or extract image from introtext
*
* @param array $row
* @return string
* @since 1.5
*/
static function extractimagesrc( $row )
{
jimport('joomla.filesystem.file');
$regex = '#<\s*img [^\>]*src\s*=\s*(["\'])(.*?)\1#im';
if (isset($row->fields['text']->display)) preg_match ($regex, $row->fields['text']->display, $matches);
if (empty($matches)) preg_match ($regex, $row->introtext, $matches);
if (empty($matches)) preg_match ($regex, $row->fulltext, $matches);
$image = !empty($matches) ? $matches[2] : '';
// Case of local file, check that file exists
if (!preg_match("#^http|^https|^ftp#i", $image))
{
$image = JFile::exists( JPATH_SITE . DS . $image ) ? $image : '';
}
return $image;
}
/**
* Logic to change the state of an item
*
* @access public
* @return void
* @since 1.0
*/
static function setitemstate($controller_obj, $type = 'html', $record_name = 'item')
{
$app = JFactory::getApplication();
$jinput = $app->input;
$id = $jinput->get('id', 0, 'int');
$jinput->set('cid', $id);
$model = $controller_obj->getModel($record_name);
$record = $model->getItem($id);
$user = JFactory::getUser();
$state = $jinput->get('state', 0, 'int');
$perms = FlexicontentHelperPerm::getPerm();
$archive_unsupported = !isset($model->supported_conditions[2]);
$trash_unsupported = !isset($model->supported_conditions[-2]);
// Determine priveleges of the current user on the given item
/*if (!in_array($record_name, array('item', 'category', 'tag', 'review', 'type', 'field', 'file')))
{
die('flexicontent_html::' . __FUNCTION__ . '() , unknown type: ' . $record_name);
}*/
// Check if locked, (we catch case that property checked_out does not exist using empty()
$canCheckin = empty($record->checked_out) || $record->checked_out == $user->id || $user->authorise('core.admin', 'com_checkin');
// Determine privileges of the current user on the given item
$has_config = $user->authorise('core.admin', 'com_flexicontent');
$has_edit_state = $model->canEditState($record);
$has_trash = $has_edit_state;
$has_archive = $record_name === 'item'
? $has_edit_state && $perms->CanArchives
: $has_edit_state;
// Clear access if record is locked
$has_edit_state = $canCheckin && $has_edit_state;
$has_trash = $canCheckin && $has_trash;
$has_archive = $canCheckin && $has_archive;
// Clear access if state is not supported
$has_trash = $has_trash && empty($trash_unsupported);
$has_archive = $has_archive && empty($archive_unsupported);
// Has access to specific state, and doing the specific state change
$has_n_doing_edit_state = $has_edit_state && (
in_array($state, array(0,1,-5)) || ($has_config && in_array($state, array(-3,-4)))
);
$has_n_doing_delete = $has_trash && $state === -2;
$has_n_doing_archive = $has_archive && $state === 2;
// Check if user can change of the item to the requested state
if (!$has_n_doing_edit_state && !$has_n_doing_delete && !$has_n_doing_archive)
{
// This must be short text, so not using 'FLEXI_NO_ACCESS_CHANGE_STATE'
jexit(JText::_('FLEXI_DENIED'));
}
// Set new item state (model will also handle cache cleaning)
if (!$model->setitemstate($id, $state))
{
$msg = JText::_('FLEXI_ERROR_SETTING_THE_ITEM_STATE') . ' : ' . $model->getError();
if ($type === 'json')
{
$app->enqueueMessage($msg, 'warning');
$data = array('error'=>flexicontent_html::get_system_messages_html(), 'html'=>'---', 'title'=>JText::_('Aborted'));
jexit(json_encode($data));
}
else
{
jexit($msg);
}
}
// Output new state icon and terminate
$tmpparams = new JRegistry();
$tmpparams->set('stateicon_popup', 'basic');
$stateicon = flexicontent_html::stateicon($state, $tmpparams, $type);
jexit($stateicon);
}
/**
* Creates a font icon or image icon for the button according to configuration object
*
* @param object $params Configuration parameters, typically of component plus some override
* @param array $config Configuration for creating the icon
* @param string $icon The icon HTML
*
* @since 3.3.0
*/
static function createFcBtnIcon($params, $config, & $icon)
{
$show_icons = (int) $params->get('show_icons', 2);
$use_font = (int) $params->get('use_font_icons', 1);
if ($show_icons && $use_font)
{
if (self::$icon_classes === null)
{
self::load_class_config();
}
$icon_class = !empty(self::$icon_classes[$config->iconname])
? self::$icon_classes[$config->iconname]
: $config->icondefault;
if ($show_icons === 2)
{
$icon_class .= ' fcIconPadRight';
}
$icon = '<i class="' . $icon_class . '"></i>';
}
elseif ($show_icons)
{
$iconpath = !empty($config->iconpath)
? $config->iconpath . '/' . $config->iconimage
: FLEXI_ICONPATH . $config->iconimage;
$icon = JHtml::image($iconpath, JText::_($config->icontitle), $attribs = '');
}
}
/**
* Creates the rss feed button
*
* @param string $print_link
* @param array $params
* @since 1.0
*/
static function feedbutton($view, &$params, $slug = null, $itemslug = null, $reserved=null, $item = null)
{
if ( !$params->get('show_feed_icon', 1) || JFactory::getApplication()->input->getInt('print', 0) ) return;
$uri = JUri::getInstance();
$base = $uri->toString( array('scheme', 'host', 'port'));
//TODO: clean this static stuff (Probs when determining the url directly with subdomains)
if ($view == 'category')
{
$non_sef_link = null;
flexicontent_html::createCatLink($slug, $non_sef_link);
$link = $base . JRoute::_($non_sef_link . '&format=feed&type=rss');
//$link = $base.JRoute::_( 'index.php?view='.$view.'&cid='.$slug.'&format=feed&type=rss', false );
}
elseif ($view == FLEXI_ITEMVIEW)
{
$link = $base . JRoute::_(FlexicontentHelperRoute::getItemRoute($itemslug, $slug, 0, $item).'&format=feed&type=rss');
//$link = $base.JRoute::_( 'index.php?view='.$view.'&cid='.$slug.'&id='.$itemslug.'&format=feed&type=rss', false );
}
elseif ($view == 'tags')
{
$link = $base . JRoute::_(FlexicontentHelperRoute::getTagRoute($itemslug) . '&format=feed&type=rss');
//$link = $base.JRoute::_( 'index.php?view='.$view.'&id='.$slug.'&format=feed&type=rss', false );
}
else
{
$link = $base . JRoute::_( 'index.php?view='.$view.'&format=feed&type=rss', false );
}
// Workaround for bug due 3rd party plugin calling methods that force JDocument format to be HTML
if (strpos($link, 'format=feed') === false)
{
$link = $link . (strpos($link, '?') !== false ? '&' : '?') . 'format=feed';
}
$status = 'status=no,toolbar=no,scrollbars=yes,titlebar=no,menubar=no,resizable=yes,left=50,width=\'+(screen.width-100)+\',top=20,height=\'+(screen.height-160)+\',directories=no,location=no';
$onclick = ' window.open(this.href,\'win2\',\''.$status.'\'); return false; ';
// Get font icon or image icon for the button
$config = (object) array(
'iconname' => 'feed',
'icondefault' => 'icon-feed',
'iconimage' => 'livemarks.png',
'icontitle' => 'FLEXI_FEED',
);
$show_icons = (int) $params->get('show_icons', 2);
$image = '';
self::createFcBtnIcon($params, $config, $image);
$overlib = JText::_( 'FLEXI_FEED_TIP' );
$text = JText::_( 'FLEXI_FEED' );
$button_classes = 'fc_feedbutton';
if ($show_icons === 1)
{
$caption = '';
$button_classes .= '';
$tooltip_placement = 'top';
}
else
{
$caption = $text;
if ( !$params->get('btn_grp_dropdown', 0) ) $button_classes .= self::$use_bootstrap ? ' btn btn-small' : ' fc_button fcsimple fcsmall';
$tooltip_placement = !$params->get('btn_grp_dropdown', 0) ? 'top' : 'left';
}
$button_classes .= ' hasTooltip';
$tooltip_title = flexicontent_html::getToolTip($text, $overlib, 0);
// $link as set above
$output = ' <a href="'.$link.'" class="'.$button_classes.'" data-placement="' . $tooltip_placement . '" title="'.$tooltip_title.'" onclick="'.$onclick.'" >'.$image.$caption.'</a>';
$output = JText::_('FLEXI_ICON_SEP') . $output . JText::_('FLEXI_ICON_SEP');
return $output;
}
/**
* Creates the delete button
*
* @param array $params
* @since 1.0
*/
static function deletebutton($item, &$params)
{
if ( !$params->get('show_deletebutton', 0) || JFactory::getApplication()->input->getInt('print', 0) ) return;
$user = JFactory::getUser();
// Determine if current user can delete the given item
$asset = 'com_content.article.' . $item->id;
$has_delete = $user->authorise('core.delete', $asset) || ($item->created_by == $user->get('id') && $user->authorise('core.delete.own', $asset));
// Create the delete button only if user can delete the give item
if (!$has_delete)
{
return;
}
// Get font icon or image icon for the button
$config = (object) array(
'iconname' => 'delete',
'icondefault' => 'icon-delete',
'iconimage' => 'delete.png',
'iconpath' => 'components/com_flexicontent/assets/images', // Use icon from flexicontent assets folder
'icontitle' => 'FLEXI_DELETE',
);
$show_icons = (int) $params->get('show_icons', 2);
$image = '';
self::createFcBtnIcon($params, $config, $image);
$overlib = JText::_( 'FLEXI_DELETE_TIP' );
$text = JText::_( 'FLEXI_DELETE' );
$button_classes = 'fc_deletebutton';
if ($show_icons === 1)
{
$caption = '';
$button_classes .= '';
$tooltip_placement = 'top';
}
else
{
$caption = $text;
if ( !$params->get('btn_grp_dropdown', 0) ) $button_classes .= self::$use_bootstrap ? ' btn btn-small' : ' fc_button fcsimple fcsmall';
$tooltip_placement = !$params->get('btn_grp_dropdown', 0) ? 'top' : 'left';
}
$button_classes .= ' hasTooltip';
$tooltip_title = flexicontent_html::getToolTip($text, $overlib, 0);
//$Itemid = JFactory::getApplication()->input->get('Itemid', 0, 'int'); // Maintain menu item ? e.g. current category view,
$Itemid = 0;
$item_url = JRoute::_(FlexicontentHelperRoute::getItemRoute($item->slug, $item->categoryslug, $Itemid, $item));
$link = $item_url . (strpos($item_url, '?') !== false ? '&' : '?') . 'task=remove' . '&' . JSession::getFormToken() . '=1';
$view = JFactory::getApplication()->input->getCm('view', '');
$link .= '&isitemview=' . ($view == 'item' ? '1' : '0');
$targetLink = "_self";
$confirm_text = JText::_('FLEXI_ARE_YOU_SURE_PERMANENT_DELETE', true);
$output = ' <a href="'.$link.'" class="'.$button_classes.'" data-placement="' . $tooltip_placement . '" onclick="return confirm(\''.$confirm_text.'\')" target="'.$targetLink.'" title="'.$tooltip_title.'">'.$image.$caption.'</a>';
$output = JText::_('FLEXI_ICON_SEP') . $output . JText::_('FLEXI_ICON_SEP');
return $output;
}
/**
* Creates the CSV export button
*
* @param array $params
* @since 1.0
*/
static function csvbutton($view, &$params, $slug = null, $itemslug = null, $reserved=null, $item = null)
{
if ( !$params->get('show_csvbutton', 0) || JFactory::getApplication()->input->getInt('print', 0) ) return;
$user = JFactory::getUser();
// Determine if current user can export csv
$has_export_csv = $user->authorise('core.export', $asset);
// Create the delete button only if user can delete the give item
if (!$has_export_csv)
{
return;
}
$uri = JUri::getInstance();
$base = $uri->toString( array('scheme', 'host', 'port'));
$has_export_all_btn = false;
$memory_limit = ini_get('memory_limit');
if (preg_match('/^(\d+)(.)$/', $memory_limit, $matches))
{
switch($matches[2])
{
case 'G': $memory_limit = $matches[1] * 1024 * 1024 *1024; break;
case 'M': $memory_limit = $matches[1] * 1024 * 1024; break;
case 'K': $memory_limit = $matches[1] * 1024; break;
default: $memory_limit = $memory_limit; break;
}
}
$export_limit = ($memory_limit - (15 * 1024 * 1024)) / (1024 * 50);
$export_limit = $export_limit > 20000 ? 20000 : $export_limit;
//TODO: clean this static stuff (Probs when determining the url directly with subdomains)
if ($view == 'category')
{
$has_export_all_btn = true;
$filters = flexicontent_html::getCatViewFilterVars();
$start = JFactory::getApplication()->input->get('start', '', 'int');
$non_sef_link = null;
flexicontent_html::createCatLink($slug, $non_sef_link);
// Current page
$link = $base . JRoute::_(
$non_sef_link
. '&format=csv'
. $filters
. ($start ? "&start=".$start : '')
);
// All pages
$link_all_pages = $base . JRoute::_(
$non_sef_link
. '&format=csv'
. $filters
. '&start=0&limit=' . $export_limit
);
//$link = $base.JRoute::_( 'index.php?view='.$view.'&cid='.$slug.'&format=csv', false );
} elseif ($view == FLEXI_ITEMVIEW) {
$link = $base . JRoute::_(FlexicontentHelperRoute::getItemRoute($itemslug, $slug, 0, $item).'&format=csv');
//$link = $base.JRoute::_( 'index.php?view='.$view.'&cid='.$slug.'&id='.$itemslug.'&format=csv', false );
} elseif ($view == 'tags') {
$link = $base . JRoute::_(FlexicontentHelperRoute::getTagRoute($itemslug).'&format=csv');
//$link = $base.JRoute::_( 'index.php?view='.$view.'&id='.$slug.'&format=csv', false );
} else {
$link = $base . JRoute::_( 'index.php?view='.$view.'&format=csv', false );
}
$status = 'status=no,toolbar=no,scrollbars=yes,titlebar=no,menubar=no,resizable=yes,left=50,width=\'+(screen.width-100)+\',top=20,height=\'+(screen.height-160)+\',directories=no,location=no';
$onclick = ' window.open(this.href,\'win2\',\''.$status.'\'); return false; ';
// Get font icon or image icon for the button
$config = (object) array(
'iconname' => 'csv',
'icondefault' => 'icon-download',
'iconimage' => 'csv.png',
'icontitle' => 'FLEXI_CSV_EXPORT',
);
$show_icons = (int) $params->get('show_icons', 2);
$image = '';
self::createFcBtnIcon($params, $config, $image);
$overlib = JText::_( 'FLEXI_CSV_TIP_THIS_PAGE' );
$text = JText::_( 'FLEXI_CSV' );
$button_classes = 'fc_csvbutton';
if ($show_icons === 1)
{
$caption = '';
$button_classes .= '';
$tooltip_placement = 'top';
}
else
{
$caption = $text;
if ( !$params->get('btn_grp_dropdown', 0) ) $button_classes .= self::$use_bootstrap ? ' btn btn-small' : ' fc_button fcsimple fcsmall';
$tooltip_placement = !$params->get('btn_grp_dropdown', 0) ? 'top' : 'left';
}
$button_classes .= ' hasTooltip';
$tooltip_title = flexicontent_html::getToolTip($text, $overlib, 0);
// Export All
$output .= JText::_('FLEXI_ICON_SEP')
. ' <a href="'.$link.'" class="'.$button_classes.'" data-placement="' . $tooltip_placement . '" title="'.$tooltip_title.'" onclick="'.$onclick.'" >'
. $image . ($has_export_all_btn? '<span class="icon-file"></span> ' : '')
. $caption // . ($has_export_all_btn? ' (Current page)' : '')
. '</a>'
. JText::_('FLEXI_ICON_SEP');
// Export current page
if (!empty($link_all_pages))
{
$overlib = JText::_( 'FLEXI_CSV_TIP' ) . ($has_export_all_btn ? '<br>' . JText::sprintf( 'FLEXI_CSV_TIP_EXPORT_LIMIT', $export_limit) : '');
$tooltip_title = flexicontent_html::getToolTip($text, $overlib, 0);
$output .= JText::_('FLEXI_ICON_SEP')
. ' <a href="'.$link_all_pages.'" class="'.$button_classes.'" data-placement="' . $tooltip_placement . '" title="'.$tooltip_title.'" onclick="'.$onclick.'" >'
. $image . ($has_export_all_btn? '<span class="icon-book"></span> ' : '')
. $caption // . ($has_export_all_btn? ' (All pages)' : '')
. '</a>'
. JText::_('FLEXI_ICON_SEP');
}
return $output;
}
/**
* Creates the print button
*
* @param string $print_link
* @param array $params
* @since 1.0
*/
static function printbutton($print_link, &$params)
{
if ( !$params->get('show_print_icon') || JFactory::getApplication()->input->getInt('print', 0) ) return;
$status = 'status=no,toolbar=no,scrollbars=yes,titlebar=no,menubar=no,resizable=yes,left=50,width=\'+(screen.width-100)+\',top=20,height=\'+(screen.height-160)+\',directories=no,location=no';
$onclick = ' window.open(this.href,\'win2\',\''.$status.'\'); return false; ';
$link = JRoute::_($print_link);
// Get font icon or image icon for the button
$config = (object) array(
'iconname' => 'print',
'icondefault' => 'icon-print',
'iconimage' => 'printButton.png',
'icontitle' => 'FLEXI_PRINT',
);
$show_icons = (int) $params->get('show_icons', 2);
$image = '';
self::createFcBtnIcon($params, $config, $image);
$overlib = JText::_( 'FLEXI_PRINT_TIP' );
$text = JText::_( 'FLEXI_PRINT' );
$button_classes = 'fc_printbutton';
if ($show_icons === 1)
{
$caption = '';
$button_classes .= '';
$tooltip_placement = 'top';
}
else
{
$caption = $text;
if ( !$params->get('btn_grp_dropdown', 0) ) $button_classes .= self::$use_bootstrap ? ' btn btn-small' : ' fc_button fcsimple fcsmall';
$tooltip_placement = !$params->get('btn_grp_dropdown', 0) ? 'top' : 'left';
}
$button_classes .= ' hasTooltip';
$tooltip_title = flexicontent_html::getToolTip($text, $overlib, 0);
// $link as set above
$output = ' <a href="'.$link.'" class="'.$button_classes.'" data-placement="' . $tooltip_placement . '" title="'.$tooltip_title.'" onclick="'.$onclick.'" rel="nofollow">'.$image.$caption.'</a>';
$output = JText::_('FLEXI_ICON_SEP') . $output . JText::_('FLEXI_ICON_SEP');
return $output;
}
/**
* Creates the email button
*
* @param string $print_link
* @param array $params
* @since 1.0
*/
static function mailbutton($view, &$params, $slug = null, $itemslug = null, $reserved=null, $item = null)
{
static $initialize = null;
static $uri, $base;
if ( !$params->get('show_email_icon') || JFactory::getApplication()->input->getInt('print', 0) ) return;
if ($initialize === null) {
if (file_exists ( JPATH_SITE.DS.'components'.DS.'com_mailto'.DS.'helpers'.DS.'mailto.php' )) {
require_once(JPATH_SITE.DS.'components'.DS.'com_mailto'.DS.'helpers'.DS.'mailto.php');
$uri = JUri::getInstance();
$base = $uri->toString( array('scheme', 'host', 'port'));
$initialize = true;
} else {
$initialize = false;
}
}
if ( $initialize === false ) return;
//TODO: clean this static stuff (Probs when determining the url directly with subdomains)
if($view == 'category') {
$non_sef_link = null;
flexicontent_html::createCatLink($slug, $non_sef_link);
$link = $base . JRoute::_($non_sef_link);
//$link = $base . JRoute::_( 'index.php?view='.$view.'&cid='.$slug, false );
} elseif($view == FLEXI_ITEMVIEW) {
$link = $base . JRoute::_(FlexicontentHelperRoute::getItemRoute($itemslug, $slug, 0, $item));
//$link = $base . JRoute::_( 'index.php?view='.$view.'&cid='.$slug.'&id='.$itemslug, false );
} elseif($view == 'tags') {
$link = $base . JRoute::_(FlexicontentHelperRoute::getTagRoute($itemslug));
//$link = $base . JRoute::_( 'index.php?view='.$view.'&id='.$slug, false );
} else {
$link = $base . JRoute::_( 'index.php?view='.$view, false );
}
$mail_to_url = JRoute::_('index.php?option=com_mailto&tmpl=component&link='.MailToHelper::addLink($link));$status = 'status=no,toolbar=no,scrollbars=yes,titlebar=no,menubar=no,resizable=yes,left=50,width=\'+(screen.width-100)+\',top=20,height=\'+(screen.height-160)+\',directories=no,location=no';
$status = 'left=50,width=\'+((screen.width-100) > 800 ? 800 : (screen.width-100))+\',top=20,height=\'+((screen.width-160) > 800 ? 800 : (screen.width-160))+\',menubar=yes,resizable=yes';
$onclick = ' window.open(this.href,\'win2\',\''.$status.'\'); return false; ';
// Get font icon or image icon for the button
$config = (object) array(
'iconname' => 'mail',
'icondefault' => 'icon-envelope',
'iconimage' => 'emailButton.png',
'icontitle' => 'FLEXI_EMAIL',
);
$show_icons = (int) $params->get('show_icons', 2);
$image = '';
self::createFcBtnIcon($params, $config, $image);
$overlib = JText::_( 'FLEXI_EMAIL_TIP' );
$text = JText::_( 'FLEXI_EMAIL' );
$button_classes = 'fc_mailbutton';
if ($show_icons === 1)
{
$caption = '';
$button_classes .= '';
$tooltip_placement = 'top';
}
else
{
$caption = $text;
if ( !$params->get('btn_grp_dropdown', 0) ) $button_classes .= self::$use_bootstrap ? ' btn btn-small' : ' fc_button fcsimple fcsmall';
$tooltip_placement = !$params->get('btn_grp_dropdown', 0) ? 'top' : 'left';
}
$button_classes .= ' hasTooltip';
$tooltip_title = flexicontent_html::getToolTip($text, $overlib, 0);
// emailed link was set above
$output = ' <a href="'.$mail_to_url.'" class="'.$button_classes.'" data-placement="' . $tooltip_placement . '" title="'.$tooltip_title.'" onclick="'.$onclick.'" rel="nofollow">'.$image.$caption.'</a>';
$output = JText::_('FLEXI_ICON_SEP') . $output . JText::_('FLEXI_ICON_SEP');
return $output;
}
/**
* Creates the pdf button
*
* @param int $id
* @param array $params
* @since 1.0
*/
static function pdfbutton($item, &$params)
{
if ( FLEXI_J16GE || !$params->get('show_pdf_icon') || JFactory::getApplication()->input->getInt('print', 0) ) return;
// Get font icon or image icon for the button
$config = (object) array(
'iconname' => 'pdf',
'icondefault' => 'icon-book',
'iconimage' => 'pdf_button.png',
'icontitle' => 'FLEXI_CREATE_PDF',
);
$show_icons = (int) $params->get('show_icons', 2);
$image = null;
self::createFcBtnIcon($params, $config, $image);
$overlib = JText::_( 'FLEXI_CREATE_PDF_TIP' );
$text = JText::_( 'FLEXI_CREATE_PDF' );
$button_classes = 'fc_pdfbutton';
if ($show_icons === 1)
{
$caption = '';
$button_classes .= '';
$tooltip_placement = 'top';
}
else
{
$caption = $text;
if ( !$params->get('btn_grp_dropdown', 0) ) $button_classes .= self::$use_bootstrap ? ' btn btn-small' : ' fc_button fcsimple fcsmall';
$tooltip_placement = !$params->get('btn_grp_dropdown', 0) ? 'top' : 'left';
}
$button_classes .= ' hasTooltip';
$tooltip_title = flexicontent_html::getToolTip($text, $overlib, 0);
$link = JRoute::_('index.php?view='.FLEXI_ITEMVIEW.'&cid='.$item->categoryslug.'&id='.$item->slug.'&format=pdf');
$output = ' <a href="'.$link.'" class="'.$button_classes.'" data-placement="' . $tooltip_placement . '" title="'.$tooltip_title.'">'.$image.$caption.'</a>';
$output = JText::_('FLEXI_ICON_SEP') . $output . JText::_('FLEXI_ICON_SEP');
return $output;
}
/**
* Creates the state selector button
*
* @param int $id
* @param array $params
* @since 1.0
*/
static function statebutton($record, $params = null, $config = null)
{
$config = $config ?: (object) array(
'controller' => 'items',
'record_name' => 'item',
'state_propname' => 'state',
'addToggler' => true,
'tipPlacement' => null,
'class' => null,
'locked' => false,
);
$user = JFactory::getUser();
$isAdmin = JFactory::getApplication()->isClient('administrator');
$isPrint = JFactory::getApplication()->input->getInt('print', 0);
// Check if state icon should not be shown (note: parameters are usually NULL in backend)
if (!$isAdmin && ($params && !$params->get('show_state_icon', 1) || $isPrint))
{
return;
}
$recordClass = 'FlexicontentModel' . ucfirst($config->record_name);
// Check if already loaded
if (!class_exists($recordClass))
{
// Prefer frontend record model if it exists
!$isAdmin && file_exists(JPATH_SITE.DS.'components'.DS.'com_flexicontent'.DS.'models'.DS.$config->record_name.'.php')
? JLoader::register($recordClass, JPATH_SITE.DS.'components'.DS.'com_flexicontent'.DS.'models'.DS.$config->record_name.'.php')
: JLoader::register($recordClass, JPATH_ADMINISTRATOR.DS.'components'.DS.'com_flexicontent'.DS.'models'.DS.$config->record_name.'.php');
}
try
{
$model = new $recordClass();
}
catch (Exception $e)
{
die('flexicontent_html::' . __FUNCTION__ . '() , unknown type: ' . $record_name);
}
$archive_unsupported = !isset($model->supported_conditions[2]);
$trash_unsupported = !isset($model->supported_conditions[-2]);
$refresh_on_success = in_array($config->record_name, array('category')) ? 'true' : 'false';
static $state_names_added = null;
if (!$state_names_added)
{
$state_names_added = true;
$state_names_js = array();
foreach ($model->supported_conditions as $state_id => $state_name)
{
JText::script($state_name, true);
$state_names_js[] = "'" . $state_id . "' : '" . $state_name . "'";
}
JFactory::getDocument()->addScriptDeclaration('
var _fc_state_titles = { ' . implode(' , ', $state_names_js) . '};
');
}
/**
* Calculate Edit / Edit state if not already calculated, some record types
* do not have atomic assets, for them we will use 'canManage' permission
*/
$canArchives = $config->record_name == 'item' ? FlexicontentHelperPerm::getPerm()->CanArchives : null;
$record->canCheckin = isset($record->canCheckin)
? $record->canCheckin
: empty($record->checked_out) || $record->checked_out == $user->id || $user->authorise('core.admin', 'com_checkin');
$record->canEditState = isset($record->canEditState) ? $record->canEditState : $model->canEditState($record);
$record->canDelete = isset($record->canDelete) ? $record->canDelete : $model->canDelete($record);
// Clear access if record is locked
$has_edit_state = $record->canCheckin && $record->canEditState;
$has_delete = $record->canCheckin && $record->canDelete;
$has_archive = $record->canCheckin && $record->canEditState && ($canArchives || $canArchives === null);
// Clear access if state is not supported
$has_delete = $has_delete && empty($trash_unsupported);
$has_archive = $has_archive && empty($archive_unsupported);
$canChangeState = ($has_edit_state || $has_delete || $has_archive) && !$config->locked;
// Some string and flags
$nullDate = JFactory::getDbo()->getNullDate();
$img_path = JUri::root(true) . '/components/com_flexicontent/assets/images/';
$use_font_icons = $isAdmin || ($params && $params->get('use_font_icons', 1));
/**
* Display state toggler if it can do any of state change
*/
static $js_and_css_added = false;
if (!$js_and_css_added && $canChangeState && $config->addToggler)
{
// File exists both in frontend & backend (and is different), so we will use 'base' method and not 'root'
JText::script('FLEXI_ACTION', true);
if ($config->record_name == 'item')
{
JText::script('FLEXI_SET_STATE_AS_IN_PROGRESS', true);
JText::script('FLEXI_SET_STATE_AS_PENDING', true);
JText::script('FLEXI_SET_STATE_AS_TO_WRITE', true);
}
JText::script('FLEXI_SET_STATE_TO', true);
JText::script('FLEXI_PUBLISH_THIS_ITEM', true);
JText::script('FLEXI_UNPUBLISH_THIS_ITEM', true);
JText::script('FLEXI_ARCHIVE_THIS_ITEM', true);
JText::script('FLEXI_TRASH_THIS_ITEM', true);
flexicontent_html::loadFramework('flexi_tmpl_common');
$doc = JFactory::getDocument();
$doc->addScript(JUri::root(true).'/components/com_flexicontent/assets/js/stateselector.js', array('version' => FLEXI_VHASH));
$js = '
var fc_statehandler_singleton = new fc_statehandler({
task: ' . json_encode($isAdmin ? $config->controller . '.setitemstate' : 'setitemstate') . ',
img_path: ' . json_encode($img_path) . ',
font_icons: ' . ($use_font_icons ? 'true' : 'false') . ',
refresh_on_success: ' . $refresh_on_success . '
});
';
$doc->addScriptDeclaration($js);
$js_and_css_added = true;
}
static $state_names = null;
static $state_descrs = null;
static $state_imgs = null;
static $font_icons = null;
static $tooltip_class = null;
static $state_tips = null;
static $button_classes = null;
static $jtext = array();
static $icon_params = null;
if (!$state_names)
{
$state_names = array(
1 => JText::_('FLEXI_PUBLISHED'),
-5 => JText::_('FLEXI_IN_PROGRESS'),
0 => JText::_('FLEXI_UNPUBLISHED'),
-3 => JText::_('FLEXI_PENDING'),
-4 => JText::_('FLEXI_TO_WRITE'),
2 => JText::_('FLEXI_ARCHIVED'),
-2 => JText::_('FLEXI_TRASHED'),
'u' => JText::_('FLEXI_UNKNOWN'),
);
$state_descrs = array(
1 => JText::_('FLEXI_PUBLISH_THIS_ITEM'),
-5 => JText::_('FLEXI_SET_STATE_AS_IN_PROGRESS'),
0 => JText::_('FLEXI_UNPUBLISH_THIS_ITEM'),
-3 => JText::_('FLEXI_SET_STATE_AS_PENDING'),
-4 => JText::_('FLEXI_SET_STATE_AS_TO_WRITE'),
2 => JText::_('FLEXI_ARCHIVE_THIS_ITEM'),
-2 => JText::_('FLEXI_TRASH_THIS_ITEM'),
'u' => JText::_('FLEXI_UNKNOWN'),
);
$state_imgs = array(
1 => 'accept.png',
-5 => 'publish_g.png',
0 => 'publish_x.png',
-3 => 'publish_r.png',
-4 => 'publish_y.png',
2 => 'archive.png',
-2 => 'trash.png',
'u' => 'unknown.png',
);
$font_icons = array(
1 => 'publish',
-5 => 'checkmark-2',
0 => 'unpublish',
-3 => 'question',
-4 => 'pencil-2',
2 => 'archive',
-2 => 'trash',
'u' => 'question-2',
);
$tooltip_class = ' hasTooltip';
$state_tips = array();
$title_header = '';//JText::_( 'FLEXI_ACTION' );
foreach ($state_names as $state_id => $i)
{
$state_tips[$state_id] = flexicontent_html::getToolTip($title_header, $state_descrs[$state_id], 0, 1);
}
$button_classes = 'fc_statebutton';
if ($config->class)
{
$button_classes .= ' ' . $config->class;
}
elseif (!$params || !$params->get('btn_grp_dropdown', 0))
{
$button_classes .= self::$use_bootstrap ? ' btn btn-small' : ' fc_button fcsimple fcsmall';
}
else
{
$button_classes .= ' btn';
}
$jtext['icon_sep'] = JText::_('FLEXI_ICON_SEP');
$jtext['start_immediately']= JText::_('FLEXI_START_IMMEDIATELY');
$jtext['start'] = JText::_('FLEXI_START');
$jtext['finish_no_expiry'] = JText::_('FLEXI_FINISH_NO_EXPIRY');
$jtext['finish'] = JText::_('FLEXI_FINISH');
$jtext['change_state'] = JText::_('FLEXI_CLICK_TO_CHANGE_STATE');
$jtext['action'] = JText::_('FLEXI_ACTION');
$icon_params = new JRegistry();
$icon_params->set('stateicon_popup', 'none');
$icon_params->set('use_font_icons', $use_font_icons);
}
// Create state icon
$state = $record->{$config->state_propname};
if (!isset($state_names[$state]))
{
$state = 'u';
}
$state_text = !empty($model->supported_conditions[$state])
? JText::_($model->supported_conditions[$state])
: null;
$stateicon = flexicontent_html::stateicon($state, $icon_params, 'html', $state_text, $record, $show_status = 2);
$tz_string = JFactory::getApplication()->getCfg('offset');
$tz = new DateTimeZone( $tz_string );
$tz_offset = $tz->getOffset(new JDate()) / 3600;
// Create publish information
$publish_info = array();
if (isset($record->publish_up))
{
if ($record->publish_up)
{
$publish_up = JFactory::getDate($record->publish_up);
$publish_up->setTimezone($tz);
}
$publish_info[] = !$record->publish_up || $record->publish_up == $nullDate
? $jtext['start_immediately']
: $jtext['start'] .": ". JHtml::_('date', $publish_up->toSql(), 'Y-m-d H:i:s');
}
if (isset($record->publish_down))
{
if ($record->publish_down)
{
$publish_down = JFactory::getDate($record->publish_down);
$publish_down->setTimezone($tz);
}
$publish_info[] = !$record->publish_down || $record->publish_down == $nullDate
? $jtext['finish_no_expiry']
: $jtext['finish'] .": ". JHtml::_('date', $publish_down->toSql(), 'Y-m-d H:i:s');
}
// Create the state selector button and return it
if ($canChangeState && $config->addToggler)
{
// Only add user's permitted states on the current item
if ($has_edit_state)
{
$state_ids = $config->record_name === 'item'
? array(1, -5, 0, -3, -4)
: array(1, 0);
}
if ($has_archive)
{
$state_ids[] = 2;
}
if ($has_delete)
{
$state_ids[] = -2;
}
if ($config->tipPlacement)
{
$tooltip_placement = $config->tipPlacement !== 'top' ? $config->tipPlacement : '';
}
elseif (!$params || !$params->get('show_icons', 2))
{
$tooltip_placement = 'top';
}
else
{
$tooltip_placement = !$params->get('btn_grp_dropdown', 0) ? 'top' : 'left';
}
$state_js_ids = array();
$state_js_titles = array();
foreach ($state_ids as $i => $state_id)
{
$state_js_ids[] = array('i' => $state_id);
if (!empty($model->supported_conditions[$state_id]))
{
//$state_js_titles[$state_id] = JText::_($model->supported_conditions[$state_id]);
}
}
$state_js_ids_list = count($state_js_ids) ? ' data-st="' . htmlspecialchars(json_encode($state_js_ids), ENT_COMPAT, 'UTF-8') . '" ' : '';
$state_js_titles_list = count($state_js_titles) ? ' data-tt="' . htmlspecialchars(json_encode($state_js_titles), ENT_COMPAT, 'UTF-8') . '" ' : '';
$tooltip_title = flexicontent_html::getToolTip(
$state_text ?: JText::_('FLEXI_PUBLISH_INFORMATION'),
' ' . implode("\n<br/> \n", $publish_info) . '<br/>' . $jtext['change_state'],
0, 1
);
$output = '
<div class="statetoggler ' . $button_classes . ' ' . $tooltip_class . '" ' . ($tooltip_placement ? ' data-placement="' . $tooltip_placement . '"' : '') . ' title="' . $tooltip_title . '" onclick="fc_statehandler_singleton.toggleSelector(this)">
<div class="statetoggler_inner">
<div id="row' . $record->id . '" class="stateopener ntxt">
' . $stateicon . '
</div>
<div class="options" data-id="' . $record->id . '" ' . $state_js_ids_list . ' ' . $state_js_titles_list . '></div>
</div>
</div>';
}
// Backend, possibly with state selector disabled
elseif ($isAdmin)
{
if ($canChangeState)
{
$publish_info[] = '<br/>' . JText::_('FLEXI_STATE_CHANGER_DISABLED');
}
$tooltip_title = flexicontent_html::getToolTip(JText::_( 'FLEXI_PUBLISH_INFORMATION' ), implode("\n<br/>\n", $publish_info), 0);
$output = '
<div id="row' . $record->id . '" class="statetoggler_disabled ' . $config->class . '">
<span class="disabled ' . $tooltip_class . '" title="' . $tooltip_title . '">
' . $stateicon . '
</span>
</div>';
$output = $jtext['icon_sep'] .$output. $jtext['icon_sep'];
}
// Frontend with no permissions to edit / delete / archive
else
{
$output = '';
}
return $output;
}
/**
* Creates the approval button
*
* @param int $id
* @param array $params
* @since 1.0
*/
static function approvalbutton($item, &$params)
{
if ( JFactory::getApplication()->input->getInt('print', 0) ) return;
static $user = null, $requestApproval = null;
if ($user === null) {
$user = JFactory::getUser();
$requestApproval = $user->authorise('flexicontent.requestapproval', 'com_flexicontent');
}
// Skip items not in draft state
if ( $item->state != -4 ) return;
// Skip not-owned items, unless having privilege to send approval request for any item
if ( !$requestApproval && $item->created_by != $user->get('id') ) return;
// Determine if current user can edit state of the given item
$asset = 'com_content.article.' . $item->id;
$has_edit_state = $user->authorise('core.edit.state', $asset) || ($item->created_by == $user->get('id') && $user->authorise('core.edit.state.own', $asset));
// Create the approval button only if user cannot edit the item (**note check at top of this method)
if ($has_edit_state)
{
return;
}
// Get font icon or image icon for the button
$config = (object) array(
'iconname' => 'approval',
'icondefault' => 'icon-key',
'iconimage' => 'key_add.png',
'iconpath' => 'components/com_flexicontent/assets/images', // Use icon from flexicontent assets folder
'icontitle' => 'FLEXI_APPROVAL_REQUEST',
);
$show_icons = (int) $params->get('show_icons', 2);
$image = null;
self::createFcBtnIcon($params, $config, $image);
$overlib = JText::_( 'FLEXI_APPROVAL_REQUEST_INFO' );
$text = JText::_( 'FLEXI_APPROVAL_REQUEST' );
$button_classes = 'fc_approvalbutton';
if ($show_icons === 1)
{
$caption = '';
$button_classes .= '';
$tooltip_placement = 'top';
}
else
{
$caption = $text;
if ( !$params->get('btn_grp_dropdown', 0) ) $button_classes .= self::$use_bootstrap ? ' btn btn-small' : ' fc_button fcsimple fcsmall';
$tooltip_placement = !$params->get('btn_grp_dropdown', 0) ? 'top' : 'left';
}
$button_classes .= ' hasTooltip';
$tooltip_title = flexicontent_html::getToolTip($text, $overlib, 0);
$Itemid = 0;
$item_url = JRoute::_(FlexicontentHelperRoute::getItemRoute($item->slug, $item->categoryslug, $Itemid, $item));
$link = $item_url . (strpos($item_url, '?') !== false ? '&' : '?') . 'task=approval' . '&' . JSession::getFormToken() . '=1';
$targetLink = "_self";
$confirm_text = JText::_('FLEXI_CONFIRM_SEND_APPROVAL', true) . "\n" . ' (' . $overlib . ')';
$output = ' <a href="'.$link.'" class="'.$button_classes.'" data-placement="' . $tooltip_placement . '" onclick="return confirm(\''.$confirm_text.'\')" target="'.$targetLink.'" title="'.$tooltip_title.'">'.$image.$caption.'</a>';
$output = JText::_('FLEXI_ICON_SEP') . $output . JText::_('FLEXI_ICON_SEP');
return $output;
}
/**
* Creates the edit button
*
* @param int $id
* @param array $params
* @since 1.0
*/
static function editbutton($item, &$params)
{
if ( !$params->get('show_editbutton', 1) || JFactory::getApplication()->input->getInt('print', 0) ) return;
$app = JFactory::getApplication();
$user = JFactory::getUser();
$tmpl = $app->input->getCmd('tmpl');
// Determine if current user can edit the given item
$asset = 'com_content.article.' . $item->id;
$has_edit_state = $user->authorise('core.edit', $asset) || ($item->created_by == $user->get('id') && $user->authorise('core.edit.own', $asset));
// Create the edit button only if user can edit the give item
if (!$has_edit_state)
{
return;
}
// Get font icon or image icon for the button
$config = (object) array(
'iconname' => 'edit',
'icondefault' => 'icon-pencil',
'iconimage' => 'edit.png',
'icontitle' => 'FLEXI_EDIT',
);
$show_icons = (int) $params->get('show_icons', 2);
$image = null;
self::createFcBtnIcon($params, $config, $image);
$overlib = JText::_( 'FLEXI_EDIT_TIP' );
$text = JText::_( 'FLEXI_EDIT' );
$button_classes = 'fc_editbutton';
if ($show_icons === 1)
{
$caption = '';
$button_classes .= '';
$tooltip_placement = 'top';
}
else
{
$caption = $text;
if ( !$params->get('btn_grp_dropdown', 0) ) $button_classes .= self::$use_bootstrap ? ' btn btn-small' : ' fc_button fcsimple fcsmall';
$tooltip_placement = !$params->get('btn_grp_dropdown', 0) ? 'top' : 'left';
}
$button_classes .= ' hasTooltip';
$tooltip_title = flexicontent_html::getToolTip($text, $overlib, 0);
if ((int) $params->get('show_editbutton', 1) === 1)
{
//$Itemid = JFactory::getApplication()->input->get('Itemid', 0, 'int'); // Maintain menu item ? e.g. current category view,
$Itemid = 0;
$item_url = JRoute::_(FlexicontentHelperRoute::getItemRoute($item->slug, $item->categoryslug, $Itemid, $item));
$link = $item_url . (strpos($item_url, '?') !== false ? '&' : '?') . 'task=edit' . ($tmpl ? '&tmpl=' . $tmpl : '');
$targetLink = "_self";
}
elseif ((int) $params->get('show_editbutton', 1) === 2)
{
$link = JUri::base(true).'/administrator/index.php?option=com_flexicontent&task=items.edit&cid[]='.$item->id;
$targetLink = "_blank";
}
$output = ' <a href="'.$link.'" class="'.$button_classes.'" data-placement="' . $tooltip_placement . '" target="'.$targetLink.'" title="'.$tooltip_title.'">'.$image.$caption.'</a>';
$output = JText::_('FLEXI_ICON_SEP') . $output . JText::_('FLEXI_ICON_SEP');
return $output;
}
/**
* Creates the add button
*
* @param array $params
* @since 1.0
*/
static function addbutton(&$params, &$submit_cat = null, $menu_itemid = 0, $btn_text = '', $auto_relations = false, $ignore_unauthorized = null)
{
if ( !$params->get('show_addbutton', 1) || JFactory::getApplication()->input->getInt('print', 0) ) return;
$app = JFactory::getApplication();
$user = JFactory::getUser();
// If not given get from component parameters
if ($ignore_unauthorized === null && !empty($submit_cat->parameters) && is_object($submit_cat->parameters))
{
$ignore_unauthorized = $submit_cat->parameters->get('nonauth_addbutton', 0);
}
// Convert to true / false
$ignore_unauthorized = !$user->id
? (int) $ignore_unauthorized === 2
: (int) $ignore_unauthorized > 0;
/**
* The 'Add' button will appear to logged users only ... unless
* we have a PERFORMANCE-SAFE option for showing it
* - either unauthorized guest users are allowed (= aka no need to calculate 'CREATE' ACL)
* - or a specific category ID was given (= aka we need to calculate 'CREATE' ACL for given category only)
*/
if (!$user->id)
{
$submit_catid_given = $submit_cat && $submit_cat->id;
if (!$ignore_unauthorized && !$submit_catid_given)
{
return '';
}
}
// IF not auto-relation given ... then check if current view / layout can use ADD button
if (!$auto_relations)
{
$view = $app->input->get('view', '', 'CMD');
$layout = $app->input->get('layout', '', 'CMD');
if ($view !== 'category' || $layout === 'author' || $layout === 'favs')
{
return '';
}
}
/**
* Check if user can ADD to (a) Given category or to (b) at Any category
*/
// (a) Given category
if ($submit_cat && $submit_cat->id)
{
$canAdd = $user->authorise('core.create', 'com_content.category.' . $submit_cat->id);
}
// (b) Any category (or to the CATEGORY IDS of given CATEGORY VIEW OBJECT)
else
{
// Given CATEGORY VIEW OBJECT may limit to specific category ids
$canAdd = $user->authorise('core.create', 'com_flexicontent');
if ($canAdd === NULL && $user->id)
{
/**
* Performance concern (NULL for $canAdd) means SOFT DENY, also check for logged user
* thus to avoid checking some/ALL categories for "create" privelege for unlogged users
*/
$specific_catids = $submit_cat ? @ $submit_cat->ids : false;
if ($specific_catids && count($specific_catids) > 3) $specific_catids = false;
$allowedcats = FlexicontentHelperPerm::getAllowedCats( $user, $actions_allowed=array('core.create'), $require_all=true, $check_published = true, $specific_catids, $find_first = true );
$canAdd = count($allowedcats);
}
}
if (!$canAdd && !$ignore_unauthorized)
{
return '';
}
/**
* Create submit button/icon text
*/
if (is_object($btn_text))
{
$btn_title = JText::_( $btn_text->title );
$btn_desc = JText::_( $btn_text->tooltip );
}
else
{
$btn_title = JText::_( 'FLEXI_ADD' );
$btn_desc = $btn_text ?
JText::_($btn_text) :
JText::_( $submit_cat && $submit_cat->id ? 'FLEXI_ADD_NEW_CONTENT_TO_CURR_CAT' : 'FLEXI_ADD_NEW_CONTENT_TO_LIST' ) ;
}
/**
* Create link
*/
// Add Itemid (if given) and do SEF URL routing it --before-- appending more variables, so that
// ... menu item URL variables from given menu item ID will be appended if SEF URLs are OFF
$menu_itemid = $menu_itemid ? $menu_itemid : (int)$params->get('addbutton_menu_itemid', 0);
$menu_typeid = 0;
if ($menu_itemid)
{
$menu = $app->getMenu()->getItem($menu_itemid);
$menu_typeid = isset($menu->query['typeid']) ? (int) $menu->query['typeid'] : 0;
}
if ($menu_typeid)
{
$link = 'index.php?option=com_flexicontent' . ($menu_itemid
? '&Itemid='.$menu_itemid
: '&view='.FLEXI_ITEMVIEW.'&task=items.add'
);
$link = JRoute::_( $link);
}
else
{
$link = 'index.php?option=com_flexicontent' . ($menu_itemid ? '&menu_id='.$menu_itemid : '')
. '&view=types&tmpl=component&layout=typeslist&action=new';
$link = JUri::base() . $link;
}
// Add main category ID (if given)
if ($submit_cat && $submit_cat->id)
{
$link .= (strstr($link, '?') ? '&' : '?') . 'maincat='.$submit_cat->id;
}
// Append autorelate information to the URL (if given)
if ($auto_relations)
{
foreach ($auto_relations as $auto_relation)
{
$link .= (strstr($link, '?') ? '&' : '?') . 'autorelation_'.$auto_relation->fieldid.'='.$auto_relation->itemid;
}
}
/**
* Finally create the submit icon / button
*/
// Get font icon or image icon for the button
$config = (object) array(
'iconname' => 'new',
'icondefault' => 'icon-new',
'iconimage' => 'plus-button.png',
'iconpath' => 'components/com_flexicontent/assets/images', // Use icon from flexicontent assets folder
'icontitle' => $btn_desc,
);
$show_icons = (int) $params->get('show_icons', 2);
$image = '';
self::createFcBtnIcon($params, $config, $image);
/*if (!$auto_relations)
{
$image = '';
}*/
$button_classes = 'fc_addbutton';
if ($show_icons === 1 && !$auto_relations)
{
$caption = '';
$button_classes .= '';
$tooltip_placement = 'top';
}
else
{
$caption = $btn_title;
if ( !$params->get('btn_grp_dropdown', 0) ) $button_classes .=
(self::$use_bootstrap ? ' btn btn-small' : ' fc_button fcsimple fcsmall')
.($auto_relations ? ' btn-success' : '');
$tooltip_placement = !$params->get('btn_grp_dropdown', 0) ? 'top' : 'left';
}
$button_classes .= ' hasTooltip';
$tooltip_title = flexicontent_html::getToolTip($btn_title, $btn_desc, 0);
$output = ' <a href="' . $link . '" class="' . $button_classes . '" data-placement="' . $tooltip_placement . '" title="' . $tooltip_title . '"
' . (!$menu_typeid
? 'onclick="var url = jQuery(this).attr(\'href\'); fc_showDialog(url, \'fc_modal_popup_container\', 0, 1200, 0, false, {\'title\': \''.flexicontent_html::encodeHTML(JText::_('FLEXI_TYPE'), 2).'\'}); return false;" '
: '') . '
>' . $image.$caption . '</a>';
if (!$auto_relations)
{
$output = JText::_('FLEXI_ICON_SEP') . $output . JText::_('FLEXI_ICON_SEP');
}
return $output;
}
/**
* Creates the stateicon
*
* @param int $state
* @param array $params
* @since 1.0
*/
static function stateicon($state, $params, $type = 'html', &$state_text = null, $item = null, $show_status = 0)
{
static $jtext_state = null;
static $tooltip_class = ' hasTooltip';
static $state_names = null;
static $state_imgs = null;
static $state_basictips = null;
static $state_fulltips = null;
static $state_icons = array();
static $font_icons = null;
if ($state_names === null)
{
$jtext_state = JText::_( 'FLEXI_STATE' );
$state_names = array(
1 => JText::_('FLEXI_PUBLISHED'),
-5 => JText::_('FLEXI_IN_PROGRESS'),
0 => JText::_('FLEXI_UNPUBLISHED'),
-3 => JText::_('FLEXI_PENDING'),
-4 => JText::_('FLEXI_TO_WRITE'),
2 => JText::_('FLEXI_ARCHIVED'),
-2 => JText::_('FLEXI_TRASHED'),
'u' => JText::_('FLEXI_UNKNOWN'),
'e' => JText::_('FLEXI_PUBLICATION_EXPIRED'),
's' => JText::_('FLEXI_SCHEDULED_FOR_PUBLICATION'),
);
$state_imgs = array(
1 => 'accept.png',
-5 => 'publish_g.png',
0 => 'publish_x.png',
-3 => 'publish_r.png',
-4 => 'publish_y.png',
2 => 'archive.png',
-2 => 'trash.png',
'u' => 'unknown.png',
'e' => 'clock.png',
's' => 'warning.png',
);
$font_icons = array(
1 => 'publish',
-5 => 'checkmark-2',
0 => 'unpublish',
-3 => 'question',
-4 => 'pencil-2',
2 => 'archive',
-2 => 'trash',
'u' => 'question-2',
'e' => 'expired',
's' => 'pending',
);
foreach($state_names as $state_id => $state_name)
{
$content = str_replace('::', '-', $state_name);
$state_fulltips[$state_id] = flexicontent_html::getToolTip($jtext_state, $content, 0);
}
foreach($state_names as $state_id => $state_name)
{
$content = str_replace('::', '-', $state_name);
$state_basictips[$state_id] = $jtext_state.' : '.$content;
}
}
// Check for invalid state
if (!isset($state_names[$state]))
{
$state = 'u';
}
// Check for expired that is published / in progress / archived
if ($item && $show_status && !empty($item->publication_expired) && in_array($state, array(1, -5, 2)))
{
$show_status === 1
? $state = 'e'
: $is_expired = true;
}
// Check for scheduled that is published / in progress / archived
elseif ($item && $show_status && !empty($item->publication_scheduled) && in_array($state, array(1, -5, 2)))
{
$show_status === 1
? $state = 's'
: $is_scheduled = true;
}
$scheduled_expired_html = !empty($is_expired)
? '<span class="fc_expired"></span>'
: (!empty($is_scheduled) ? '<span class="fc_scheduled"></span>' : '');
$show_icons = (int) $params->get('show_icons', 1);
$state_text = $state_text ?: $state_names[$state];
// Return state name if not showing icons
if (!$show_icons)
{
return $state_names[$state];
}
// Return cached icon if already calculated
$popup_type = $type === 'json'
? 'basic'
: $params->get('stateicon_popup', 'full');
if (isset($state_icons[$state][$popup_type]))
{
return $scheduled_expired_html . $state_icons[$state][$popup_type];
}
// If using font icons
$use_font = $params->get('use_font_icons', 1);
$icon_class = $use_font ? 'icon-'.$font_icons[$state] : '';
// Create output
$data = array();
switch ( $popup_type )
{
case 'none':
$data['class'] = $icon_class;
break;
case 'basic':
case 'full': default:
$data['class'] = $icon_class . ' ' . ($popup_type != 'basic' ? $tooltip_class : '');
$data['title'] = $state_basictips[$state];
break;
}
// Special case return uncached JSON encoded data
if ($type === 'json')
{
$data['html'] = ($use_font
? '<span class="' . $data['class'] . '"></span>'
: JHtml::image('components/com_flexicontent/assets/images/'.$state_imgs[$state], $state_text, '')
) . ($show_icons === 2
? '<span class="fc-mssg-inline fc-info fc-iblock fc-nobgimage">' . $state_text . '</span>'
: ''
);
unset($data['class']);
return json_encode($data);
}
// Create state icon image, cache it and return it
$tag_attribs = '';
foreach($data as $key => $val)
{
$tag_attribs .= ' ' . $key . '="' . $val . '" ';
}
$state_icons[$state][$popup_type] = ($use_font
? '<span ' . $tag_attribs . '></span>'
: JHtml::image('components/com_flexicontent/assets/images/'.$state_imgs[$state], $state_text, $tag_attribs)
) . ($show_icons === 2
? '<span class="fc-mssg-inline fc-info fc-iblock fc-nobgimage">' . $state_text . '</span>'
: ''
);
return $scheduled_expired_html . $state_icons[$state][$popup_type];
}
/**
* Creates the ratingbar
*
* @deprecated
* @param array $item
* @since 1.0
*/
static function ratingbar($item)
{
if ((int) $item->votes <= 0)
{
return '<span class="badge">'.JText::_( 'FLEXI_NOT_YET_RATED' ).'</span>';
}
// Round to integer percentage in case it was not done already in the SQL query
$rating = round($item->votes);
$tooltip_class = ' hasTooltip';
$tooltip_title = flexicontent_html::getToolTip(JText::_('FLEXI_RATING'), JText::_( 'FLEXI_SCORE' ).': '.$rating.'%', 0, 1);
$output = '<span class="qf_ratingbarcontainer'.$tooltip_class.'" title="'.$tooltip_title.'">';
$output .= '<span class="qf_ratingbar" style="width:'.$rating.'%;"> </span></span>';
return $output;
}
/**
* Creates the voteicons
* Deprecated to ajax votes
*
* @param array $params
* @since 1.0
*/
static function voteicons($item, &$params)
{
static $voteup, $votedown, $tooltip_class, $tip_vote_up, $tip_vote_down;
if (!$tooltip_class)
{
$tooltip_class = ' hasTooltip';
$show_icons = (int) $params->get('show_icons');
if ($show_icons)
{
$voteup = JHtml::image('components/com_flexicontent/assets/images/'.'thumb_up.png', JText::_( 'FLEXI_GOOD' ), NULL);
$votedown = JHtml::image('components/com_flexicontent/assets/images/'.'thumb_down.png', JText::_( 'FLEXI_BAD' ), NULL);
}
else
{
$voteup = JText::_( 'FLEXI_GOOD' ). ' ';
$votedown = ' '.JText::_( 'FLEXI_BAD' );
}
$tip_vote_up = flexicontent_html::getToolTip('FLEXI_VOTE_UP', 'FLEXI_VOTE_UP_TIP', 1, 1);
$tip_vote_down = flexicontent_html::getToolTip('FLEXI_VOTE_DOWN', 'FLEXI_VOTE_DOWN_TIP', 1, 1);
}
$item_url = JRoute::_('index.php?task=vote&vote=1&cid='.$item->categoryslug.'&id='.$item->slug.'&layout='.$params->get('ilayout'));
$link = $item_url . (strpos($item_url, '?') !== false ? '&' : '?');
$output = '<a href="'.$link.'vote=1" class="fc_vote_up'.$tooltip_class.'" title="'.$tip_vote_up.'">'.$voteup.'</a>';
$output .= ' - ';
$output .= '<a href="'.$link.'vote=1" class="fc_vote_down'.$tooltip_class.'" title="'.$tip_vote_down.'">'.$votedown.'</a>';
return $output;
}
/**
* Creates the ajax voting stars system
*
* @param array $field
* @param int or string $xid
* @since 1.0
*/
static function ItemVote(&$field, $xid, $vote)
{
// Check for invalid xid
if ($xid !== 'main' && $xid !== 'extra' && $xid !== 'all' && !(int) $xid)
{
return 'ItemVote(): invalid xid \'' . $xid . '\' was given';
}
if (!$vote)
{
$vote = new stdClass();
$vote->rating_sum = $vote->rating_count = 0;
}
elseif (!isset($vote->rating_sum) || !isset($vote->rating_sum))
{
$vote->rating_sum = $vote->rating_count = 0;
}
$html = '';
$int_xid = (int) $xid;
$item_id = $field->item_id;
// Get extra voting option (composite voting)
$xids = array();
$enable_extra_votes = (int) $field->parameters->get('enable_extra_votes', 0);
if ($enable_extra_votes && ($xid === 'all' || $xid === 'extra' || $int_xid))
{
// Retrieve and split-up extra vote types, (removing last one if empty)
$extra_votes = $field->parameters->get('extra_votes', '');
$extra_votes = preg_split("/[\s]*%%[\s]*/", $extra_votes);
if (empty($extra_votes[count($extra_votes)-1]))
{
unset($extra_votes[count($extra_votes)-1]);
}
// Split extra voting ids (xid) and their titles
foreach ($extra_votes as $extra_vote)
{
@list($extra_id, $extra_title, $extra_desc) = explode("##", $extra_vote);
$xids[$extra_id] = new stdClass();
$xids[$extra_id]->id = (int) $extra_id;
$xids[$extra_id]->title = JText::_($extra_title);
$xids[$extra_id]->desc = JText::_($extra_desc);
}
}
// Get user current history so that it is reflected on the voting
$vote_history = JFactory::getSession()->get('vote_history', array(),'flexicontent');
if (!isset($vote_history[$item_id]) || !is_array($vote_history[$item_id]))
{
$vote_history[$item_id] = array();
}
// Add main voting option
if ($xid === 'main' || $xid === 'all')
{
$vote_label = JText::_($field->parameters->get('main_label', 'FLEXI_VOTE_AVERAGE_RATING'));
$counter_show_label = $field->parameters->get('main_counter_show_label', 1);
$add_review_form = (int) $field->parameters->get('allow_reviews', 0);
$html .= flexicontent_html::ItemVoteDisplay(
$field,
$item_id,
$vote->rating_sum,
$vote->rating_count,
'main',
$vote_label,
$stars_override = 0,
($allow_vote = isset($vote->allow_vote) ? $vote->allow_vote : true),
$vote_counter = 'default',
$counter_show_label,
$add_review_form,
$xids,
$review_type='item'
);
}
// Add extra voting option
if ($xid === 'all' || $xid === 'extra' || ($int_xid && isset($xids[$xid])))
{
/**
* If integer then add specific voting option for the given XID,
* if string (either 'all' or 'extra') then add all extra voting options
*/
$_xids = $int_xid
? array($int_xid => $xids[$int_xid])
: $xids;
$counter_show_label = $field->parameters->get('extra_counter_show_label', 1);
foreach ($_xids as $extra_id => $xid_obj)
{
if (!isset($vote->extra[$extra_id]))
{
$extra_vote = new stdClass();
$extra_vote->rating_sum = $extra_vote->rating_count = 0;
$extra_vote->extra_id = $extra_id;
}
else
{
$extra_vote = $vote->extra[$extra_id];
}
// Display incomplete vote
if ((int) $extra_id && !isset($vote_history[$item_id]['main']) && isset($vote_history[$item_id][$extra_id]))
{
$rating_sum = $vote_history[$item_id][$extra_id];
$rating_count = 1;
}
else
{
$rating_sum = 0;
$rating_count = 0;
}
$html .= flexicontent_html::ItemVoteDisplay(
$field,
$item_id,
($extra_vote->rating_sum + $rating_sum),
($extra_vote->rating_count + $rating_count),
$extra_vote->extra_id,
$xid_obj,
$stars_override = 0,
($allow_vote = isset($vote->allow_vote) ? $vote->allow_vote : true),
$vote_counter = 'default',
$counter_show_label
);
}
}
return '
<div class="' . $field->name . '-group">
' . $html . '
</div>';
}
/**
* Method that creates the stars
*
* @param array $field
* @param int $id
* @param int $rating_sum
* @param int $rating_count
* @param int or string $xid
* @since 1.0
*/
static function ItemVoteDisplay($field, $id, $rating_sum, $rating_count, $xid, $xiddata='', $stars_override=0, $allow_vote=true, $vote_counter='default', $counter_show_label=true, $add_review_form=0, $xids=array(), $review_type='item')
{
static $acclvl_names = null;
static $star_tooltips = null;
static $star_classes = null;
$user = JFactory::getUser();
$db = JFactory::getDbo();
$cparams = JComponentHelper::getParams('com_flexicontent');
$app = JFactory::getApplication();
$view = $app->input->get('flexi_callview', '', 'cmd');
// Only label given
if (!is_object($xiddata))
{
$label = $xiddata;
$desc = '';
}
// Label & description
else
{
$label = $xiddata->title;
$desc = $xiddata->desc;
}
$int_xid = (int) $xid;
/**
* Find if user has the ACCESS level required for voting
*/
// Note will need to remove static calculation, if this gets implemented per type
static $has_acclvl, $acclvl;
if ($has_acclvl === null)
{
$aid_arr = JAccess::getAuthorisedViewLevels($user->id);
$acclvl = (int) $field->parameters->get('submit_acclvl', 1);
$has_acclvl = in_array($acclvl, $aid_arr);
}
/**
* Calculate NO access actions, (case that user cannot vote)
*/
if (!$has_acclvl)
{
if ($user->id)
{
$no_acc_msg = $field->parameters->get('logged_no_acc_msg', '');
$no_acc_url = $field->parameters->get('logged_no_acc_url', '');
$no_acc_doredirect = (int) $field->parameters->get('logged_no_acc_doredirect', 0);
$no_acc_askredirect = (int) $field->parameters->get('logged_no_acc_askredirect', 1);
}
else
{
$no_acc_msg = $field->parameters->get('guest_no_acc_msg', '');
$no_acc_url = $field->parameters->get('guest_no_acc_url', '');
$no_acc_doredirect = (int) $field->parameters->get('guest_no_acc_doredirect', 2);
$no_acc_askredirect = (int) $field->parameters->get('guest_no_acc_askredirect', 1);
}
// Decide no access Redirect URLs
if ($no_acc_doredirect === 2)
{
$com_users = 'com_users';
$no_acc_url = $cparams->get('login_page', 'index.php?option='.$com_users.'&view=login');
}
elseif ($no_acc_doredirect === 0)
{
$no_acc_url = '';
}
// else unchanged
// Decide no access Redirect Message
$no_acc_msg = $no_acc_msg ? JText::_($no_acc_msg, true) : null;
// Find name of required Access Level
if (!$no_acc_msg)
{
$acclvl_name = '';
// Retrieve this ONCE (static var)
if ($acclvl && empty($acclvl_names))
{
$acclvl_names = flexicontent_db::getAccessNames();
}
$acclvl_name = !empty($acclvl_names[$acclvl])
? $acclvl_names[$acclvl]
: 'Access Level: ' . $acclvl . ' not found / was deleted';
$no_acc_msg = JText::sprintf('FLEXI_VOTE_NO_ACCESS_TO_VOTE', $acclvl_name);
}
$no_acc_msg_redirect = JText::_($no_acc_doredirect === 2
? 'FLEXI_VOTE_CONFIM_REDIRECT_TO_LOGIN_REGISTER'
: 'FLEXI_VOTE_CONFIM_REDIRECT'
);
}
if ($vote_counter !== 'default' && $vote_counter !== '')
{
$counter = $vote_counter ? 1 : 0;
}
else
{
$counter = (int) $field->parameters->get($int_xid ? 'extra_counter' : 'main_counter', 1);
}
$class = $field->name . '-row';
// Display info e.g. counter if unrated, TODO add parameter
$show_unrated = (int) $field->parameters->get('show_unrated', 0);
$show_percentage = (int) $field->parameters->get($int_xid ? 'extra_counter_show_percentage' : 'main_counter_show_percentage', 0);
// Get number of displayed stars, configuration
$rating_resolution = (int)$field->parameters->get('rating_resolution', 5);
$rating_resolution = $rating_resolution >= 5 ? $rating_resolution : 5;
$rating_resolution = $rating_resolution <= 100 ? $rating_resolution : 100;
// Get number of displayed stars, configuration
$rating_stars = (int) ($stars_override ? $stars_override : $field->parameters->get('rating_stars', 5));
$rating_stars = $rating_stars > $rating_resolution ? $rating_resolution : $rating_stars; // Limit stars to resolution
static $js_and_css_added = false;
if (!$js_and_css_added)
{
$cparams = JComponentHelper::getParams( 'com_flexicontent' );
// Load tooltips JS
if ($cparams->get('add_tooltips', 1)) JHtml::_('bootstrap.tooltip');
flexicontent_html::loadFramework('jQuery');
flexicontent_html::loadFramework('flexi_tmpl_common');
$document = JFactory::getDocument();
$document->addStyleSheet(JUri::root(true).'/components/com_flexicontent/assets/css/fcvote.css', array('version' => FLEXI_VHASH));
$document->addScript(JUri::root(true).'/components/com_flexicontent/assets/js/fcvote.js', array('version' => FLEXI_VHASH));
$image = $field->parameters->get( 'main_image', 'components/com_flexicontent/assets/images/star-medium.png' );
$img_path = JUri::root(true).'/'.$image;
$dim = $field->parameters->get( 'main_dimension', 24 );
$element_width = $rating_resolution * $dim;
if ($rating_stars) $element_width = (int) $element_width * ($rating_stars / $rating_resolution);
$css = '
/* This is via voting field parameter, please edit field configuration to override them */
.'.$class.' div.fcvote.fcvote-box-main {
line-height:'.$dim.'px!important;
}
.'.$class.' div.fcvote.fcvote-box-main > ul.fcvote_list {
height:'.$dim.'px!important;
width:'.$element_width.'px!important;
}
.'.$class.' div.fcvote.fcvote-box-main > ul.fcvote_list > li.voting-links a,
.'.$class.' div.fcvote.fcvote-box-main > ul.fcvote_list > li.current-rating {
height:'.$dim.'px!important;
line-height:'.$dim.'px!important;
}
.'.$class.' div.fcvote.fcvote-box-main > ul.fcvote_list,
.'.$class.' div.fcvote.fcvote-box-main > ul.fcvote_list > li.voting-links a:hover,
.'.$class.' div.fcvote.fcvote-box-main > ul.fcvote_list > li.current-rating {
background-image:url('.$img_path.')!important;
}
';
// Always add image configuration for composite (extra) votes in case some type is using them
$image = $field->parameters->get( 'extra_image', 'components/com_flexicontent/assets/images/star-medium.png' );
$img_path = JUri::root(true).'/'.$image;
$dim = $field->parameters->get( 'extra_dimension', 24 );
$element_width = $rating_resolution * $dim;
if ($rating_stars) $element_width = (int) $element_width * ($rating_stars / $rating_resolution);
$css .= '
/* This is via voting field parameter, please edit field configuration to override them */
.'.$class.' div.fcvote > ul.fcvote_list {
height:'.$dim.'px!important;
width:'.$element_width.'px!important;
}
.'.$class.' div.fcvote > ul.fcvote_list > li.voting-links a,
.'.$class.' div.fcvote > ul.fcvote_list > li.current-rating {
height:'.$dim.'px!important;
line-height:'.$dim.'px!important;
}
.'.$class.' div.fcvote > ul.fcvote_list,
.'.$class.' div.fcvote > ul.fcvote_list > li.voting-links a:hover,
.'.$class.' div.fcvote > ul.fcvote_list > li.current-rating {
background-image:url('.$img_path.')!important;
}
';
$rating_texts = trim($field->parameters->get(
'rating_texts',
'FLEXI_VOTE_VERY_POOR, FLEXI_VOTE_POOR, FLEXI_VOTE_FAIR, FLEXI_VOTE_GOOD, FLEXI_VOTE_EXCELLENT'
));
$rating_texts = preg_split("/\s*,\s*/u", $rating_texts);
$star_tooltips = array();
$star_classes = array();
for ($i = 1; $i <= $rating_resolution; $i++)
{
$star_zindex = $rating_resolution - $i + 2;
$star_percent = (int) round(100 * ($i / $rating_resolution));
$css .= '.' . $class . ' div.fcvote ul.fcvote_list > .voting-links a.star' . $i . ' { width: ' . $star_percent . '%!important; z-index: ' . $star_zindex . '; }' . "\n";
$star_classes[$i] = 'star' . $i;
switch (true)
{
case $star_percent <= 20:
$star_tooltips[$i] = JText::_(isset($rating_texts[0]) ? $rating_texts[0] : 'FLEXI_VOTE_VERY_POOR');
break;
case $star_percent <= 40:
$star_tooltips[$i] = JText::_(isset($rating_texts[1]) ? $rating_texts[1] : 'FLEXI_VOTE_POOR');
break;
case $star_percent <= 60:
$star_tooltips[$i] = JText::_(isset($rating_texts[2]) ? $rating_texts[2] : 'FLEXI_VOTE_FAIR');
break;
case $star_percent <= 80:
$star_tooltips[$i] = JText::_(isset($rating_texts[3]) ? $rating_texts[3] : 'FLEXI_VOTE_GOOD');
break;
default:
$star_tooltips[$i] = JText::_(isset($rating_texts[4]) ? $rating_texts[4] : 'FLEXI_VOTE_EXCELLENT');
break;
}
$star_tooltips[$i] .= ' ' . $i . '/' . $rating_resolution;
}
$document->addStyleDeclaration($css);
$js_and_css_added = true;
}
$percent = 0;
$factor = (int) round(100 / $rating_resolution);
if ((int) $rating_count !== 0)
{
$percent = number_format(((int) $rating_sum / (int) $rating_count) * $factor, 2);
}
elseif ($show_unrated === 0)
{
$counter = -1;
}
// Disable showing vote counter in extra votes
if ($int_xid)
{
$counter !== 2 ?: $counter = 0;
}
// Disable showing vote counter in main vote
else
{
$counter !== 3 ?: $counter = 0;
}
$nocursor = !$allow_vote
? 'cursor: unset !important;'
: '';
$html_vote_links = '';
if ($allow_vote)
{
// HAS Voting ACCESS
if ($has_acclvl)
{
$href = 'javascript:;';
$onclick = '';
}
// NO Voting ACCESS
else
{
// WITHOUT Redirection
if (!$no_acc_url)
{
$href = 'javascript:;';
$popup_msg = addcslashes($no_acc_msg, "'");
$onclick = 'alert(\''.$popup_msg.'\');';
}
// WITH Redirection
else
{
$href = $no_acc_url;
$popup_msg = addcslashes($no_acc_msg . "\\n\\n" . $no_acc_msg_redirect, "'");
if ($no_acc_askredirect==2) $onclick = 'return confirm(\''.$popup_msg.'\');';
else if ($no_acc_askredirect==1) $onclick = 'alert(\''.$popup_msg.'\'); return true;';
else $onclick = 'return true;';
}
}
$dovote_class = ' hasTooltip ' . ($has_acclvl ? 'fc_dovote' : '');
for ($i = 1; $i <= $rating_resolution; $i++)
{
$html_vote_links .= '
<li class="voting-links"><a onclick="'.$onclick.'" href="'.$href.'" title="'.$star_tooltips[$i].'" class="'.$dovote_class.' '.$star_classes[$i].'" data-rel="'.$id.'_'.$xid.'">'.$i.'</a></li>';
}
}
return '
<div class="'.$class.' '.$class.'_'.$xid.'">
<div class="fcvote fcvote-box-'.$xid.'">
<div class="nowrap_box fcvote-label-outer">
'.($label ? '<div class="fcvote-label xid-'.$xid.'">'.$label.'</div>' : '').'
<div class="fc-mssg fc-info fc-iblock fc-nobgimage fcvote-count" '.( !$rating_count || (($counter==-1 || $counter==0) && !$show_percentage) ? 'style="display:none;"' : '' ).'>'.
($show_percentage ? ((int)$percent ? (int)$percent.'%' : '') : '').
( $counter==-1 || $counter==0 ? '' :
($show_percentage && (int)$percent ? ' - ' : '').
($rating_count ? $rating_count : '0').
($counter_show_label ? ' '.JText::_( $rating_count!=1 ? 'FLEXI_VOTES' : 'FLEXI_VOTE' ) : '')
).'
</div>'.
(!(int)$percent || $int_xid || $view !== 'item' ? '' : '
<span itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
<meta itemprop="itemReviewed" content="'.htmlspecialchars($field->item_title, ENT_QUOTES, 'UTF-8').'" />
<meta itemprop="ratingValue" content="'.round($percent).'" />
<meta itemprop="bestRating" content="100" />
<meta itemprop="ratingCount" content="'.$rating_count.'" />
</span>').'
</div>
<ul class="fcvote_list">
<li class="current-rating" style="width:'.(int)$percent.'%;'.$nocursor.'"></li>
'.$html_vote_links.'
</ul>
<div class="fcvote_message" ></div>
'.($add_review_form ? '
<input type="button" class="btn btn-primary fcvote_toggle_review_form"
onclick="fcvote_open_review_form(jQuery(\'#fcvote_review_form_box_'.$id.'\').attr(\'id\'), '.$id.', \''.$review_type.'\', this)"
value="'.JText::_('FLEXI_VOTE_REVIEW_THIS_ITEM').'"/>
<div id="fcvote_review_form_box_'.$id.'_loading" class="fcvote_review_form_box_loading"></div>
<span class="fcclear"></span>
<div id="fcvote_review_form_box_'.$id.'" class="fcvote_review_form_box" style="display:none;"></div>' : '').'
'.( $desc ? '<div class="fcvote-desc">'.$desc.'</div>' :'' ).'
</div>
</div>';
}
/**
* Creates the favourited by user list
*
* @param array $params
* @since 1.0
*/
static function favoured_userlist($field, $item, & $favourites, $type='item')
{
$layouts_path = null;
/**
* field: 'Favourites' field
* item: item or category record
* type: 'item' or 'category'
* favourites: value (of field)
*/
$displayData = array(
'field' => $field,
'item' => $item,
'type' => 'item',
'favourites' => $favourites,
);
return JLayoutHelper::render('flexicontent_fields.favourites.userlist', $displayData, $layouts_path);
}
/**
* Creates the favourite icons
*
* @param array $params
* @since 1.0
*/
static function favicon($field, & $favoured, $item, $type='item')
{
$layouts_path = null;
/**
* field: 'Favourites' field
* item: item or category record
* type: 'item' or 'category'
* favoured: value (of field)
*/
$displayData = array(
'field' => $field,
'item' => $item,
'type' => 'item',
'favoured' => $favoured,
);
return JLayoutHelper::render('flexicontent_fields.favourites.favicon', $displayData, $layouts_path);
}
/**
* Method to build a list of radio or checkbox buttons
*
* @return array
* @since 1.5
*/
static function buildradiochecklist($options, $name, $selected, $buildtype=0, $attribs = '', $tagid=null, $label_class='', $label_on_class='', $fset_attribs='')
{
$add_fset = $buildtype==1 || $buildtype==3;
$selected = is_array($selected) ? $selected : array($selected);
$tagid = $tagid ? $tagid : str_replace( '[', '_', preg_replace('#\]|\[\]#', '',($name)) );
// Set input-set attributes and input's label class if not given
$fset_attribs = !$fset_attribs && $add_fset
? ' class="radio btn-group group-fcinfo"'
: $fset_attribs;
$label_class = !$label_class && $add_fset
? ''
: $label_class;
$label_on_class = !$label_on_class && $add_fset
? ''
: $label_on_class;
$html = $add_fset ? '<fieldset ' . $fset_attribs . '>' : '';
$n = 0;
foreach ($options as $value => $text) {
$tagid_n = $tagid.$n;
$html .='
<input type="'.($buildtype > 1 ? 'checkbox' : 'radio').'" '.(in_array($value, $selected) ? ' checked="checked" ' : '').' value="'.$value.'" id="'.$tagid_n.'" name="'.$name.'" '.$attribs.'/>
<label id="'.$tagid_n.'-lbl" for="'.$tagid_n.'" class="' . (in_array($value, $selected) ? $label_on_class : '') . $label_class.'">'.$text.'</label>
';
$n++;
}
$html .= $add_fset ? '</fieldset>' : '';
return $html;
}
/**
* Method to build the list for types
*
* @return array
* @since 1.5
*/
static function buildtypesselect($types, $name, $selected, $displaytype, $attribs = 'class="inputbox"', $tagid=null, $check_perms=false)
{
$_list = array();
if (!is_numeric($displaytype) && is_string($displaytype))
$_list[] = JHtml::_( 'select.option', '', $displaytype );
else if ($displaytype)
$_list[] = JHtml::_( 'select.option', '', JText::_( 'FLEXI_SELECT_TYPE' ) );
if ($check_perms)
$user = JFactory::getUser();
$selected_arr = is_array($selected) ? $selected : ($selected ? array($selected) : array());
foreach ($types as $type)
{
$allowed = true;
if ($check_perms)
{
$allowed = !$type->id || in_array($type->id, $selected_arr) || !$type->itemscreatable || $user->authorise('core.create', 'com_flexicontent.type.' . $type->id);
}
if ( !$allowed && $type->itemscreatable == 1 ) continue;
if ( !$allowed && $type->itemscreatable == 2 )
$_list[] = JHtml::_( 'select.option', $type->id, JText::_($type->name), 'value', 'text', $disabled = true );
else
$_list[] = JHtml::_( 'select.option', $type->id, JText::_($type->name));
}
$tagid = $tagid ? $tagid : str_replace( '[', '_', preg_replace('#\]|\[\]#', '',($name)) );
return JHtml::_('select.genericlist', $_list, $name, $attribs, 'value', 'text', $selected, $tagid );
}
/**
* Method to build the list of the autors
*
* @return array
* @since 1.5
*/
static function buildauthorsselect($list, $name, $selected, $displaytype, $attribs = 'class="inputbox"', $tagid=null)
{
$_list = array();
if (!is_numeric($displaytype) && is_string($displaytype))
$_list[] = JHtml::_( 'select.option', '', $displaytype );
else if ($displaytype)
$_list[] = JHtml::_( 'select.option', '', JText::_( 'FLEXI_SELECT_AUTHOR' ) );
$user_id_str = JText::_('FLEXI_ID') .': ';
foreach ($list as $item) {
$_list[] = JHtml::_( 'select.option', $item->id, $item->name ? $item->name : $user_id_str . $item->id );
}
$tagid = $tagid ? $tagid : str_replace( '[', '_', preg_replace('#\]|\[\]#', '',($name)) );
return JHtml::_('select.genericlist', $_list, $name, $attribs, 'value', 'text', $selected, $tagid );
}
/**
* Method to build the list of the autors
*
* @return array
* @since 1.5
*/
static function buildtagsselect($name, $attribs, $selected, $displaytype=1, $tagid=null)
{
$db = JFactory::getDbo();
$query = 'SELECT id, name'
. ' FROM #__flexicontent_tags'
. ' ORDER BY name ASC'
;
$db->setQuery($query);
$data = $db->loadObjectList();
$options = array();
if (!is_numeric($displaytype) && is_string($displaytype))
$options[] = JHtml::_( 'select.option', '', $displaytype);
else if ($displaytype)
$options[] = JHtml::_( 'select.option', '', JText::_( 'FLEXI_SELECT_TAG' ));
foreach ($data as $val)
$options[] = JHtml::_( 'select.option', $val->id, $val->name);
$tagid = $tagid ? $tagid : str_replace( '[', '_', preg_replace('#\]|\[\]#', '',($name)) );
return JHtml::_('select.genericlist', $options, $name, $attribs, 'value', 'text', $selected, $tagid );
}
/**
* Method to build the list for types when performing an edit action
*
* @return array
* @since 1.5
*/
static function buildfieldtypeslist($list, $name, $selected, $displaytype, $attribs = 'class="inputbox"', $tagid=null)
{
$tagid = $tagid ? $tagid : str_replace( '[', '_', preg_replace('#\]|\[\]#', '',($name)) );
// $displaytype: 0, is ungrouped
if (!$displaytype)
{
ksort( $list, SORT_STRING );
return JHtml::_('select.genericlist', $list, $name, $attribs, 'value', 'text', $selected, $tagid );
}
// $displaytype: 1, is grouped
else
{
$attribs = is_array($attribs)
? ArrayHelper::toString($attribs)
: $attribs;
$field_types = array();
$n = 0;
$in_grp = false;
foreach ($list as $key => $data)
{
if ( !is_numeric($key) )
{
$field_types[$key] = $data;
$in_grp = true;
}
else
{
$n = !$in_grp ? $n : ($n + 1);
$field_types[$n]['items'][] = $data;
$in_grp = false;
}
}
$xml = new SimpleXMLElement("<element $attribs />");
$xml = (array)$xml->attributes();
$attributes = $xml['@attributes'];
$attribs = array(
'id' => $tagid, // HTML id for select field
'group.id' => 'id',
'list.attr' => $attributes, // array(), // additional HTML attributes for select field
'list.translate'=>false, // true to translate
'option.key'=>'value', // key name for value in data array
'option.text'=>'text', // key name for text in data array
'option.attr'=>'attr', // key name for attr in data array
'list.select'=>$selected, // value of the SELECTED field
);
return JHtml::_('select.groupedlist', $field_types, $name, $attribs);
}
}
/**
* Method to build the file extension list
*
* @return array
* @since 1.5
*/
static function buildfilesextlist($name, $attribs, $selected, $displaytype=1, $tagid=null)
{
$db = JFactory::getDbo();
$query = 'SELECT DISTINCT ext'
. ' FROM #__flexicontent_files'
. ' ORDER BY ext ASC'
;
$db->setQuery($query);
$data = $db->loadColumn();
if (!is_numeric($displaytype) && is_string($displaytype))
$options[] = JHtml::_( 'select.option', '', $displaytype);
else if ($displaytype)
$options[] = JHtml::_( 'select.option', '', JText::_( 'FLEXI_ALL_EXT' ));
foreach ($data as $val)
$options[] = JHtml::_( 'select.option', $val, $val);
$tagid = $tagid ? $tagid : str_replace( '[', '_', preg_replace('#\]|\[\]#', '',($name)) );
return JHtml::_('select.genericlist', $options, $name, $attribs, 'value', 'text', $selected, $tagid );
}
/**
* Method to build the uploader list
*
* @return array
* @since 1.5
*/
static function builduploaderlist($name, $attribs, $selected, $displaytype=1, $tagid=null)
{
$db = JFactory::getDbo();
$query = 'SELECT DISTINCT f.uploaded_by AS uid, u.name AS name'
. ' FROM #__flexicontent_files AS f'
. ' LEFT JOIN #__users AS u ON u.id = f.uploaded_by'
. ' ORDER BY f.ext ASC'
;
$db->setQuery($query);
$data = $db->loadObjectList();
if (!is_numeric($displaytype) && is_string($displaytype))
$options[] = JHtml::_( 'select.option', '', $displaytype);
else if ($displaytype)
$options[] = JHtml::_( 'select.option', '', JText::_( 'FLEXI_ALL_UPLOADERS' ));
foreach ($data as $val)
$options[] = JHtml::_( 'select.option', $val->uid, $val->name ?? '' );
$tagid = $tagid ? $tagid : str_replace( '[', '_', preg_replace('#\]|\[\]#', '',($name)) );
return JHtml::_('select.genericlist', $options, $name, $attribs, 'value', 'text', $selected, $tagid );
}
/**
* Method to build the Joomfish languages list
*
* @return object
* @since 1.5
*/
static function buildlanguageslist($name, $attribs, $selected, $displaytype=1, $allowed_langs=null, $published_only=true, $disable_langs=null, $add_all=true, $radio_conf=false)
{
$db = JFactory::getDbo();
$tagid = null; // ... not provided
$tagid = $tagid ? $tagid : str_replace( '[', '_', preg_replace('#\]|\[\]#', '',($name)) );
$selected_found = false;
$all_langs = FLEXIUtilities::getlanguageslist($published_only, $add_all);
$user_langs = null;
if ($allowed_langs)
{
$_allowed = array_flip($allowed_langs);
foreach ($all_langs as $index => $lang)
{
if (isset($_allowed[$lang->code]))
{
$user_langs[] = $lang;
// Check if selected language was added to the user langs
$selected_found = ($lang->code == $selected) ? true : $selected_found;
}
}
}
else
{
$user_langs = $all_langs;
$selected_found = true;
}
if ($disable_langs)
{
$_disabled = array_flip($disable_langs);
$_user_langs = array();
foreach ($user_langs as $index => $lang)
{
if (!isset($_disabled[$lang->code]))
{
$_user_langs[] = $lang;
// Check if selected language was added to the user langs
$selected_found = ($lang->code == $selected) ? true : $selected_found;
}
}
$user_langs = $_user_langs;
}
if (!count($user_langs))
{
return "user is not allowed to use any language";
}
// Force first language to be selected
if (!$selected_found)
{
$selected = $user_langs[0]->code;
}
/**
* For radio cases
*/
if ($radio_conf && empty($radio_conf['flags']) && empty($radio_conf['texts']))
{
$radio_conf['flags'] = $radio_conf['texts'] = 1;
}
$required = $radio_conf && !empty($radio_conf['required'])
? ' required validate-radio '
: '';
$langs = array();
switch ($displaytype)
{
// Drop-down SELECT of ALL languages
case 1: case 2: default:
// WITH custom prompt to select language
if (!is_numeric($displaytype) && is_string($displaytype))
{
$langs[] = JHtml::_('select.option', '', $displaytype);
}
// WITH empty prompt to select language, e.g. used in items/category manager
elseif ($displaytype == 2)
{
$langs[] = JHtml::_('select.option', '', JText::_( 'FLEXI_SELECT_LANGUAGE' ));
}
foreach ($user_langs as $lang)
{
$langs[] = JHtml::_('select.option', $lang->code, $lang->name );
}
$list = JHtml::_('select.genericlist', $langs, $name, $attribs, 'value', 'text', $selected, $tagid);
break;
// RADIO selection of ALL languages (Flag icons only) e.g. item form,
case 3:
$checked = '';
$list = '<div class="group-fcset fc_input_set">';
foreach ($user_langs as $lang)
{
if ($lang->code == $selected)
{
$checked = ' checked="checked"';
}
$list .= '<input id="'.$tagid.'_'.$lang->id.'" type="radio" name="'.$name.'" value="'.$lang->code.'"'.$checked.' class="'.$required.'" data-element-grpid="'.$tagid.'" />';
$list .= '<label class="lang_box" for="'.$tagid.'_'.$lang->id.'" title="'.$lang->name.'" >';
if ($lang->shortcode === '*')
{
$list .= JText::_('FLEXI_ALL');
}
else
{
// Add Flag if configure and it exists
if (!$radio_conf || $radio_conf['flags'])
{
$list .= !empty($lang->imgsrc)
? '<img src="' . $lang->imgsrc . '" alt="' . $lang->name . '" />'
: $lang->code;
}
// Add text if configured
if ( !$radio_conf || $radio_conf['texts']==1 ) {
$list .= $lang->code;
} else if ( $radio_conf['texts']==2 ) {
$list .= $lang->title;
} else if ( $radio_conf['texts']==3 ) {
$list .= $lang->title_native;
} else if ( $conf['texts']==4 ) {
$list .= $lang->name;
} else {
$list .= '';
}
}
$list .= '</label>';
$checked = '';
}
$list .= '</div>';
break;
// RADIO selection of ALL languages, with empty default option "Keep original language", e.g. when copying/moving items
case 4:
$list = '<input id="lang9999" type="radio" name="'.$name.'" class="'.$required.'" value="" checked="checked" data-element-grpid="'.$tagid.'" />';
$list .= '<label class="lang_box" for="lang9999" title="'.JText::_( 'FLEXI_NOCHANGE_LANGUAGE_DESC' ).'" >';
$list .= JText::_( 'FLEXI_NOCHANGE_LANGUAGE' );
$list .= '</label><div class="fcclear"></div>';
$list .= '<div class="group-fcset fc_input_set">';
foreach ($user_langs as $lang)
{
$list .= '<input id="'.$tagid.'_'.$lang->id.'" type="radio" name="'.$name.'" class="'.$required.'" value="'.$lang->code.'" data-element-grpid="'.$tagid.'" />';
$list .= '<label class="lang_box" for="'.$tagid.'_'.$lang->id.'" title="'.$lang->name.'">';
if ($lang->shortcode === '*')
{
$list .= JText::_('FLEXI_ALL');
}
elseif (@$lang->imgsrc)
{
$list .= '<img src="'.$lang->imgsrc.'" alt="'.$lang->name.'" />';
}
else
{
$list .= $lang->name;
}
$list .= ' </label>';
}
$list .= '</div>';
break;
// RADIO selection of ALL languages, EXCLUDE selected language, e.g. when translating items into another language
case 5:
// Also exclude '*' (ALL) language
case 7:
$list = '<div class="group-fcset fc_input_set">';
foreach ($user_langs as $lang)
{
if ($lang->code == $selected) continue;
if ($displaytype == 7 && $lang->shortcode === '*') continue;
$list .= '<input id="'.$tagid.'_'.$lang->id.'" type="radio" name="'.$name.'" class="'.$required.'" value="'.$lang->code.'" data-element-grpid="'.$tagid.'" />';
$list .= '<label class="lang_box" for="'.$tagid.'_'.$lang->id.'" title="'.$lang->name.'">';
if ($lang->shortcode === '*')
{
$list .= JText::_('FLEXI_ALL');
} else if (@$lang->imgsrc) {
$list .= '<img src="'.$lang->imgsrc.'" alt="'.$lang->name.'" />';
} else {
$list .= $lang->name;
}
$list .= '</label>';
}
$list .= '</div>';
break;
// RADIO selection of ALL languages, with empty option "Use language column", e.g. used in CSV import view
case 6:
$list = '<div class="group-fcset fc_input_set">';
$checked = $selected == '-99' ? 'checked="checked"' : '';
$list .= '<input id="lang-99" type="radio" name="'.$name.'" class="'.$required.'" value="-99" '.$checked.' data-element-grpid="'.$tagid.'" />';
$tooltip_class = ' hasTooltip';
$tooltip_title = flexicontent_html::getToolTip('FLEXI_USE_LANGUAGE_COLUMN', 'FLEXI_USE_LANGUAGE_COLUMN_TIP', 1, 1);
$list .= '<label class="lang_box'.$tooltip_class.'" for="lang-99" title="'.$tooltip_title.'">';
$list .= JText::_( 'FLEXI_USE_LANGUAGE_COLUMN' );
$list .= '</label>';
foreach ($user_langs as $lang)
{
$checked = $lang->code==$selected ? 'checked="checked"' : '';
$list .= '<input id="'.$tagid.'_'.$lang->id.'" type="radio" name="'.$name.'" class="'.$required.'" value="'.$lang->code.'" '.$checked.' data-element-grpid="'.$tagid.'" />';
$list .= '<label class="lang_box" for="'.$tagid.'_'.$lang->id.'" title="'.$lang->name.'">';
if ($lang->shortcode === '*')
{
$list .= JText::_('FLEXI_ALL');
}
/*elseif (@$lang->imgsrc)
{
$list .= '<img src="'.$lang->imgsrc.'" alt="'.$lang->name.'" />';
}*/
else
{
$list .= $lang->name;
}
$list .= ' </label>';
}
$list .= '</div>';
break;
}
return $list;
}
/**
* Method to build the Joomfish languages list
*
* @return object
* @since 1.5
*/
static function buildstateslist($name, $attribs, $selected, $displaytype=1, $tagid=null)
{
static $state_names = null;
static $state_descrs = null;
static $state_imgs = null;
if (!$state_names)
{
$state_names = array(
1 => JText::_('FLEXI_PUBLISHED'),
-5 => JText::_('FLEXI_IN_PROGRESS'),
0 => JText::_('FLEXI_UNPUBLISHED'),
-3 => JText::_('FLEXI_PENDING'),
-4 => JText::_('FLEXI_TO_WRITE'),
2 => JText::_('FLEXI_ARCHIVED'),
-2 => JText::_('FLEXI_TRASHED'),
'u' => JText::_('FLEXI_UNKNOWN'),
);
$state_descrs = array(
1 => JText::_('FLEXI_PUBLISH_THIS_ITEM'),
-5 => JText::_('FLEXI_SET_STATE_AS_IN_PROGRESS'),
0 => JText::_('FLEXI_UNPUBLISH_THIS_ITEM'),
-3 => JText::_('FLEXI_SET_STATE_AS_PENDING'),
-4 => JText::_('FLEXI_SET_STATE_AS_TO_WRITE'),
2 => JText::_('FLEXI_ARCHIVE_THIS_ITEM'),
-2 => JText::_('FLEXI_TRASH_THIS_ITEM'),
'' => 'FLEXI_UNKNOWN',
);
$state_imgs = array(
1 => 'accept.png',
-5 => 'publish_g.png',
0 => 'publish_x.png',
-3 => 'publish_r.png',
-4 => 'publish_y.png',
2 => 'archive.png',
-2 => 'trash.png',
'' => 'unknown.png',
);
}
$state[] = JHtml::_('select.option', '', JText::_(!is_numeric($displaytype) && is_string($displaytype) ? $displaytype : 'FLEXI_DO_NOT_CHANGE'));
$state[] = JHtml::_('select.option', -4, $state_names[-4]);
$state[] = JHtml::_('select.option', -3, $state_names[-3]);
$state[] = JHtml::_('select.option', -5, $state_names[-5]);
$state[] = JHtml::_('select.option', 1, $state_names[1]);
$state[] = JHtml::_('select.option', 0, $state_names[0]);
$state[] = JHtml::_('select.option', 2, $state_names[2]);
$state[] = JHtml::_('select.option', -2, $state_names[-2]);
$tagid = $tagid ? $tagid : str_replace( '[', '_', preg_replace('#\]|\[\]#', '',($name)) );
if ($displaytype == 1 || (!is_numeric($displaytype) && is_string($displaytype)))
{
$list = JHtml::_('select.genericlist', $state, $name, $attribs, 'value', 'text', $selected, $tagid);
}
elseif ($displaytype == 2)
{
$state_ids = array(1, -5, 0, -3, -4); // published: 1, -5 unpublished: 0, -3, -4
$state_ids[] = 2; // archived
$state_ids[] = -2; // trashed
$state_colors= array(1=>'darkgreen', -5=>'darkgreen', 0=>'darkred', -3=>'darkred', -4=>'darkred', 2=>'darkblue', -2=>'gray');
$img_path = JUri::root(true)."/components/com_flexicontent/assets/images/";
$list = '<div class="group-fcset fc_input_set">';
$checked = $selected == '-99' ? ' checked="checked"' : '';
$list .= '<input id="state-99" type="radio" name="state" class="state" value="-99" '.$checked.'/>';
$tooltip_class = ' hasTooltip';
$tooltip_title = flexicontent_html::getToolTip('FLEXI_USE_STATE_COLUMN', 'FLEXI_USE_STATE_COLUMN_TIP', 1, 1);
$list .= '<label class="state_box'.$tooltip_class.'" for="state-99" title="'.$tooltip_title.'">';
$list .= JText::_( 'FLEXI_USE_STATE_COLUMN' );
$list .= '</label>';
foreach ($state_ids as $i => $state_id)
{
//if ($state_id==0 || $state_id==2) $list .= "<br/>";
$checked = $state_id==$selected ? ' checked="checked"' : '';
$list .= '<input id="state'.$state_id.'" type="radio" name="state" class="state" value="'.$state_id.'" '.$checked.'/>';
$list .= '<label class="state_box" for="state'.$state_id.'" title="'.$state_names[$state_id].'" style="color:'.$state_colors[$state_id].';">';
$list .= $state_names[$state_id];
//$list .= '<img src="'.$img_path.$state_imgs[$state_id].'" width="16" height="16" style="border-width:0;" alt="'.$state_names[$state_id].'" />';
$list .= '</label>';
}
$list .= '</div>';
}
else
{
$list = 'Bad type in buildstateslist()';
}
return $list;
}
/**
* Method to get the user's Current Language
*
* @return string
* @since 1.5
*/
static function getUserCurrentLang($short_tag=true)
{
static $UILang = null;
if ($UILang) return $UILang[$short_tag];
// Get CURRENT user interface language. Content language can be natively switched in J2.5
// by using (a) the language switcher module and (b) the Language Filter - System Plugin
$UILang[false] = JFactory::getLanguage()->getTag();
$UILang[true] = substr($UILang[false], 0,2);
return $UILang[$short_tag];
}
static function loadComponentLanguage($client = 0)
{
static $loaded = array();
if (isset($loaded[$client])) return;
if (JFactory::getApplication()->isClient('administrator') && $client = 0) return;
// Load english language file for 'com_flexicontent' and then override with current language file. Do not force a reload for either (not needed)
JFactory::getLanguage()->load('com_flexicontent', ($client ? JPATH_ADMINISTRATOR : JPATH_SITE), 'en-GB', $force_reload = false, $load_default = true);
JFactory::getLanguage()->load('com_flexicontent', ($client ? JPATH_ADMINISTRATOR : JPATH_SITE), null, $force_reload = false, $load_default = true);
$loaded[$client] = true;
}
static function loadModuleLanguage($modulename)
{
static $loaded = array();
if (isset($loaded[$modulename])) return;
// Load english language file for current module then override (forcing a reload) with current language file
JFactory::getLanguage()->load($modulename, JPATH_SITE, 'en-GB', $force_reload = false, $load_default = true);
JFactory::getLanguage()->load($modulename, JPATH_SITE, null, $force_reload = true, $load_default = true);
// Load component frontend language file
flexicontent_html::loadComponentLanguage($client = 0);
$loaded[$modulename] = true;
}
/**
* Method to get Site (Frontend) default language
* NOTE: ... this is the default language of created content for J1.5, but in J1.6+ is '*' (=all)
* NOTE: ... joomfish creates translations in all other languages
*
* @return string
* @since 1.5
*/
static function getSiteDefaultLang()
{
$languages = JComponentHelper::getParams('com_languages');
$lang = $languages->get('site', 'en-GB');
return $lang;
}
static function nl2space($string) {
if(gettype($string)!="string") return false;
$strlen = strlen($string);
$array = array();
$str = "";
for($i=0;$i<$strlen;$i++) {
if(ord($string[$i])===ord("\n")) {
$str .= ' ';
continue;
}
$str .= $string[$i];
}
return $str;
}
/**
Diff implemented in pure php, written from scratch.
Copyright (C) 2003 Daniel Unterberger <diff.phpnet@holomind.de>
Copyright (C) 2005 Nils Knappmeier next version
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
http://www.gnu.org/licenses/gpl.html
About:
I searched a function to compare arrays and the array_diff()
was not specific enough. It ignores the order of the array-values.
So I reimplemented the diff-function which is found on unix-systems
but this you can use directly in your code and adopt for your needs.
Simply adopt the formatline-function. with the third-parameter of arr_diff()
you can hide matching lines. Hope someone has use for this.
Contact: d.u.diff@holomind.de <daniel unterberger>
**/
## PHPDiff returns the differences between $old and $new, formatted
## in the standard diff(1) output format.
static function PHPDiff($t1,$t2)
{
# split the source text into arrays of lines
//$t1 = explode("\n",$old);
$x=array_pop($t1);
if ($x>'') $t1[]="$x\n\\ No newline at end of file";
//$t2 = explode("\n",$new);
$x=array_pop($t2);
if ($x>'') $t2[]="$x\n\\ No newline at end of file";
# build a reverse-index array using the line as key and line number as value
# don't store blank lines, so they won't be targets of the shortest distance
# search
foreach($t1 as $i=>$x) if ($x>'') $r1[$x][]=$i;
foreach($t2 as $i=>$x) if ($x>'') $r2[$x][]=$i;
$a1=0; $a2=0; # start at beginning of each list
$actions=array();
# walk this loop until we reach the end of one of the lists
while ($a1<count($t1) && $a2<count($t2))
{
# if we have a common element, save it and go to the next
if ($t1[$a1]==$t2[$a2]) { $actions[]=4; $a1++; $a2++; continue; }
# otherwise, find the shortest move (Manhattan-distance) from the
# current location
$best1=count($t1); $best2=count($t2);
$s1=$a1; $s2=$a2;
while(($s1+$s2-$a1-$a2) < ($best1+$best2-$a1-$a2)) {
$d=-1;
foreach((array)@$r1[$t2[$s2]] as $n)
if ($n>=$s1) { $d=$n; break; }
if ($d>=$s1 && ($d+$s2-$a1-$a2)<($best1+$best2-$a1-$a2))
{ $best1=$d; $best2=$s2; }
$d=-1;
foreach((array)@$r2[$t1[$s1]] as $n)
if ($n>=$s2) { $d=$n; break; }
if ($d>=$s2 && ($s1+$d-$a1-$a2)<($best1+$best2-$a1-$a2))
{ $best1=$s1; $best2=$d; }
$s1++; $s2++;
}
while ($a1<$best1) { $actions[]=1; $a1++; } # deleted elements
while ($a2<$best2) { $actions[]=2; $a2++; } # added elements
}
# we've reached the end of one list, now walk to the end of the other
while($a1<count($t1)) { $actions[]=1; $a1++; } # deleted elements
while($a2<count($t2)) { $actions[]=2; $a2++; } # added elements
# and this marks our ending point
$actions[]=8;
# now, let's follow the path we just took and report the added/deleted
# elements into $out.
$op = 0;
$x0=$x1=0; $y0=$y1=0;
$out1 = array();
$out2 = array();
foreach($actions as $act) {
if ($act==1) { $op|=$act; $x1++; continue; }
if ($act==2) { $op|=$act; $y1++; continue; }
if ($op>0) {
//$xstr = ($x1==($x0+1)) ? $x1 : ($x0+1).",$x1";
//$ystr = ($y1==($y0+1)) ? $y1 : ($y0+1).",$y1";
/*if ($op==1) $out[] = "{$xstr}d{$y1}";
elseif ($op==3) $out[] = "{$xstr}c{$ystr}";*/
while ($x0<$x1) { $out1[] = $x0; $x0++; } # deleted elems
/*if ($op==2) $out[] = "{$x1}a{$ystr}";
elseif ($op==3) $out[] = '---';*/
while ($y0<$y1) { $out2[] = $y0; $y0++; } # added elems
}
$x1++; $x0=$x1;
$y1++; $y0=$y1;
$op=0;
}
//$out1[] = '';
//$out2[] = '';
return array($out1, $out2);
}
/*static function flexiHtmlDiff($old, $new, $mode=0)
{
$t1 = explode(" ",$old);
$t2 = explode(" ",$new);
$out = flexicontent_html::PHPDiff( $t1, $t2 );
$html1 = array();
$html2 = array();
foreach($t1 as $k=>$o) {
if(in_array($k, $out[0])) $html1[] = "<s>".($mode?htmlspecialchars($o, ENT_QUOTES):$o)."</s>";
else $html1[] = ($mode?htmlspecialchars($o, ENT_QUOTES)."<br/>":$o);
}
foreach($t2 as $k=>$n) {
if(in_array($k, $out[1])) $html2[] = "<u>".($mode?htmlspecialchars($n, ENT_QUOTES):$n)."</u>";
else $html2[] = ($mode?htmlspecialchars($n, ENT_QUOTES)."<br/>":$n);
}
$html1 = implode(" ", $html1);
$html2 = implode(" ", $html2);
return array($html1, $html2);
}*/
static function flexiHtmlDiff($before, $after, $mode=0)
{
require_once (JPATH_SITE.'/components/com_flexicontent/librairies/phpdiff/diff.php');
$diff = new fc_diff_class;
$difference = new stdClass;
$difference->mode = 'w';
$difference->patch = true;
$after_patch = new stdClass;
if ($diff->FormatDiffAsHtml($before, $after, $difference) && $diff->Patch($before, $difference->difference, $after_patch))
{
//echo '<div>Difference</div><div class="frameResults">', $difference->html, '</div>';
//echo '<div>Patch</div><div class="frameResults">', ($after === $after_patch->after ? 'OK: The patched text matches the text after.' : 'There is a BUG: The patched text (<b>'.HtmlSpecialChars($after_patch->after).'</b>) does not match the text after (<b>'.HtmlSpecialChars($after).'</b>).'), '</div>';
return array(
0 => ($mode ? htmlspecialchars($before, ENT_QUOTES, 'UTF-8') : $before),
1 => ($mode ? htmlspecialchars($after, ENT_QUOTES, 'UTF-8') : $after),
2 => ($mode ? $difference->html : htmlspecialchars_decode($difference->html)),
);
}
else
{
echo '<div>Error: ', htmlspecialchars($diff->error), '</div>';
return array(0 => $before . '<br>' . $diff->error, $after);
}
}
/**
* Method to retrieve mappings of CORE fields (Names to Types and reverse)
*
* @return object
* @since 1.5
*/
static function getJCoreFields($ffield=NULL, $map_maintext_to_introtext=false, $reverse=false) {
if(!$reverse) // MAPPING core fields NAMEs => core field TYPEs
{
$flexifield = array(
'title'=>'title',
'categories'=>'categories',
'tags'=>'tags',
'text'=>'maintext',
'created'=>'created',
'created_by'=>'createdby',
'modified'=>'modified',
'modified_by'=>'modifiedby',
'hits'=>'hits',
'document_type'=>'type',
'version'=>'version',
'state'=>'state'
);
if ($map_maintext_to_introtext)
{
$flexifield['introtext'] = 'maintext';
}
}
else // MAPPING core field TYPEs => core fields NAMEs
{
$flexifield = array(
'title'=>'title',
'categories'=>'categories',
'tags'=>'tags',
'maintext'=>'text',
'created'=>'created',
'createdby'=>'created_by',
'modified'=>'modified',
'modifiedby'=>'modified_by',
'hits'=>'hits',
'type'=>'document_type',
'version'=>'version',
'state'=>'state'
);
if ($map_maintext_to_introtext)
{
$flexifield['maintext'] = 'introtext';
}
}
if($ffield===NULL) return $flexifield;
return isset($flexifield[$ffield])?$flexifield[$ffield]:NULL;
}
static function getFlexiFieldId($jfield=NULL) {
$flexifields = array(
'introtext'=>1,
'text'=>1,
'created'=>2,
'created_by'=>3,
'modified'=>4,
'modified_by'=>5,
'title'=>6,
'hits'=>7,
'version'=>9,
'state'=>10,
'catid'=>13,
);
if($jfield===NULL) return $flexifields;
return isset($flexifields[$jfield])?$flexifields[$jfield]:0;
}
static function getFlexiField($jfield=NULL) {
$flexifields = array(
'introtext'=>'text',
'fulltext'=>'text',
'created'=>'created',
'created_by'=>'createdby',
'modified'=>'modified',
'modified_by'=>'modifiedby',
'title'=>'title',
'hits'=>'hits',
'version'=>'version',
'state'=>'state'
);
if($jfield===NULL) return $flexifields;
return isset($flexifields[$jfield])?$flexifields[$jfield]:0;
}
/**
* Method to get types list e.g. when performing an edit action optionally checking 'create' ACCESS for the types
*
* @return array
* @since 1.5
*/
static function getTypeslist ( $type_ids=false, $check_perms = false, $published=true )
{
// Return cached result
static $all_types;
if ( empty( $type_ids ) && isset( $all_types[$check_perms][$published] ) ) return $all_types[$check_perms][$published];
// Custom type_ids array given, do the query
$type_ids_list = false;
if ( !empty($type_ids) && is_array($type_ids) )
{
$type_ids = ArrayHelper::toInteger($type_ids);
$type_ids_list = implode(',', $type_ids);
}
$where = array();
if ($published)
$where[] = 'published = 1';
if ($type_ids_list)
$where[] = 'id IN ('. $type_ids_list .' ) ';
$db = JFactory::getDbo();
$query = 'SELECT * '
. ' FROM #__flexicontent_types'
. ($where ? ' WHERE ' . implode(' AND ', $where) : '')
. ' ORDER BY name ASC';
$db->setQuery($query);
$types = $db->loadObjectList('id');
if ($check_perms)
{
$user = JFactory::getUser();
$_types = array();
foreach ($types as $type_id => $type) {
$allowed = ! $type->itemscreatable || $user->authorise('core.create', 'com_flexicontent.type.' . $type->id);
if ( $allowed ) $_types[$type_id] = $type;
}
$types = $_types;
}
if (!$published) {
foreach ($types as $type_id => $type) {
if ( !$type->published ) $types[$type_id]->name .= ' -U-';
}
}
// Cache function result
if ( empty($type_ids ) ) $all_types[$check_perms][$published] = $types;
return $types;
}
/**
* Displays a list of the available access view levels
*
* @param string The form field name.
* @param string The name of the selected section.
* @param string Additional attributes to add to the select field.
* @param mixed True to add "All Sections" option or and array of option
* @param string The form field id
*
* @return string The required HTML for the SELECT tag.
*/
static function userlevel($name, $selected, $attribs = '', $extra_options = true, $id = false, $createlist = true)
{
static $options;
if (!$options)
{
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('a.id AS value, a.title AS text');
$query->from('#__viewlevels AS a');
if (!$createlist)
{
$query->where('a.id="'.$selected.'"');
}
$query->group('a.id');
$query->order('a.ordering ASC');
$query->order('`title` ASC');
// Get the options.
$options = $db->setQuery($query)->loadObjectList('value');
// Return ACCESS LEVEL NAME
if (!$createlist)
{
$_option = reset($options);
return $_option->text;
}
// If params is an array, push these options to the array
if (is_array($extra_options))
{
$options = array_merge($extra_options, $options);
}
// If all levels is allowed, push it into the array.
elseif ($extra_options)
{
//array_unshift($options, JHtml::_('select.option', '', JText::_('JOPTION_ACCESS_SHOW_ALL_LEVELS')));
}
}
$ops = $options;
$selected_arr = is_array($selected) ? $selected : array($selected);
foreach($selected_arr as $sel)
{
if ( !isset($ops[$sel]) ) $ops[] = (object) array('value'=>$sel, 'text'=>$sel);
}
return JHtml::_('select.genericlist', $ops, $name,
array(
'list.attr' => $attribs,
'list.select' => $selected,
'id' => $id
)
);
}
/*
* Method to create a Tabset for given label-html arrays
* param string $date
* return boolean true if valid date, false otherwise
*/
static function createFieldTabber( &$field_html, &$field_tab_labels, $class )
{
$not_in_tabs = "";
$output = "<!-- tabber start --><div class='fctabber ".$class."'>"."\n";
foreach ($field_html as $i => $html) {
// Hide field when it has no label, and skip creating tab
$no_label = ! isset( $field_tab_labels[$i] );
$not_in_tabs .= $no_label ? "<div style='display:none!important'>".$field_html[$i]."</div>" : "";
if ( $no_label ) continue;
$output .= " <div class='tabbertab'>"."\n";
$output .= " <h3 class='tabberheading'>".$field_tab_labels[$i]."</h3>"."\n"; // Current TAB LABEL
$output .= " ".$not_in_tabs."\n"; // Output hidden fields (no tab created), by placing them inside the next appearing tab
$output .= " ".$field_html[$i]."\n"; // Current TAB CONTENTS
$output .= " </div>"."\n";
$not_in_tabs = ""; // Clear the hidden fields variable
}
$output .= "</div><!-- tabber end -->";
$output .= $not_in_tabs; // Output ENDING hidden fields, by placing them outside the tabbing area
return $output;
}
// * Create a spacer inside Joomla Toolbar
static function spacer($width = 32)
{
static $i = 0;
$btn_name = 'fc_toolbar_spacer_' . ($i++);
$toolbar = JToolbar::getInstance('toolbar');
$toolbar->appendButton('Custom', '<span style="width: ' . (int) $width. 'px; height: 1px; display: inline-block;"></span>', $btn_name);
}
// * Create a custom button inside Joomla Toolbar
static function addToolBarButton(
$text='Button Text', $btn_name='btnname', $full_js='', $err_msg='', $confirm_msg='', $task='btntask', $extra_js='',
$list=true, $menu=true, $confirm=true, $btn_class="", $btn_icon="", $attrs='', $auto_add = true, $tag_type='a',
$tbname = 'toolbar'
)
{
$toolbar = JToolbar::getInstance($tbname);
$text = JText::_($text);
$class = $btn_icon ? $btn_icon : 'icon-32-'.$btn_name;
$btn_sm_class = FLEXI_J40GE ? 'btn btn-sm' : 'btn btn-small';
if ( !$full_js )
{
$err_msg = $err_msg ? $err_msg : JText::sprintf('FLEXI_SELECT_LIST_ITEMS_TO', $btn_name);
$err_msg = flexicontent_html::escapeJsText(strip_tags($err_msg), "d");
$confirm_msg = $confirm_msg ? $confirm_msg : JText::_('FLEXI_ARE_YOU_SURE');
$confirm_msg = flexicontent_html::escapeJsText(strip_tags($confirm_msg), "d");
$full_js = $extra_js ."; Joomla.submitbutton('$task');";
if ($confirm)
{
$full_js = "if (confirm('".$confirm_msg."')) { ".$full_js." }";
}
if (!$menu)
{
$full_js = "hideMainMenu(); " . $full_js;
}
}
if ($list)
{
$full_js = "if (document.adminForm.boxchecked.value==0) { alert('".$err_msg."') ;} else { ".$full_js." }";
}
$full_js = "javascript: $full_js";
$button_html = '
<'.$tag_type.' '.($tag_type=='a' ? 'href="javascript:;"' : '').'
onclick="'.htmlspecialchars($full_js, ENT_QUOTES, 'UTF-8').'"
class="toolbar ' . $btn_sm_class . ' ' . $btn_class . '"
' . $attrs . '
>
<span class="'.$class.'" title="'.htmlspecialchars($text, ENT_QUOTES, 'UTF-8').'"></span>
'.$text.'
</'.$tag_type.'>';
if (!$auto_add)
{
return $button_html;
}
$toolbar->appendButton('Custom', $button_html, $btn_name);
}
// * Create a drop down button menu inside Joomla Toolbar
static function addToolBarDropMenu($btn_arr, $btn_group_name, $drop_btn = null, $ops = array(), $tbname = 'toolbar')
{
JHtml::_('bootstrap.dropdown');
$toolbar = JToolbar::getInstance($tbname);
static $btngroup_id = 0;
$btngroup_id++;
if (count($btn_arr) < 2 || !empty($ops['add_inline']))
{
if (count($btn_arr) === 1 || !empty($ops['add_inline']))
{
foreach ($btn_arr as $btn_name => $btn_html)
{
$btn_html = str_replace('_DDI_class_', '', $btn_html);
$toolbar->appendButton('Custom', $btn_html, $btn_name);
}
}
return;
}
if (!empty($ops['drop_class_full']))
{
$drop_btn_class = $ops['drop_class_full'];
}
else
{
$drop_btn_class =
(FLEXI_J40GE
? 'btn btn-sm toolbar dropdown-toggle dropdown-toggle-split'
: 'btn btn-small toolbar dropdown-toggle'
) .
(!empty($ops['drop_class_extra'])
? ' ' . $ops['drop_class_extra']
: ''
);
}
if ($drop_btn)
{
$drop_btn = str_replace('<button ', '<button id="btngroup_id_' . $btngroup_id . '" ', $drop_btn);
}
$buttons_html = '
<div class="buttons btn-group' . (FLEXI_J40GE ? ' dropdown' : '') . '">
'.array_shift($btn_arr).'
'.($drop_btn ?: '
<button class="' . $drop_btn_class . '"
' . (FLEXI_J40GE ? ' data-bs-toggle="dropdown" ' : ' data-toggle="dropdown" ') .'
id="btngroup_id_' . $btngroup_id . '" aria-expanded="false"
>
<span class="caret"></span>
</button>').'
<ul class="dropdown-menu dropdown-menu-right" role="menu" aria-labelledby="btngroup_id_' . $btngroup_id . '">
<li>' . implode("</li>\n<li>", $btn_arr) . '</li>
</ul>
</div>';
// Add drop-down class to the items
$buttons_html = str_replace('_DDI_class_', 'dropdown-item', $buttons_html);
$toolbar->appendButton(
'Custom',
$buttons_html,
$btn_group_name
);
}
// ************************************************************************
// Calculate CSS classes needed to add special styling markups to the items
// ************************************************************************
static function calculateItemMarkups($items, $params)
{
global $globalcats;
global $globalnoroute;
$globalnoroute = !is_array($globalnoroute) ? array() : $globalnoroute;
$db = JFactory::getDbo();
$user = JFactory::getUser();
$aids = JAccess::getAuthorisedViewLevels($user->id);
// **************************************
// Get configuration about markups to add
// **************************************
// Get addcss parameters
$mu_addcss_cats = $params->get('mu_addcss_cats', array('featured'));
$mu_addcss_cats = FLEXIUtilities::paramToArray($mu_addcss_cats);
$mu_addcss_acclvl = $params->get('mu_addcss_acclvl', array('needed_acc', 'obtained_acc'));
$mu_addcss_acclvl = FLEXIUtilities::paramToArray($mu_addcss_acclvl);
$mu_addcss_radded = $params->get('mu_addcss_radded', 0);
$mu_addcss_rupdated = $params->get('mu_addcss_rupdated', 0);
// Calculate addcss flags
$add_featured_cats = in_array('featured', $mu_addcss_cats);
$add_other_cats = in_array('other', $mu_addcss_cats);
$add_no_acc = in_array('no_acc', $mu_addcss_acclvl);
$add_free_acc = in_array('free_acc', $mu_addcss_acclvl);
$add_needed_acc = in_array('needed_acc', $mu_addcss_acclvl);
$add_obtained_acc = in_array('obtained_acc', $mu_addcss_acclvl);
// Get addtext parameters
$mu_addtext_cats = $params->get('mu_addtext_cats', 1);
$mu_addtext_acclvl = $params->get('mu_addtext_acclvl', array('no_acc', 'free_acc', 'needed_acc', 'obtained_acc'));
$mu_addtext_acclvl = FLEXIUtilities::paramToArray($mu_addtext_acclvl);
$mu_addtext_radded = $params->get('mu_addtext_radded', 1);
$mu_addtext_rupdated = $params->get('mu_addtext_rupdated', 1);
// Calculate addtext flags
$add_txt_no_acc = in_array('no_acc', $mu_addtext_acclvl);
$add_txt_free_acc = in_array('free_acc', $mu_addtext_acclvl);
$add_txt_needed_acc = in_array('needed_acc', $mu_addtext_acclvl);
$add_txt_obtained_acc = in_array('obtained_acc', $mu_addtext_acclvl);
$mu_add_condition_obtainded_acc = $params->get('mu_add_condition_obtainded_acc', 1);
$mu_no_acc_text = JText::_( $params->get('mu_no_acc_text', 'FLEXI_MU_NO_ACC') );
$mu_free_acc_text = JText::_( $params->get('mu_free_acc_text', 'FLEXI_MU_NO_ACC') );
// *******************************
// Prepare data needed for markups
// *******************************
// a. Get Featured categories and language filter their titles
$featured_cats_parent = $params->get('featured_cats_parent', 0);
$disabled_cats = $params->get('featured_cats_parent_disable', 1) ? array($featured_cats_parent) : array();
$featured_cats = array();
if ( $add_featured_cats && $featured_cats_parent )
{
$where[] = isset($globalcats[$featured_cats_parent]) ?
'id IN (' . $globalcats[$featured_cats_parent]->descendants . ')' :
'parent_id = '. $featured_cats_parent
;
if (!empty($disabled_cats)) $where[] = 'id NOT IN (' . implode(", ", $disabled_cats) . ')'; // optionally exclude category root of featured subtree
$query = 'SELECT c.id'
. ' FROM #__categories AS c'
. (count($where) ? ' WHERE ' . implode( ' AND ', $where ) : '')
;
$db->setQuery($query);
$featured_cats = $db->loadColumn();
$featured_cats = $featured_cats ? array_flip($featured_cats) : array();
foreach ($featured_cats as $featured_cat => $i)
{
$featured_cats_titles[$featured_cat] = JText::_($globalcats[$featured_cat]->title);
}
}
// b. Get Access Level names (language filter them)
if ( $add_needed_acc || $add_obtained_acc )
{
$access_names = flexicontent_db::getAccessNames();
}
// c. Calculate creation time intervals
if ( $mu_addcss_radded )
{
$nowdate_secs = time();
$ra_timeframes = trim($params->get('mu_ra_timeframe_intervals', '24h,2d,7d,1m,3m,1y,3y'));
$ra_timeframes = preg_split("/\s*,\s*/u", $ra_timeframes);
$ra_names = trim($params->get('mu_ra_timeframe_names', 'FLEXI_24H_RA , FLEXI_2D_RA , FLEXI_7D_RA , FLEXI_1M_RA , FLEXI_3M_RA , FLEXI_1Y_RA , FLEXI_3Y_RA'));
$ra_names = preg_split("/\s*,\s*/u", $ra_names);
$unit_hour_map = array('h'=>1, 'd'=>24, 'm'=>24*30, 'y'=>24*365);
$unit_word_map = array('h'=>'hours', 'd'=>'days', 'm'=>'months', 'y'=>'years');
$unit_text_map = array(
'h'=>'FLEXI_MU_HOURS', 'd'=>'FLEXI_MU_DAYS', 'm'=>'FLEXI_MU_MONTHS', 'y'=>'FLEXI_MU_YEARS'
);
foreach($ra_timeframes as $i => $timeframe) {
$unit = substr($timeframe, -1);
if ( !isset($unit_hour_map[$unit]) ) {
echo "Improper timeframe ': ".$timeframe."' for recently added content, please fix in configuration";
continue;
}
$timeframe = (int) $timeframe;
$ra_css_classes[$i] = '_item_added_within_' . $timeframe . $unit_word_map[$unit];
$ra_timeframe_secs[$i] = $timeframe * $unit_hour_map[$unit] * 3600;
$ra_timeframe_text[$i] = @ $ra_names[$i] ? JText::_($ra_names[$i]) : JText::_('FLEXI_MU_ADDED') . JText::sprintf($unit_text_map[$unit], $timeframe);
}
}
// d. Calculate updated time intervals
if ( $mu_addcss_rupdated )
{
$nowdate_secs = time();
$ru_timeframes = trim($params->get('mu_ru_timeframe_intervals', '24h,2d,7d,1m,3m,1y,3y'));
$ru_timeframes = preg_split("/\s*,\s*/u", $ru_timeframes);
$ru_names = trim($params->get('mu_ru_timeframe_names', 'FLEXI_24H_RU , FLEXI_2D_RU , FLEXI_7D_RU , FLEXI_1M_RU , FLEXI_3M_RU , FLEXI_1Y_RU , FLEXI_3Y_RU'));
$ru_names = preg_split("/\s*,\s*/u", $ru_names);
$unit_hour_map = array('h'=>1, 'd'=>24, 'm'=>24*30, 'y'=>24*365);
$unit_word_map = array('h'=>'hours', 'd'=>'days', 'm'=>'months', 'y'=>'years');
$unit_text_map = array(
'h'=>'FLEXI_MU_HOURS', 'd'=>'FLEXI_MU_DAYS', 'm'=>'FLEXI_MU_MONTHS', 'y'=>'FLEXI_MU_YEARS'
);
foreach($ru_timeframes as $i => $timeframe) {
$unit = substr($timeframe, -1);
if ( !isset($unit_hour_map[$unit]) ) {
echo "Improper timeframe ': ".$timeframe."' for recently updated content, please fix in configuration";
continue;
}
$timeframe = (int) $timeframe;
$ru_css_classes[$i] = '_item_updated_within_' . $timeframe . $unit_word_map[$unit];
$ru_timeframe_secs[$i] = $timeframe * $unit_hour_map[$unit] * 3600;
$ru_timeframe_text[$i] = @ $ru_names[$i] ? JText::_($ru_names[$i]) : JText::_('FLEXI_MU_UPDATED') . JText::sprintf($unit_text_map[$unit], $timeframe);
}
}
// **********************************
// Create CSS markup classes per item
// **********************************
$public_acclvl = 1;
foreach ($items as $item)
{
$item->css_markups = array();
//$item->categories = isset($item->categories) ? $item->categories : array();
// Category markups
if ( $add_featured_cats || $add_other_cats ) foreach ($item->categories as $item_cat) {
$is_featured_cat = isset( $featured_cats[$item_cat->id] );
if ( $is_featured_cat && !$add_featured_cats ) continue; // not adding featured cats
if ( !$is_featured_cat && !$add_other_cats ) continue; // not adding other cats
if ( in_array($item_cat->id, $globalnoroute) ) continue; // non-linkable/routable 'special' category
$item->css_markups['itemcats'][] = '_itemcat_'.$item_cat->id;
$item->ecss_markups['itemcats'][] = ($is_featured_cat ? ' mu_featured_cat' : ' mu_normal_cat') . ($mu_addtext_cats ? ' mu_has_text' : '');
$item->title_markups['itemcats'][] = $mu_addtext_cats ? ($is_featured_cat ? $featured_cats_titles[$item_cat->id] : (isset($globalcats[$item_cat->id]) ? $globalcats[$item_cat->id]->title : '')) : '';
}
// recently-added Timeframe markups
if ($mu_addcss_radded) {
$item_timeframe_secs = $nowdate_secs - strtotime($item->created);
$mr = -1;
foreach($ra_timeframe_secs as $i => $timeframe_secs) {
// Check if item creation time has surpassed this time frame
if ( $item_timeframe_secs > $timeframe_secs) continue;
// Check if this time frame is more recent than the best one found so far
if ($mr != -1 && $timeframe_secs > $ra_timeframe_secs[$mr]) continue;
// Use current time frame
$mr = $i;
}
if ($mr >= 0) {
$item->css_markups['timeframe'][] = $ra_css_classes[$mr];
$item->ecss_markups['timeframe'][] = ' mu_ra_timeframe' . ($mu_addtext_radded ? ' mu_has_text' : '');
$item->title_markups['timeframe'][] = $mu_addtext_radded ? $ra_timeframe_text[$mr] : '';
}
}
// recently-updated Timeframe markups
if ($mu_addcss_rupdated) {
$item_timeframe_secs = $nowdate_secs - strtotime($item->modified);
$mr = -1;
foreach($ru_timeframe_secs as $i => $timeframe_secs) {
// Check if item creation time has surpassed this time frame
if ( $item_timeframe_secs > $timeframe_secs) continue;
// Check if this time frame is more recent than the best one found so far
if ($mr != -1 && $timeframe_secs > $ru_timeframe_secs[$mr]) continue;
// Use current time frame
$mr = $i;
}
if ($mr >= 0) {
$item->css_markups['timeframe'][] = $ru_css_classes[$mr];
$item->ecss_markups['timeframe'][] = ' mu_ru_timeframe' . ($mu_addtext_rupdated ? ' mu_has_text' : '');
$item->title_markups['timeframe'][] = $mu_addtext_rupdated ? $ru_timeframe_text[$mr] : '';
}
}
// Get item's access levels if this is needed
if ($add_free_acc || $add_needed_acc || $add_obtained_acc) {
$all_acc_lvls = array();
$all_acc_lvls[] = $item->access;
$all_acc_lvls[] = $item->category_access;
$all_acc_lvls[] = $item->type_access;
$all_acc_lvls = array_unique($all_acc_lvls);
}
// No access markup
if ($add_no_acc && !$item->has_access) {
$item->css_markups['access'][] = '_item_no_access';
$item->ecss_markups['access'][] = ($add_txt_no_acc ? ' mu_has_text' : '');
$item->title_markups['access'][] = $add_txt_no_acc ? $mu_no_acc_text : '';
}
// Free access markup, Add ONLY if item has a single access level the public one ...
if ( $add_free_acc && $item->has_access && count($all_acc_lvls)==1 && $public_acclvl == reset($all_acc_lvls) )
{
$item->css_markups['access'][] = '_item_free_access';
$item->ecss_markups['access'][] = $add_txt_free_acc ? ' mu_has_text' : '';
$item->title_markups['access'][] = $add_txt_free_acc ? $mu_free_acc_text : '';
}
// Needed / Obtained access levels markups
if ($add_needed_acc || $add_obtained_acc)
{
foreach($all_acc_lvls as $all_acc_lvl)
{
if ($public_acclvl == $all_acc_lvl) continue; // handled separately above
$has_acclvl = in_array($all_acc_lvl, $aids);
if (!$has_acclvl) {
if (!$add_needed_acc) continue; // not adding needed levels
$item->css_markups['access'][] = '_acclvl_'.$all_acc_lvl;
$item->ecss_markups['access'][] = ' mu_needed_acclvl' . ($add_txt_needed_acc ? ' mu_has_text' : '');
$item->title_markups['access'][] = $add_txt_needed_acc ? $access_names[$all_acc_lvl] : '';
} else {
if (!$add_obtained_acc) continue; // not adding obtained levels
if ($mu_add_condition_obtainded_acc==0 && !$item->has_access) continue; // do not add obtained level markups if item is inaccessible
$item->css_markups['access'][] = '_acclvl_'.$all_acc_lvl;
$item->ecss_markups['access'][] = ' mu_obtained_acclvl' . ($add_txt_obtained_acc ? ' mu_has_text' : '');
$item->title_markups['access'][] = $add_txt_obtained_acc ? $access_names[$all_acc_lvl] : '';
}
}
}
}
}
static function createCatLink($slug, &$non_sef_link, $catmodel=null)
{
$menus = JFactory::getApplication()->getMenu();
$menu = $menus->getActive();
$Itemid = $menu ? $menu->id : 0;
// Get URL variables
$urlvars = flexicontent_html::getCatViewLayoutVars($catmodel, $use_slug = true);
// Category link for single/multiple category(-ies) --OR-- "current layout" link for myitems/author/favs/tags layouts
$non_sef_link = FlexicontentHelperRoute::getCategoryRoute($slug, $Itemid, $urlvars);
$category_link = JRoute::_($non_sef_link);
return $category_link;
}
static function getCatViewLayoutVars($obj=null, $use_slug = false)
{
static $_layout_vars = array();
if (isset($_layout_vars[$use_slug]))
{
return $_layout_vars[$use_slug];
}
// Get URL variables
$app = JFactory::getApplication();
$layout_vars = array();
$layout_vars['layout'] = $obj && isset($obj->_layout) ? $obj->_layout : $app->input->get('layout', '', 'CMD');
if (!$use_slug)
{
$layout_vars['cid'] = $obj && isset($obj->_id) ? $obj->_id : $app->input->get('cid', 0, 'INT');
$layout_vars['authorid'] = $obj && isset($obj->_authorid) ? $obj->_authorid : $app->input->get('authorid', 0, 'INT');
$layout_vars['tagid'] = $obj && isset($obj->_tagid) ? $obj->_tagid : $app->input->get('tagid', 0, 'INT');
}
else
{
$layout_vars['cid'] = $obj && isset($obj->_id) ? $obj->_id : $app->input->get('cid', 0, 'STRING');
$layout_vars['authorid'] = $obj && isset($obj->_authorid_slug) ? $obj->_authorid_slug : $app->input->get('authorid', 0, 'STRING');
$layout_vars['tagid'] = $obj && isset($obj->_tagid_slug) ? $obj->_tagid_slug : $app->input->get('tagid', 0, 'STRING');
}
if ($obj && isset($obj->_ids))
{
$layout_vars['cids'] = !is_array($obj->_ids)
? $obj->_ids
: implode(',' , $obj->_ids);
}
else
{
$cids = $app->input->get('cids', array(), 'array');
if (!is_array($cids))
{
$cids = preg_replace( '/[^0-9,]/i', '', (string) $cids );
$cids = explode(',', $cids);
}
$cids = ArrayHelper::toInteger($cids);
$layout_vars['cids'] = implode(',' , $cids);
}
$_layout_vars[$use_slug] = $layout_vars;
return $layout_vars;
}
static function getCatViewFilterVars($obj=null)
{
$app = JFactory::getApplication();
$jinput = $app->input;
$filters_count = 0;
$filters_string = '';
foreach($jinput->get->get->getArray() as $i => $v)
{
if (substr($i, 0, 6) !== "filter")
{
continue;
}
if (is_array($v))
{
foreach($v as $ii => &$vv)
{
if (is_array($vv))
{
foreach($vv as $iii => &$vvv)
{
$filters_string .= '&' . $i . '[' . $ii . '][' . $iii . ']=' . $vvv;
}
}
else
{
$filters_string .= '&' . $i . '[' . $ii . ']=' . $vv;
}
}
}
else
{
$filters_string .= '&' . $i . '=' . $v;
}
$filters_count++;
}
return $filters_string;
}
// Get Prefix - Suffix - Separator parameters and other common parameters
static function getDateFieldDisplay($field_parameters, $date = '', $pfx = '')
{
// Some variables
$config = JFactory::getConfig();
$user = JFactory::getUser();
// Timezone configuration
$date_allowtime = $field_parameters->get( $pfx.'date_allowtime', 1 ) ;
$use_editor_tz = $field_parameters->get( $pfx.'use_editor_tz', 0 ) ;
$use_editor_tz = $date_allowtime ? $use_editor_tz : 0; // Timezone IS disabled, if time usage is disabled
$customdate = $field_parameters->get( $pfx.'custom_date', 'DATE_FORMAT_LC2' ) ;
$dateformat = $field_parameters->get( $pfx.'date_format', '' ) ;
$dateformat = $dateformat && $dateformat != '_custom_' ? JText::_($dateformat) :
($field_parameters->get( $pfx.'lang_filter_format', 0) ? JText::_($customdate) : $customdate);
$display_tz_logged = $field_parameters->get( $pfx.'display_tz_logged', 2) ;
$display_tz_guests = $field_parameters->get( $pfx.'display_tz_guests', 2) ;
$display_tz_suffix = $field_parameters->get( $pfx.'display_tz_suffix', 1) ;
// Get timezone to use for displaying the date, this is a string for J2.5 and an (offset) number for J1.5
if ($user->id) {
$tz_suffix_type = $display_tz_logged;
} else {
$tz_suffix_type = $display_tz_guests;
}
// Decide the timezone to use
$tz_info = '';
switch ($tz_suffix_type)
{
default: // including value -1 for raw for output, see above
case 0:
$timezone = 'UTC';
break;
case 1:
$timezone = 'UTC'; // ' UTC+0'
break;
case 2:
$timezone = $config->get('offset'); // Site's timezone
break;
case 3:
$timezone = $user->getParam('timezone' ); // User's local time
break;
}
// Display timezone suffix if this is enabled
if ($display_tz_suffix && $tz_suffix_type > 0)
{
$tz = new DateTimeZone($timezone);
$tz_offset = $tz->getOffset(new JDate()) / 3600;
$tz_info = $tz_offset > 0 ? ' UTC +'.$tz_offset : ' UTC '.$tz_offset;
}
// Return date
try {
return JHtml::_('date', $date, $dateformat, $timezone ) . $tz_info;
} catch ( Exception $e ) {
return '';
}
}
// Get site template full, or name only
public static function getSiteTemplate($full_path = false)
{
static $site_template, $site_template_full_path;
if ($site_template === null)
{
// This does not work in backend because JPATH_THEMES is set to backend folder and folder exists check fails ...
//$site_template = CMSApplication::getInstance('site')->getTemplate();
$app = JFactory::getApplication();
$db = JFactory::getDbo();
$site_template = $app->isClient('site')
? $app->getTemplate()
: $db->setQuery('SELECT template FROM #__template_styles WHERE client_id = 0 AND home = 1')->loadResult();
$site_template_full_path = JPath::clean(JPATH_SITE . '/templates/' . $site_template);
}
return $full_path ? $site_template_full_path : $site_template;
}
// Get SEF url regardless of being in backend / frontend
public static function getSefUrl($url, $xhtml = true, $ssl = null)
{
static $site_router, $site_instance, $isAdmin, $isSH404SEF, $useSiteApp;
/**
* J4 case
*/
if (FLEXI_J40GE)
{
// This also works in J4
// return $url = JRoute::link('site', $url);
$router = Router::getInstance('site'); // ALTERNATIVE: CMSApplication::getInstance('site')->getRouter('site');
$url = $router->build($url);
$url = $url->toString();
return $url;
}
/**
* J3 case
*/
// Get frontend route instance if we are in the backend and SH404SEF is not installed
if ($site_router === null)
{
$isAdmin = JFactory::getApplication()->isClient('administrator');
$isSH404SEF = defined('SH404SEF_IS_RUNNING') && JFactory::getConfig()->get('sef');
$useSiteApp = $isAdmin; // && $isSH404SEF;
$site_instance = $useSiteApp
? JApplication::getInstance('site') // In J4 use CMSApplication::getInstance('site')
: JFactory::getApplication();
$site_router = $site_instance->getRouter('site');
}
if (!is_array($url) && (strpos($url, '&') !== 0) && (strpos($url, 'index.php') !== 0))
{
return $url;
}
// Build route
$uri = $site_router->build($url);
$scheme = array('path', 'query', 'fragment');
/*
* Get the secure/unsecure URLs.
*
* If the first 5 characters of the BASE are 'https', then we are on an ssl connection over
* https and need to set our secure URL to the current request URL, if not, and the scheme is
* 'http', then we need to do a quick string manipulation to switch schemes.
*/
if ((int) $ssl || $uri->isSsl())
{
static $host_port;
if (!is_array($host_port))
{
$uri2 = JUri::getInstance();
$host_port = array($uri2->getHost(), $uri2->getPort());
}
// Determine which scheme we want.
$uri->setScheme(((int) $ssl === 1 || $uri->isSsl()) ? 'https' : 'http');
$uri->setHost($host_port[0]);
$uri->setPort($host_port[1]);
$scheme = array_merge($scheme, array('host', 'port', 'scheme'));
}
$url = $uri->toString($scheme);
// Replace spaces.
$url = preg_replace('/\s/u', '%20', $url);
if ($xhtml)
{
$url = htmlspecialchars($url, ENT_COMPAT, 'UTF-8');
}
/**
* Needed in older Joomla versions like J3.7 (and maybe for J3.8, J3.9). Check if we are in the backend again
* and remove '/administrator' from URL as it is added even though we've set the application to the site app
*/
if ($useSiteApp)
{
$url = str_replace(JUri::base(true), JUri::root(true), $url);
}
return $url;
}
// Check and if needed install Joomla template overrides into current Joomla template
public static function install_template_overrides($display_mssg = false)
{
jimport('joomla.filesystem.path' );
jimport('joomla.filesystem.folder');
jimport('joomla.filesystem.file');
$app = JFactory::getApplication();
$pathDestFolder_arr = array(
JPath::clean(JPATH_BASE.'/templates/'.$app->getTemplate().'/html/com_media/images/'),
JPath::clean(JPATH_BASE.'/templates/'.$app->getTemplate().'/html/com_media/imageslist/')
);
$pathSourceFolder_arr = array(
JPath::clean(JPATH_ROOT.'/components/com_flexicontent/layouts/html/com_media/images'),
JPath::clean(JPATH_ROOT.'/components/com_flexicontent/layouts/html/com_media/imageslist')
);
$install_count = $update_count = 0;
foreach($pathDestFolder_arr as $i => $pathDestFolder)
{
$pathSourceFolder = $pathSourceFolder_arr[$i];
// 1. Check DESTINATION folder
if ( !JFolder::exists($pathDestFolder) && !JFolder::create($pathDestFolder) )
{
echo '<span class="alert alert-warning"> Error, unable to create folder: '. $pathDestFolder.'</span>';
}
// 2. Copy override files
$files = glob($pathSourceFolder . '/*.*');
foreach($files as $sourcepath)
{
$dest_path = $pathDestFolder . basename($sourcepath);
$not_exists = !JFile::exists($dest_path);
if ($not_exists || filemtime($sourcepath) > filemtime($dest_path))
{
$not_exists ? $install_count++ : $update_count++;
copy($sourcepath, $dest_path);
}
}
}
if ($display_mssg)
{
if ($install_count)
{
JFactory::getApplication()->enqueueMessage('<span class="badge">' . JText::_('FLEXI_INSTALLED') . '</span> ' . $install_count . ' template overrides', 'message');
}
if ($display_mssg && $update_count)
{
JFactory::getApplication()->enqueueMessage('<span class="badge">' . JText::_('FLEXI_UPDATED') . '</span> ' . $update_count . ' template overrides', 'message');
}
}
}
/**
* Method to diplay field showing inherited value
*
* @access private
* @return void
* @since 1.5
*/
public static function getInheritedFieldDisplay($field, $params, $_v = null)
{
$_v = $params ? $params->get($field->fieldname) : $_v;
if ($_v === '' || $_v === null)
{
return $field->input;
}
elseif ($field->getAttribute('type')==='fcordering' || $field->getAttribute('type')==='list' || ($field->getAttribute('type')==='multilist' && $field->getAttribute('subtype')==='list'))
{
$_v = htmlspecialchars( $_v, ENT_COMPAT, 'UTF-8' );
if (preg_match('/<option\s*value="' . preg_quote($_v, '/') . '"\s*>(.*?)<\/option>/', $field->input, $matches))
{
return str_replace(
JText::_('FLEXI_USE_GLOBAL'),
JText::_('FLEXI_USE_GLOBAL') . ' (' . $matches[1] . ')',
$field->input);
}
}
elseif ($field->getAttribute('type')==='radio' || $field->getAttribute('type')==='fcradio' || ($field->getAttribute('type')==='multilist' && $field->getAttribute('subtype')==='radio'))
{
$_v = htmlspecialchars( $_v, ENT_COMPAT, 'UTF-8' );
$has_btn_check = strpos($field->input, 'btn-check') !== 0;
return str_replace(
'value="'.$_v.'"',
'value="'.$_v.'" class="fc-inherited-value' . ($has_btn_check ? ' btn-check' : '') . '" ',
$field->input);
}
elseif ($field->getAttribute('type')==='fccheckbox' && is_array($_v))
{
$_input = $field->input;
foreach ($_v as $v)
{
$v = htmlspecialchars( $v, ENT_COMPAT, 'UTF-8' );
$_input = str_replace(
'value="'.$v.'"',
'value="'.$v.'" class="fc-inherited-value" ',
$_input);
}
return $_input;
}
elseif ($field->getAttribute('type')==='text' || $field->getAttribute('type')==='fcmedia' || $field->getAttribute('type')==='media')
{
$_v = htmlspecialchars( preg_replace('/[\n\r]/', ' ', $_v), ENT_COMPAT, 'UTF-8' );
return str_replace(
'<input ',
'<input placeholder="'.$_v.'" ',
preg_replace('/^(\s*<input\s[^>]+)placeholder="[^"]+"/i', '\1 ', $field->input)
);
}
elseif ($field->getAttribute('type')==='textarea')
{
$_v = htmlspecialchars(preg_replace('/[\n\r]/', ' ', $_v), ENT_COMPAT, 'UTF-8' );
return str_replace(
'<textarea ',
'<textarea placeholder="'.$_v.'" ',
preg_replace('/^(\s*<textarea\s[^>]+)placeholder="[^"]+"/i', '\1 ', $field->input)
);
}
elseif ( method_exists($field, 'setInherited') )
{
$field->setInherited($_v);
return $field->input;
}
return $field->input;
}
}