first commit
This commit is contained in:
697
components/com_jce/editor/libraries/classes/document.php
Normal file
697
components/com_jce/editor/libraries/classes/document.php
Normal file
@@ -0,0 +1,697 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2009-2022 Ryan Demmer. All rights reserved
|
||||
* @license GNU/GPL 2 or later - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* JCE is free software. This version may have been modified pursuant
|
||||
* to the GNU General Public License, and as distributed it includes or
|
||||
* is derivative of works licensed under the GNU General Public License or
|
||||
* other free or open source software licenses
|
||||
*/
|
||||
defined('JPATH_PLATFORM') or die;
|
||||
|
||||
class WFDocument extends JObject
|
||||
{
|
||||
/**
|
||||
* Array of linked scripts.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $scripts = array();
|
||||
|
||||
/**
|
||||
* Array of scripts placed in the header.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $script = array();
|
||||
|
||||
/**
|
||||
* Array of linked style sheets.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $styles = array();
|
||||
|
||||
/**
|
||||
* Array of head items.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $head = array();
|
||||
|
||||
/**
|
||||
* Body content.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $body = '';
|
||||
|
||||
/**
|
||||
* Document title.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $title = '';
|
||||
|
||||
/**
|
||||
* Contains the document language setting.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $language = 'en-gb';
|
||||
|
||||
/**
|
||||
* Contains the document direction setting.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $direction = 'ltr';
|
||||
|
||||
private static $queryMap = array(
|
||||
'imgmanager'=> 'image',
|
||||
'imgmanager_ext' => 'imagepro'
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor activating the default information of the class.
|
||||
*/
|
||||
public function __construct($config = array())
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// set document title
|
||||
if (isset($config['title'])) {
|
||||
$this->setTitle($config['title']);
|
||||
}
|
||||
|
||||
$this->setProperties($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to a WFDocument object.
|
||||
*
|
||||
* This method must be invoked as:
|
||||
* <pre> $document = WFDocument::getInstance();</pre>
|
||||
*
|
||||
* @return object WFDocument
|
||||
*/
|
||||
public static function getInstance($config = array())
|
||||
{
|
||||
static $instance;
|
||||
|
||||
if (!is_object($instance)) {
|
||||
$instance = new self($config);
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the document title.
|
||||
*
|
||||
* @param string $title
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the document title.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the document name.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the document name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the editor URL.
|
||||
*
|
||||
* @param bool $relative
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getURL($relative = false)
|
||||
{
|
||||
if ($relative) {
|
||||
return JURI::root(true) . '/components/com_jce/editor';
|
||||
}
|
||||
|
||||
return JURI::root() . 'components/com_jce/editor';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the global document language declaration. Default is English (en-gb).
|
||||
*
|
||||
* @param string $lang
|
||||
*/
|
||||
public function setLanguage($lang = 'en-gb')
|
||||
{
|
||||
$this->language = strtolower($lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the document language.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLanguage()
|
||||
{
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the global document direction declaration. Default is left-to-right (ltr).
|
||||
*
|
||||
* @param string $lang
|
||||
*/
|
||||
public function setDirection($dir = 'ltr')
|
||||
{
|
||||
$this->direction = strtolower($dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the document language.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDirection()
|
||||
{
|
||||
return $this->direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JCE resource url.
|
||||
*
|
||||
* @param string The path to resolve eg: libaries
|
||||
* @param bool Create a relative url
|
||||
*
|
||||
* @return full url
|
||||
*/
|
||||
private function getBaseURL($path, $type = '')
|
||||
{
|
||||
static $url;
|
||||
|
||||
if (!isset($url)) {
|
||||
$url = array();
|
||||
}
|
||||
|
||||
$signature = serialize(array($type, $path));
|
||||
|
||||
// Check if value is already stored
|
||||
if (!isset($url[$signature])) {
|
||||
// get the plugin name using this document instance
|
||||
$plugin = $this->get('name');
|
||||
|
||||
$base = $this->getURL(true) . '/';
|
||||
|
||||
$parts = explode('.', $path);
|
||||
$path = array_shift($parts);
|
||||
|
||||
switch ($path) {
|
||||
// JCE root folder
|
||||
case 'jce':
|
||||
$pre = $base . '';
|
||||
break;
|
||||
// JCE libraries resource folder
|
||||
case 'libraries':
|
||||
$pre = $base . 'libraries/' . $type;
|
||||
break;
|
||||
case 'pro':
|
||||
$pre = $base . 'libraries/pro/' . $type;
|
||||
break;
|
||||
case 'jquery':
|
||||
$pre = $base . 'libraries/vendor/jquery/' . $type;
|
||||
break;
|
||||
// TinyMCE folder
|
||||
case 'tiny_mce':
|
||||
$pre = $base . 'tiny_mce';
|
||||
break;
|
||||
// Tinymce plugins folder
|
||||
case 'plugins':
|
||||
$pre = $base . 'tiny_mce/plugins/' . $plugin . '/' . $type;
|
||||
break;
|
||||
// Extensions folder
|
||||
case 'extensions':
|
||||
$pre = $base . 'extensions';
|
||||
break;
|
||||
case 'joomla':
|
||||
return JURI::root(true);
|
||||
break;
|
||||
case 'media':
|
||||
return JURI::root(true) . '/media/system';
|
||||
break;
|
||||
case 'component':
|
||||
$pre = JURI::root(true) . '/administrator/components/com_jce/media/' . $type;
|
||||
break;
|
||||
default:
|
||||
$pre = $base . $path;
|
||||
break;
|
||||
}
|
||||
|
||||
if (count($parts)) {
|
||||
$pre = rtrim($pre, '/') . '/' . implode('/', $parts);
|
||||
}
|
||||
|
||||
// Store url
|
||||
$url[$signature] = $pre;
|
||||
}
|
||||
|
||||
return $url[$signature];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a url to path.
|
||||
*
|
||||
* @param string $url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function urlToPath($url)
|
||||
{
|
||||
jimport('joomla.filesystem.path');
|
||||
|
||||
$root = JURI::root(true);
|
||||
|
||||
// remove root from url
|
||||
if (!empty($root)) {
|
||||
$url = substr($url, strlen($root));
|
||||
}
|
||||
|
||||
return WFUtility::makePath(JPATH_SITE, JPath::clean($url));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an image url.
|
||||
*
|
||||
* @param string The file to load including path and extension eg: libaries.image.gif
|
||||
*
|
||||
* @return Image url
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public function image($image, $root = 'libraries')
|
||||
{
|
||||
$parts = explode('.', $image);
|
||||
$parts = preg_replace('#[^A-Z0-9-_]#i', '', $parts);
|
||||
|
||||
$ext = array_pop($parts);
|
||||
$name = trim(array_pop($parts), '/');
|
||||
|
||||
$parts[] = 'img';
|
||||
$parts[] = $name . '.' . $ext;
|
||||
|
||||
return $this->getBaseURL($root) . implode('/', $parts);
|
||||
}
|
||||
|
||||
public function removeScript($file, $root = 'libraries')
|
||||
{
|
||||
$file = $this->buildScriptPath($file, $root);
|
||||
unset($this->scripts[$file]);
|
||||
}
|
||||
|
||||
public function removeCss($file, $root = 'libraries')
|
||||
{
|
||||
$file = $this->buildStylePath($file, $root);
|
||||
unset($this->styles[$file]);
|
||||
}
|
||||
|
||||
public function buildScriptPath($file, $root)
|
||||
{
|
||||
$file = preg_replace('#[^A-Z0-9-_\/\.]#i', '', $file);
|
||||
// get base dir
|
||||
$base = dirname($file);
|
||||
// remove extension if present
|
||||
$file = basename($file, '.js');
|
||||
// strip . and trailing /
|
||||
$file = trim(trim($base, '.'), '/') . '/' . $file . '.js';
|
||||
// remove leading and trailing slashes
|
||||
$file = trim($file, '/');
|
||||
// create path
|
||||
$file = $this->getBaseURL($root, 'js') . '/' . $file;
|
||||
// remove duplicate slashes
|
||||
$file = preg_replace('#[/\\\\]+#', '/', $file);
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
public function buildStylePath($file, $root)
|
||||
{
|
||||
$file = preg_replace('#[^A-Z0-9-_\/\.]#i', '', $file);
|
||||
// get base dir
|
||||
$base = dirname($file);
|
||||
// remove extension if present
|
||||
$file = basename($file, '.css');
|
||||
// strip . and trailing /
|
||||
$file = trim(trim($base, '.'), '/') . '/' . $file . '.css';
|
||||
// remove leading and trailing slashes
|
||||
$file = trim($file, '/');
|
||||
// create path
|
||||
$file = $this->getBaseURL($root, 'css') . '/' . $file;
|
||||
// remove duplicate slashes
|
||||
$file = preg_replace('#[/\\\\]+#', '/', $file);
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a javascript file.
|
||||
*
|
||||
* @param string The file to load including path eg: libaries.manager
|
||||
* @param bool Debug mode load src file
|
||||
*
|
||||
* @return echo script html
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public function addScript($files, $root = 'libraries', $type = 'text/javascript')
|
||||
{
|
||||
$files = (array) $files;
|
||||
|
||||
foreach ($files as $file) {
|
||||
// external link
|
||||
if (strpos($file, '://') !== false || strpos($file, 'index.php?option=com_jce') !== false) {
|
||||
$this->scripts[$file] = $type;
|
||||
} else {
|
||||
$file = $this->buildScriptPath($file, $root);
|
||||
// store path
|
||||
$this->scripts[$file] = $type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a css file.
|
||||
*
|
||||
* @param string The file to load including path eg: libaries.manager
|
||||
* @param string Root folder
|
||||
*
|
||||
* @return echo css html
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public function addStyleSheet($files, $root = 'libraries', $type = 'text/css')
|
||||
{
|
||||
$files = (array) $files;
|
||||
|
||||
foreach ($files as $file) {
|
||||
$url = $this->buildStylePath($file, $root);
|
||||
// store path
|
||||
$this->styles[$url] = $type;
|
||||
}
|
||||
}
|
||||
|
||||
public function addScriptDeclaration($content, $type = 'text/javascript')
|
||||
{
|
||||
if (!isset($this->script[strtolower($type)])) {
|
||||
$this->script[strtolower($type)] = $content;
|
||||
} else {
|
||||
$this->script[strtolower($type)] .= chr(13) . $content;
|
||||
}
|
||||
}
|
||||
|
||||
private function getScriptDeclarations()
|
||||
{
|
||||
return $this->script;
|
||||
}
|
||||
|
||||
private function getScripts()
|
||||
{
|
||||
return $this->scripts;
|
||||
}
|
||||
|
||||
private function getStyleSheets()
|
||||
{
|
||||
return $this->styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup head data.
|
||||
*/
|
||||
private function setHead($data)
|
||||
{
|
||||
if (is_array($data)) {
|
||||
$this->head = array_merge($this->head, $data);
|
||||
} else {
|
||||
$this->head[] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
public function getQueryString($query = array())
|
||||
{
|
||||
$app = JFactory::getApplication();
|
||||
|
||||
// get plugin name and assign to query
|
||||
$name = $this->get('name');
|
||||
|
||||
// re-map plugin name
|
||||
if (array_key_exists($name, self::$queryMap)) {
|
||||
$name = self::$queryMap[$name];
|
||||
}
|
||||
|
||||
$query['plugin'] = $name;
|
||||
|
||||
// set slot
|
||||
$query['slot'] = $app->input->getCmd('slot');
|
||||
|
||||
// set standalone mode (for File Browser etc)
|
||||
$query['standalone'] = $this->get('standalone');
|
||||
|
||||
// set context id
|
||||
$query['context'] = $app->input->getInt('context');
|
||||
|
||||
// get token
|
||||
$token = JSession::getFormToken();
|
||||
|
||||
// set token
|
||||
$query[$token] = 1;
|
||||
|
||||
$output = array();
|
||||
|
||||
foreach ($query as $key => $value) {
|
||||
if ($value) {
|
||||
$output[] = $key . '=' . $value;
|
||||
}
|
||||
}
|
||||
|
||||
return implode('&', $output);
|
||||
}
|
||||
|
||||
private function getHash($files)
|
||||
{
|
||||
$seed = '';
|
||||
$hash = '';
|
||||
|
||||
// cast as array
|
||||
$files = (array) $files;
|
||||
|
||||
foreach ($files as $file) {
|
||||
|
||||
// only add stamp to static stylesheets
|
||||
if (strpos($file, '://') === false && strpos($file, 'index.php?option=com_jce') === false) {
|
||||
$seed .= basename($file);
|
||||
}
|
||||
}
|
||||
|
||||
if ($seed) {
|
||||
$hash = md5(WF_VERSION . $seed);
|
||||
}
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render document head data.
|
||||
*/
|
||||
private function getHead()
|
||||
{
|
||||
// set title
|
||||
$output = '<title>' . $this->getTitle() . '</title>' . "\n";
|
||||
|
||||
// render stylesheets
|
||||
if ($this->get('compress_css', 0)) {
|
||||
$file = JURI::base(true) . '/index.php?option=com_jce&' . $this->getQueryString(array('task' => 'plugin.pack', 'type' => 'css'));
|
||||
// add hash
|
||||
$file .= '&' . $this->getHash(array_keys($this->styles));
|
||||
|
||||
$output .= "\t\t<link href=\"" . $file . "\" rel=\"stylesheet\" type=\"text/css\" />\n";
|
||||
} else {
|
||||
foreach ($this->styles as $src => $type) {
|
||||
$hash = $this->getHash($src);
|
||||
|
||||
// only add stamp to static stylesheets
|
||||
if (!empty($hash)) {
|
||||
$hash = strpos($src, '?') === false ? '?' . $hash : '&' . $hash;
|
||||
}
|
||||
|
||||
$output .= "\t\t<link href=\"" . $src . $hash . '" rel="stylesheet" type="' . $type . "\" />\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Render scripts
|
||||
if ($this->get('compress_javascript', 0)) {
|
||||
$script = JURI::base(true) . '/index.php?option=com_jce&' . $this->getQueryString(array('task' => 'plugin.pack'));
|
||||
// add hash
|
||||
$script .= '&' . $this->getHash(array_keys($this->scripts));
|
||||
|
||||
$output .= "\t\t<script data-cfasync=\"false\" type=\"text/javascript\" src=\"" . $script . "\"></script>\n";
|
||||
} else {
|
||||
foreach ($this->scripts as $src => $type) {
|
||||
$hash = $this->getHash($src);
|
||||
|
||||
// only add stamp to static stylesheets
|
||||
if (!empty($hash)) {
|
||||
$hash = strpos($src, '?') === false ? '?' . $hash : '&' . $hash;
|
||||
}
|
||||
|
||||
$output .= "\t\t<script data-cfasync=\"false\" type=\"" . $type . '" src="' . $src . $hash . "\"></script>\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Script declarations
|
||||
foreach ($this->script as $type => $content) {
|
||||
$output .= "\t\t<script data-cfasync=\"false\" type=\"" . $type . '">' . $content . '</script>';
|
||||
}
|
||||
|
||||
// Other head data
|
||||
foreach ($this->head as $head) {
|
||||
$output .= "\t" . $head . "\n";
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function setBody($data = '')
|
||||
{
|
||||
$this->body = $data;
|
||||
}
|
||||
|
||||
private function getBody()
|
||||
{
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
private function loadData()
|
||||
{
|
||||
//get the file content
|
||||
ob_start();
|
||||
require_once WF_EDITOR_LIBRARIES . '/views/plugin/index.php';
|
||||
$data = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the document.
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
// assign language
|
||||
$this->language = $this->getLanguage();
|
||||
$this->direction = $this->getDirection();
|
||||
|
||||
// load template data
|
||||
$output = $this->loadData();
|
||||
$output = $this->parseData($output);
|
||||
|
||||
exit($output);
|
||||
}
|
||||
|
||||
private function parseData($data)
|
||||
{
|
||||
$data = preg_replace_callback('#<!-- \[head\] -->#', array($this, 'getHead'), $data);
|
||||
$data = preg_replace_callback('#<!-- \[body\] -->#', array($this, 'getBody'), $data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* pack function for plugins.
|
||||
*/
|
||||
public function pack($minify = true, $gzip = false)
|
||||
{
|
||||
$app = JFactory::getApplication();
|
||||
|
||||
if ($app->input->getCmd('task') == 'pack') {
|
||||
|
||||
// check token
|
||||
JSession::checkToken('get') or jexit();
|
||||
|
||||
$type = $app->input->getWord('type', 'javascript');
|
||||
|
||||
// create packer
|
||||
$packer = new WFPacker(array('type' => $type));
|
||||
|
||||
$files = array();
|
||||
|
||||
switch ($type) {
|
||||
case 'javascript':
|
||||
$data = '';
|
||||
|
||||
foreach ($this->getScripts() as $src => $type) {
|
||||
if (strpos($src, '://') === false && strpos($src, 'index.php') === false) {
|
||||
$src .= preg_match('/\.js$/', $src) ? '' : '.js';
|
||||
|
||||
$files[] = $this->urlToPath($src);
|
||||
}
|
||||
}
|
||||
|
||||
// parse ini language files
|
||||
$parser = new WFLanguageParser(array(
|
||||
'plugins' => array('core' => array($this->getName()), 'external' => array()),
|
||||
'sections' => array('dlg', $this->getName() . '_dlg'),
|
||||
'mode' => 'plugin',
|
||||
'language' => WFLanguage::getTag()
|
||||
));
|
||||
|
||||
$data .= $parser->load();
|
||||
|
||||
// add script declarations
|
||||
/*foreach ($this->getScriptDeclarations() as $script) {
|
||||
$data .= $script;
|
||||
}*/
|
||||
|
||||
$packer->setContentEnd($data);
|
||||
|
||||
break;
|
||||
case 'css':
|
||||
foreach ($this->getStyleSheets() as $style => $type) {
|
||||
if (strpos($style, '://') === false && strpos($style, 'index.php') === false) {
|
||||
$style .= preg_match('/\.css$/', $style) ? '' : '.css';
|
||||
|
||||
$files[] = $this->urlToPath($style);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$packer->setFiles($files);
|
||||
$packer->pack($minify, $gzip);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user