Server : LiteSpeed System : Linux server 3.10.0-1160.90.1.el7.x86_64 #1 SMP Thu May 4 15:21:22 UTC 2023 x86_64 User : alsaif ( 1057) PHP Version : 7.4.33 Disable Function : show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/alsaif/domains/alsaif.group/public_html/plugins/editors/tinymce/ |
<?php
/**
* @package Joomla.Plugin
* @subpackage Editors.tinymce
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\HTML\HTMLHelper;
/**
* TinyMCE Editor Plugin
*
* @since 1.5
*/
class PlgEditorTinymce extends JPlugin
{
/**
* Base path for editor files
*
* @since 3.5
*/
protected $_basePath = 'media/editors/tinymce';
/**
* Load the language file on instantiation.
*
* @var boolean
* @since 3.1
*/
protected $autoloadLanguage = true;
/**
* Loads the application object
*
* @var JApplicationCms
* @since 3.2
*/
protected $app = null;
/**
* Initialises the Editor.
*
* @return void
*
* @since 1.5
*/
public function onInit()
{
JHtml::_('behavior.core');
JHtml::_('behavior.polyfill', array('event'), 'lt IE 9');
JHtml::_('script', $this->_basePath . '/tinymce.min.js', array('version' => 'auto'));
JHtml::_('script', 'editors/tinymce/tinymce.min.js', array('version' => 'auto', 'relative' => true));
}
/**
* TinyMCE WYSIWYG Editor - get the editor content
*
* @param string $id The name of the editor
*
* @since 1.5
*
* @return string
*
* @deprecated 4.0 Use directly the returned code
*/
public function onGetContent($id)
{
return 'Joomla.editors.instances[' . json_encode($id) . '].getValue();';
}
/**
* TinyMCE WYSIWYG Editor - set the editor content
*
* @param string $id The name of the editor
* @param string $html The html to place in the editor
*
* @since 1.5
*
* @return string
*
* @deprecated 4.0 Use directly the returned code
*/
public function onSetContent($id, $html)
{
return 'Joomla.editors.instances[' . json_encode($id) . '].setValue(' . json_encode($html) . ');';
}
/**
* TinyMCE WYSIWYG Editor - copy editor content to form field
*
* @param string $id The name of the editor
*
* @since 1.5
*
* @return void
*
* @deprecated 4.0 Use directly the returned code
*/
public function onSave($id)
{
}
/**
* Inserts html code into the editor
*
* @param string $name The name of the editor
*
* @since 1.5
*
* @return string
*
* @deprecated 3.5 tinyMCE (API v4) will get the content automatically from the text area
*/
public function onGetInsertMethod($name)
{
}
/**
* Display the editor area.
*
* @param string $name The name of the editor area.
* @param string $content The content of the field.
* @param string $width The width of the editor area.
* @param string $height The height of the editor area.
* @param int $col The number of columns for the editor area.
* @param int $row The number of rows for the editor area.
* @param boolean $buttons True and the editor buttons will be displayed.
* @param string $id An optional ID for the textarea. If not supplied the name is used.
* @param string $asset The object asset
* @param object $author The author.
* @param array $params Associative array of editor parameters.
*
* @return string
*/
public function onDisplay(
$name, $content, $width, $height, $col, $row, $buttons = true, $id = null, $asset = null, $author = null, $params = array())
{
$app = JFactory::getApplication();
// Check for old params for B/C
$config_warn_count = $app->getUserState('plg_editors_tinymce.config_legacy_warn_count', 0);
if ($this->params->exists('mode') && $this->params->exists('alignment'))
{
if ($app->isClient('administrator') && $config_warn_count < 2)
{
$link = JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . $this->getPluginId());
$app->enqueueMessage(JText::sprintf('PLG_TINY_LEGACY_WARNING', $link), 'warning');
$app->setUserState('plg_editors_tinymce.config_legacy_warn_count', ++$config_warn_count);
}
return $this->onDisplayLegacy($name, $content, $width, $height, $col, $row, $buttons, $id, $asset, $author, $params);
}
if (empty($id))
{
$id = $name;
}
$id = preg_replace('/(\s|[^A-Za-z0-9_])+/', '_', $id);
$nameGroup = explode('[', preg_replace('/\[\]|\]/', '', $name));
$fieldName = end($nameGroup);
$scriptOptions = array();
// Check for existing options
$doc = JFactory::getDocument();
$options = $doc->getScriptOptions('plg_editor_tinymce');
// Only add "px" to width and height if they are not given as a percentage
if (is_numeric($width))
{
$width .= 'px';
}
if (is_numeric($height))
{
$height .= 'px';
}
// Data object for the layout
$textarea = new stdClass;
$textarea->name = $name;
$textarea->id = $id;
$textarea->class = 'mce_editable joomla-editor-tinymce';
$textarea->cols = $col;
$textarea->rows = $row;
$textarea->width = $width;
$textarea->height = $height;
$textarea->content = $content;
// Set editor to readonly mode
$textarea->readonly = !empty($params['readonly']);
// Render Editor markup
$editor = '<div class="js-editor-tinymce">';
$editor .= JLayoutHelper::render('joomla.tinymce.textarea', $textarea);
$editor .= $this->_toogleButton($id);
$editor .= '</div>';
// Prepare the instance specific options, actually the ext-buttons
if (empty($options['tinyMCE'][$fieldName]['joomlaExtButtons']))
{
$btns = $this->tinyButtons($id, $buttons);
if (!empty($btns['names']))
{
JHtml::_('script', 'editors/tinymce/tiny-close.min.js', array('version' => 'auto', 'relative' => true), array('defer' => 'defer'));
}
// Set editor to readonly mode
if (!empty($params['readonly']))
{
$options['tinyMCE'][$fieldName]['readonly'] = 1;
}
$options['tinyMCE'][$fieldName]['joomlaMergeDefaults'] = true;
$options['tinyMCE'][$fieldName]['joomlaExtButtons'] = $btns;
$doc->addScriptOptions('plg_editor_tinymce', $options, false);
}
// Setup Default (common) options for the Editor script
// Check whether we already have them
if (!empty($options['tinyMCE']['default']))
{
return $editor;
}
$user = JFactory::getUser();
$language = JFactory::getLanguage();
$theme = 'modern';
$ugroups = array_combine($user->getAuthorisedGroups(), $user->getAuthorisedGroups());
// Prepare the parameters
$levelParams = new Joomla\Registry\Registry;
$extraOptions = new stdClass;
$toolbarParams = new stdClass;
$extraOptionsAll = $this->params->get('configuration.setoptions', array());
$toolbarParamsAll = $this->params->get('configuration.toolbars', array());
// Get configuration depend from User group
foreach ($extraOptionsAll as $set => $val)
{
$val->access = empty($val->access) ? array() : $val->access;
// Check whether User in one of allowed group
foreach ($val->access as $group)
{
if (isset($ugroups[$group]))
{
$extraOptions = $val;
$toolbarParams = $toolbarParamsAll->$set;
}
}
}
// Merge the params
$levelParams->loadObject($toolbarParams);
$levelParams->loadObject($extraOptions);
// List the skins
$skindirs = glob(JPATH_ROOT . '/media/editors/tinymce/skins' . '/*', GLOB_ONLYDIR);
// Set the selected skin
$skin = 'lightgray';
$side = $app->isClient('administrator') ? 'skin_admin' : 'skin';
if ((int) $levelParams->get($side, 0) < count($skindirs))
{
$skin = basename($skindirs[(int) $levelParams->get($side, 0)]);
}
$langMode = $levelParams->get('lang_mode', 1);
$langPrefix = $levelParams->get('lang_code', 'en');
if ($langMode)
{
if (file_exists(JPATH_ROOT . '/media/editors/tinymce/langs/' . $language->getTag() . '.js'))
{
$langPrefix = $language->getTag();
}
elseif (file_exists(JPATH_ROOT . '/media/editors/tinymce/langs/' . substr($language->getTag(), 0, strpos($language->getTag(), '-')) . '.js'))
{
$langPrefix = substr($language->getTag(), 0, strpos($language->getTag(), '-'));
}
else
{
$langPrefix = 'en';
}
}
$text_direction = 'ltr';
if ($language->isRtl())
{
$text_direction = 'rtl';
}
$use_content_css = $levelParams->get('content_css', 1);
$content_css_custom = $levelParams->get('content_css_custom', '');
/*
* Lets get the default template for the site application
*/
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('template')
->from('#__template_styles')
->where('client_id=0 AND home=' . $db->quote('1'));
$db->setQuery($query);
try
{
$template = $db->loadResult();
}
catch (RuntimeException $e)
{
$app->enqueueMessage(JText::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error');
return '';
}
$content_css = null;
$templates_path = JPATH_SITE . '/templates';
// Loading of css file for 'styles' dropdown
if ($content_css_custom)
{
// If URL, just pass it to $content_css
if (strpos($content_css_custom, 'http') !== false)
{
$content_css = $content_css_custom;
}
// If it is not a URL, assume it is a file name in the current template folder
else
{
$content_css = JUri::root(true) . '/templates/' . $template . '/css/' . $content_css_custom;
// Issue warning notice if the file is not found (but pass name to $content_css anyway to avoid TinyMCE error
if (!file_exists($templates_path . '/' . $template . '/css/' . $content_css_custom))
{
$msg = sprintf(JText::_('PLG_TINY_ERR_CUSTOMCSSFILENOTPRESENT'), $content_css_custom);
JLog::add($msg, JLog::WARNING, 'jerror');
}
}
}
else
{
// Process when use_content_css is Yes and no custom file given
if ($use_content_css)
{
// First check templates folder for default template
// if no editor.css file in templates folder, check system template folder
if (!file_exists($templates_path . '/' . $template . '/css/editor.css'))
{
// If no editor.css file in system folder, show alert
if (!file_exists($templates_path . '/system/css/editor.css'))
{
JLog::add(JText::_('PLG_TINY_ERR_EDITORCSSFILENOTPRESENT'), JLog::WARNING, 'jerror');
}
else
{
$content_css = JUri::root(true) . '/templates/system/css/editor.css';
}
}
else
{
$content_css = JUri::root(true) . '/templates/' . $template . '/css/editor.css';
}
}
}
$ignore_filter = false;
// Text filtering
if ($levelParams->get('use_config_textfilters', 0))
{
// Use filters from com_config
$filter = static::getGlobalFilters();
$ignore_filter = $filter === false;
$tagBlacklist = !empty($filter->tagBlacklist) ? $filter->tagBlacklist : array();
$attrBlacklist = !empty($filter->attrBlacklist) ? $filter->attrBlacklist : array();
$tagArray = !empty($filter->tagArray) ? $filter->tagArray : array();
$attrArray = !empty($filter->attrArray) ? $filter->attrArray : array();
$invalid_elements = implode(',', array_merge($tagBlacklist, $attrBlacklist, $tagArray, $attrArray));
// Valid elements are all whitelist entries in com_config, which are now missing in the tagBlacklist
$default_filter = JFilterInput::getInstance();
$valid_elements = implode(',', array_diff($default_filter->tagBlacklist, $tagBlacklist));
$extended_elements = '';
}
else
{
// Use filters from TinyMCE params
$invalid_elements = trim($levelParams->get('invalid_elements', 'script,applet,iframe'));
$extended_elements = trim($levelParams->get('extended_elements', ''));
$valid_elements = trim($levelParams->get('valid_elements', ''));
}
$html_height = $this->params->get('html_height', '550');
$html_width = $this->params->get('html_width', '');
if ($html_width == 750)
{
$html_width = '';
}
// The param is true for vertical resizing only, false or both
$resizing = (bool) $levelParams->get('resizing', true);
$resize_horizontal = (bool) $levelParams->get('resize_horizontal', true);
if ($resizing && $resize_horizontal)
{
$resizing = 'both';
}
// Set of always available plugins
$plugins = array(
'autolink',
'lists',
'colorpicker',
'importcss',
);
// Allowed elements
$elements = array(
'hr[id|title|alt|class|width|size|noshade]',
);
if ($extended_elements)
{
$elements = array_merge($elements, explode(',', $extended_elements));
}
// Prepare the toolbar/menubar
$knownButtons = static::getKnownButtons();
// Check if there no value at all
if (!$levelParams->get('menu') && !$levelParams->get('toolbar1') && !$levelParams->get('toolbar2'))
{
// Get from preset
$presets = static::getToolbarPreset();
/*
* Predefine group as:
* Set 0: for Administrator, Editor, Super Users (4,7,8)
* Set 1: for Registered, Manager (2,6), all else are public
*/
switch (true)
{
case isset($ugroups[4]) || isset($ugroups[7]) || isset($ugroups[8]):
$preset = $presets['advanced'];
break;
case isset($ugroups[2]) || isset($ugroups[6]):
$preset = $presets['medium'];
break;
default:
$preset = $presets['simple'];
}
$levelParams->loadArray($preset);
}
$menubar = (array) $levelParams->get('menu', array());
$toolbar1 = (array) $levelParams->get('toolbar1', array());
$toolbar2 = (array) $levelParams->get('toolbar2', array());
// Make an easy way to check which button is enabled
$allButtons = array_merge($toolbar1, $toolbar2);
$allButtons = array_combine($allButtons, $allButtons);
// Check for button-specific plugins
foreach ($allButtons as $btnName)
{
if (!empty($knownButtons[$btnName]['plugin']))
{
$plugins[] = $knownButtons[$btnName]['plugin'];
}
}
// Template
$templates = array();
if (!empty($allButtons['template']))
{
// Note this check for the template_list.js file will be removed in Joomla 4.0
if (is_file(JPATH_ROOT . '/media/editors/tinymce/templates/template_list.js'))
{
// If using the legacy file we need to include and input the files the new way
$str = file_get_contents(JPATH_ROOT . '/media/editors/tinymce/templates/template_list.js');
// Find from one [ to the last ]
$matches = array();
preg_match_all('/\[.*\]/', $str, $matches);
// Set variables
foreach ($matches['0'] as $match)
{
$values = array();
preg_match_all('/\".*\"/', $match, $values);
$result = trim($values['0']['0'], '"');
$final_result = explode(',', $result);
$templates[] = array(
'title' => trim($final_result['0'], ' " '),
'description' => trim($final_result['2'], ' " '),
'url' => JUri::root(true) . '/' . trim($final_result['1'], ' " '),
);
}
}
else
{
foreach (glob(JPATH_ROOT . '/media/editors/tinymce/templates/*.html') as $filename)
{
$filename = basename($filename, '.html');
if ($filename !== 'index')
{
$lang = JFactory::getLanguage();
$title = $filename;
$description = ' ';
if ($lang->hasKey('PLG_TINY_TEMPLATE_' . strtoupper($filename) . '_TITLE'))
{
$title = JText::_('PLG_TINY_TEMPLATE_' . strtoupper($filename) . '_TITLE');
}
if ($lang->hasKey('PLG_TINY_TEMPLATE_' . strtoupper($filename) . '_DESC'))
{
$description = JText::_('PLG_TINY_TEMPLATE_' . strtoupper($filename) . '_DESC');
}
$templates[] = array(
'title' => $title,
'description' => $description,
'url' => JUri::root(true) . '/media/editors/tinymce/templates/' . $filename . '.html',
);
}
}
}
}
// Check for extra plugins, from the setoptions form
foreach (array('wordcount' => 1, 'advlist' => 1, 'autosave' => 1, 'contextmenu' => 1) as $pName => $def)
{
if ($levelParams->get($pName, $def))
{
$plugins[] = $pName;
}
}
// User custom plugins and buttons
$custom_plugin = trim($levelParams->get('custom_plugin', ''));
$custom_button = trim($levelParams->get('custom_button', ''));
if ($custom_plugin)
{
$separator = strpos($custom_plugin, ',') !== false ? ',' : ' ';
$plugins = array_merge($plugins, explode($separator, $custom_plugin));
}
if ($custom_button)
{
$separator = strpos($custom_button, ',') !== false ? ',' : ' ';
$toolbar1 = array_merge($toolbar1, explode($separator, $custom_button));
}
// Drag and drop Images
$allowImgPaste = false;
$dragdrop = $levelParams->get('drag_drop', 1);
if ($dragdrop && $user->authorise('core.create', 'com_media'))
{
$externalPlugins['jdragdrop'] = HTMLHelper::_(
'script',
'editors/tinymce/plugins/dragdrop/plugin.min.js',
array('relative' => true, 'version' => 'auto', 'pathOnly' => true)
);
$allowImgPaste = true;
$isSubDir = '';
$session = JFactory::getSession();
$uploadUrl = JUri::base() . 'index.php?option=com_media&task=file.upload&tmpl=component&'
. $session->getName() . '=' . $session->getId()
. '&' . JSession::getFormToken() . '=1'
. '&asset=image&format=json';
if ($app->isClient('site'))
{
$uploadUrl = htmlentities($uploadUrl, 0, 'UTF-8', false);
}
// Is Joomla installed in subdirectory
if (JUri::root(true) !== '/')
{
$isSubDir = JUri::root(true);
}
JText::script('PLG_TINY_ERR_UNSUPPORTEDBROWSER');
$scriptOptions['setCustomDir'] = $isSubDir;
$scriptOptions['mediaUploadPath'] = $levelParams->get('path', '');
$scriptOptions['uploadUri'] = $uploadUrl;
}
// Build the final options set
$scriptOptions = array_merge(
$scriptOptions,
array(
'suffix' => '.min',
'baseURL' => JUri::root(true) . '/media/editors/tinymce',
'directionality' => $text_direction,
'language' => $langPrefix,
'autosave_restore_when_empty' => false,
'skin' => $skin,
'theme' => $theme,
'schema' => 'html5',
// Toolbars
'menubar' => empty($menubar) ? false : implode(' ', array_unique($menubar)),
'toolbar1' => empty($toolbar1) ? null : implode(' ', $toolbar1),
'toolbar2' => empty($toolbar2) ? null : implode(' ', $toolbar2),
'plugins' => implode(',', array_unique($plugins)),
// Cleanup/Output
'inline_styles' => true,
'gecko_spellcheck' => true,
'entity_encoding' => $levelParams->get('entity_encoding', 'raw'),
'verify_html' => !$ignore_filter,
'valid_elements' => $valid_elements,
'extended_valid_elements' => implode(',', $elements),
'invalid_elements' => $invalid_elements,
// URL
'relative_urls' => (bool) $levelParams->get('relative_urls', true),
'remove_script_host' => false,
// Layout
'content_css' => $content_css,
'document_base_url' => JUri::root(true) . '/',
'paste_data_images' => $allowImgPaste,
'importcss_append' => true,
'image_title' => true,
'height' => $html_height,
'width' => $html_width,
'resize' => $resizing,
'templates' => $templates,
'image_advtab' => (bool) $levelParams->get('image_advtab', false),
'external_plugins' => empty($externalPlugins) ? null : $externalPlugins,
'contextmenu' => (bool) $levelParams->get('contextmenu', true) ? null : false,
'elementpath' => (bool) $levelParams->get('element_path', true),
)
);
if ($levelParams->get('newlines'))
{
// Break
$scriptOptions['force_br_newlines'] = true;
$scriptOptions['force_p_newlines'] = false;
$scriptOptions['forced_root_block'] = '';
}
else
{
// Paragraph
$scriptOptions['force_br_newlines'] = false;
$scriptOptions['force_p_newlines'] = true;
$scriptOptions['forced_root_block'] = 'p';
}
$scriptOptions['rel_list'] = array(
array('title' => 'None', 'value' => ''),
array('title' => 'Alternate', 'value' => 'alternate'),
array('title' => 'Author', 'value' => 'author'),
array('title' => 'Bookmark', 'value' => 'bookmark'),
array('title' => 'Help', 'value' => 'help'),
array('title' => 'License', 'value' => 'license'),
array('title' => 'Lightbox', 'value' => 'lightbox'),
array('title' => 'Next', 'value' => 'next'),
array('title' => 'No Follow', 'value' => 'nofollow'),
array('title' => 'No Referrer', 'value' => 'noreferrer'),
array('title' => 'Prefetch', 'value' => 'prefetch'),
array('title' => 'Prev', 'value' => 'prev'),
array('title' => 'Search', 'value' => 'search'),
array('title' => 'Tag', 'value' => 'tag'),
);
/**
* Shrink the buttons if not on a mobile or if mobile view is off.
* If mobile view is on force into simple mode and enlarge the buttons
**/
if (!$this->app->client->mobile)
{
$scriptOptions['toolbar_items_size'] = 'small';
}
elseif ($levelParams->get('mobile', 0))
{
$scriptOptions['menubar'] = false;
unset($scriptOptions['toolbar2']);
}
$options['tinyMCE']['default'] = $scriptOptions;
$doc->addStyleDeclaration('.mce-in { padding: 5px 10px !important;}');
$doc->addScriptOptions('plg_editor_tinymce', $options);
return $editor;
}
/**
* Get the toggle editor button
*
* @param string $name Editor name
*
* @return string
*/
private function _toogleButton($name)
{
return JLayoutHelper::render('joomla.tinymce.togglebutton', $name);
}
/**
* Get the XTD buttons and render them inside tinyMCE
*
* @param string $name the id of the editor field
* @param string $excluded the buttons that should be hidden
*
* @return array
*/
private function tinyButtons($name, $excluded)
{
// Get the available buttons
$buttons = $this->_subject->getButtons($name, $excluded);
// Init the arrays for the buttons
$tinyBtns = array();
$btnsNames = array();
// Build the script
foreach ($buttons as $i => $button)
{
if ($button->get('name'))
{
// Set some vars
$name = 'button-' . $i . str_replace(' ', '', $button->get('text'));
$title = $button->get('text');
$onclick = $button->get('onclick') ?: null;
$options = $button->get('options');
$icon = $button->get('name');
if ($button->get('link') !== '#')
{
$href = JUri::base() . $button->get('link');
}
else
{
$href = null;
}
// We do some hack here to set the correct icon for 3PD buttons
$icon = 'none icon-' . $icon;
$tempConstructor = array();
// Now we can built the script
$tempConstructor[] = '!(function(){';
// Get the modal width/height
if ($options && is_scalar($options))
{
$tempConstructor[] = 'var getBtnOptions=new Function("return ' . addslashes($options) . '"),';
$tempConstructor[] = 'btnOptions=getBtnOptions(),';
$tempConstructor[] = 'modalWidth=btnOptions.size&&btnOptions.size.x?btnOptions.size.x:null,';
$tempConstructor[] = 'modalHeight=btnOptions.size&&btnOptions.size.y?btnOptions.size.y:null;';
}
else
{
$tempConstructor[] = 'var btnOptions={},modalWidth=null,modalHeight=null;';
}
// Now we can built the script
// AddButton starts here
$tempConstructor[] = 'editor.addButton("' . $name . '",{';
$tempConstructor[] = 'text:"' . $title . '",';
$tempConstructor[] = 'title:"' . $title . '",';
$tempConstructor[] = 'icon:"' . $icon . '",';
// Onclick starts here
$tempConstructor[] = 'onclick:function(){';
if ($href || $button->get('modal'))
{
// TinyMCE standard modal options
$tempConstructor[] = 'var modalOptions={';
$tempConstructor[] = 'title:"' . $title . '",';
$tempConstructor[] = 'url:"' . $href . '",';
$tempConstructor[] = 'buttons:[{text: "Close",onclick:"close"}]';
$tempConstructor[] = '};';
// Set width/height
$tempConstructor[] = 'if(modalWidth){modalOptions.width=modalWidth;}';
$tempConstructor[] = 'if(modalHeight){modalOptions.height = modalHeight;}';
$tempConstructor[] = 'var win=editor.windowManager.open(modalOptions);';
if (JFactory::getApplication()->client->mobile)
{
$tempConstructor[] = 'win.fullscreen(true);';
}
if ($onclick && ($button->get('modal') || $href))
{
// Adds callback for close button
$tempConstructor[] = $onclick . ';';
}
}
else
{
// Adds callback for the button, eg: readmore
$tempConstructor[] = $onclick . ';';
}
// Onclick ends here
$tempConstructor[] = '}';
// AddButton ends here
$tempConstructor[] = '});';
// IIFE ends here
$tempConstructor[] = '})();';
// The array with the toolbar buttons
$btnsNames[] = $name . ' | ';
// The array with code for each button
$tinyBtns[] = implode('', $tempConstructor);
}
}
return array(
'names' => $btnsNames,
'script' => $tinyBtns
);
}
/**
* Get the global text filters to arbitrary text as per settings for current user groups
*
* @return JFilterInput
*
* @since 3.6
*/
protected static function getGlobalFilters()
{
// Filter settings
$config = JComponentHelper::getParams('com_config');
$user = JFactory::getUser();
$userGroups = JAccess::getGroupsByUser($user->get('id'));
$filters = $config->get('filters');
$blackListTags = array();
$blackListAttributes = array();
$customListTags = array();
$customListAttributes = array();
$whiteListTags = array();
$whiteListAttributes = array();
$whiteList = false;
$blackList = false;
$customList = false;
$unfiltered = false;
// Cycle through each of the user groups the user is in.
// Remember they are included in the public group as well.
foreach ($userGroups as $groupId)
{
// May have added a group but not saved the filters.
if (!isset($filters->$groupId))
{
continue;
}
// Each group the user is in could have different filtering properties.
$filterData = $filters->$groupId;
$filterType = strtoupper($filterData->filter_type);
if ($filterType === 'NH')
{
// Maximum HTML filtering.
}
elseif ($filterType === 'NONE')
{
// No HTML filtering.
$unfiltered = true;
}
else
{
// Blacklist or whitelist.
// Preprocess the tags and attributes.
$tags = explode(',', $filterData->filter_tags);
$attributes = explode(',', $filterData->filter_attributes);
$tempTags = array();
$tempAttributes = array();
foreach ($tags as $tag)
{
$tag = trim($tag);
if ($tag)
{
$tempTags[] = $tag;
}
}
foreach ($attributes as $attribute)
{
$attribute = trim($attribute);
if ($attribute)
{
$tempAttributes[] = $attribute;
}
}
// Collect the blacklist or whitelist tags and attributes.
// Each list is cummulative.
if ($filterType === 'BL')
{
$blackList = true;
$blackListTags = array_merge($blackListTags, $tempTags);
$blackListAttributes = array_merge($blackListAttributes, $tempAttributes);
}
elseif ($filterType === 'CBL')
{
// Only set to true if Tags or Attributes were added
if ($tempTags || $tempAttributes)
{
$customList = true;
$customListTags = array_merge($customListTags, $tempTags);
$customListAttributes = array_merge($customListAttributes, $tempAttributes);
}
}
elseif ($filterType === 'WL')
{
$whiteList = true;
$whiteListTags = array_merge($whiteListTags, $tempTags);
$whiteListAttributes = array_merge($whiteListAttributes, $tempAttributes);
}
}
}
// Remove duplicates before processing (because the blacklist uses both sets of arrays).
$blackListTags = array_unique($blackListTags);
$blackListAttributes = array_unique($blackListAttributes);
$customListTags = array_unique($customListTags);
$customListAttributes = array_unique($customListAttributes);
$whiteListTags = array_unique($whiteListTags);
$whiteListAttributes = array_unique($whiteListAttributes);
// Unfiltered assumes first priority.
if ($unfiltered)
{
// Dont apply filtering.
return false;
}
else
{
// Custom blacklist precedes Default blacklist
if ($customList)
{
$filter = JFilterInput::getInstance(array(), array(), 1, 1);
// Override filter's default blacklist tags and attributes
if ($customListTags)
{
$filter->tagBlacklist = $customListTags;
}
if ($customListAttributes)
{
$filter->attrBlacklist = $customListAttributes;
}
}
// Blacklists take second precedence.
elseif ($blackList)
{
// Remove the white-listed tags and attributes from the black-list.
$blackListTags = array_diff($blackListTags, $whiteListTags);
$blackListAttributes = array_diff($blackListAttributes, $whiteListAttributes);
$filter = JFilterInput::getInstance($blackListTags, $blackListAttributes, 1, 1);
// Remove whitelisted tags from filter's default blacklist
if ($whiteListTags)
{
$filter->tagBlacklist = array_diff($filter->tagBlacklist, $whiteListTags);
}
// Remove whitelisted attributes from filter's default blacklist
if ($whiteListAttributes)
{
$filter->attrBlacklist = array_diff($filter->attrBlacklist, $whiteListAttributes);
}
}
// Whitelists take third precedence.
elseif ($whiteList)
{
// Turn off XSS auto clean
$filter = JFilterInput::getInstance($whiteListTags, $whiteListAttributes, 0, 0, 0);
}
// No HTML takes last place.
else
{
$filter = JFilterInput::getInstance();
}
return $filter;
}
}
/**
* Return list of known TinyMCE buttons
*
* @return array
*
* @since 3.7.0
*/
public static function getKnownButtons()
{
// See https://www.tinymce.com/docs/demo/full-featured/
// And https://www.tinymce.com/docs/plugins/
$buttons = array(
// General buttons
'|' => array('label' => JText::_('PLG_TINY_TOOLBAR_BUTTON_SEPARATOR'), 'text' => '|'),
'undo' => array('label' => 'Undo'),
'redo' => array('label' => 'Redo'),
'bold' => array('label' => 'Bold'),
'italic' => array('label' => 'Italic'),
'underline' => array('label' => 'Underline'),
'strikethrough' => array('label' => 'Strikethrough'),
'styleselect' => array('label' => JText::_('PLG_TINY_TOOLBAR_BUTTON_STYLESELECT'), 'text' => 'Formats'),
'formatselect' => array('label' => JText::_('PLG_TINY_TOOLBAR_BUTTON_FORMATSELECT'), 'text' => 'Paragraph'),
'fontselect' => array('label' => JText::_('PLG_TINY_TOOLBAR_BUTTON_FONTSELECT'), 'text' => 'Font Family'),
'fontsizeselect' => array('label' => JText::_('PLG_TINY_TOOLBAR_BUTTON_FONTSIZESELECT'), 'text' => 'Font Sizes'),
'alignleft' => array('label' => 'Align left'),
'aligncenter' => array('label' => 'Align center'),
'alignright' => array('label' => 'Align right'),
'alignjustify' => array('label' => 'Justify'),
'outdent' => array('label' => 'Decrease indent'),
'indent' => array('label' => 'Increase indent'),
'bullist' => array('label' => 'Bullet list'),
'numlist' => array('label' => 'Numbered list'),
'link' => array('label' => 'Insert/edit link', 'plugin' => 'link'),
'unlink' => array('label' => 'Remove link', 'plugin' => 'link'),
'subscript' => array('label' => 'Subscript'),
'superscript' => array('label' => 'Superscript'),
'blockquote' => array('label' => 'Blockquote'),
'cut' => array('label' => 'Cut'),
'copy' => array('label' => 'Copy'),
'paste' => array('label' => 'Paste', 'plugin' => 'paste'),
'pastetext' => array('label' => 'Paste as text', 'plugin' => 'paste'),
'removeformat' => array('label' => 'Clear formatting'),
// Buttons from the plugins
'forecolor' => array('label' => 'Text color', 'plugin' => 'textcolor'),
'backcolor' => array('label' => 'Background color', 'plugin' => 'textcolor'),
'anchor' => array('label' => 'Anchor', 'plugin' => 'anchor'),
'hr' => array('label' => 'Horizontal line', 'plugin' => 'hr'),
'ltr' => array('label' => 'Left to right', 'plugin' => 'directionality'),
'rtl' => array('label' => 'Right to left', 'plugin' => 'directionality'),
'code' => array('label' => 'Source code', 'plugin' => 'code'),
'codesample' => array('label' => 'Insert/Edit code sample', 'plugin' => 'codesample'),
'table' => array('label' => 'Table', 'plugin' => 'table'),
'charmap' => array('label' => 'Special character', 'plugin' => 'charmap'),
'visualchars' => array('label' => 'Show invisible characters', 'plugin' => 'visualchars'),
'visualblocks' => array('label' => 'Show blocks', 'plugin' => 'visualblocks'),
'nonbreaking' => array('label' => 'Nonbreaking space', 'plugin' => 'nonbreaking'),
'emoticons' => array('label' => 'Emoticons', 'plugin' => 'emoticons'),
'image' => array('label' => 'Insert/edit image', 'plugin' => 'image'),
'media' => array('label' => 'Insert/edit video', 'plugin' => 'media'),
'pagebreak' => array('label' => 'Page break', 'plugin' => 'pagebreak'),
'print' => array('label' => 'Print', 'plugin' => 'print'),
'preview' => array('label' => 'Preview', 'plugin' => 'preview'),
'fullscreen' => array('label' => 'Fullscreen', 'plugin' => 'fullscreen'),
'template' => array('label' => 'Insert template', 'plugin' => 'template'),
'searchreplace' => array('label' => 'Find and replace', 'plugin' => 'searchreplace'),
'insertdatetime' => array('label' => 'Insert date/time', 'plugin' => 'insertdatetime'),
// 'spellchecker' => array('label' => 'Spellcheck', 'plugin' => 'spellchecker'),
);
return $buttons;
}
/**
* Return toolbar presets
*
* @return array
*
* @since 3.7.0
*/
public static function getToolbarPreset()
{
$preset = array();
$preset['simple'] = array(
'menu' => array(),
'toolbar1' => array(
'bold', 'underline', 'strikethrough', '|',
'undo', 'redo', '|',
'bullist', 'numlist', '|',
'pastetext'
),
'toolbar2' => array(),
);
$preset['medium'] = array(
'menu' => array('edit', 'insert', 'view', 'format', 'table', 'tools'),
'toolbar1' => array(
'bold', 'italic', 'underline', 'strikethrough', '|',
'alignleft', 'aligncenter', 'alignright', 'alignjustify', '|',
'formatselect', '|',
'bullist', 'numlist', '|',
'outdent', 'indent', '|',
'undo', 'redo', '|',
'link', 'unlink', 'anchor', 'code', '|',
'hr', 'table', '|',
'subscript', 'superscript', '|',
'charmap', 'pastetext' , 'preview'
),
'toolbar2' => array(),
);
$preset['advanced'] = array(
'menu' => array('edit', 'insert', 'view', 'format', 'table', 'tools'),
'toolbar1' => array(
'bold', 'italic', 'underline', 'strikethrough', '|',
'alignleft', 'aligncenter', 'alignright', 'alignjustify', '|',
'styleselect', '|',
'formatselect', 'fontselect', 'fontsizeselect', '|',
'searchreplace', '|',
'bullist', 'numlist', '|',
'outdent', 'indent', '|',
'undo', 'redo', '|',
'link', 'unlink', 'anchor', 'image', '|',
'code', '|',
'forecolor', 'backcolor', '|',
'fullscreen', '|',
'table', '|',
'subscript', 'superscript', '|',
'charmap', 'emoticons', 'media', 'hr', 'ltr', 'rtl', '|',
'cut', 'copy', 'paste', 'pastetext', '|',
'visualchars', 'visualblocks', 'nonbreaking', 'blockquote', 'template', '|',
'print', 'preview', 'codesample', 'insertdatetime', 'removeformat',
),
'toolbar2' => array(),
);
return $preset;
}
/**
* Gets the plugin extension id.
*
* @return int The plugin id.
*
* @since 3.7.0
*/
private function getPluginId()
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select($db->quoteName('extension_id'))
->from($db->quoteName('#__extensions'))
->where($db->quoteName('folder') . ' = ' . $db->quote($this->_type))
->where($db->quoteName('element') . ' = ' . $db->quote($this->_name));
$db->setQuery($query);
return (int) $db->loadResult();
}
/**
* Display the editor area.
*
* @param string $name The name of the editor area.
* @param string $content The content of the field.
* @param string $width The width of the editor area.
* @param string $height The height of the editor area.
* @param int $col The number of columns for the editor area.
* @param int $row The number of rows for the editor area.
* @param boolean $buttons True and the editor buttons will be displayed.
* @param string $id An optional ID for the textarea. If not supplied the name is used.
* @param string $asset The object asset
* @param object $author The author.
* @param array $params Associative array of editor parameters.
*
* @return string
*
* @since 3.7.0
*
* @deprecated 4.0
*/
private function onDisplayLegacy(
$name, $content, $width, $height, $col, $row, $buttons = true, $id = null, $asset = null, $author = null, $params = array())
{
if (empty($id))
{
$id = $name;
}
$id = preg_replace('/(\s|[^A-Za-z0-9_])+/', '_', $id);
$nameGroup = explode('[', preg_replace('/\[\]|\]/', '', $name));
$fieldName = end($nameGroup);
$scriptOptions = array();
// Check for existing options
$doc = JFactory::getDocument();
$options = $doc->getScriptOptions('plg_editor_tinymce');
// Only add "px" to width and height if they are not given as a percentage
if (is_numeric($width))
{
$width .= 'px';
}
if (is_numeric($height))
{
$height .= 'px';
}
// Data object for the layout
$textarea = new stdClass;
$textarea->name = $name;
$textarea->id = $id;
$textarea->class = 'mce_editable joomla-editor-tinymce';
$textarea->cols = $col;
$textarea->rows = $row;
$textarea->width = $width;
$textarea->height = $height;
$textarea->content = $content;
// Set editor to readonly mode
$textarea->readonly = !empty($params['readonly']);
// Render Editor markup
$editor = '<div class="editor js-editor-tinymce">';
$editor .= JLayoutHelper::render('joomla.tinymce.textarea', $textarea);
$editor .= $this->_toogleButton($id);
$editor .= '</div>';
// Prepare instance specific options, actually the ext-buttons
if (empty($options['tinyMCE'][$fieldName]['joomlaExtButtons']))
{
$btns = $this->tinyButtons($id, $buttons);
if (!empty($btns['names']))
{
JHtml::_('script', 'editors/tinymce/tiny-close.min.js', array('version' => 'auto', 'relative' => true), array('defer' => 'defer'));
}
// Set editor to readonly mode
if (!empty($params['readonly']))
{
$options['tinyMCE'][$fieldName]['readonly'] = 1;
}
$options['tinyMCE'][$fieldName]['joomlaMergeDefaults'] = true;
$options['tinyMCE'][$fieldName]['joomlaExtButtons'] = $btns;
$doc->addScriptOptions('plg_editor_tinymce', $options, false);
}
// Setup Default options for the Editor script
// Check whether we already have them
if (!empty($options['tinyMCE']['default']))
{
return $editor;
}
$app = JFactory::getApplication();
$user = JFactory::getUser();
$language = JFactory::getLanguage();
$mode = (int) $this->params->get('mode', 1);
$theme = 'modern';
// List the skins
$skindirs = glob(JPATH_ROOT . '/media/editors/tinymce/skins' . '/*', GLOB_ONLYDIR);
// Set the selected skin
$skin = 'lightgray';
$side = $app->isClient('administrator') ? 'skin_admin' : 'skin';
if ((int) $this->params->get($side, 0) < count($skindirs))
{
$skin = basename($skindirs[(int) $this->params->get($side, 0)]);
}
$langMode = $this->params->get('lang_mode', 0);
$langPrefix = $this->params->get('lang_code', 'en');
if ($langMode)
{
if (file_exists(JPATH_ROOT . "/media/editors/tinymce/langs/" . $language->getTag() . ".js"))
{
$langPrefix = $language->getTag();
}
elseif (file_exists(JPATH_ROOT . "/media/editors/tinymce/langs/" . substr($language->getTag(), 0, strpos($language->getTag(), '-')) . ".js"))
{
$langPrefix = substr($language->getTag(), 0, strpos($language->getTag(), '-'));
}
else
{
$langPrefix = "en";
}
}
$text_direction = 'ltr';
if ($language->isRtl())
{
$text_direction = 'rtl';
}
$use_content_css = $this->params->get('content_css', 1);
$content_css_custom = $this->params->get('content_css_custom', '');
/*
* Lets get the default template for the site application
*/
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('template')
->from('#__template_styles')
->where('client_id=0 AND home=' . $db->quote('1'));
$db->setQuery($query);
try
{
$template = $db->loadResult();
}
catch (RuntimeException $e)
{
$app->enqueueMessage(JText::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error');
return;
}
$content_css = null;
$templates_path = JPATH_SITE . '/templates';
// Loading of css file for 'styles' dropdown
if ($content_css_custom)
{
// If URL, just pass it to $content_css
if (strpos($content_css_custom, 'http') !== false)
{
$content_css = $content_css_custom;
}
// If it is not a URL, assume it is a file name in the current template folder
else
{
$content_css = JUri::root(true) . '/templates/' . $template . '/css/' . $content_css_custom;
// Issue warning notice if the file is not found (but pass name to $content_css anyway to avoid TinyMCE error
if (!file_exists($templates_path . '/' . $template . '/css/' . $content_css_custom))
{
$msg = sprintf(JText::_('PLG_TINY_ERR_CUSTOMCSSFILENOTPRESENT'), $content_css_custom);
JLog::add($msg, JLog::WARNING, 'jerror');
}
}
}
else
{
// Process when use_content_css is Yes and no custom file given
if ($use_content_css)
{
// First check templates folder for default template
// if no editor.css file in templates folder, check system template folder
if (!file_exists($templates_path . '/' . $template . '/css/editor.css'))
{
// If no editor.css file in system folder, show alert
if (!file_exists($templates_path . '/system/css/editor.css'))
{
JLog::add(JText::_('PLG_TINY_ERR_EDITORCSSFILENOTPRESENT'), JLog::WARNING, 'jerror');
}
else
{
$content_css = JUri::root(true) . '/templates/system/css/editor.css';
}
}
else
{
$content_css = JUri::root(true) . '/templates/' . $template . '/css/editor.css';
}
}
}
$ignore_filter = false;
// Text filtering
if ($this->params->get('use_config_textfilters', 0))
{
// Use filters from com_config
$filter = static::getGlobalFilters();
$ignore_filter = $filter === false;
$tagBlacklist = !empty($filter->tagBlacklist) ? $filter->tagBlacklist : array();
$attrBlacklist = !empty($filter->attrBlacklist) ? $filter->attrBlacklist : array();
$tagArray = !empty($filter->tagArray) ? $filter->tagArray : array();
$attrArray = !empty($filter->attrArray) ? $filter->attrArray : array();
$invalid_elements = implode(',', array_merge($tagBlacklist, $attrBlacklist, $tagArray, $attrArray));
// Valid elements are all whitelist entries in com_config, which are now missing in the tagBlacklist
$default_filter = JFilterInput::getInstance();
$valid_elements = implode(',', array_diff($default_filter->tagBlacklist, $tagBlacklist));
$extended_elements = '';
}
else
{
// Use filters from TinyMCE params
$invalid_elements = $this->params->get('invalid_elements', 'script,applet,iframe');
$extended_elements = $this->params->get('extended_elements', '');
$valid_elements = $this->params->get('valid_elements', '');
}
// Advanced Options
$access = $user->getAuthorisedViewLevels();
// Flip for performance, so we can direct check for the key isset($access[$key])
$access = array_flip($access);
$html_height = $this->params->get('html_height', '550');
$html_width = $this->params->get('html_width', '');
if ($html_width == 750)
{
$html_width = '';
}
// Image advanced options
$image_advtab = $this->params->get('image_advtab', true);
if (isset($access[$image_advtab]))
{
$image_advtab = true;
}
else
{
$image_advtab = false;
}
// The param is true for vertical resizing only, false or both
$resizing = $this->params->get('resizing', '1');
$resize_horizontal = $this->params->get('resize_horizontal', '1');
if ($resizing || $resizing == 'true')
{
if ($resize_horizontal || $resize_horizontal == 'true')
{
$resizing = 'both';
}
else
{
$resizing = true;
}
}
else
{
$resizing = false;
}
$toolbar1_add = array();
$toolbar2_add = array();
$toolbar3_add = array();
$toolbar4_add = array();
$elements = array();
$plugins = array(
'autolink',
'lists',
'image',
'charmap',
'print',
'preview',
'anchor',
'pagebreak',
'code',
'save',
'textcolor',
'colorpicker',
'importcss');
$toolbar1_add[] = 'bold';
$toolbar1_add[] = 'italic';
$toolbar1_add[] = 'underline';
$toolbar1_add[] = 'strikethrough';
// Alignment buttons
$alignment = $this->params->get('alignment', 1);
if (isset($access[$alignment]))
{
$toolbar1_add[] = '|';
$toolbar1_add[] = 'alignleft';
$toolbar1_add[] = 'aligncenter';
$toolbar1_add[] = 'alignright';
$toolbar1_add[] = 'alignjustify';
}
$toolbar1_add[] = '|';
$toolbar1_add[] = 'styleselect';
$toolbar1_add[] = '|';
$toolbar1_add[] = 'formatselect';
// Fonts
$fonts = $this->params->get('fonts', 1);
if (isset($access[$fonts]))
{
$toolbar1_add[] = 'fontselect';
$toolbar1_add[] = 'fontsizeselect';
}
// Search & replace
$searchreplace = $this->params->get('searchreplace', 1);
if (isset($access[$searchreplace]))
{
$plugins[] = 'searchreplace';
$toolbar2_add[] = 'searchreplace';
}
$toolbar2_add[] = '|';
$toolbar2_add[] = 'bullist';
$toolbar2_add[] = 'numlist';
$toolbar2_add[] = '|';
$toolbar2_add[] = 'outdent';
$toolbar2_add[] = 'indent';
$toolbar2_add[] = '|';
$toolbar2_add[] = 'undo';
$toolbar2_add[] = 'redo';
$toolbar2_add[] = '|';
// Insert date and/or time plugin
$insertdate = $this->params->get('insertdate', 1);
if (isset($access[$insertdate]))
{
$plugins[] = 'insertdatetime';
$toolbar4_add[] = 'inserttime';
}
// Link plugin
$link = $this->params->get('link', 1);
if (isset($access[$link]))
{
$plugins[] = 'link';
$toolbar2_add[] = 'link';
$toolbar2_add[] = 'unlink';
}
$toolbar2_add[] = 'anchor';
$toolbar2_add[] = 'image';
$toolbar2_add[] = '|';
$toolbar2_add[] = 'code';
// Colors
$colors = $this->params->get('colors', 1);
if (isset($access[$colors]))
{
$toolbar2_add[] = '|';
$toolbar2_add[] = 'forecolor,backcolor';
}
// Fullscreen
$fullscreen = $this->params->get('fullscreen', 1);
if (isset($access[$fullscreen]))
{
$plugins[] = 'fullscreen';
$toolbar2_add[] = '|';
$toolbar2_add[] = 'fullscreen';
}
// Table
$table = $this->params->get('table', 1);
if (isset($access[$table]))
{
$plugins[] = 'table';
$toolbar3_add[] = 'table';
$toolbar3_add[] = '|';
}
$toolbar3_add[] = 'subscript';
$toolbar3_add[] = 'superscript';
$toolbar3_add[] = '|';
$toolbar3_add[] = 'charmap';
// Emotions
$smilies = $this->params->get('smilies', 1);
if (isset($access[$smilies]))
{
$plugins[] = 'emoticons';
$toolbar3_add[] = 'emoticons';
}
// Media plugin
$media = $this->params->get('media', 1);
if (isset($access[$media]))
{
$plugins[] = 'media';
$toolbar3_add[] = 'media';
}
// Horizontal line
$hr = $this->params->get('hr', 1);
if (isset($access[$hr]))
{
$plugins[] = 'hr';
$elements[] = 'hr[id|title|alt|class|width|size|noshade]';
$toolbar3_add[] = 'hr';
}
else
{
$elements[] = 'hr[id|class|title|alt]';
}
// RTL/LTR buttons
$directionality = $this->params->get('directionality', 1);
if (isset($access[$directionality]))
{
$plugins[] = 'directionality';
$toolbar3_add[] = 'ltr rtl';
}
if ($extended_elements != "")
{
$elements = explode(',', $extended_elements);
}
$toolbar4_add[] = 'cut';
$toolbar4_add[] = 'copy';
// Paste
$paste = $this->params->get('paste', 1);
if (isset($access[$paste]))
{
$plugins[] = 'paste';
$toolbar4_add[] = 'paste';
}
$toolbar4_add[] = '|';
// Visualchars
$visualchars = $this->params->get('visualchars', 1);
if (isset($access[$visualchars]))
{
$plugins[] = 'visualchars';
$toolbar4_add[] = 'visualchars';
}
// Visualblocks
$visualblocks = $this->params->get('visualblocks', 1);
if (isset($access[$visualblocks]))
{
$plugins[] = 'visualblocks';
$toolbar4_add[] = 'visualblocks';
}
// Non-breaking
$nonbreaking = $this->params->get('nonbreaking', 1);
if (isset($access[$nonbreaking]))
{
$plugins[] = 'nonbreaking';
$toolbar4_add[] = 'nonbreaking';
}
// Blockquote
$blockquote = $this->params->get('blockquote', 1);
if (isset($access[$blockquote]))
{
$toolbar4_add[] = 'blockquote';
}
// Template
$template = $this->params->get('template', 1);
$templates = array();
if (isset($access[$template]))
{
$plugins[] = 'template';
$toolbar4_add[] = 'template';
// Note this check for the template_list.js file will be removed in Joomla 4.0
if (is_file(JPATH_ROOT . "/media/editors/tinymce/templates/template_list.js"))
{
// If using the legacy file we need to include and input the files the new way
$str = file_get_contents(JPATH_ROOT . "/media/editors/tinymce/templates/template_list.js");
// Find from one [ to the last ]
$matches = array();
preg_match_all('/\[.*\]/', $str, $matches);
// Set variables
foreach ($matches['0'] as $match)
{
$values = array();
preg_match_all('/\".*\"/', $match, $values);
$result = trim($values["0"]["0"], '"');
$final_result = explode(',', $result);
$templates[] = array(
'title' => trim($final_result['0'], ' " '),
'description' => trim($final_result['2'], ' " '),
'url' => JUri::root(true) . '/' . trim($final_result['1'], ' " '),
);
}
}
else
{
foreach (glob(JPATH_ROOT . '/media/editors/tinymce/templates/*.html') as $filename)
{
$filename = basename($filename, '.html');
if ($filename !== 'index')
{
$lang = JFactory::getLanguage();
$title = $filename;
$description = ' ';
if ($lang->hasKey('PLG_TINY_TEMPLATE_' . strtoupper($filename) . '_TITLE'))
{
$title = JText::_('PLG_TINY_TEMPLATE_' . strtoupper($filename) . '_TITLE');
}
if ($lang->hasKey('PLG_TINY_TEMPLATE_' . strtoupper($filename) . '_DESC'))
{
$description = JText::_('PLG_TINY_TEMPLATE_' . strtoupper($filename) . '_DESC');
}
$templates[] = array(
'title' => $title,
'description' => $description,
'url' => JUri::root(true) . '/media/editors/tinymce/templates/' . $filename . '.html',
);
}
}
}
}
// Print
$print = $this->params->get('print', 1);
if (isset($access[$print]))
{
$plugins[] = 'print';
$toolbar4_add[] = '|';
$toolbar4_add[] = 'print';
$toolbar4_add[] = 'preview';
}
// Spellchecker
$spell = $this->params->get('spell', 0);
if (isset($access[$spell]))
{
$plugins[] = 'spellchecker';
$toolbar4_add[] = '|';
$toolbar4_add[] = 'spellchecker';
}
// Wordcount
$wordcount = $this->params->get('wordcount', 1);
if (isset($access[$wordcount]))
{
$plugins[] = 'wordcount';
}
// Advlist
$advlist = $this->params->get('advlist', 1);
if (isset($access[$advlist]))
{
$plugins[] = 'advlist';
}
// Codesample
$advlist = $this->params->get('code_sample', 1);
if (isset($access[$advlist]))
{
$plugins[] = 'codesample';
$toolbar4_add[] = 'codesample';
}
// Autosave
$autosave = $this->params->get('autosave', 1);
if (isset($access[$autosave]))
{
$plugins[] = 'autosave';
}
// Context menu
$contextmenu = $this->params->get('contextmenu', 1);
if (isset($access[$contextmenu]))
{
$plugins[] = 'contextmenu';
}
$custom_plugin = $this->params->get('custom_plugin', '');
if ($custom_plugin != "")
{
$plugins[] = $custom_plugin;
}
$custom_button = $this->params->get('custom_button', '');
if ($custom_button != "")
{
$toolbar4_add[] = $custom_button;
}
// Drag and drop Images
$externalPlugins = array();
$allowImgPaste = false;
$dragdrop = $this->params->get('drag_drop', 1);
if ($dragdrop && $user->authorise('core.create', 'com_media'))
{
$allowImgPaste = true;
$isSubDir = '';
$session = JFactory::getSession();
$uploadUrl = JUri::base() . 'index.php?option=com_media&task=file.upload&tmpl=component&'
. $session->getName() . '=' . $session->getId()
. '&' . JSession::getFormToken() . '=1'
. '&asset=image&format=json';
if ($app->isClient('site'))
{
$uploadUrl = htmlentities($uploadUrl, 0, 'UTF-8', false);
}
// Is Joomla installed in subdirectory
if (JUri::root(true) != '/')
{
$isSubDir = JUri::root(true);
}
JText::script('PLG_TINY_ERR_UNSUPPORTEDBROWSER');
$scriptOptions['setCustomDir'] = $isSubDir;
$scriptOptions['mediaUploadPath'] = $this->params->get('path', '');
$scriptOptions['uploadUri'] = $uploadUrl;
$externalPlugins = array(
array(
'jdragdrop' => HTMLHelper::_(
'script',
'editors/tinymce/plugins/dragdrop/plugin.min.js',
array('relative' => true, 'version' => 'auto', 'pathOnly' => true)
),
),
);
}
// Prepare config variables
$plugins = implode(',', $plugins);
$elements = implode(',', $elements);
// Prepare config variables
$toolbar1 = implode(' ', $toolbar1_add) . ' | '
. implode(' ', $toolbar2_add) . ' | '
. implode(' ', $toolbar3_add) . ' | '
. implode(' ', $toolbar4_add);
// See if mobileVersion is activated
$mobileVersion = $this->params->get('mobile', 0);
$scriptOptions = array_merge(
$scriptOptions,
array(
'suffix' => '.min',
'baseURL' => JUri::root(true) . '/media/editors/tinymce',
'directionality' => $text_direction,
'language' => $langPrefix,
'autosave_restore_when_empty' => false,
'skin' => $skin,
'theme' => $theme,
'schema' => 'html5',
// Cleanup/Output
'inline_styles' => true,
'gecko_spellcheck' => true,
'entity_encoding' => $this->params->get('entity_encoding', 'raw'),
'verify_html' => !$ignore_filter,
// URL
'relative_urls' => (bool) $this->params->get('relative_urls', true),
'remove_script_host' => false,
// Layout
'content_css' => $content_css,
'document_base_url' => JUri::root(true) . '/',
'paste_data_images' => $allowImgPaste,
'externalPlugins' => json_encode($externalPlugins),
)
);
if ($this->params->get('newlines'))
{
// Break
$scriptOptions['force_br_newlines'] = true;
$scriptOptions['force_p_newlines'] = false;
$scriptOptions['forced_root_block'] = '';
}
else
{
// Paragraph
$scriptOptions['force_br_newlines'] = false;
$scriptOptions['force_p_newlines'] = true;
$scriptOptions['forced_root_block'] = 'p';
}
/**
* Shrink the buttons if not on a mobile or if mobile view is off.
* If mobile view is on force into simple mode and enlarge the buttons
**/
if (!$this->app->client->mobile)
{
$scriptOptions['toolbar_items_size'] = 'small';
}
elseif ($mobileVersion)
{
$mode = 0;
}
switch ($mode)
{
case 0: /* Simple mode*/
$scriptOptions['menubar'] = false;
$scriptOptions['toolbar1'] = 'bold italic underline strikethrough | undo redo | bullist numlist | code';
$scriptOptions['plugins'] = ' code';
break;
case 1:
default: /* Advanced mode*/
$toolbar1 = "bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | formatselect | bullist numlist "
. "| outdent indent | undo redo | link unlink anchor code | hr table | subscript superscript | charmap";
$scriptOptions['valid_elements'] = $valid_elements;
$scriptOptions['extended_valid_elements'] = $elements;
$scriptOptions['invalid_elements'] = $invalid_elements;
$scriptOptions['plugins'] = 'table link code hr charmap autolink lists importcss ';
$scriptOptions['toolbar1'] = $toolbar1;
$scriptOptions['removed_menuitems'] = 'newdocument';
$scriptOptions['importcss_append'] = true;
$scriptOptions['height'] = $html_height;
$scriptOptions['width'] = $html_width;
$scriptOptions['resize'] = $resizing;
break;
case 2: /* Extended mode*/
$scriptOptions['valid_elements'] = $valid_elements;
$scriptOptions['extended_valid_elements'] = $elements;
$scriptOptions['invalid_elements'] = $invalid_elements;
$scriptOptions['plugins'] = $plugins;
$scriptOptions['toolbar1'] = $toolbar1;
$scriptOptions['removed_menuitems'] = 'newdocument';
$scriptOptions['rel_list'] = array(
array('title' => 'None', 'value' => ''),
array('title' => 'Alternate', 'value' => 'alternate'),
array('title' => 'Author', 'value' => 'author'),
array('title' => 'Bookmark', 'value' => 'bookmark'),
array('title' => 'Help', 'value' => 'help'),
array('title' => 'License', 'value' => 'license'),
array('title' => 'Lightbox', 'value' => 'lightbox'),
array('title' => 'Next', 'value' => 'next'),
array('title' => 'No Follow', 'value' => 'nofollow'),
array('title' => 'No Referrer', 'value' => 'noreferrer'),
array('title' => 'Prefetch', 'value' => 'prefetch'),
array('title' => 'Prev', 'value' => 'prev'),
array('title' => 'Search', 'value' => 'search'),
array('title' => 'Tag', 'value' => 'tag'),
);
$scriptOptions['importcss_append'] = true;
$scriptOptions['image_advtab'] = $image_advtab;
$scriptOptions['height'] = $html_height;
$scriptOptions['width'] = $html_width;
$scriptOptions['resize'] = $resizing;
$scriptOptions['templates'] = $templates;
break;
}
$options['tinyMCE']['default'] = $scriptOptions;
$doc->addStyleDeclaration(".mce-in { padding: 5px 10px !important;}");
$doc->addScriptOptions('plg_editor_tinymce', $options);
return $editor;
}
}