dolibarr 19.0.3
modules_boxes.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2004-2013 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
4 * Copyright (C) 2014 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
5 * Copyright (C) 2015 Frederic France <frederic.france@free.fr>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * or see https://www.gnu.org/
20 */
21
34class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" boxes
35{
39 public $db;
40
44 public $error = '';
45
49 public $max = 5;
50
54 public $enabled = 1;
55
59 public $hidden = false;
60
64 public $rowid;
65
70 public $id;
71
75 public $position;
76
80 public $box_order;
81
85 public $fk_user;
86
90 public $sourcefile;
91
95 public $class;
96
100 public $box_id;
101
105 public $boxcode;
106
110 public $note;
111
115 public $widgettype = '';
116
117
124 public function __construct($db, $param = '')
125 {
126 $this->db = $db;
127 }
128
134 public function error()
135 {
136 return $this->error;
137 }
138
139
147 public function fetch($rowid)
148 {
149 global $conf;
150
151 // Recupere liste des boites d'un user si ce dernier a sa propre liste
152 $sql = "SELECT b.rowid as id, b.box_id, b.position, b.box_order, b.fk_user";
153 $sql .= " FROM ".MAIN_DB_PREFIX."boxes as b";
154 $sql .= " WHERE b.entity = ".$conf->entity;
155 $sql .= " AND b.rowid = ".((int) $rowid);
156 dol_syslog(get_class($this)."::fetch rowid=".$rowid);
157
158 $resql = $this->db->query($sql);
159 if ($resql) {
160 $obj = $this->db->fetch_object($resql);
161 if ($obj) {
162 $this->id = $obj->id;
163 $this->rowid = $obj->id; // For backward compatibility
164 $this->box_id = $obj->box_id;
165 $this->position = $obj->position;
166 $this->box_order = $obj->box_order;
167 $this->fk_user = $obj->fk_user;
168 return 1;
169 } else {
170 return -1;
171 }
172 } else {
173 return -1;
174 }
175 }
176
185 public function showBox($head = null, $contents = null, $nooutput = 0)
186 {
187 global $langs, $user, $conf;
188
189 if (!empty($this->hidden)) {
190 return '\n<!-- Box ".get_class($this)." hidden -->\n'; // Nothing done if hidden (for example when user has no permission)
191 }
192
193 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
194
195 $MAXLENGTHBOX = 60; // Mettre 0 pour pas de limite
196
197 $cachetime = 900; // 900 : 15mn
198 $cachedir = DOL_DATA_ROOT.'/boxes/temp';
199 $fileid = get_class($this).'id-'.$this->box_id.'-e'.$conf->entity.'-u'.$user->id.'-s'.$user->socid.'.cache';
200 $filename = '/box-'.$fileid;
201 $refresh = dol_cache_refresh($cachedir, $filename, $cachetime);
202 $out = '';
203
204 if ($refresh) {
205 dol_syslog(get_class($this).'::showBox');
206
207 // Define nbcol and nblines of the box to show
208 $nbcol = 0;
209 if (isset($contents[0])) {
210 $nbcol = count($contents[0]);
211 }
212 $nblines = count($contents);
213
214 $out .= "\n<!-- Box ".get_class($this)." start -->\n";
215
216 $out .= '<div class="box divboxtable boxdraggable" id="boxto_'.$this->box_id.'">'."\n";
217
218 if (!empty($head['text']) || !empty($head['sublink']) || !empty($head['subpicto']) || $nblines) {
219 $out .= '<table summary="boxtable'.$this->box_id.'" width="100%" class="noborder boxtable">'."\n";
220 }
221
222 // Show box title
223 if (!empty($head['text']) || !empty($head['sublink']) || !empty($head['subpicto'])) {
224 $out .= '<tr class="liste_titre box_titre">';
225 $out .= '<th';
226 if (!empty($head['nbcol'])) {
227 $nbcol = $head['nbcol'];
228 }
229 if ($nbcol > 1) {
230 $out .= ' colspan="'.$nbcol.'"';
231 }
232 $out .= '>';
233 if (!empty($conf->use_javascript_ajax)) {
234 //$out.= '<table summary="" class="nobordernopadding" width="100%"><tr><td class="tdoverflowmax150 maxwidth150onsmartphone">';
235 $out .= '<div class="tdoverflowmax400 maxwidth250onsmartphone float">';
236 }
237 if (!empty($head['text'])) {
238 $s = dol_trunc($head['text'], isset($head['limit']) ? $head['limit'] : $MAXLENGTHBOX);
239 $out .= $s;
240 }
241 if (!empty($conf->use_javascript_ajax)) {
242 $out .= '</div>';
243 }
244 //$out.= '</td>';
245
246 if (!empty($conf->use_javascript_ajax)) {
247 $sublink = '';
248 if (!empty($head['sublink'])) {
249 $sublink .= '<a href="'.$head['sublink'].'"'.(empty($head['target']) ? '' : ' target="'.$head['target'].'"').'>';
250 }
251 if (!empty($head['subpicto'])) {
252 $sublink .= img_picto($head['subtext'], $head['subpicto'], 'class="opacitymedium marginleftonly '.(empty($head['subclass']) ? '' : $head['subclass']).'" id="idsubimg'.$this->boxcode.'"');
253 }
254 if (!empty($head['sublink'])) {
255 $sublink .= '</a>';
256 }
257
258 //$out.= '<td class="nocellnopadd boxclose right nowraponall">';
259 $out .= '<div class="nocellnopadd boxclose floatright nowraponall">';
260 $out .= $sublink;
261 // The image must have the class 'boxhandle' beause it's value used in DOM draggable objects to define the area used to catch the full object
262 $out .= img_picto($langs->trans("MoveBox", $this->box_id), 'grip_title', 'class="opacitymedium boxhandle hideonsmartphone cursormove marginleftonly"');
263 $out .= img_picto($langs->trans("CloseBox", $this->box_id), 'close_title', 'class="opacitymedium boxclose cursorpointer marginleftonly" rel="x:y" id="imgclose'.$this->box_id.'"');
264 $label = $head['text'];
265 //if (!empty($head['graph'])) $label.=' ('.$langs->trans("Graph").')';
266 if (!empty($head['graph'])) {
267 $label .= ' <span class="opacitymedium fas fa-chart-bar"></span>';
268 }
269 $out .= '<input type="hidden" id="boxlabelentry'.$this->box_id.'" value="'.dol_escape_htmltag($label).'">';
270 //$out.= '</td></tr></table>';
271 $out .= '</div>';
272 }
273
274 $out .= "</th>";
275 $out .= "</tr>\n";
276 }
277
278 // Show box lines
279 if ($nblines) {
280 // Loop on each record
281 for ($i = 0, $n = $nblines; $i < $n; $i++) {
282 if (isset($contents[$i])) {
283 // TR
284 if (isset($contents[$i][0]['tr'])) {
285 $out .= '<tr '.$contents[$i][0]['tr'].'>';
286 } else {
287 $out .= '<tr class="oddeven">';
288 }
289
290 // Loop on each TD
291 $nbcolthisline = count($contents[$i]);
292 for ($j = 0; $j < $nbcolthisline; $j++) {
293 // Define tdparam
294 $tdparam = '';
295 if (!empty($contents[$i][$j]['td'])) {
296 $tdparam .= ' '.$contents[$i][$j]['td'];
297 }
298
299 $text = isset($contents[$i][$j]['text']) ? $contents[$i][$j]['text'] : '';
300 $textwithnotags = preg_replace('/<([^>]+)>/i', '', $text);
301 $text2 = isset($contents[$i][$j]['text2']) ? $contents[$i][$j]['text2'] : '';
302 $text2withnotags = preg_replace('/<([^>]+)>/i', '', $text2);
303
304 $textnoformat = isset($contents[$i][$j]['textnoformat']) ? $contents[$i][$j]['textnoformat'] : '';
305 //$out.= "xxx $textwithnotags y";
306 if (empty($contents[$i][$j]['tooltip'])) {
307 $contents[$i][$j]['tooltip'] = "";
308 }
309 $tooltip = isset($contents[$i][$j]['tooltip']) ? $contents[$i][$j]['tooltip'] : '';
310
311 $out .= '<td'.$tdparam.'>'."\n";
312
313 // Url
314 if (!empty($contents[$i][$j]['url']) && empty($contents[$i][$j]['logo'])) {
315 $out .= '<a href="'.$contents[$i][$j]['url'].'"';
316 if (!empty($tooltip)) {
317 $out .= ' title="'.dol_escape_htmltag($langs->trans("Show").' '.$tooltip, 1).'" class="classfortooltip"';
318 }
319 //$out.= ' alt="'.$textwithnotags.'"'; // Pas de alt sur un "<a href>"
320 $out .= isset($contents[$i][$j]['target']) ? ' target="'.$contents[$i][$j]['target'].'"' : '';
321 $out .= '>';
322 }
323
324 // Logo
325 if (!empty($contents[$i][$j]['logo'])) {
326 $logo = preg_replace("/^object_/i", "", $contents[$i][$j]['logo']);
327 $out .= '<a href="'.$contents[$i][$j]['url'].'">';
328 $out .= img_object($langs->trans("Show").' '.$tooltip, $logo, 'class="classfortooltip"');
329 }
330
331 $maxlength = $MAXLENGTHBOX;
332 if (isset($contents[$i][$j]['maxlength'])) {
333 $maxlength = $contents[$i][$j]['maxlength'];
334 }
335
336 if ($maxlength) {
337 $textwithnotags = dol_trunc($textwithnotags, $maxlength);
338 }
339 if (preg_match('/^<(img|div|span)/i', $text) || !empty($contents[$i][$j]['asis'])) {
340 $out .= $text; // show text with no html cleaning
341 } else {
342 $out .= $textwithnotags; // show text with html cleaning
343 }
344
345 // End Url
346 if (!empty($contents[$i][$j]['url'])) {
347 $out .= '</a>';
348 }
349
350 if (preg_match('/^<(img|div|span)/i', $text2) || !empty($contents[$i][$j]['asis2'])) {
351 $out .= $text2; // show text with no html cleaning
352 } else {
353 $out .= $text2withnotags; // show text with html cleaning
354 }
355
356 if (!empty($textnoformat)) {
357 $out .= "\n".$textnoformat."\n";
358 }
359
360 $out .= "</td>\n";
361 }
362
363 $out .= "</tr>\n";
364 }
365 }
366 }
367
368 if (!empty($head['text']) || !empty($head['sublink']) || !empty($head['subpicto']) || $nblines) {
369 $out .= "</table>\n";
370 }
371
372 // If invisible box with no contents
373 if (empty($head['text']) && empty($head['sublink']) && empty($head['subpicto']) && !$nblines) {
374 $out .= "<br>\n";
375 }
376
377 $out .= "</div>\n";
378
379 $out .= "<!-- Box ".get_class($this)." end -->\n\n";
380 if (getDolGlobalString('MAIN_ACTIVATE_FILECACHE')) {
381 dol_filecache($cachedir, $filename, $out);
382 }
383 } else {
384 dol_syslog(get_class($this).'::showBoxCached');
385 $out = "<!-- Box ".get_class($this)." from cache -->";
386 $out .= dol_readcachefile($cachedir, $filename);
387 }
388
389 if ($nooutput) {
390 return $out;
391 } else {
392 print $out;
393 }
394
395 return '';
396 }
397
398
406 public static function getWidgetsList($forcedirwidget = null)
407 {
408 global $conf, $langs, $db;
409
410 $files = array();
411 $fullpath = array();
412 $relpath = array();
413 $iscoreorexternal = array();
414 $modules = array();
415 $orders = array();
416 $i = 0;
417
418 //$dirwidget=array_merge(array('/core/boxes/'), $conf->modules_parts['widgets']);
419 $dirwidget = array('/core/boxes/'); // $conf->modules_parts['widgets'] is not required
420 if (is_array($forcedirwidget)) {
421 $dirwidget = $forcedirwidget;
422 }
423
424 foreach ($dirwidget as $reldir) {
425 $dir = dol_buildpath($reldir, 0);
426 $newdir = dol_osencode($dir);
427
428 // Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php at each call)
429 if (!is_dir($newdir)) {
430 continue;
431 }
432
433 $handle = opendir($newdir);
434 if (is_resource($handle)) {
435 while (($file = readdir($handle)) !== false) {
436 $reg = array();
437 if (is_readable($newdir.'/'.$file) && preg_match('/^(.+)\.php/', $file, $reg)) {
438 if (preg_match('/\.back$/', $file) || preg_match('/^(.+)\.disabled\.php/', $file)) {
439 continue;
440 }
441
442 $part1 = $reg[1];
443
444 $modName = ucfirst($reg[1]);
445 //print "file=$file"; print "modName=$modName"; exit;
446 if (in_array($modName, $modules)) {
447 $langs->load("errors");
448 print '<div class="error">'.$langs->trans("Error").' : '.$langs->trans("ErrorDuplicateWidget", $modName, "").'</div>';
449 } else {
450 try {
451 include_once $newdir.'/'.$file;
452 } catch (Exception $e) {
453 print $e->getMessage();
454 }
455 }
456
457 $files[$i] = $file;
458 $fullpath[$i] = $dir.'/'.$file;
459 $relpath[$i] = preg_replace('/^\//', '', $reldir).'/'.$file;
460 $iscoreorexternal[$i] = ($reldir == '/core/boxes/' ? 'internal' : 'external');
461 $modules[$i] = $modName;
462 $orders[$i] = $part1; // Set sort criteria value
463
464 $i++;
465 }
466 }
467 closedir($handle);
468 }
469 }
470 //echo "<pre>";print_r($modules);echo "</pre>";
471
472 asort($orders);
473
474 $widget = array();
475 $j = 0;
476
477 // Loop on each widget
478 foreach ($orders as $key => $value) {
479 $modName = $modules[$key];
480 if (empty($modName)) {
481 continue;
482 }
483
484 if (!class_exists($modName)) {
485 print 'Error: A widget file was found but its class "'.$modName.'" was not found.'."<br>\n";
486 continue;
487 }
488
489 $objMod = new $modName($db);
490 if (is_object($objMod)) {
491 // Define disabledbyname and disabledbymodule
492 $disabledbyname = 0;
493 $disabledbymodule = 0; // TODO Set to 2 if module is not enabled
494 $module = '';
495
496 // Check if widget file is disabled by name
497 if (preg_match('/NORUN$/i', $files[$key])) {
498 $disabledbyname = 1;
499 }
500
501 // We set info of modules
502 $widget[$j]['picto'] = (empty($objMod->picto) ? (empty($objMod->boximg) ? img_object('', 'generic') : $objMod->boximg) : img_object('', $objMod->picto));
503 $widget[$j]['file'] = $files[$key];
504 $widget[$j]['fullpath'] = $fullpath[$key];
505 $widget[$j]['relpath'] = $relpath[$key];
506 $widget[$j]['iscoreorexternal'] = $iscoreorexternal[$key];
507 $widget[$j]['version'] = empty($objMod->version) ? '' : $objMod->version;
508 $widget[$j]['status'] = img_picto($langs->trans("Active"), 'tick');
509 if ($disabledbyname > 0 || $disabledbymodule > 1) {
510 $widget[$j]['status'] = '';
511 }
512
513 $text = '<b>'.$langs->trans("Description").':</b><br>';
514 $text .= $objMod->boxlabel.'<br>';
515 $text .= '<br><b>'.$langs->trans("Status").':</b><br>';
516 if ($disabledbymodule == 2) {
517 $text .= $langs->trans("WidgetDisabledAsModuleDisabled", $module).'<br>';
518 }
519
520 $widget[$j]['info'] = $text;
521 }
522 $j++;
523 }
524 return $widget;
525 }
526}
Class ModeleBoxes.
showBox($head=null, $contents=null, $nooutput=0)
Standard method to show a box (usage by boxes not mandatory, a box can still use its own showBox func...
fetch($rowid)
Load a box line from its rowid.
error()
Return last error message.
__construct($db, $param='')
Constructor.
static getWidgetsList($forcedirwidget=null)
Return list of widget.
dol_filecache($directory, $filename, $object)
Store object in file.
dol_readcachefile($directory, $filename)
Read object from cachefile.
dol_cache_refresh($directory, $filename, $cachetime)
Test if Refresh needed.
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
rtl background position
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e rowid
Definition invoice.php:1926