dolibarr  9.0.0
doleditor.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2006-2008 Laurent Destailleur <eldy@users.sourceforge.net>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  * or see http://www.gnu.org/
17  */
18 
29 class DolEditor
30 {
31  var $tool; // Store the selected tool
32 
33  // If using fckeditor
34  var $editor;
35 
36  // If not using fckeditor
37  var $content;
38  var $htmlname;
39  var $toolbarname;
40  var $toolbarstartexpanded;
41  var $rows;
42  var $cols;
43  var $height;
44  var $width;
45  var $readonly;
46 
47 
67  function __construct($htmlname, $content, $width='', $height=200, $toolbarname='Basic', $toolbarlocation='In', $toolbarstartexpanded=false, $uselocalbrowser=true, $okforextendededitor=true, $rows=0, $cols=0, $readonly=0)
68  {
69  global $conf,$langs;
70 
71  dol_syslog(get_class($this)."::DolEditor htmlname=".$htmlname." width=".$width." height=".$height." toolbarname=".$toolbarname);
72 
73  if (! $rows) $rows=round($height/20);
74  if (! $cols) $cols=($width?round($width/6):80);
75  $shorttoolbarname=preg_replace('/_encoded$/','',$toolbarname);
76 
77  // Name of extended editor to use (FCKEDITOR_EDITORNAME can be 'ckeditor' or 'fckeditor')
78  $defaulteditor='ckeditor';
79  $this->tool=empty($conf->global->FCKEDITOR_EDITORNAME)?$defaulteditor:$conf->global->FCKEDITOR_EDITORNAME;
80  $this->uselocalbrowser=$uselocalbrowser;
81  $this->readonly=$readonly;
82 
83  // Check if extended editor is ok. If not we force textarea
84  if ((empty($conf->fckeditor->enabled) && $okforextendededitor != 'ace') || empty($okforextendededitor)) $this->tool = 'textarea';
85  if ($okforextendededitor === 'ace') $this->tool='ace';
86  //if ($conf->dol_use_jmobile) $this->tool = 'textarea'; // ckeditor and ace seems ok with mobile
87 
88  // Define content and some properties
89  if ($this->tool == 'ckeditor')
90  {
91  $content=dol_htmlentitiesbr($content); // If content is not HTML, we convert to HTML.
92  }
93  if ($this->tool == 'fckeditor')
94  {
95  require_once DOL_DOCUMENT_ROOT.'/includes/fckeditor/fckeditor.php';
96 
97  $content=dol_htmlentitiesbr($content); // If content is not HTML, we convert to HTML.
98 
99  $this->editor = new FCKeditor($htmlname);
100  $this->editor->BasePath = DOL_URL_ROOT.'/includes/fckeditor/' ;
101  $this->editor->Value = $content;
102  $this->editor->Height = $height;
103  if (! empty($width)) $this->editor->Width = $width;
104  $this->editor->ToolbarSet = $shorttoolbarname; // Profile of this toolbar set is deinfed into theme/mytheme/ckeditor/config.js
105  $this->editor->Config['AutoDetectLanguage'] = 'true'; // Language of user (browser)
106  $this->editor->Config['ToolbarLocation'] = $toolbarlocation ? $toolbarlocation : 'In';
107  $this->editor->Config['ToolbarStartExpanded'] = $toolbarstartexpanded;
108 
109  // Rem: Le forcage de ces 2 parametres ne semble pas fonctionner.
110  // Dolibarr utilise toujours liens avec modulepart='fckeditor' quelque soit modulepart.
111  // Ou se trouve donc cette valeur /viewimage.php?modulepart=fckeditor&file=' ?
112  $modulepart='fckeditor';
113  $this->editor->Config['UserFilesPath'] = '/viewimage.php?modulepart='.$modulepart.'&entity='.$conf->entity.'&file=';
114  $this->editor->Config['UserFilesAbsolutePath'] = DOL_DATA_ROOT.'/'.$modulepart.'/' ;
115 
116  $this->editor->Config['LinkBrowser']=($uselocalbrowser?'true':'false');
117  $this->editor->Config['ImageBrowser']=($uselocalbrowser?'true':'false');
118 
119  if (file_exists(DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/fckeditor/fckconfig.js'))
120  {
121  $this->editor->Config['CustomConfigurationsPath'] = DOL_URL_ROOT.'/theme/'.$conf->theme.'/fckeditor/fckconfig.js';
122  $this->editor->Config['SkinPath'] = DOL_URL_ROOT.'/theme/'.$conf->theme.'/fckeditor/';
123  }
124  }
125 
126  // Define some properties
127  if (in_array($this->tool,array('textarea','ckeditor','ace')))
128  {
129  $this->content = $content;
130  $this->htmlname = $htmlname;
131  $this->toolbarname = $shorttoolbarname;
132  $this->toolbarstartexpanded = $toolbarstartexpanded;
133  $this->rows = max(ROWS_3,$rows);
134  $this->cols = (preg_match('/%/',$cols)?$cols:max(40,$cols)); // If $cols is a percent, we keep it, otherwise, we take max
135  $this->height = $height;
136  $this->width = $width;
137  }
138  }
139 
140  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
152  function Create($noprint=0, $morejs='', $disallowAnyContent=true, $titlecontent='', $option='')
153  {
154  // phpcs:enable
155  global $conf,$langs;
156 
157  $fullpage=false;
158  if (isset($conf->global->FCKEDITOR_ALLOW_ANY_CONTENT))
159  {
160  $disallowAnyContent=empty($conf->global->FCKEDITOR_ALLOW_ANY_CONTENT); // Only predefined list of html tags are allowed or all
161  }
162 
163  $found=0;
164  $out='';
165 
166  if ($this->tool == 'fckeditor') // not used anymore
167  {
168  $found=1;
169  $this->editor->Create();
170  }
171  if (in_array($this->tool,array('textarea','ckeditor')))
172  {
173  $found=1;
174  //$out.= '<textarea id="'.$this->htmlname.'" name="'.$this->htmlname.'" '.($this->readonly?' disabled':'').' rows="'.$this->rows.'"'.(preg_match('/%/',$this->cols)?' style="margin-top: 5px; width: '.$this->cols.'"':' cols="'.$this->cols.'"').' class="flat">';
175  // TODO We do not put the disabled tag because on a read form, it change style with grey.
176  $out.= '<textarea id="'.$this->htmlname.'" name="'.$this->htmlname.'" rows="'.$this->rows.'"'.(preg_match('/%/',$this->cols)?' style="margin-top: 5px; width: '.$this->cols.'"':' cols="'.$this->cols.'"').' class="flat">';
177  $out.= $this->content;
178  $out.= '</textarea>';
179 
180  if ($this->tool == 'ckeditor' && ! empty($conf->use_javascript_ajax))
181  {
182  if (! defined('REQUIRE_CKEDITOR')) define('REQUIRE_CKEDITOR','1');
183 
184  if (! empty($conf->global->FCKEDITOR_SKIN)) {
185  $skin = $conf->global->FCKEDITOR_SKIN;
186  } else {
187  $skin = 'moono-lisa'; // default with ckeditor 4.6 : moono-lisa
188  }
189 
190  $htmlencode_force=preg_match('/_encoded$/',$this->toolbarname)?'true':'false';
191 
192  $out.= '<!-- Output ckeditor $disallowAnyContent='.$disallowAnyContent.' toolbarname='.$this->toolbarname.' -->'."\n";
193  $out.= '<script type="text/javascript">
194  $(document).ready(function () {
195  /* if (CKEDITOR.loadFullCore) CKEDITOR.loadFullCore(); */
196  /* should be editor=CKEDITOR.replace but what if serveral editors ? */
197  CKEDITOR.replace(\''.$this->htmlname.'\',
198  {
199  /* property:xxx is same than CKEDITOR.config.property = xxx */
200  customConfig : ckeditorConfig,
201  readOnly : '.($this->readonly?'true':'false').',
202  htmlEncodeOutput :'.$htmlencode_force.',
203  allowedContent :'.($disallowAnyContent?'false':'true').',
204  extraAllowedContent : \'\',
205  fullPage : '.($fullpage?'true':'false').',
206  toolbar: \''.$this->toolbarname.'\',
207  toolbarStartupExpanded: '.($this->toolbarstartexpanded ? 'true' : 'false').',
208  width: '.($this->width ? '\''.$this->width.'\'' : '\'\'').',
209  height: '.$this->height.',
210  skin: \''.$skin.'\',
211  language: \''.$langs->defaultlang.'\',
212  textDirection: \''.$langs->trans("DIRECTION").'\',
213  on :
214  {
215  instanceReady : function( ev )
216  {
217  // Output paragraphs as <p>Text</p>.
218  this.dataProcessor.writer.setRules( \'p\',
219  {
220  indent : false,
221  breakBeforeOpen : true,
222  breakAfterOpen : false,
223  breakBeforeClose : false,
224  breakAfterClose : true
225  });
226  }
227  }';
228  if ($this->uselocalbrowser)
229  {
230  $out.= ','."\n";
231  // To use filemanager with old fckeditor (GPL)
232  $out.= ' filebrowserBrowseUrl : ckeditorFilebrowserBrowseUrl,';
233  $out.= ' filebrowserImageBrowseUrl : ckeditorFilebrowserImageBrowseUrl,';
234  //$out.= ' filebrowserUploadUrl : \''.DOL_URL_ROOT.'/includes/fckeditor/editor/filemanagerdol/connectors/php/upload.php?Type=File\',';
235  //$out.= ' filebrowserImageUploadUrl : \''.DOL_URL_ROOT.'/includes/fckeditor/editor/filemanagerdol/connectors/php/upload.php?Type=Image\',';
236  $out.= "\n";
237  // To use filemanager with ckfinder (Non free) and ckfinder directory is inside htdocs/includes
238  /* $out.= ' filebrowserBrowseUrl : \''.DOL_URL_ROOT.'/includes/ckfinder/ckfinder.html\',
239  filebrowserImageBrowseUrl : \''.DOL_URL_ROOT.'/includes/ckfinder/ckfinder.html?Type=Images\',
240  filebrowserFlashBrowseUrl : \''.DOL_URL_ROOT.'/includes/ckfinder/ckfinder.html?Type=Flash\',
241  filebrowserUploadUrl : \''.DOL_URL_ROOT.'/includes/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files\',
242  filebrowserImageUploadUrl : \''.DOL_URL_ROOT.'/includes/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Images\',
243  filebrowserFlashUploadUrl : \''.DOL_URL_ROOT.'/includes/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Flash\','."\n";
244  */
245  $out.= ' filebrowserWindowWidth : \'900\',
246  filebrowserWindowHeight : \'500\',
247  filebrowserImageWindowWidth : \'900\',
248  filebrowserImageWindowHeight : \'500\'';
249  }
250  $out.= ' })'.$morejs;
251  $out.= '});'."\n";
252  $out.= '</script>'."\n";
253  }
254  }
255 
256  // Output editor ACE
257  // Warning: ace.js and ext-statusbar.js must be loaded by the parent page.
258  if (preg_match('/^ace/', $this->tool))
259  {
260  $found=1;
261  $format=$option;
262 
263  $out.= "\n".'<!-- Output Ace editor -->'."\n";
264 
265  if ($titlecontent)
266  {
267  $out.= '<div class="aceeditorstatusbar" id="statusBar'.$this->htmlname.'">'.$titlecontent;
268  $out.= ' &nbsp; - &nbsp; <a id="morelines" href="#" class="right morelines'.$this->htmlname.'">'.dol_escape_htmltag($langs->trans("ShowMoreLines")).'</a> &nbsp; &nbsp; ';
269  $out.= '</div>';
270  $out.= '<script type="text/javascript" language="javascript">'."\n";
271  $out.= 'jQuery(document).ready(function() {'."\n";
272  $out.= ' var aceEditor = window.ace.edit("'.$this->htmlname.'aceeditorid");
273  var StatusBar = window.ace.require("ace/ext/statusbar").StatusBar; // Init status bar. Need lib ext-statusbar
274  var statusBar = new StatusBar(aceEditor, document.getElementById("statusBar'.$this->htmlname.'")); // Init status bar. Need lib ext-statusbar
275  var oldNbOfLines = 0
276  jQuery(".morelines'.$this->htmlname.'").click(function() {
277  var aceEditorClicked = window.ace.edit("'.$this->htmlname.'aceeditorid");
278  currentline = aceEditorClicked.getOption("maxLines");
279  if (oldNbOfLines == 0)
280  {
281  oldNbOfLines = currentline;
282  }
283  console.log("We click on more lines, oldNbOfLines is "+oldNbOfLines+", we have currently "+currentline);
284  if (currentline < 500)
285  {
286  aceEditorClicked.setOptions({ maxLines: 500 });
287  }
288  else
289  {
290  aceEditorClicked.setOptions({ maxLines: oldNbOfLines });
291  }
292  });
293  })';
294  $out.= '</script>'."\n";
295  }
296 
297  $out.= '<pre id="'.$this->htmlname.'aceeditorid" style="'.($this->width?'width: '.$this->width.'px; ':'');
298  $out.= ($this->height?' height: '.$this->height.'px; ':'');
299  //$out.=" min-height: 100px;";
300  $out.= '">';
301  $out.= htmlspecialchars($this->content);
302  $out.= '</pre>';
303  $out.= '<textarea id="'.$this->htmlname.'" name="'.$this->htmlname.'" style="width:0px; height: 0px; display: none;">';
304  $out.= htmlspecialchars($this->content);
305  $out.= '</textarea>';
306 
307  $out.= '<script type="text/javascript" language="javascript">'."\n";
308  $out.= 'var aceEditor = window.ace.edit("'.$this->htmlname.'aceeditorid");
309 
310  aceEditor.session.setMode("ace/mode/'.$format.'");
311  aceEditor.setOptions({
312  enableBasicAutocompletion: true, // the editor completes the statement when you hit Ctrl + Space. Need lib ext-language_tools.js
313  enableLiveAutocompletion: false, // the editor completes the statement while you are typing. Need lib ext-language_tools.js
314  showPrintMargin: false, // hides the vertical limiting strip
315  minLines: 10,
316  maxLines: '.(empty($this->height)?'34':(round($this->height/10))).',
317  fontSize: "110%" // ensures that the editor fits in the environment
318  });
319 
320  // defines the style of the editor
321  aceEditor.setTheme("ace/theme/chrome");
322  // hides line numbers (widens the area occupied by error and warning messages)
323  //aceEditor.renderer.setOption("showLineNumbers", false);
324  // ensures proper autocomplete, validation and highlighting of JavaScript code
325  //aceEditor.getSession().setMode("ace/mode/javascript_expression");
326  '."\n";
327 
328  $out.= 'jQuery(document).ready(function() {
329  jQuery(".buttonforacesave").click(function() {
330  console.log("We click on savefile button for component '.$this->htmlname.'");
331  var aceEditor = window.ace.edit("'.$this->htmlname.'aceeditorid")
332  console.log(aceEditor.getSession().getValue());
333  jQuery("#'.$this->htmlname.'").val(aceEditor.getSession().getValue());
334  /*if (jQuery("#'.$this->htmlname.'").html().length > 0) return true;
335  else return false;*/
336  });
337  })';
338  $out.= '</script>'."\n";
339  }
340 
341  if (empty($found))
342  {
343  $out.= 'Error, unknown value for tool '.$this->tool.' in DolEditor Create function.';
344  }
345 
346  if ($noprint) return $out;
347  else print $out;
348  }
349 }
print
Draft customers invoices.
Definition: index.php:91
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
Create($noprint=0, $morejs='', $disallowAnyContent=true, $titlecontent='', $option='')
Output edit area inside the HTML stream.
__construct($htmlname, $content, $width='', $height=200, $toolbarname='Basic', $toolbarlocation='In', $toolbarstartexpanded=false, $uselocalbrowser=true, $okforextendededitor=true, $rows=0, $cols=0, $readonly=0)
Create an object to build an HTML area to edit a large string content.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
Class to manage a WYSIWYG editor.