Source for file widget_html.php

Documentation is available at widget_html.php

  1. <?php
  2. /**
  3. * @package midcom.helper.datamanager
  4. * @author The Midgard Project, http://www.midgard-project.org
  5. * @version $Id: widget_html.php,v 1.12.2.1 2005/11/18 15:17:40 bergius Exp $
  6. * @copyright The Midgard Project, http://www.midgard-project.org
  7. * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
  8. */
  9.  
  10. /**
  11. * This is a WYSIWYG HTML widget, built on HTMLArea.
  12. *
  13. * This widget should only be used with the text type configured to an unlimited-length
  14. * field.
  15. *
  16. * <b>Configuration parameters:</b>
  17. *
  18. * <b>widget_html_stripmstags:</b> This option will activate a couple of regular
  19. * expressions that filter out a lot of the crap that M$ products like Word insert
  20. * into the stuff they copy into the clipborard. If you leave this deactivated, any
  21. * content copy/pasted from Word will most probably override your site style in
  22. * almost any thinkable way. As this modifies content, this is disabled by default.
  23. *
  24. * <b>widget_html_css_url:</b> The CSS file in this URL is used by the HTMLArea to
  25. * render the content within the HTMLArea to have a better preview what the content
  26. * will look like on-site. Note, that with strongly CSS formatted content, this is
  27. * not always a good idea.
  28. *
  29. * <b>widget_htmlarea_customconfig:</b> The most powerful and complex part of the
  30. * HTMLArea configuration. It is inserted into the HTMLArea startup code and allows
  31. * you to adapt the widget to your personal surroundings. The example below gives
  32. * you an insight what can be possible, albeit it is far from complete. Refer to the
  33. * HTMLArea documentation for details about this.
  34. *
  35. * <b>Sample configuration</b>
  36. *
  37. * <pre>
  38. * "html" => array (
  39. * "description" => "WYSIWYG HTML",
  40. * "datatype" => "text",
  41. * "location" => "attachment",
  42. * "widget" => "html",
  43. * "widget_html_stripmstags" => true,
  44. * "widget_html_css_url" => "http://my.host.com/css/htmlarea_iframe.css",
  45. * "widget_html_customconfig" => <<<EOF
  46. * config.formatblock = {
  47. * "H2": "h2",
  48. * "H3": "h3",
  49. * "H4": "h4",
  50. * "H5": "h5",
  51. * "Paragraph": "p",
  52. * "Preformatted": "pre",
  53. * "Block Quote": "blockquote",
  54. * "Address": "address"
  55. * };
  56. * config.toolbar = [
  57. * [ "formatblock", "space",
  58. * "bold", "italic", "underline", "strikethrough", "subscript", "superscript", "separator",
  59. * "copy", "cut", "paste", "space", "undo", "redo" ],
  60. * [ "insertorderedlist", "insertunorderedlist", "outdent", "indent", "separator",
  61. * "inserthorizontalrule", "createlink", "insertimage", "inserttable", "htmlmode", "separator",
  62. * "popupeditor", "separator", "showhelp", "about" ]
  63. * ];
  64. * EOF
  65. * ),
  66. * </pre>
  67. *
  68. * <b>CSS Styles in use by the Widget</b>
  69. *
  70. * The select widget will be both of select.list and select.multiple.
  71. *
  72. * <b>HTMLArea licence information</b>
  73. *
  74. * Portions (c) dynarch.com, 2003-2004
  75. *
  76. * A free WYSIWYG editor replacement for <textarea> fields.
  77. * For full source code and docs, visit http://www.interactivetools.com/
  78. * or http://www.htmlarea.com/
  79. *
  80. * Version 3.0 developed by Mihai Bazon. http://dynarch.com/mishoo
  81. *
  82. * @todo Add a section about configuration of HTMLArea or at least add a corresponding docuemnt to the distribution.
  83. * @package midcom.helper.datamanager
  84. */
  85.  
  86. class midcom_helper_datamanager_widget_html extends midcom_helper_datamanager_widget {
  87. /**
  88. * The URL of the CSS file to use inside of the HTMLArea.
  89. *
  90. * @var string
  91. * @access private
  92. */
  93. var $_css_url;
  94. /**
  95. * Custom JScript configuration block
  96. *
  97. * @var string
  98. * @access private
  99. */
  100. var $_customconfig;
  101. /**
  102. * Flag to enable the M$ HTML crap filter(tm).
  103. *
  104. * @var bool
  105. * @access private
  106. */
  107. var $_stripmstags;
  108.  
  109. /**
  110. * Flag to enable HTML Tidy cleaning
  111. * Requires the PECL Tidy extension
  112. *
  113. * @var bool
  114. * @access private
  115. */
  116. var $_tidy;
  117. /**
  118. * The constructor will add the corresponding Javascript code only if we are
  119. * running AIS. On-Site usage is not yet possible.
  120. */
  121. function _constructor (&$datamanager, $field, $defaultvalue) {
  122. $this->_datamanager =& $datamanager;
  123. $this->_field = $field;
  124. $this->_fieldname = $this->_datamanager->form_prefix . "field_" . $field["name"];
  125. $this->_value = $defaultvalue;
  126. if (!array_key_exists("widget_html_css_url", $this->_field))
  127. {
  128. $this->_field["widget_html_css_url"] = null;
  129. }
  130. if (!array_key_exists("widget_html_customconfig", $this->_field))
  131. {
  132. $this->_field["widget_html_customconfig"] = "";
  133. }
  134. if (!array_key_exists("widget_html_stripmstags", $this->_field))
  135. {
  136. $this->_field["widget_html_stripmstags"] = false;
  137. }
  138. if (!array_key_exists("widget_html_enable_tidy", $field))
  139. {
  140. $field["widget_html_enable_tidy"] = true;
  141. }
  142. $this->_css_url = $this->_field["widget_html_css_url"];
  143. $this->_customconfig = $this->_field["widget_html_customconfig"];
  144. $this->_stripmstags = $this->_field["widget_html_stripmstags"];
  145. $this->_tidy = $field["widget_html_enable_tidy"];
  146. $this->_read_formdata();
  147. // Ensure that AIS is running
  148. if (array_key_exists("view_contentmgr", $GLOBALS))
  149. {
  150. $midgard = $GLOBALS["midcom"]->get_midgard();
  151. // Language negotiation ($i18n->_current_language and $i18n->_fallback_language)
  152. $i18n =& $GLOBALS["midcom"]->get_service("i18n");
  153. $langprefix = MIDCOM_STATIC_ROOT . '/midcom.helper.datamanager/htmlarea/lang/';
  154. if (file_exists($langprefix . $i18n->get_current_language() . '.js'))
  155. {
  156. $htmlarea_lang = $i18n->get_current_language();
  157. }
  158. else if (file_exists($langprefix . $i18n->get_fallback_language() . '.js'))
  159. {
  160. $htmlarea_lang = $i18n->get_fallback_language();
  161. }
  162. else
  163. {
  164. $htmlarea_lang = 'en';
  165. }
  166. $urlprefix = MIDCOM_STATIC_URL . '/midcom.helper.datamanager/htmlarea/';
  167.  
  168. // Disable HTMLArea language selection
  169. // The translations are incomplete, and missing strings break at least
  170. // the insert link popup due to jscript errors.
  171. $GLOBALS["midcom"]->add_jscript("
  172. _editor_url = '{$urlprefix}';
  173. // _editor_lang = '{$htmlarea_lang}';\n");
  174. $GLOBALS["midcom"]->add_jsfile($urlprefix. 'htmlarea.js');
  175.  
  176. // Add here all Plugins you wish to use with your HTMLArea.
  177. // The Context Menu Plugin is disabled, as it makes trouble with
  178. // default Mozilla (scripts may not copy/paste by default anymore).
  179. // TODO: Make this configurable.
  180. $GLOBALS["midcom"]->add_jscript("
  181.  
  182. HTMLArea.loadPlugin('TableOperations');
  183. HTMLArea.loadPlugin('ContextMenu');\n");
  184. $GLOBALS["midcom"]->add_jscript($this->_get_config_js());
  185. $GLOBALS["midcom"]->add_jsonload($this->_fieldname . "_init()");
  186. // fix so that HTMLArea doesn't break on slow lines.
  187. // Commented out due to caching issues.
  188. //$this->_preloadImages();
  189. }
  190. }
  191.  
  192. function draw_view ()
  193. {
  194. echo "<div class='form_htmleditor'>{$this->_value}</div>\n";
  195. }
  196. function draw_widget ()
  197. {
  198. echo "<textarea class='htmleditor' id='{$this->_fieldname}' name='{$this->_fieldname}'>{$this->_value}</textarea>\n";
  199. }
  200.  
  201. /**
  202. * Overridden to allow for the post-processing of the HTMLArea generated content.
  203. *
  204. * Two things happen:
  205. *
  206. * - First, a newline will be added after all closing td, tr, table,
  207. * p and div tags for better readability of the source
  208. * - Second, if enabled, the M$ HTML crap filter (tm) is invoked.
  209. *
  210. * <b>The M$ HTML crap filter(tm):</b>
  211. *
  212. * It will remove about this, and is incomplete yet:
  213. *
  214. * - mso, navigointipaa1 and windowtext tags within p, b, div and span tags
  215. * - all font tags
  216. * - all msnormal class tags
  217. *
  218. * This might be replaced by HTMLTidy on the long run.
  219. */
  220. function _read_formdata ()
  221. {
  222. if (array_key_exists($this->_fieldname, $_REQUEST))
  223. {
  224. $this->_value = $_REQUEST[$this->_fieldname];
  225. // bring some linbreaks into tables and after p/div to make it more readable.
  226. $this->_value = preg_replace("'</((td|tr|table|p|div)[^>]*)><'im", "</\\1>\n<", $this->_value);
  227.  
  228. // Run HTML Tidy if available
  229. // This requires libtidy and the PECL Tidy extension to be installed
  230. if ( $this->
  231. _tidy
  232. && function_exists('tidy_repair_string')
  233. && function_exists('tidy_setopt'))
  234. {
  235. // Default options for Tidy
  236. // See http://public.planetmirror.com/pub/tidy for docs
  237. // TODO: Enable custom options in DM field config
  238. tidy_setopt('show-body-only', TRUE);
  239. tidy_setopt('output-xhtml', TRUE);
  240. tidy_setopt('enclose-block-text', TRUE);
  241. tidy_setopt('drop-empty-paras', TRUE);
  242. // Don't make a mess out of UTF-8 characters
  243. // TODO: Check encoding from MidCOM i18n service
  244. tidy_setopt('char-encoding', 'utf8');
  245. tidy_setopt('input-encoding', 'utf8');
  246. tidy_setopt('output-encoding', 'utf8');
  247.  
  248. // Proper indentation will make RCS diffs more useful
  249. tidy_setopt('indent', TRUE);
  250. tidy_setopt('indent-spaces', 4);
  251. tidy_setopt('break-before-br', TRUE);
  252. // TODO: Make these depend on stripmstags?
  253. tidy_setopt('drop-font-tags', TRUE);
  254. tidy_setopt('drop-proprietary-attributes', TRUE);
  255. tidy_setopt('bare', TRUE);
  256.  
  257. $this->_value = tidy_repair_string($this->_value);
  258. }
  259. // If configured accordingly, strip all nasty word spans/p's/divs to something usable
  260. if ($this->_stripmstags)
  261. {
  262. $search = Array (
  263. "'<([PB]|DIV|SPAN)[^>]*(mso|navigointipaa1|windowtext)+[^>]*>'im",
  264. "'<FONT[^>]*>'i",
  265. "'</FONT>'i",
  266. '$class="msonormal" $i'
  267. );
  268. $replace = Array (
  269. "<\\1>",
  270. "",
  271. "",
  272. ""
  273. );
  274. $this->_value = preg_replace ($search, $replace, $this->_value);
  275. }
  276. }
  277. }
  278.  
  279. /**
  280. * Prepares the HTMLArea configuration scriptlet. It will search the templates in this order:
  281. *
  282. * - /sitegroup-config/midcom.helper.datamanager.widget_html/config
  283. * - file:/midcom/helper/datamanager/config/midcom.helper.datamanger.widget_html
  284. * - local fallback default configuration
  285. *
  286. * Look at the source of this function how your template should look like.
  287. *
  288. * @return string JS configuration code for the current HTMLArea
  289. */
  290. function _get_config_js ()
  291. {
  292. // Check for sitegroup-config
  293. if (mgd_snippet_exists('/sitegroup-config/midcom.helper.datamanager.widget_html/config'))
  294. {
  295. $snippet = mgd_get_snippet_by_path('/sitegroup-config/midcom.helper.datamanager.widget_html/config');
  296. if (! $snippet)
  297. {
  298. return false;
  299. }
  300. eval ('?>' . mgd_preparse($snippet->code));
  301. }
  302. else if ( file_exists(MIDCOM_ROOT . '/midcom/helper/datamanager/config/midcom.helper.datamanger.widget_html') )
  303. {
  304. $code = file_get_contents(MIDCOM_ROOT . '/midcom/helper/datamanager/config/midcom.helper.datamanger.widget_html');
  305. if ($code)
  306. {
  307. eval ('?>' . $code );
  308. }
  309. }
  310. else
  311. {
  312. $file = MIDCOM_ROOT . 'lib/midcom/helper/datamanager/config/midcom.helper.datamanger.widget_html';
  313. $result = <<<EOF
  314. // FIELD {$this->_fieldname} HTMLAREA init script START
  315. var {$this->_fieldname} = null;
  316. function {$this->_fieldname}_init() {
  317.  
  318. if (!document.getElementById("{$this->_fieldname}")) {
  319. return;
  320. }
  321. config = new HTMLArea.Config();
  322. config.bodyStyle = "background-color: #fff;";
  323.  
  324. config.formatblock = {
  325. "Normal": "p",
  326. "Heading 2": "h2",
  327. "Heading 3": "h3",
  328. "Heading 4": "h4",
  329. "Formatted": "pre",
  330. "Address": "address",
  331. "Quote": "blockquote"
  332. };
  333. config.fontsize = {
  334. "1 (small)": "1",
  335. "2 (footnote)": "2",
  336. "3 (regular)": "3",
  337. "4 (large)": "4",
  338. "5 (big)": "5"
  339. };
  340.  
  341. // "fontname" and "fontsize" disabled by default, add if required
  342. config.toolbar = [
  343. [ "formatblock", "space",
  344. "bold", "italic", "separator",
  345. "strikethrough", "subscript", "superscript", "separator",
  346. "copy", "cut", "paste", "space", "undo", "redo" ],
  347. [ "justifyleft", "justifycenter", "justifyright", "justifyfull", "separator",
  348. "insertorderedlist", "insertunorderedlist", "outdent", "indent", "separator",
  349. "inserthorizontalrule", "createlink", "insertimage", "inserttable", "htmlmode", "separator",
  350. "popupeditor", "separator", "showhelp", "about" ]
  351. ];
  352.  
  353. {$this->_customconfig}
  354. {$this->_fieldname} = new HTMLArea("{$this->_fieldname}",config);
  355. {$this->_fieldname}.registerPlugin("TableOperations");
  356. {$this->_fieldname}.registerPlugin("ContextMenu");
  357. {$this->_fieldname}.generate();
  358. };
  359. // FIELD {$this->_fieldname} HTMLAREA init script END
  360. EOF; }
  361. return $result;
  362. }
  363. /**
  364. * Preload images used by htmlarea.
  365. *
  366. * This makes HTMLArea more stable in IE.
  367. *
  368. * @access private
  369. */
  370. function _preloadImages() {
  371. $images = array (
  372. 'ed_about.gif',
  373. 'ed_align_center.gif',
  374. 'ed_align_justify.gif',
  375. 'ed_align_left.gif',
  376. 'ed_align_right.gif',
  377. 'ed_blank.gif',
  378. 'ed_charmap.gif',
  379. 'ed_color_bg.gif',
  380. 'ed_color_fg.gif',
  381. 'ed_copy.gif',
  382. 'ed_custom.gif',
  383. 'ed_cut.gif',
  384. 'ed_delete.gif',
  385. 'ed_format_bold.gif',
  386. 'ed_format_italic.gif',
  387. 'ed_format_strike.gif',
  388. 'ed_format_sub.gif',
  389. 'ed_format_sup.gif',
  390. 'ed_format_underline.gif',
  391. 'ed_help.gif',
  392. 'ed_hr.gif',
  393. 'ed_html.gif',
  394. 'ed_image.gif',
  395. 'ed_indent_less.gif',
  396. 'ed_indent_more.gif',
  397. 'ed_left_to_right.gif',
  398. 'ed_link.gif',
  399. 'ed_list_bullet.gif',
  400. 'ed_list_num.gif',
  401. 'ed_paste.gif',
  402. 'ed_redo.gif',
  403. 'ed_right_to_left.gif',
  404. 'ed_save.gif',
  405. 'ed_show_border.gif',
  406. 'ed_splitcel.gif',
  407. 'ed_undo.gif',
  408. );
  409. foreach ($images as $image) {
  410. $GLOBALS['midcom']->add_object_head('',array('data' => MIDCOM_STATIC_ROOT . '/midcom.helper.datamanager/htmlarea/images/' . $image));
  411. }
  412. }
  413.  
  414. }

Documentation generated on Mon, 21 Nov 2005 18:24:44 +0100 by phpDocumentor 1.3.0RC3