PageRenderTime 36ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/components/com_jce/editor/libraries/classes/document.php

https://bitbucket.org/pastor399/newcastleunifc
PHP | 662 lines | 330 code | 109 blank | 223 comment | 31 complexity | 3b73ad092d911f7370905eb5a8348f39 MD5 | raw file
  1. <?php
  2. /**
  3. * @package JCE
  4. * @copyright Copyright (c) 2009-2013 Ryan Demmer. All rights reserved.
  5. * @license GNU/GPL 2 or later - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  6. * JCE is free software. This version may have been modified pursuant
  7. * to the GNU General Public License, and as distributed it includes or
  8. * is derivative of works licensed under the GNU General Public License or
  9. * other free or open source software licenses.
  10. */
  11. defined('_JEXEC') or die('RESTRICTED');
  12. class WFDocument extends JObject {
  13. /**
  14. * Array of linked scripts
  15. *
  16. * @var array
  17. * @access private
  18. */
  19. private $_scripts = array();
  20. /**
  21. * Array of scripts placed in the header
  22. *
  23. * @var array
  24. * @access private
  25. */
  26. private $_script = array();
  27. /**
  28. * Array of linked style sheets
  29. *
  30. * @var array
  31. * @access private
  32. */
  33. private $_styles = array();
  34. /**
  35. * Array of head items
  36. *
  37. * @var array
  38. * @access private
  39. */
  40. private $_head = array();
  41. /**
  42. * Body content
  43. *
  44. * @var array
  45. * @access private
  46. */
  47. private $_body = '';
  48. /**
  49. * Document title
  50. *
  51. * @var string
  52. * @access public
  53. */
  54. public $title = '';
  55. /**
  56. * Document version
  57. *
  58. * @var string
  59. * @access public
  60. */
  61. public $version = '000000';
  62. /**
  63. * Contains the document language setting
  64. *
  65. * @var string
  66. * @access public
  67. */
  68. public $language = 'en-gb';
  69. /**
  70. * Contains the document direction setting
  71. *
  72. * @var string
  73. * @access public
  74. */
  75. public $direction = 'ltr';
  76. /**
  77. * Constructor activating the default information of the class
  78. *
  79. * @access protected
  80. */
  81. public function __construct($config = array()) {
  82. parent::__construct();
  83. // set document title
  84. if (isset($config['title'])) {
  85. $this->setTitle($config['title']);
  86. }
  87. $this->setProperties($config);
  88. }
  89. /**
  90. * Returns a reference to a WFDocument object
  91. *
  92. * This method must be invoked as:
  93. * <pre> $document = WFDocument::getInstance();</pre>
  94. *
  95. * @access public
  96. * @return object WFDocument
  97. */
  98. public static function getInstance($config = array()) {
  99. static $instance;
  100. if (!is_object($instance)) {
  101. $instance = new WFDocument($config);
  102. }
  103. return $instance;
  104. }
  105. /**
  106. * Set the document title
  107. * @access public
  108. * @param string $title
  109. */
  110. public function setTitle($title) {
  111. $this->title = $title;
  112. }
  113. /**
  114. * Get the document title
  115. * @access public
  116. * @return string
  117. */
  118. public function getTitle() {
  119. return $this->title;
  120. }
  121. /**
  122. * Set the document name
  123. * @access public
  124. * @param string $name
  125. */
  126. public function setName($name) {
  127. $this->name = $name;
  128. }
  129. /**
  130. * Get the document name
  131. * @access public
  132. * @return string
  133. */
  134. public function getName() {
  135. return $this->name;
  136. }
  137. /**
  138. * Get the editor URL
  139. * @access private
  140. * @param bool $relative
  141. * @return string
  142. */
  143. private function getURL($relative = false) {
  144. if ($relative) {
  145. return JURI::root(true) . '/components/com_jce/editor';
  146. }
  147. return JURI::root() . 'components/com_jce/editor';
  148. }
  149. /**
  150. * Sets the global document language declaration. Default is English (en-gb).
  151. * @access public
  152. * @param string $lang
  153. */
  154. public function setLanguage($lang = "en-gb") {
  155. $this->language = strtolower($lang);
  156. }
  157. /**
  158. * Returns the document language.
  159. *
  160. * @return string
  161. * @access public
  162. */
  163. public function getLanguage() {
  164. return $this->language;
  165. }
  166. /**
  167. * Sets the global document direction declaration. Default is left-to-right (ltr).
  168. *
  169. * @access public
  170. * @param string $lang
  171. */
  172. public function setDirection($dir = "ltr") {
  173. $this->direction = strtolower($dir);
  174. }
  175. /**
  176. * Returns the document language.
  177. *
  178. * @return string
  179. * @access public
  180. */
  181. public function getDirection() {
  182. return $this->direction;
  183. }
  184. /**
  185. * Returns a JCE resource url
  186. *
  187. * @access private
  188. * @param string The path to resolve eg: libaries
  189. * @param boolean Create a relative url
  190. * @return full url
  191. */
  192. private function getBaseURL($path, $type = '') {
  193. static $url;
  194. if (!isset($url)) {
  195. $url = array();
  196. }
  197. $signature = serialize(array($type, $path));
  198. // Check if value is already stored
  199. if (!isset($url[$signature])) {
  200. // get the plugin name using this document instance
  201. $plugin = $this->get('name');
  202. $base = $this->getURL(true) . '/';
  203. $parts = explode('.', $path);
  204. $path = array_shift($parts);
  205. switch ($path) {
  206. // JCE root folder
  207. case 'jce':
  208. $pre = $base . '';
  209. break;
  210. // JCE libraries resource folder
  211. default:
  212. case 'libraries':
  213. $pre = $base . 'libraries/' . $type;
  214. break;
  215. case 'jquery':
  216. $pre = $base . 'libraries/jquery/' . $type;
  217. break;
  218. case 'mediaelement':
  219. $pre = $base . 'libraries/mediaelement/' . $type;
  220. break;
  221. case 'bootstrap':
  222. $pre = $base . 'libraries/bootstrap/' . $type;
  223. break;
  224. // TinyMCE folder
  225. case 'tiny_mce':
  226. $pre = $base . 'tiny_mce';
  227. break;
  228. // JCE current plugin folder
  229. case 'plugins':
  230. $pre = $base . 'tiny_mce/plugins/' . $plugin . '/' . $type;
  231. break;
  232. // Extensions folder
  233. case 'extensions':
  234. $pre = $base . 'extensions';
  235. break;
  236. case 'joomla':
  237. return JURI::root(true);
  238. break;
  239. case 'media':
  240. return JURI::root(true) . '/media/system';
  241. break;
  242. case 'component':
  243. $pre = JURI::root(true) . '/administrator/components/com_jce/media/' . $type;
  244. break;
  245. default:
  246. $pre = $base . $path;
  247. break;
  248. }
  249. if (count($parts)) {
  250. $pre = rtrim($pre, '/') . '/' . implode('/', $parts);
  251. }
  252. // Store url
  253. $url[$signature] = $pre;
  254. }
  255. return $url[$signature];
  256. }
  257. /**
  258. * Convert a url to path
  259. *
  260. * @param string $url
  261. * @return string
  262. */
  263. private function urlToPath($url) {
  264. jimport('joomla.filesystem.path');
  265. $bool = strpos($url, JURI::root()) === false;
  266. return WFUtility::makePath(JPATH_SITE, JPath::clean(ltrim($url, JURI::root($bool))));
  267. }
  268. /**
  269. * Returns an image url
  270. *
  271. * @access public
  272. * @param string The file to load including path and extension eg: libaries.image.gif
  273. * @return Image url
  274. * @since 1.5
  275. */
  276. public function image($image, $root = 'libraries') {
  277. $parts = explode('.', $image);
  278. $parts = preg_replace('#[^A-Z0-9-_]#i', '', $parts);
  279. $ext = array_pop($parts);
  280. $name = trim(array_pop($parts), '/');
  281. $parts[] = 'img';
  282. $parts[] = $name . "." . $ext;
  283. return $this->getBaseURL($root) . implode('/', $parts);
  284. }
  285. public function removeScript($file, $root = 'libraries') {
  286. $file = $this->buildScriptPath($file, $root);
  287. unset($this->_scripts[$file]);
  288. }
  289. public function removeCss($file, $root = 'libraries') {
  290. $file = $this->buildStylePath($file, $root);
  291. unset($this->_styles[$file]);
  292. }
  293. public function buildScriptPath($file, $root) {
  294. $file = preg_replace('#[^A-Z0-9-_\/\.]#i', '', $file);
  295. // get base dir
  296. $base = dirname($file);
  297. // remove extension if present
  298. $file = basename($file, '.js');
  299. // strip . and trailing /
  300. $file = trim(trim($base, '.'), '/') . '/' . $file . '.js';
  301. // remove leading and trailing slashes
  302. $file = trim($file, '/');
  303. // create path
  304. $file = $this->getBaseURL($root, 'js') . '/' . $file;
  305. return $file;
  306. }
  307. public function buildStylePath($file, $root) {
  308. $file = preg_replace('#[^A-Z0-9-_\/\.]#i', '', $file);
  309. // get base dir
  310. $base = dirname($file);
  311. // remove extension if present
  312. $file = basename($file, '.css');
  313. // strip . and trailing /
  314. $file = trim(trim($base, '.'), '/') . '/' . $file . '.css';
  315. // remove leading and trailing slashes
  316. $file = trim($file, '/');
  317. // create path
  318. $file = $this->getBaseURL($root, 'css') . '/' . $file;
  319. return $file;
  320. }
  321. /**
  322. * Loads a javascript file
  323. *
  324. * @access public
  325. * @param string The file to load including path eg: libaries.manager
  326. * @param boolean Debug mode load src file
  327. * @return echo script html
  328. * @since 1.5
  329. */
  330. public function addScript($files, $root = 'libraries', $type = 'text/javascript') {
  331. $files = (array) $files;
  332. foreach ($files as $file) {
  333. // external link
  334. if (strpos($file, '://') !== false || strpos($file, 'index.php?option=com_jce') !== false) {
  335. $this->_scripts[$file] = $type;
  336. } else {
  337. $file = $this->buildScriptPath($file, $root);
  338. // store path
  339. $this->_scripts[$file] = $type;
  340. }
  341. }
  342. }
  343. /**
  344. * Loads a css file
  345. *
  346. * @access public
  347. * @param string The file to load including path eg: libaries.manager
  348. * @param string Root folder
  349. * @return echo css html
  350. * @since 1.5
  351. */
  352. public function addStyleSheet($files, $root = 'libraries', $type = 'text/css') {
  353. $files = (array) $files;
  354. jimport('joomla.environment.browser');
  355. $browser = JBrowser::getInstance();
  356. foreach ($files as $file) {
  357. $url = $this->buildStylePath($file, $root);
  358. // store path
  359. $this->_styles[$url] = $type;
  360. if ($browser->getBrowser() == 'msie') {
  361. // All versions
  362. $file = $file . '_ie.css';
  363. $path = $this->urlToPath($url);
  364. if (file_exists(dirname($path) . '/' . $file)) {
  365. $this->_styles[dirname($url) . '/' . $file] = $type;
  366. }
  367. }
  368. }
  369. }
  370. public function addScriptDeclaration($content, $type = 'text/javascript') {
  371. if (!isset($this->_script[strtolower($type)])) {
  372. $this->_script[strtolower($type)] = $content;
  373. } else {
  374. $this->_script[strtolower($type)] .= chr(13) . $content;
  375. }
  376. }
  377. private function getScriptDeclarations() {
  378. return $this->_script;
  379. }
  380. private function getScripts() {
  381. return $this->_scripts;
  382. }
  383. private function getStyleSheets() {
  384. return $this->_styles;
  385. }
  386. /**
  387. * Setup head data
  388. */
  389. private function setHead($data) {
  390. if (is_array($data)) {
  391. $this->_head = array_merge($this->_head, $data);
  392. } else {
  393. $this->_head[] = $data;
  394. }
  395. }
  396. public function getQueryString($query = array()) {
  397. // get version
  398. $version = $this->get('version', '000000');
  399. // get layout
  400. $layout = JRequest::getWord('layout');
  401. // set layout and item, eg: &layout=plugin&plugin=link
  402. $query['layout'] = $layout;
  403. $query[$layout] = JRequest::getWord($layout);
  404. // set dialog
  405. if (JRequest::getWord('dialog')) {
  406. $query['dialog'] = JRequest::getWord('dialog');
  407. }
  408. // set standalone mode (for File Browser etc)
  409. if ($this->get('standalone') == 1) {
  410. $query['standalone'] = 1;
  411. }
  412. // get component id
  413. $component_id = JRequest::getInt('component_id');
  414. // set component id
  415. if ($component_id) {
  416. $query['component_id'] = $component_id;
  417. }
  418. // get token
  419. $token = WFToken::getToken();
  420. // set token
  421. $query[$token] = 1;
  422. if (preg_match('/\d+/', $version)) {
  423. // set version
  424. $query['v'] = preg_replace('#[^a-z0-9]#i', '', $version);
  425. }
  426. $output = array();
  427. foreach ($query as $key => $value) {
  428. $output[] = $key . '=' . $value;
  429. }
  430. return implode('&', $output);
  431. }
  432. /**
  433. * Render document head data
  434. */
  435. private function getHead() {
  436. $version = $this->get('version', '000000');
  437. // set title
  438. $output = '<title>' . $this->getTitle() . '</title>' . "\n";
  439. // render stylesheets
  440. if ($this->get('compress_css', 0)) {
  441. $file = JURI::base(true) . '/index.php?option=com_jce&view=editor&' . $this->getQueryString(array('task' => 'pack', 'type' => 'css'));
  442. $output .= "\t\t<link href=\"" . $file . "\" rel=\"stylesheet\" type=\"text/css\" />\n";
  443. } else {
  444. foreach ($this->_styles as $src => $type) {
  445. $stamp = '';
  446. if (strpos($src, '://') === false) {
  447. $stamp = strpos($src, '?') === false ? '?v=' . $version : '&v=' . $version;
  448. }
  449. $output .= "\t\t<link href=\"" . $src . $stamp . "\" rel=\"stylesheet\" type=\"" . $type . "\" />\n";
  450. }
  451. }
  452. // Render scripts
  453. if ($this->get('compress_javascript', 0)) {
  454. $script = JURI::base(true) . '/index.php?option=com_jce&view=editor&' . $this->getQueryString(array('task' => 'pack'));
  455. $output .= "\t\t<script type=\"text/javascript\" src=\"" . $script . "\"></script>\n";
  456. } else {
  457. foreach ($this->_scripts as $src => $type) {
  458. $stamp = '';
  459. if (strpos($src, '://') === false) {
  460. $stamp = strpos($src, '?') === false ? '?v=' . $version : '&v=' . $version;
  461. }
  462. $output .= "\t\t<script type=\"" . $type . "\" src=\"" . $src . $stamp . "\"></script>\n";
  463. }
  464. // Script declarations
  465. foreach ($this->_script as $type => $content) {
  466. $output .= "\t\t<script type=\"" . $type . "\">" . $content . "</script>";
  467. }
  468. }
  469. // Other head data
  470. foreach ($this->_head as $head) {
  471. $output .= "\t" . $head . "\n";
  472. }
  473. return $output;
  474. }
  475. public function setBody($data = '') {
  476. $this->_body = $data;
  477. }
  478. private function getBody() {
  479. return $this->_body;
  480. }
  481. private function loadData() {
  482. //get the file content
  483. ob_start();
  484. require_once(WF_EDITOR_LIBRARIES . '/views/plugin/index.php');
  485. $data = ob_get_contents();
  486. ob_end_clean();
  487. return $data;
  488. }
  489. /**
  490. * Render the document
  491. */
  492. public function render() {
  493. // assign language
  494. $this->language = $this->getLanguage();
  495. $this->direction = $this->getDirection();
  496. // load template data
  497. $output = $this->loadData();
  498. $output = $this->parseData($output);
  499. exit($output);
  500. }
  501. private function parseData($data) {
  502. $data = preg_replace_callback('#<!-- \[head\] -->#', array($this, 'getHead'), $data);
  503. $data = preg_replace_callback('#<!-- \[body\] -->#', array($this, 'getBody'), $data);
  504. return $data;
  505. }
  506. /**
  507. * pack function for plugins
  508. */
  509. public function pack($minify = true, $gzip = false) {
  510. if (JRequest::getCmd('task') == 'pack') {
  511. // check token
  512. WFToken::checkToken('GET') or die('RESTRICTED');
  513. wfimport('admin.classes.packer');
  514. wfimport('admin.classes.language');
  515. $component = WFExtensionHelper::getComponent();
  516. $params = new WFParameter($component->params);
  517. $type = JRequest::getWord('type', 'javascript');
  518. // create packer
  519. $packer = new WFPacker(array('type' => $type));
  520. $files = array();
  521. switch ($type) {
  522. case 'javascript':
  523. $data = '';
  524. foreach ($this->getScripts() as $script => $type) {
  525. $script .= preg_match('/\.js$/', $script) ? '' : '.js';
  526. $files[] = $this->urlToPath($script);
  527. }
  528. // parse ini language files
  529. $parser = new WFLanguageParser(array(
  530. 'plugins' => array($this->getName()),
  531. 'sections' => array('dlg', $this->getName() . '_dlg'),
  532. 'mode' => 'plugin'
  533. ));
  534. $data .= $parser->load();
  535. // add script declarations
  536. foreach ($this->getScriptDeclarations() as $script) {
  537. $data .= $script;
  538. }
  539. $packer->setContentEnd($data);
  540. break;
  541. case 'css':
  542. foreach ($this->getStyleSheets() as $style => $type) {
  543. $style .= preg_match('/\.css$/', $style) ? '' : '.css';
  544. $files[] = $this->urlToPath($style);
  545. }
  546. break;
  547. }
  548. $packer->setFiles($files);
  549. $packer->pack($minify, $gzip);
  550. }
  551. }
  552. }
  553. ?>