Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.1] TinyMCE changes for child templates 3/3 #36011

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions plugins/editors/tinymce/forms/setoptions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,9 @@

<field
name="content_template_path"
type="folderlist"
type="templateslist"
label="PLG_TINY_FIELD_CUSTOM_CONTENT_TEMPLATE_PATH_LABEL"
description="PLG_TINY_FIELD_CUSTOM_CONTENT_TEMPLATE_PATH_DESC"
directory="/templates"
hide_none="true"
recursive="true"
exclude="system"
default=""
folderFilter="^tinymce"
validate="options"
Expand Down
98 changes: 98 additions & 0 deletions plugins/editors/tinymce/src/Field/TemplateslistField.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php
/**
* @package Joomla.Plugin
* @subpackage Editors.tinymce
*
* @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/

namespace Joomla\Plugin\Editors\TinyMCE\Field;

\defined('_JEXEC') or die;

use Joomla\CMS\Form\Field\FolderlistField;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;

/**
* Generates the list of directories available for template snippets.
*
* @since __DEPLOY_VERSION__
*/
class TemplatesListField extends FolderlistField
{
protected $type = 'templatesList';

/**
* Method to attach a JForm object to the field.
*
* @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object.
* @param mixed $value The form field value to validate.
* @param string $group The field name group control value. This acts as an array container for the field.
* For example if the field has name="foo" and the group value is set to "bar" then the
* full field name would end up being "bar[foo]".
*
* @return boolean True on success.
*
* @see \Joomla\CMS\Form\FormField::setup()
* @since __DEPLOY_VERSION__
*/
public function setup(\SimpleXMLElement $element, $value, $group = null)
{
$return = parent::setup($element, $value, $group);

// Set some defaults.
$this->recursive = true;
$this->hideDefault = true;
$this->exclude = 'system';
$this->hideNone = true;

return $return;
}

/**
* Method to get the directories options.
*
* @return array The dirs option objects.
*
* @since __DEPLOY_VERSION__
*/
public function getOptions()
{
$def = new \stdClass;
$def->value = '';
$def->text = Text::_('JOPTION_DO_NOT_USE');
$options = [0 => $def];
$directories = [JPATH_ROOT . '/templates', JPATH_ROOT . '/media/templates/site'];

foreach ($directories as $directory)
{
$this->directory = $directory;
$options = array_merge($options, parent::getOptions());
}

return $options;
}

/**
* Method to get the field input markup for the list of directories.
*
* @return string The field input markup.
*
* @since __DEPLOY_VERSION__
*/
protected function getInput()
{
return HTMLHelper::_(
'select.genericlist',
(array) $this->getOptions(),
$this->name,
'class="form-select"',
'value',
'text',
$this->value,
$this->id
);
}
}
195 changes: 138 additions & 57 deletions plugins/editors/tinymce/tinymce.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
use Joomla\CMS\Access\Access;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Filesystem\File;
use Joomla\CMS\Filesystem\Folder;
use Joomla\CMS\Filter\InputFilter;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Session\Session;
use Joomla\CMS\Uri\Uri;
Expand Down Expand Up @@ -262,36 +262,7 @@ public function onDisplay(

$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 = Factory::getDbo();
$query = $db->getQuery(true)
->select($db->quoteName('template'))
->from($db->quoteName('#__template_styles'))
->where(
[
$db->quoteName('client_id') . ' = 0',
$db->quoteName('home') . ' = ' . $db->quote('1'),
]
);

$db->setQuery($query);

try
{
$template = $db->loadResult();
}
catch (RuntimeException $e)
{
$this->app->enqueueMessage(Text::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error');

return '';
}

$content_css = null;
$templates_path = JPATH_SITE . '/templates';
$content_css = null;

// Loading of css file for 'styles' dropdown
if ($content_css_custom)
Expand All @@ -305,39 +276,15 @@ public function onDisplay(
// If it is not a URL, assume it is a file name in the current template folder
else
{
$content_css = Uri::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(Text::_('PLG_TINY_ERR_CUSTOMCSSFILENOTPRESENT'), $content_css_custom);
Log::add($msg, Log::WARNING, 'jerror');
}
$content_css = $this->includeRelativeFiles('css', $content_css_custom);
}
}
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'))
{
Log::add(Text::_('PLG_TINY_ERR_EDITORCSSFILENOTPRESENT'), Log::WARNING, 'jerror');
}
else
{
$content_css = Uri::root(true) . '/templates/system/css/editor.css';
}
}
else
{
$content_css = Uri::root(true) . '/templates/' . $template . '/css/editor.css';
}
$content_css = $this->includeRelativeFiles('css', 'editor' . (JDEBUG ? '' : '.min') . '.css');
}
}

Expand Down Expand Up @@ -1159,4 +1106,138 @@ private function removeElementWithValue($array, $key, $value)

return $array;
}

/**
* Helper function to get the active Site template
*
* @return object
*
* @since __DEPLOY_VERSION__
*/
protected function getActiveSiteTemplate()
{
$db = Factory::getContainer()->get('db');
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__template_styles'))
->where(
[
$db->quoteName('client_id') . ' = 0',
$db->quoteName('home') . ' = ' . $db->quote('1'),
]
);

$db->setQuery($query);

try
{
return $db->loadObject();
}
catch (RuntimeException $e)
{
$this->app->enqueueMessage(Text::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error');

return new \stdClass;
}
}

/**
* Compute the files to be included
*
* @param string $folder Folder name to search in (i.e. images, css, js).
* @param string $file Path to file.
*
* @return array files to be included.
*
* @since __DEPLOY_VERSION__
*/
protected function includeRelativeFiles($folder, $file)
{
$fallback = Uri::root(true) . '/media/system/css/editor' . (JDEBUG ? '' : '.min') . '.css';
$template = $this->getActiveSiteTemplate();

if (!(array) $template)
{
return $fallback;
}

// Extract extension and strip the file
$file = File::stripExt($file). '.' . File::getExt($file);
$templaPath = JPATH_ROOT . '/templates';

if ($template->inheritable || (isset($template->parent) && $template->parent !== ''))
{
$templaPath = JPATH_ROOT . '/media/templates/site';
}

if (isset($template->parent) && $template->parent !== '')
{
$found = static::resolveFileUrl("$templaPath/$template->template/$folder/$file");

if (empty($found))
{
$found = static::resolveFileUrl("$templaPath/$template->parent/$folder/$file");
}
}
else
{
$found = static::resolveFileUrl("$templaPath/$template->template/$folder/$file");
}

if (empty($found))
{
return $fallback;
}

return $found;
}

/**
* Method that searches if file exists in given path and returns the relative path. If a minified version exists it will be preferred.
*
* @param string $path The actual path of the file
*
* @return string The relative path of the file
*
* @since __DEPLOY_VERSION__
*/
protected static function resolveFileUrl($path = '')
{
$position = strrpos($path, '.min.');

// We are handling a name.min.ext file:
if ($position !== false)
{
$minifiedPath = $path;
$nonMinifiedPath = substr_replace($path, '', $position, 4);

if (JDEBUG && is_file($nonMinifiedPath))
{
return Uri::root(true) . str_replace(JPATH_ROOT, '', $nonMinifiedPath);
}
elseif (is_file($minifiedPath))
{
return Uri::root(true) . str_replace(JPATH_ROOT, '', $minifiedPath);
}
else
{
return '';
}
}

$minifiedPath = pathinfo($path, PATHINFO_DIRNAME) . '/' . pathinfo($path, PATHINFO_FILENAME) . '.min.' . pathinfo($path, PATHINFO_EXTENSION);

if (JDEBUG && is_file($path))
{
return Uri::root(true) . str_replace(JPATH_ROOT, '', $path);
}
elseif (is_file($minifiedPath))
{
return Uri::root(true) . str_replace(JPATH_ROOT, '', $minifiedPath);
}
else
{
return '';
}
}
}