BxBaseEditorTinyMCE.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup UnaBaseView UNA Base Representation Classes
  7. * @{
  8. */
  9. /**
  10. * TinyMCE editor representation.
  11. * @see BxDolEditor
  12. */
  13. class BxBaseEditorTinyMCE extends BxDolEditor
  14. {
  15. /**
  16. * Common initialization params
  17. */
  18. protected static $CONF_COMMON = <<<EOS
  19. jQuery('{bx_var_selector}').tinymce({
  20. {bx_var_custom_init}
  21. {bx_var_custom_conf}
  22. document_base_url: '{bx_url_root}',
  23. theme_url: '{bx_url_tinymce}themes/modern/theme.min.js',
  24. skin_url: '{bx_url_tinymce}skins/{bx_var_skin}/',
  25. language_url: '{bx_url_tinymce}langs/{bx_var_lang}.js',
  26. content_css: '{bx_var_css_path}',
  27. entity_encoding: 'raw',
  28. browser_spellcheck: true,
  29. branding: false,
  30. body_class: 'bx-def-color-bg-block',
  31. mentions: {
  32. queryBy: 'label',
  33. source: function (query, process, delimiter) {
  34. if (delimiter === '@') {
  35. $.getJSON('{bx_url_root}searchExtended.php?action=get_authors&term=' + query, function (data) {
  36. process(data)
  37. });
  38. }
  39. },
  40. insert: function(item) {
  41. return '<a data-profile-id="' + item.value + '" href="' + item.url + '">' + item.label + '</a>';
  42. },
  43. render: function(item) {
  44. return '<li><a href="javascript:;">' + item.label + '</a></li>';
  45. },
  46. renderDropdown: function() {
  47. return '<ul class="rte-autocomplete"></ul>';
  48. }
  49. }
  50. });
  51. EOS;
  52. /**
  53. * Standard view initialization params
  54. */
  55. protected static $CONF_STANDARD = "
  56. external_plugins: {
  57. advlist: '{bx_url_tinymce}plugins/advlist/plugin.min.js',
  58. autolink: '{bx_url_tinymce}plugins/autolink/plugin.min.js',
  59. autosave: '{bx_url_tinymce}plugins/autosave/plugin.min.js',
  60. code: '{bx_url_tinymce}plugins/code/plugin.min.js',
  61. hr: '{bx_url_tinymce}plugins/hr/plugin.min.js',
  62. image: '{bx_url_tinymce}plugins/image/plugin.min.js',
  63. link: '{bx_url_tinymce}plugins/link/plugin.min.js',
  64. lists: '{bx_url_tinymce}plugins/lists/plugin.min.js',
  65. media: '{bx_url_tinymce}plugins/media/plugin.min.js',
  66. paste: '{bx_url_tinymce}plugins/paste/plugin.min.js',
  67. fullscreen: '{bx_url_tinymce}plugins/fullscreen/plugin.min.js',
  68. mention: '{bx_var_plugins_path}tinymce-mention/plugin.min.js',
  69. },
  70. width: '100%',
  71. height: '270',
  72. toolbar: 'undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image',
  73. statusbar: true,
  74. resize: true,
  75. ";
  76. /**
  77. * Minimal view initialization params
  78. */
  79. protected static $CONF_MINI = "
  80. menubar: false,
  81. external_plugins: {
  82. autolink: '{bx_url_tinymce}plugins/autolink/plugin.min.js',
  83. image: '{bx_url_tinymce}plugins/image/plugin.min.js',
  84. link: '{bx_url_tinymce}plugins/link/plugin.min.js',
  85. lists: '{bx_url_tinymce}plugins/lists/plugin.min.js',
  86. paste: '{bx_url_tinymce}plugins/paste/plugin.min.js',
  87. fullscreen: '{bx_url_tinymce}plugins/fullscreen/plugin.min.js',
  88. mention: '{bx_var_plugins_path}tinymce-mention/plugin.min.js',
  89. },
  90. width: '100%',
  91. height: '150',
  92. toolbar: 'bold italic underline removeformat | bullist numlist | alignleft aligncenter alignright | blockquote | link unlink image',
  93. statusbar: true,
  94. resize: true,
  95. ";
  96. /**
  97. * Full view initialization params
  98. */
  99. protected static $CONF_FULL = "
  100. external_plugins: {
  101. advlist: '{bx_url_tinymce}plugins/advlist/plugin.min.js',
  102. anchor: '{bx_url_tinymce}plugins/anchor/plugin.min.js',
  103. autolink: '{bx_url_tinymce}plugins/autolink/plugin.min.js',
  104. autoresize: '{bx_url_tinymce}plugins/autoresize/plugin.min.js',
  105. autosave: '{bx_url_tinymce}plugins/autosave/plugin.min.js',
  106. charmap: '{bx_url_tinymce}plugins/charmap/plugin.min.js',
  107. code: '{bx_url_tinymce}plugins/code/plugin.min.js',
  108. emoticons: '{bx_url_tinymce}plugins/emoticons/plugin.min.js',
  109. hr: '{bx_url_tinymce}plugins/hr/plugin.min.js',
  110. image: '{bx_url_tinymce}plugins/image/plugin.min.js',
  111. link: '{bx_url_tinymce}plugins/link/plugin.min.js',
  112. lists: '{bx_url_tinymce}plugins/lists/plugin.min.js',
  113. media: '{bx_url_tinymce}plugins/media/plugin.min.js',
  114. nonbreaking: '{bx_url_tinymce}plugins/nonbreaking/plugin.min.js',
  115. pagebreak: '{bx_url_tinymce}plugins/pagebreak/plugin.min.js',
  116. preview: '{bx_url_tinymce}plugins/preview/plugin.min.js',
  117. print: '{bx_url_tinymce}plugins/print/plugin.min.js',
  118. paste: '{bx_url_tinymce}plugins/paste/plugin.min.js',
  119. save: '{bx_url_tinymce}plugins/save/plugin.min.js',
  120. searchreplace: '{bx_url_tinymce}plugins/searchreplace/plugin.min.js',
  121. table: '{bx_url_tinymce}plugins/table/plugin.min.js',
  122. textcolor: '{bx_url_tinymce}plugins/textcolor/plugin.min.js',
  123. visualblocks: '{bx_url_tinymce}plugins/visualblocks/plugin.min.js',
  124. fullscreen: '{bx_url_tinymce}plugins/fullscreen/plugin.min.js',
  125. mention: '{bx_var_plugins_path}tinymce-mention/plugin.min.js',
  126. },
  127. width: '100%',
  128. height: '320',
  129. toolbar: [
  130. 'undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image',
  131. 'print preview media | forecolor emoticons | fullscreen'
  132. ],
  133. statusbar: true,
  134. resize: true,
  135. image_advtab: true,
  136. ";
  137. protected $_sConfCustom = '';
  138. /**
  139. * Available editor languages
  140. */
  141. protected static $CONF_LANGS = array('af_ZA' => 1, 'ar' => 1, 'be' => 1, 'bg_BG' => 1, 'ca' => 1, 'cs' => 1, 'cy' => 1, 'da' => 1, 'de' => 1, 'de_AT' => 1, 'dv' => 1, 'el' => 1, 'en' => 1, 'en_CA' => 1, 'en_GB' => 1, 'es' => 1, 'es_MX' => 1, 'et' => 1, 'fa_IR' => 1, 'fr_FR' => 1, 'ga' => 1, 'gl' => 1, 'he_IL' => 1, 'hr' => 1, 'hu_HU' => 1, 'it' => 1, 'ja' => 1, 'ka_GE' => 1, 'kab' => 1, 'kk' => 1, 'km_KH' => 1, 'ko_KR' => 1, 'lv' => 1, 'nb_NO' => 1, 'nl' => 1, 'pl' => 1, 'pt_BR' => 1, 'pt_PT' => 1, 'ro' => 1, 'ru' => 1, 'sk' => 1, 'sl_SI' => 1, 'sv_SE' => 1, 'ta' => 1, 'ta_IN' => 1, 'th_TH' => 1, 'tr' => 1, 'tr_TR' => 1, 'uk' => 1, 'uk_UA' => 1, 'uz' => 1, 'vi_VN' => 1, 'zh_CN' => 1, 'zh_TW' => 1);
  142. protected $_oTemplate;
  143. protected $_bJsCssAdded = false;
  144. public function __construct ($aObject, $oTemplate)
  145. {
  146. parent::__construct ($aObject);
  147. if ($oTemplate)
  148. $this->_oTemplate = $oTemplate;
  149. else
  150. $this->_oTemplate = BxDolTemplate::getInstance();
  151. }
  152. /**
  153. * Set custom TinyMCE configuration option
  154. */
  155. public function setCustomConf ($s)
  156. {
  157. $this->_sConfCustom = $s;
  158. }
  159. /**
  160. * Attach editor to HTML element, in most cases - textarea.
  161. * @param $sSelector - jQuery selector to attach editor to.
  162. * @param $iViewMode - editor view mode: BX_EDITOR_STANDARD, BX_EDITOR_MINI, BX_EDITOR_FULL
  163. * @param $bDynamicMode - is AJAX mode or not, the HTML with editor area is loaded dynamically.
  164. */
  165. public function attachEditor ($sSelector, $iViewMode = BX_EDITOR_STANDARD, $bDynamicMode = false)
  166. {
  167. // set visual mode
  168. switch ($iViewMode) {
  169. case BX_EDITOR_MINI:
  170. $sToolsItems = self::$CONF_MINI;
  171. break;
  172. case BX_EDITOR_FULL:
  173. $sToolsItems = self::$CONF_FULL;
  174. break;
  175. case BX_EDITOR_STANDARD:
  176. default:
  177. $sToolsItems = self::$CONF_STANDARD;
  178. }
  179. // detect language
  180. $sLang = BxDolLanguages::getInstance()->detectLanguageFromArray (self::$CONF_LANGS);
  181. $sCss = 'editor.less';
  182. $aCss = BxDolTemplate::getInstance()->_lessCss(array(
  183. 'path' => $this->_oTemplate->getCssPath($sCss),
  184. 'url' => $this->_oTemplate->getCssUrl($sCss)
  185. ));
  186. // initialize editor
  187. $sInitEditor = $this->_replaceMarkers(self::$CONF_COMMON, array(
  188. 'bx_var_custom_init' => $sToolsItems,
  189. 'bx_var_custom_conf' => $this->_sConfCustom,
  190. 'bx_var_plugins_path' => bx_js_string(BX_DOL_URL_PLUGINS_PUBLIC, BX_ESCAPE_STR_APOS),
  191. 'bx_var_css_path' => bx_js_string($aCss['url'], BX_ESCAPE_STR_APOS),
  192. 'bx_var_skin' => bx_js_string($this->_aObject['skin'], BX_ESCAPE_STR_APOS),
  193. 'bx_var_lang' => bx_js_string($sLang, BX_ESCAPE_STR_APOS),
  194. 'bx_var_selector' => bx_js_string($sSelector, BX_ESCAPE_STR_APOS),
  195. 'bx_url_root' => bx_js_string(BX_DOL_URL_ROOT, BX_ESCAPE_STR_APOS),
  196. 'bx_url_tinymce' => bx_js_string(BX_DOL_URL_PLUGINS_PUBLIC . 'tinymce/', BX_ESCAPE_STR_APOS),
  197. ));
  198. if ($bDynamicMode) {
  199. $sScript = "<script>
  200. if ('undefined' == typeof(jQuery(document).tinymce)) {
  201. window.tinyMCEPreInit = {base : '" . bx_js_string(BX_DOL_URL_PLUGINS_PUBLIC . 'tinymce', BX_ESCAPE_STR_APOS) . "', suffix : '.min', query : ''};
  202. $.getScript('" . bx_js_string(BX_DOL_URL_ROOT . 'inc/js/editor.tinymce.js', BX_ESCAPE_STR_APOS) . "');
  203. $.getScript('" . bx_js_string(BX_DOL_URL_PLUGINS_PUBLIC . 'tinymce/tinymce.min.js', BX_ESCAPE_STR_APOS) . "', function(data, textStatus, jqxhr) {
  204. $.getScript('" . bx_js_string(BX_DOL_URL_PLUGINS_PUBLIC . 'tinymce/jquery.tinymce.min.js', BX_ESCAPE_STR_APOS) . "', function(data, textStatus, jqxhr) {
  205. $sInitEditor
  206. });
  207. });
  208. } else {
  209. setTimeout(function () {
  210. $sInitEditor
  211. }, 10); // wait while html is rendered in case of dynamic adding html with tinymce
  212. }
  213. </script>";
  214. } else {
  215. $sScript = "
  216. <script>
  217. $(document).ready(function () {
  218. $sInitEditor
  219. });
  220. </script>";
  221. }
  222. return $this->_addJsCss($bDynamicMode) . $sScript;
  223. }
  224. /**
  225. * Add css/js files which are needed for editor display and functionality.
  226. */
  227. protected function _addJsCss($bDynamicMode = false, $sInitEditor = '')
  228. {
  229. if ($bDynamicMode)
  230. return '';
  231. if ($this->_bJsCssAdded)
  232. return '';
  233. $this->_oTemplate->addJs(array('tinymce/tinymce.min.js', 'tinymce/jquery.tinymce.min.js', 'editor.tinymce.js'));
  234. $this->_bJsCssAdded = true;
  235. return '';
  236. }
  237. }
  238. /** @} */