dolibarr 25.0.0-alpha
html.formother.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 2002-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
5 * Copyright (C) 2004 Sebastien Di Cintio <sdicintio@ressource-toi.org>
6 * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
7 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
8 * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
9 * Copyright (C) 2006 Marc Barilley/Ocebo <marc@ocebo.com>
10 * Copyright (C) 2007 Franky Van Liedekerke <franky.van.liedekerker@telenet.be>
11 * Copyright (C) 2007 Patrick Raguin <patrick.raguin@gmail.com>
12 * Copyright (C) 2019 Thibault FOUCART <support@ptibogxiv.net>
13 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
14 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program. If not, see <https://www.gnu.org/licenses/>.
28 */
29
42{
46 private $db;
47
51 public $error;
52
53
59 public function __construct($db)
60 {
61 $this->db = $db;
62 }
63
73 public function getHTMLScannerForm($jstoexecuteonadd = 'barcodescannerjs', $mode = 'all', $warehouseselect = 0)
74 {
75 global $langs;
76
77 $out = '';
78
79 $out .= '<!-- Popup for mass barcode scanning -->'."\n";
80 $out .= '<div class="div-for-modal-topright" style="padding: 15px">';
81 $out .= '<center>'.img_picto('', 'barcode', 'class="pictofixedwidth"').'<strong>Barcode scanner tool...</strong></center><br>';
82
83 if ($mode == 'product') {
84 $out .= '<input type="hidden" name="barcodemode" value="barcodeforproduct" id="barcodeforproduct">';
85 } elseif ($mode == 'lot') {
86 $out .= '<input type="hidden" name="barcodemode" value="barcodeforlotserial" id="barcodeforlotserial">';
87 } else { // $mode = 'all'
88 $out .= '<input type="radio" name="barcodemode" value="barcodeforautodetect" id="barcodeforautodetect" checked="checked"> <label for="barcodeforautodetect">Autodetect if we scan a product barcode or a lot/serial barcode</label><br>';
89 $out .= '<input type="radio" name="barcodemode" value="barcodeforproduct" id="barcodeforproduct"> <label for="barcodeforproduct">Scan a product barcode</label><br>';
90 $out .= '<input type="radio" name="barcodemode" value="barcodeforlotserial" id="barcodeforlotserial"> <label for="barcodeforlotserial">Scan a product lot or serial number</label><br>';
91 }
92 $stringaddbarcode = $langs->trans("QtyToAddAfterBarcodeScan", "tmphtml");
93 $htmltoreplaceby = '<select name="selectaddorreplace"><option selected value="add">'.$langs->trans("Add").'</option><option value="replace">'.$langs->trans("ToReplace").'</option></select>';
94 $stringaddbarcode = str_replace("tmphtml", $htmltoreplaceby, $stringaddbarcode);
95 $out .= $stringaddbarcode.': <input type="text" name="barcodeproductqty" class="width40 right" value="1"><br>';
96 if ($warehouseselect > 0) {
97 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
98 $formproduct = new FormProduct($this->db);
99 $formproduct->loadWarehouses();
100 $out .= img_picto('', 'stock', 'class="pictofixedwidth"');
101 $out .= $formproduct->selectWarehouses('', "warehousenew", '', 0, 0, 0, '', 0, 1);
102 $out .= '<br>';
103 $out .= '<br>';
104 }
105 $out .= '<textarea type="text" name="barcodelist" class="centpercent" autofocus rows="'.ROWS_3.'" placeholder="'.dol_escape_htmltag($langs->trans("ScanOrTypeOrCopyPasteYourBarCodes")).'"></textarea>';
106
107 /*print '<br>'.$langs->trans("or").'<br>';
108
109 print '<br>';
110
111 print '<input type="text" name="barcodelotserial" class="width200"> &nbsp; &nbsp; Qty <input type="text" name="barcodelotserialqty" class="width50 right" value="1"><br>';
112 */
113 $out .= '<br>';
114 $out .= '<center>';
115 $out .= '<input type="submit" class="button marginleftonly marginrightonly" id="exec'.dol_escape_js($jstoexecuteonadd).'" name="addscan" value="'.dolPrintHTMLForAttribute($langs->trans("Add")).'">';
116 $out .= '<input type="submit" class="button marginleftonly marginrightonly" name="cancel" value="'.dol_escape_htmltag($langs->trans("CloseWindow")).'">';
117 $out .= '</center>';
118 $out .= '<br>';
119 $out .= '<div type="text" id="scantoolmessage" class="scantoolmessage ok nopadding"></div>';
120
121 $out .= '<script nonce="'.getNonce().'">';
122 $out .= 'jQuery("#barcodeforautodetect, #barcodeforproduct, #barcodeforlotserial").click(function(){';
123 $out .= 'console.log("select choice");';
124 $out .= 'jQuery("#scantoolmessage").text("");';
125 $out .= '});'."\n";
126 // $jstoexecuteonadd is a name of a js function
127 // TODO: dol_escape_js($jstoexecuteonadd) seems wrong for execution, verify, fix
128 $out .= '$(\'#exec'.dol_escape_js($jstoexecuteonadd).'\').click(function(){
129 console.log(\'We call js to execute '.dol_escape_js($jstoexecuteonadd).'\');
130 '.dol_escape_js($jstoexecuteonadd).'();
131 return false; /* We want to stay on the scan tool */
132 })';
133 $out .= '</script>';
134
135 $out .= '</center>';
136 $out .= '</div>';
137
138 return $out;
139 }
140
141 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
152 public function select_export_model($selected = '', $htmlname = 'exportmodelid', $type = '', $useempty = 0, $fk_user = null)
153 {
154 // phpcs:enable
155 global $langs;
156
157 $sql = "SELECT rowid, label, fk_user";
158 $sql .= " FROM ".$this->db->prefix()."export_model";
159 $sql .= " WHERE type = '".$this->db->escape($type)."'";
160 if (!getDolGlobalString('EXPORTS_SHARE_MODELS')) { // EXPORTS_SHARE_MODELS means all templates are visible, whatever is owner.
161 $sql .= " AND fk_user IN (0, ".((int) $fk_user).")";
162 }
163 $sql .= " ORDER BY label";
164 $result = $this->db->query($sql);
165 if ($result) {
166 print '<select class="flat minwidth200" name="'.$htmlname.'" id="'.$htmlname.'">';
167 if ($useempty) {
168 if (is_numeric($useempty)) {
169 print '<option value="-1">&nbsp;</option>';
170 } else {
171 print '<option value="-1">'.$langs->trans($useempty).'</option>';
172 }
173 }
174
175 $tmpuser = new User($this->db);
176
177 $num = $this->db->num_rows($result);
178 $i = 0;
179 while ($i < $num) {
180 $obj = $this->db->fetch_object($result);
181
182 $label = $obj->label;
183 if ($obj->fk_user == 0) {
184 $label .= ' <span class="opacitymedium">('.$langs->trans("Everybody").')</span>';
185 } elseif ($obj->fk_user > 0) {
186 $tmpuser->fetch($obj->fk_user);
187 $label .= ' <span class="opacitymedium">('.$tmpuser->getFullName($langs).')</span>';
188 }
189
190 if ($selected == $obj->rowid) {
191 print '<option value="'.$obj->rowid.'" selected data-html="'.dolPrintHTMLForAttribute($label).'">';
192 } else {
193 print '<option value="'.$obj->rowid.'" data-html="'.dolPrintHTMLForAttribute($label).'">';
194 }
195 print $label;
196 print '</option>';
197 $i++;
198 }
199 if ($num == 0) {
200 print '<option value="-1" disabled data-html="'.dolPrintHTMLForAttribute('<span class="opacitymedium">'.$langs->transnoentitiesnoconv("NoPredefinedExportProfileYet").'</span>').'">'.$langs->transnoentitiesnoconv("NoPredefinedProfileYet").'</option>';
201 }
202 print "</select>";
203 print ajax_combobox($htmlname);
204 } else {
205 dol_print_error($this->db);
206 }
207 }
208
209
210 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
221 public function select_import_model($selected = '', $htmlname = 'importmodelid', $type = '', $useempty = 0, $fk_user = null)
222 {
223 // phpcs:enable
224 global $langs;
225
226 $sql = "SELECT rowid, label, fk_user";
227 $sql .= " FROM ".$this->db->prefix()."import_model";
228 $sql .= " WHERE type = '".$this->db->escape($type)."'";
229 if (!getDolGlobalString('EXPORTS_SHARE_MODELS')) { // EXPORTS_SHARE_MODELS means all templates are visible, whatever is owner.
230 $sql .= " AND fk_user IN (0, ".((int) $fk_user).")";
231 }
232 $sql .= " ORDER BY label";
233 $result = $this->db->query($sql);
234 if ($result) {
235 print '<select class="flat minwidth200" name="'.$htmlname.'" id="'.$htmlname.'">';
236 if (is_numeric($useempty)) {
237 print '<option value="-1">&nbsp;</option>';
238 } else {
239 print '<option value="-1">'.$langs->trans($useempty).'</option>';
240 }
241
242 $tmpuser = new User($this->db);
243
244 $num = $this->db->num_rows($result);
245 $i = 0;
246 while ($i < $num) {
247 $obj = $this->db->fetch_object($result);
248
249 $label = $obj->label;
250 if ($obj->fk_user == 0) {
251 $label .= ' <span class="opacitymedium">('.$langs->trans("Everybody").')</span>';
252 } elseif ($obj->fk_user > 0) {
253 $tmpuser->fetch($obj->fk_user);
254 $label .= ' <span class="opacitymedium">('.$tmpuser->getFullName($langs).')</span>';
255 }
256
257 if ($selected == $obj->rowid) {
258 print '<option value="'.$obj->rowid.'" selected data-html="'.dol_escape_htmltag($label).'">';
259 } else {
260 print '<option value="'.$obj->rowid.'" data-html="'.dol_escape_htmltag($label).'">';
261 }
262 print $label;
263 print '</option>';
264 $i++;
265 }
266 if ($num == 0) {
267 print '<option value="-1" disabled data-html="'.dolPrintHTMLForAttribute('<span class="opacitymedium">'.$langs->transnoentitiesnoconv("NoPredefinedProfileYet").'</span>').'">'.$langs->transnoentitiesnoconv("NoPredefinedProfileYet").'</option>';
268 }
269 print "</select>";
270 print ajax_combobox($htmlname);
271 } else {
272 dol_print_error($this->db);
273 }
274 }
275
276
277 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
285 public function select_ecotaxes($selected = '', $htmlname = 'ecotaxe_id')
286 {
287 // phpcs:enable
288 global $langs;
289
290 $sql = "SELECT e.rowid, e.code, e.label, e.price, e.organization,";
291 $sql .= " c.label as country";
292 $sql .= " FROM ".$this->db->prefix()."c_ecotaxe as e,".$this->db->prefix()."c_country as c";
293 $sql .= " WHERE e.active = 1 AND e.fk_pays = c.rowid";
294 $sql .= " ORDER BY country, e.organization ASC, e.code ASC";
295
296 dol_syslog(get_class($this).'::select_ecotaxes', LOG_DEBUG);
297 $resql = $this->db->query($sql);
298 if ($resql) {
299 print '<select class="flat" name="'.$htmlname.'">';
300 $num = $this->db->num_rows($resql);
301 $i = 0;
302 print '<option value="-1">&nbsp;</option>'."\n";
303 if ($num) {
304 while ($i < $num) {
305 $obj = $this->db->fetch_object($resql);
306 if ($selected && $selected == $obj->rowid) {
307 print '<option value="'.$obj->rowid.'" selected>';
308 } else {
309 print '<option value="'.$obj->rowid.'">';
310 //print '<option onmouseover="showtip(\''.$obj->label.'\')" onMouseout="hidetip()" value="'.$obj->rowid.'">';
311 }
312 $selectOptionValue = $obj->code.' - '.$obj->label.' : '.price($obj->price).' '.$langs->trans("HT").' ('.$obj->organization.')';
313 print $selectOptionValue;
314 print '</option>';
315 $i++;
316 }
317 }
318 print '</select>';
319 return 0;
320 } else {
321 dol_print_error($this->db);
322 return 1;
323 }
324 }
325
326
327 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
336 public function select_revenue_stamp($selected = '', $htmlname = 'revenuestamp', $country_code = '')
337 {
338 // phpcs:enable
339 global $langs;
340
341 $out = '';
342
343 $sql = "SELECT r.taux, r.revenuestamp_type";
344 $sql .= " FROM ".$this->db->prefix()."c_revenuestamp as r,".$this->db->prefix()."c_country as c";
345 $sql .= " WHERE r.active = 1 AND r.fk_pays = c.rowid";
346 $sql .= " AND c.code = '".$this->db->escape($country_code)."'";
347
348 dol_syslog(get_class($this).'::select_revenue_stamp', LOG_DEBUG);
349 $resql = $this->db->query($sql);
350 if ($resql) {
351 $out .= '<select class="flat" name="'.$htmlname.'">';
352 $num = $this->db->num_rows($resql);
353 $i = 0;
354 $out .= '<option value="0">&nbsp;</option>'."\n";
355 if ($num) {
356 while ($i < $num) {
357 $obj = $this->db->fetch_object($resql);
358 if (($selected && $selected == $obj->taux) || $num == 1) {
359 $out .= '<option value="'.$obj->taux.($obj->revenuestamp_type == 'percent' ? '%' : '').'"'.($obj->revenuestamp_type == 'percent' ? ' data-type="percent"' : '').' selected>';
360 } else {
361 $out .= '<option value="'.$obj->taux.($obj->revenuestamp_type == 'percent' ? '%' : '').'"'.($obj->revenuestamp_type == 'percent' ? ' data-type="percent"' : '').'>';
362 }
363 $out .= $obj->taux.($obj->revenuestamp_type == 'percent' ? '%' : '');
364 $out .= '</option>';
365 $i++;
366 }
367 }
368 $out .= '</select>';
369 return $out;
370 } else {
371 dol_print_error($this->db);
372 return '';
373 }
374 }
375
376
377 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
390 public function select_percent($selected = 0, $htmlname = 'percent', $disabled = 0, $increment = 5, $start = 0, $end = 100, $showempty = 0)
391 {
392 // phpcs:enable
393 $return = '<select class="flat maxwidth75 right" name="'.$htmlname.'" '.($disabled ? 'disabled' : '').'>';
394 if ($showempty) {
395 $return .= '<option value="-1"'.(($selected == -1 || $selected == '') ? ' selected' : '').'>&nbsp;</option>';
396 }
397
398 for ($i = $start; $i <= $end; $i += $increment) {
399 if ($selected != '' && (int) $selected == $i) {
400 $return .= '<option value="'.$i.'" selected>';
401 } else {
402 $return .= '<option value="'.$i.'">';
403 }
404 $return .= $i.' % ';
405 $return .= '</option>';
406 }
407
408 $return .= '</select>';
409
410 return $return;
411 }
412
413 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
426 public function select_categories($type, $selected = 0, $htmlname = 'search_categ', $nocateg = 0, $showempty = 1, $morecss = '')
427 {
428 // phpcs:enable
429 global $conf, $langs;
430 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
431
432 // For backward compatibility
433 if (is_numeric($type)) {
434 dol_syslog(__METHOD__.': using numeric value for parameter type is deprecated. Use string code instead.', LOG_WARNING);
435 }
436
437 // Load list of "categories"
438 $static_categs = new Categorie($this->db);
439 $tab_categs = $static_categs->get_full_arbo($type);
440
441 $moreforfilter = '';
442
443 // Print a select with each of them
444 $moreforfilter .= '<select class="flat minwidth100'.($morecss ? ' '.$morecss : '').'" id="select_categ_'.$htmlname.'" name="'.$htmlname.'">';
445 if ($showempty) {
446 $textforempty = ' ';
447 if (!empty($conf->use_javascript_ajax)) {
448 $textforempty = '&nbsp;'; // If we use ajaxcombo, we need &nbsp; here to avoid to have an empty element that is too small.
449 }
450 if (!is_numeric($showempty)) {
451 $textforempty = $showempty;
452 }
453 $moreforfilter .= '<option class="optiongrey" value="'.($showempty < 0 ? $showempty : -1).'"'.($selected == $showempty ? ' selected' : '');
454 //$moreforfilter .= ' data-html="'.dol_escape_htmltag($textforempty).'"';
455 $moreforfilter .= '>'.dol_escape_htmltag($textforempty).'</option>'."\n";
456 }
457
458 if (is_array($tab_categs)) {
459 foreach ($tab_categs as $categ) {
460 $moreforfilter .= '<option value="'.$categ['id'].'"';
461 if ($categ['id'] == $selected) {
462 $moreforfilter .= ' selected';
463 }
464 $moreforfilter .= ' data-html="'.dol_escape_htmltag(img_picto('', 'category', 'class="pictofixedwidth" style="color: #'.$categ['color'].'"').dol_trunc($categ['fulllabel'], 50, 'middle')).'"';
465 $moreforfilter .= '>'.dol_trunc($categ['fulllabel'], 50, 'middle').'</option>';
466 }
467 }
468 if ($nocateg) {
469 $langs->load("categories");
470 $moreforfilter .= '<option value="-2"'.($selected == -2 ? ' selected' : '').'>- '.$langs->trans("NotCategorized").' -</option>';
471 }
472 $moreforfilter .= '</select>';
473
474 // Enhance with select2
475 if ($conf->use_javascript_ajax) {
476 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
477 $comboenhancement = ajax_combobox('select_categ_'.$htmlname);
478 $moreforfilter .= $comboenhancement;
479 }
480
481 return $moreforfilter;
482 }
483
484
485 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
498 public function select_salesrepresentatives($selected, $htmlname, $user, $showstatus = 0, $showempty = 1, $morecss = '', $norepresentative = 0)
499 {
500 // phpcs:enable
501 global $conf, $langs, $hookmanager;
502 global $action;
503
504 $langs->load('users');
505
506 $out = '';
507
508 $reshook = $hookmanager->executeHooks('addSQLWhereFilterOnSelectSalesRep', array(), $this, $action);
509
510 // Select each sales and print them in a select input
511 $out .= '<select class="flat'.($morecss ? ' '.$morecss : '').'" id="'.$htmlname.'" name="'.$htmlname.'">';
512 if ($showempty) {
513 $textforempty = ' ';
514 if (!is_numeric($showempty)) {
515 $textforempty = $showempty;
516 }
517 if (!empty($conf->use_javascript_ajax) && $textforempty == ' ') {
518 $textforempty = '&nbsp;'; // If we use ajaxcombo, we need &nbsp; here to avoid to have an empty element that is too small.
519 }
520 $out .= '<option class="optiongrey" value="'.($showempty < 0 ? $showempty : -1).'"'.($selected == $showempty ? ' selected' : '').'>'.$textforempty.'</option>'."\n";
521 }
522
523 // Get list of users allowed to be viewed
524 $sql_usr = "SELECT u.rowid, u.lastname, u.firstname, u.statut as status, u.login, u.photo, u.gender, u.entity, u.admin";
525 $sql_usr .= " FROM ".$this->db->prefix()."user as u";
526
527 if (getDolGlobalInt('MULTICOMPANY_TRANSVERSE_MODE')) {
528 if (!empty($user->admin) && empty($user->entity) && $conf->entity == 1) {
529 $sql_usr .= " WHERE u.entity IS NOT NULL"; // Show all users
530 } else {
531 $sql_usr .= " WHERE EXISTS (SELECT ug.fk_user FROM ".$this->db->prefix()."usergroup_user as ug WHERE u.rowid = ug.fk_user AND ug.entity IN (".getEntity('usergroup')."))";
532 $sql_usr .= " OR u.entity = 0"; // Show always superadmin
533 }
534 } else {
535 $sql_usr .= " WHERE u.entity IN (".getEntity('user').")";
536 }
537
538 if (!$user->hasRight('user', 'user', 'lire')) {
539 $sql_usr .= " AND u.rowid = ".((int) $user->id);
540 }
541 if (!empty($user->socid)) {
542 $sql_usr .= " AND u.fk_soc = ".((int) $user->socid);
543 }
544 if (getDolUserString('USER_HIDE_NONEMPLOYEE_IN_COMBOBOX', getDolGlobalString('USER_HIDE_NONEMPLOYEE_IN_COMBOBOX'))) {
545 $sql_usr .= " AND u.employee <> 0";
546 }
547 if (getDolUserString('USER_HIDE_EXTERNAL_IN_COMBOBOX', getDolGlobalString('USER_HIDE_EXTERNAL_IN_COMBOBOX'))) {
548 $sql_usr .= " AND u.fk_soc IS NULL";
549 }
550 if (getDolUserString('USER_HIDE_INACTIVE_IN_COMBOBOX', getDolGlobalString('USER_HIDE_INACTIVE_IN_COMBOBOX'))) { // Can be set in setup of module User.
551 $sql_usr .= " AND u.statut <> 0";
552 }
553
554 //Add hook to filter on user (for example on usergroup define in custom modules)
555 if (!empty($reshook)) {
556 $sql_usr .= $hookmanager->resArray[0]; // Trust the hook: @phan-suppress-current-line SqlInjection
557 }
558
559 // Add existing sales representatives of thirdparty of external user
560 if (!$user->hasRight('user', 'user', 'lire') && $user->socid) {
561 $sql_usr .= " UNION ";
562 $sql_usr .= "SELECT u2.rowid, u2.lastname, u2.firstname, u2.statut as status, u2.login, u2.photo, u2.gender, u2.entity, u2.admin";
563 $sql_usr .= " FROM ".$this->db->prefix()."user as u2, ".$this->db->prefix()."societe_commerciaux as sc";
564
565 if (getDolGlobalInt('MULTICOMPANY_TRANSVERSE_MODE')) {
566 if (!empty($user->admin) && empty($user->entity) && $conf->entity == 1) {
567 $sql_usr .= " WHERE u2.entity IS NOT NULL"; // Show all users
568 } else {
569 $sql_usr .= " WHERE EXISTS (SELECT ug2.fk_user FROM ".$this->db->prefix()."usergroup_user as ug2 WHERE u2.rowid = ug2.fk_user AND ug2.entity IN (".getEntity('usergroup')."))";
570 }
571 } else {
572 $sql_usr .= " WHERE u2.entity IN (".getEntity('user').")";
573 }
574
575 $sql_usr .= " AND u2.rowid = sc.fk_user AND sc.fk_soc = ".((int) $user->socid);
576
577 //Add hook to filter on user (for example on usergroup define in custom modules)
578 if (!empty($reshook)) {
579 $sql_usr .= $hookmanager->resArray[1]; // Trust the hook: @phan-suppress-current-line SqlInjection
580 }
581 }
582
583 if (!getDolGlobalString('MAIN_FIRSTNAME_NAME_POSITION')) { // MAIN_FIRSTNAME_NAME_POSITION is 0 means firstname+lastname
584 $sql_usr .= " ORDER BY status DESC, firstname ASC, lastname ASC";
585 } else {
586 $sql_usr .= " ORDER BY status DESC, lastname ASC, firstname ASC";
587 }
588 //print $sql_usr;exit;
589
590 $resql_usr = $this->db->query($sql_usr);
591 if ($resql_usr) {
592 $userstatic = new User($this->db);
593
594 while ($obj_usr = $this->db->fetch_object($resql_usr)) {
595 $userstatic->id = $obj_usr->rowid;
596 $userstatic->lastname = $obj_usr->lastname;
597 $userstatic->firstname = $obj_usr->firstname;
598 $userstatic->photo = $obj_usr->photo;
599 $userstatic->status = $obj_usr->status;
600 $userstatic->entity = $obj_usr->entity;
601 $userstatic->admin = $obj_usr->admin;
602
603 $labeltoshow = dolGetFirstLastname($obj_usr->firstname, $obj_usr->lastname);
604 if (empty($obj_usr->firstname) && empty($obj_usr->lastname)) {
605 $labeltoshow = $obj_usr->login;
606 }
607
608 $out .= '<option value="'.$obj_usr->rowid.'"';
609 if ($obj_usr->rowid == $selected) {
610 $out .= ' selected';
611 }
612 $out .= ' data-html="';
613 $outhtml = $userstatic->getNomUrl(-3, '', 0, 1, 24, 1, 'login', '', 1).' ';
614 if ($showstatus >= 0 && $obj_usr->status == 0) {
615 $outhtml .= '<strike class="opacitymediumxxx">';
616 }
617 $outhtml .= $labeltoshow;
618 if ($showstatus >= 0 && $obj_usr->status == 0) {
619 $outhtml .= '</strike>';
620 }
621 $out .= dol_escape_htmltag($outhtml);
622 $out .= '">';
623
624 $out .= $labeltoshow;
625 // Complete name with more info
626 $moreinfo = 0;
627 if (getDolGlobalString('MAIN_SHOW_LOGIN')) {
628 $out .= ($moreinfo ? ' - ' : ' (').$obj_usr->login;
629 $moreinfo++;
630 }
631 if ($showstatus >= 0) {
632 if ($obj_usr->status == 1 && $showstatus == 1) {
633 $out .= ($moreinfo ? ' - ' : ' (').$langs->trans('Enabled');
634 $moreinfo++;
635 }
636 if ($obj_usr->status == 0) {
637 $out .= ($moreinfo ? ' - ' : ' (').$langs->trans('Disabled');
638 $moreinfo++;
639 }
640 }
641 $out .= ($moreinfo ? ')' : '');
642 $out .= '</option>';
643 }
644 $this->db->free($resql_usr);
645 } else {
646 dol_print_error($this->db);
647 }
648
649 if ($norepresentative) {
650 $langs->load("companies");
651 $out .= '<option value="-2"'.($selected == -2 ? ' selected' : '').'>- '.$langs->trans("NoSalesRepresentativeAffected").' -</option>';
652 }
653
654 $out .= '</select>';
655
656 // Enhance with select2
657 if ($conf->use_javascript_ajax) {
658 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
659
660 $comboenhancement = ajax_combobox($htmlname);
661 if ($comboenhancement) {
662 $out .= $comboenhancement;
663 }
664 }
665
666 return $out;
667 }
668
684 public function selectProjectTasks($selectedtask = 0, $projectid = 0, $htmlname = 'task_parent', $modeproject = 0, $modetask = 0, $mode = 0, $useempty = 0, $disablechildoftaskid = 0, $filteronprojstatus = '', $morecss = '')
685 {
686 global $user, $langs;
687
688 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
689
690 //print $modeproject.'-'.$modetask;
691 $task = new Task($this->db);
692 $tasksarray = $task->getTasksArray($modetask ? $user : 0, $modeproject ? $user : 0, $projectid, 0, $mode, '', $filteronprojstatus);
693 if ($tasksarray) {
694 print '<select class="flat'.($morecss ? ' '.$morecss : '').'" name="'.$htmlname.'" id="'.$htmlname.'">';
695 if ($useempty) {
696 print '<option value="0">&nbsp;</option>';
697 }
698 $j = 0;
699 $level = 0;
700 $this->_pLineSelect($j, 0, $tasksarray, $level, $selectedtask, $projectid, $disablechildoftaskid);
701 print '</select>';
702
703 print ajax_combobox($htmlname);
704 } else {
705 print '<div class="warning">'.$langs->trans("NoProject").'</div>';
706 }
707 }
708
721 private function _pLineSelect(&$inc, $parent, $lines, $level = 0, $selectedtask = 0, $selectedproject = 0, $disablechildoftaskid = 0)
722 {
723 global $langs, $user, $conf;
724
725 $lastprojectid = 0;
726
727 $numlines = count($lines);
728 for ($i = 0; $i < $numlines; $i++) {
729 if ($lines[$i]->fk_task_parent == $parent) {
730 //var_dump($selectedproject."--".$selectedtask."--".$lines[$i]->fk_project."_".$lines[$i]->id); // $lines[$i]->id may be empty if project has no lines
731
732 // Break on a new project
733 if ($parent == 0) { // We are on a task at first level
734 if ($lines[$i]->fk_project != $lastprojectid) { // Break found on project
735 if ($i > 0) {
736 print '<option value="0" disabled>----------</option>';
737 }
738 print '<option value="'.$lines[$i]->fk_project.'_0"';
739 if ($selectedproject == $lines[$i]->fk_project) {
740 print ' selected';
741 }
742
743 $labeltoshow = $lines[$i]->projectref;
744 //$labeltoshow .= ' '.$lines[$i]->projectlabel;
745 if (empty($lines[$i]->public)) {
746 //$labeltoshow .= ' <span class="opacitymedium">('.$langs->trans("Visibility").': '.$langs->trans("PrivateProject").')</span>';
747 $labeltoshow = img_picto($lines[$i]->projectlabel, 'project', 'class="pictofixedwidth"').$labeltoshow;
748 } else {
749 //$labeltoshow .= ' <span class="opacitymedium">('.$langs->trans("Visibility").': '.$langs->trans("SharedProject").')</span>';
750 $labeltoshow = img_picto($lines[$i]->projectlabel, 'projectpub', 'class="pictofixedwidth"').$labeltoshow;
751 }
752
753 print ' data-html="'.dol_escape_htmltag($labeltoshow).'"';
754 print '>'; // Project -> Task
755 print $labeltoshow;
756 print "</option>\n";
757
758 $lastprojectid = $lines[$i]->fk_project;
759 $inc++;
760 }
761 }
762
763 $newdisablechildoftaskid = $disablechildoftaskid;
764
765 // Print task
766 if (isset($lines[$i]->id)) { // We use isset because $lines[$i]->id may be null if project has no task and are on root project (tasks may be caught by a left join). We enter here only if '0' or >0
767 // Check if we must disable entry
768 $disabled = 0;
769 if ($disablechildoftaskid && (($lines[$i]->id == $disablechildoftaskid || $lines[$i]->fk_task_parent == $disablechildoftaskid))) {
770 $disabled++;
771 if ($lines[$i]->fk_task_parent == $disablechildoftaskid) {
772 $newdisablechildoftaskid = $lines[$i]->id; // If task is child of a disabled parent, we will propagate id to disable next child too
773 }
774 }
775
776 print '<option value="'.$lines[$i]->fk_project.'_'.$lines[$i]->id.'"';
777 if (($lines[$i]->id == $selectedtask) || ($lines[$i]->fk_project.'_'.$lines[$i]->id == $selectedtask)) {
778 print ' selected';
779 }
780 if ($disabled) {
781 print ' disabled';
782 }
783
784 $labeltoshow = $lines[$i]->projectref;
785 //$labeltoshow .= ' '.$lines[$i]->projectlabel;
786 if (empty($lines[$i]->public)) {
787 //$labeltoshow .= ' <span class="opacitymedium">('.$langs->trans("Visibility").': '.$langs->trans("PrivateProject").')</span>';
788 $labeltoshow = img_picto($lines[$i]->projectlabel, 'project', 'class="pictofixedwidth"').$labeltoshow;
789 } else {
790 //$labeltoshow .= ' <span class="opacitymedium">('.$langs->trans("Visibility").': '.$langs->trans("SharedProject").')</span>';
791 $labeltoshow = img_picto($lines[$i]->projectlabel, 'projectpub', 'class="pictofixedwidth"').$labeltoshow;
792 }
793 if ($lines[$i]->id) {
794 $labeltoshow .= ' > ';
795 }
796 for ($k = 0; $k < $level; $k++) {
797 $labeltoshow .= "&nbsp;&nbsp;&nbsp;";
798 }
799 $labeltoshow .= $lines[$i]->ref.' '.$lines[$i]->label;
800
801 print ' data-html="'.dol_escape_htmltag($labeltoshow).'"';
802 print '>';
803 print $labeltoshow;
804 print "</option>\n";
805 $inc++;
806 }
807
808 $level++;
809 if ($lines[$i]->id) {
810 $this->_pLineSelect($inc, $lines[$i]->id, $lines, $level, $selectedtask, $selectedproject, $newdisablechildoftaskid);
811 }
812 $level--;
813 }
814 }
815 }
816
817
826 public static function showColor($color, $textifnotdefined = '')
827 {
828 $textcolor = 'FFF';
829 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
830 if (colorIsLight($color)) {
831 $textcolor = '000';
832 }
833
834 $color = colorArrayToHex(colorStringToArray($color, array()), '');
835
836 if ($color) {
837 return '<input type="text" class="colorthumb" disabled style="padding: 1px; margin-top: 0; margin-bottom: 0; color: #'.$textcolor.'; background-color: #'.$color.'" value="'.$color.'">';
838 } else {
839 return $textifnotdefined;
840 }
841 }
842
843 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
856 public function select_color($set_color = '', $prefix = 'f_color', $form_name = '', $showcolorbox = 1, $arrayofcolors = [])
857 {
858 // phpcs:enable
859 print $this->selectColor($set_color, $prefix, $form_name, $showcolorbox, $arrayofcolors);
860 }
861
876 public static function selectColor($set_color = '', $prefix = 'f_color', $form_name = '', $showcolorbox = 1, $arrayofcolors = [], $morecss = '', $setpropertyonselect = '', $default = '')
877 {
878 // Deprecation warning
879 if ($form_name) {
880 dol_syslog(__METHOD__.": form_name parameter is deprecated", LOG_WARNING);
881 }
882
883 global $langs, $conf;
884
885 $out = '';
886
887 if (!is_array($arrayofcolors) || count($arrayofcolors) < 1) {
888 // Case of selection of any color
889 $langs->load("other");
890 if (empty($conf->dol_use_jmobile) && !empty($conf->use_javascript_ajax) && !getDolGlobalInt('MAIN_USE_HTML5_COLOR_SELECTOR')) {
891 $out .= '<link rel="stylesheet" media="screen" type="text/css" href="'.DOL_URL_ROOT.'/public/includes/jquery/plugins/jpicker/css/jPicker-1.1.6.css" />';
892 $out .= '<script nonce="'.getNonce().'" type="text/javascript" src="'.DOL_URL_ROOT.'/public/includes/jquery/plugins/jpicker/jpicker-1.1.6.js"></script>';
893 $out .= '<script nonce="'.getNonce().'" type="text/javascript">
894 jQuery(document).ready(function(){
895 var originalhex = null;
896 $(\'#colorpicker'.$prefix.'\').jPicker( {
897 window: {
898 title: \''.dol_escape_js($langs->trans("SelectAColor")).'\', /* any title for the jPicker window itself - displays "Drag Markers To Pick A Color" if left null */
899 effects:
900 {
901 type: \'show\', /* effect used to show/hide an expandable picker. Acceptable values "slide", "show", "fade" */
902 speed:
903 {
904 show: \'fast\', /* duration of "show" effect. Acceptable values are "fast", "slow", or time in ms */
905 hide: \'fast\' /* duration of "hide" effect. Acceptable values are "fast", "slow", or time in ms */
906 }
907 },
908 position:
909 {
910 x: \'screenCenter\', /* acceptable values "left", "center", "right", "screenCenter", or relative px value */
911 y: \'center\' /* acceptable values "top", "bottom", "center", or relative px value */
912 },
913 },
914 images: {
915 clientPath: \''.DOL_URL_ROOT.'/public/includes/jquery/plugins/jpicker/images/\',
916 picker: { file: \'../../../../../../theme/common/colorpicker.png\', width: 14, height: 14 }
917 },
918 localization: // alter these to change the text presented by the picker (e.g. different language)
919 {
920 text:
921 {
922 title: \''.dol_escape_js($langs->trans("SelectAColor")).'\',
923 newColor: \''.dol_escape_js($langs->trans("New")).'\',
924 currentColor: \''.dol_escape_js($langs->trans("Current")).'\',
925 ok: \''.dol_escape_js($langs->trans("Validate")).'\',
926 cancel: \''.dol_escape_js($langs->trans("Cancel")).'\'
927 }
928 }
929 },
930 function(color, context) { console.log("close color selector"); },
931 function(color, context) { var hex = color.val(\'hex\'); console.log("new color selected in jpicker "+hex+\' setpropertyonselect='.dol_escape_js($setpropertyonselect).'\');';
932 if ($setpropertyonselect) {
933 $out .= 'if (originalhex == null) {';
934 $out .= ' originalhex = getComputedStyle(document.querySelector(":root")).getPropertyValue(\'--'.dol_escape_js($setpropertyonselect).'\');';
935 $out .= ' console.log("original color is saved into originalhex = "+originalhex);';
936 $out .= '}';
937 $out .= 'if (hex != null) {';
938 $out .= ' document.documentElement.style.setProperty(\'--'.dol_escape_js($setpropertyonselect).'\', \'#\'+hex);';
939 $out .= '}';
940 }
941 $out .= '},
942 function(color, context) {
943 console.log("cancel selection of color");';
944 if ($setpropertyonselect) {
945 $out .= 'if (originalhex != null) {
946 console.log("Restore old color "+originalhex);
947 document.documentElement.style.setProperty(\'--'.dol_escape_js($setpropertyonselect).'\', originalhex);
948 }';
949 }
950 $out .= '
951 }
952 );
953 });
954 </script>';
955 $out .= '<input id="colorpicker'.$prefix.'" name="'.$prefix.'" size="6" maxlength="7" class="colorpicker flat valignmiddle'.($morecss ? ' '.$morecss : '').'" type="text" value="'.dol_escape_htmltag($set_color).'" />';
956 } else {
957 $color = ($set_color !== '' ? $set_color : ($default !== '' ? $default : 'FFFFFF'));
958 $out .= '<input id="colorpicker'.$prefix.'" name="'.$prefix.'" size="6" maxlength="7" class="colorpicker flat input-nobottom colorselector valignmiddle '.($morecss ? ' '.$morecss : '').'" type="color" data-default="'.$default.'" value="'.dol_escape_htmltag(preg_match('/^#/', $color) ? $color : '#'.$color).'" />';
959 $out .= '<script nonce="'.getNonce().'" type="text/javascript">
960 jQuery(document).ready(function(){
961 var originalhex = null;
962 jQuery("#colorpicker'.$prefix.'").on(\'change\', function() {
963 var hex = jQuery("#colorpicker'.$prefix.'").val();
964 console.log("new color selected in input color "+hex+\' setpropertyonselect='.dol_escape_js($setpropertyonselect).'\');';
965 if ($setpropertyonselect) {
966 $out .= 'if (originalhex == null) {';
967 $out .= ' originalhex = getComputedStyle(document.querySelector(":root")).getPropertyValue(\'--'.dol_escape_js($setpropertyonselect).'\');';
968 $out .= ' console.log("original color is saved into originalhex = "+originalhex);';
969 $out .= '}';
970 $out .= 'if (hex != null) {';
971 $out .= ' document.documentElement.style.setProperty(\'--'.dol_escape_js($setpropertyonselect).'\', hex);';
972 $out .= '}';
973 }
974 $out .= '
975 });
976 });
977 </script>';
978 }
979 } else {
980 // In most cases, this is not used. We used instead function with no specific list of colors
981 if (empty($conf->dol_use_jmobile) && !empty($conf->use_javascript_ajax)) {
982 $out .= '<link rel="stylesheet" href="'.DOL_URL_ROOT.'/public/includes/jquery/plugins/colorpicker/jquery.colorpicker.css" type="text/css" media="screen" />';
983 $out .= '<script nonce="'.getNonce().'" src="'.DOL_URL_ROOT.'/public/includes/jquery/plugins/colorpicker/jquery.colorpicker.js" type="text/javascript"></script>';
984 $out .= '<script nonce="'.getNonce().'" type="text/javascript">
985 jQuery(document).ready(function(){
986 jQuery(\'#colorpicker'.$prefix.'\').colorpicker({
987 size: 14,
988 label: \'\',
989 hide: true
990 });
991 });
992 </script>';
993 }
994 $out .= '<select id="colorpicker'.$prefix.'" class="colorpicker flat'.($morecss ? ' '.$morecss : '').'" name="'.$prefix.'">';
995 //print '<option value="-1">&nbsp;</option>';
996 foreach ($arrayofcolors as $val) {
997 $out .= '<option value="'.$val.'"';
998 if ($set_color == $val) {
999 $out .= ' selected';
1000 }
1001 $out .= '>'.$val.'</option>';
1002 }
1003 $out .= '</select>';
1004 }
1005
1006 return $out;
1007 }
1008
1009 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1020 public function CreateColorIcon($color, $module, $name, $x = 12, $y = 12)
1021 {
1022 // phpcs:enable
1023 global $conf;
1024
1025 $file = $conf->$module->dir_temp.'/'.$name.'.png';
1026
1027 // We create temp directory
1028 if (!file_exists($conf->$module->dir_temp)) {
1029 dol_mkdir($conf->$module->dir_temp);
1030 }
1031
1032 // On cree l'image en vraies couleurs
1033 $image = imagecreatetruecolor($x, $y);
1034
1035 $color = substr($color, 1, 6);
1036
1037 $red = hexdec(substr($color, 0, 2)); // Red channel conversion
1038 $green = hexdec(substr($color, 2, 2)); // Green channel conversion
1039 $blue = hexdec(substr($color, 4, 2)); // Blue channel conversion
1040
1041 $couleur = imagecolorallocate($image, $red, $green, $blue);
1042 //print $red.$green.$blue;
1043 imagefill($image, 0, 0, $couleur); // Fill the image
1044 // Create the colr and store it in a variable to maintain it
1045 imagepng($image, $file); // Returns an image in PNG format
1046 imagedestroy($image);
1047 }
1048
1049 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1058 public function select_dayofweek($selected = '', $htmlname = 'weekid', $useempty = 0)
1059 {
1060 // phpcs:enable
1061 global $langs;
1062
1063 $week = array(
1064 0 => $langs->trans("Day0"),
1065 1 => $langs->trans("Day1"),
1066 2 => $langs->trans("Day2"),
1067 3 => $langs->trans("Day3"),
1068 4 => $langs->trans("Day4"),
1069 5 => $langs->trans("Day5"),
1070 6 => $langs->trans("Day6")
1071 );
1072
1073 $select_week = '<select class="flat" name="'.$htmlname.'" id="'.$htmlname.'">';
1074 if ($useempty) {
1075 $select_week .= '<option value="-1">&nbsp;</option>';
1076 }
1077 foreach ($week as $key => $val) {
1078 if ($selected == $key) {
1079 $select_week .= '<option value="'.$key.'" selected>';
1080 } else {
1081 $select_week .= '<option value="'.$key.'">';
1082 }
1083 $select_week .= $val;
1084 $select_week .= '</option>';
1085 }
1086 $select_week .= '</select>';
1087
1088 $select_week .= ajax_combobox($htmlname);
1089
1090 return $select_week;
1091 }
1092
1103 public function selectDay($selected = '', $htmlname = 'dayid', $useempty = 0, $morecss = 'minwidth50 maxwidth75imp valignmiddle', $addjscombo = false)
1104 {
1105 $select_day = '<select class="flat'.($morecss ? ' '.$morecss : '').'" name="'.$htmlname.'" id="'.$htmlname.'">';
1106 if ($useempty) {
1107 $select_day .= '<option value="0">&nbsp;</option>';
1108 }
1109 for ($i = 1; $i <= 31; $i++) {
1110 if ((int) $selected == $i) {
1111 $select_day .= '<option value="'.$i.'" selected>';
1112 } else {
1113 $select_day .= '<option value="'.$i.'">';
1114 }
1115 $select_day .= sprintf("%02d", $i);
1116 $select_day .= '</option>';
1117 }
1118 $select_day .= '</select>';
1119
1120 // Add code for jquery to use multiselect
1121 if ($addjscombo) {
1122 // Enhance with select2
1123 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
1124 $select_day .= ajax_combobox($htmlname);
1125 }
1126
1127 return $select_day;
1128 }
1129
1130 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1142 public function select_month($selected = '', $htmlname = 'monthid', $useempty = 0, $longlabel = 0, $morecss = 'minwidth50 maxwidth75imp valignmiddle', $addjscombo = false)
1143 {
1144 // phpcs:enable
1145 global $langs;
1146
1147 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
1148
1149 if ($longlabel) {
1150 $montharray = monthArray($langs, 0); // Get array of month with long labels
1151 } else {
1152 $montharray = monthArray($langs, 1); // Get array of month with short labels
1153 }
1154
1155 $select_month = '<select class="flat'.($morecss ? ' '.$morecss : '').'" name="'.$htmlname.'" id="'.$htmlname.'">';
1156 if ($useempty) {
1157 if (is_numeric($useempty)) {
1158 $select_month .= '<option value="0">&nbsp;</option>';
1159 } else {
1160 $select_month .= '<option value="-1">'.$useempty.'</option>';
1161 }
1162 }
1163 foreach ($montharray as $key => $val) {
1164 if ((int) $selected == $key) {
1165 $select_month .= '<option value="'.$key.'" selected>';
1166 } else {
1167 $select_month .= '<option value="'.$key.'">';
1168 }
1169 $select_month .= $val;
1170 $select_month .= '</option>';
1171 }
1172 $select_month .= '</select>';
1173
1174 // Add code for jquery to use multiselect
1175 if ($addjscombo) {
1176 // Enhance with select2
1177 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
1178 $select_month .= ajax_combobox($htmlname);
1179 }
1180
1181 return $select_month;
1182 }
1183
1184 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1201 public function select_year($selected = '', $htmlname = 'yearid', $useempty = 0, $min_year = 10, $max_year = 5, $offset = 0, $invert = 0, $option = '', $morecss = 'valignmiddle maxwidth75imp', $addjscombo = false)
1202 {
1203 // phpcs:enable
1204 print $this->selectyear($selected, $htmlname, $useempty, $min_year, $max_year, $offset, $invert, $option, $morecss, $addjscombo);
1205 }
1206
1222 public function selectyear($selected = '', $htmlname = 'yearid', $useempty = 0, $min_year = 10, $max_year = 5, $offset = 0, $invert = 0, $option = '', $morecss = 'valignmiddle width75', $addjscombo = false)
1223 {
1224 $out = '';
1225
1226 $currentyear = idate("Y") + $offset;
1227 $max_year = $currentyear + $max_year;
1228 $min_year = $currentyear - $min_year;
1229 if (empty($selected) && empty($useempty)) {
1230 $selected = $currentyear;
1231 }
1232
1233 $out .= '<select class="flat'.($morecss ? ' '.$morecss : '').'" id="'.$htmlname.'" name="'.$htmlname.'"'.$option.' >';
1234 if ($useempty) {
1235 $selected_html = '';
1236 if ((string) $selected == '') {
1237 $selected_html = ' selected';
1238 }
1239 $out .= '<option value=""'.$selected_html.'>&nbsp;</option>';
1240 }
1241 if (!$invert) {
1242 for ($y = $max_year; $y >= $min_year; $y--) {
1243 $selected_html = '';
1244 if ((int) $selected > 0 && $y == (int) $selected) {
1245 $selected_html = ' selected';
1246 }
1247 $out .= '<option value="'.$y.'"'.$selected_html.' >'.$y.'</option>';
1248 }
1249 } else {
1250 for ($y = $min_year; $y <= $max_year; $y++) {
1251 $selected_html = '';
1252 if ((int) $selected > 0 && $y == (int) $selected) {
1253 $selected_html = ' selected';
1254 }
1255 $out .= '<option value="'.$y.'"'.$selected_html.' >'.$y.'</option>';
1256 }
1257 }
1258 $out .= "</select>\n";
1259
1260 // Add code for jquery to use multiselect
1261 if ($addjscombo) {
1262 // Enhance with select2
1263 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
1264 $out .= ajax_combobox($htmlname);
1265 }
1266
1267 return $out;
1268 }
1269
1270
1279 public static function getBoxesArea($user, $areacode)
1280 {
1281 global $conf, $langs, $db;
1282
1283 include_once DOL_DOCUMENT_ROOT.'/core/class/infobox.class.php';
1284 // From include
1285 '
1286 @phan-var-force ModeleBoxes[] $boxactivated
1287 @phan-var-force int[] $boxidactivatedforuser
1288 ';
1289
1290 $confuserzone = 'MAIN_BOXES_'.$areacode;
1291
1292
1293
1294 // $boxactivated will be array of boxes enabled into global setup
1295 // $boxidactivatedforuser will be array of boxes chose by user
1296
1297 $selectboxlist = '';
1298 $boxactivated = InfoBox::listBoxes($db, 'activated', (int) $areacode, (empty($user->conf->$confuserzone) ? null : $user), array(), 0); // Search boxes of common+user (or common only if user has no specific setup)
1299
1300 $boxidactivatedforuser = array();
1301 foreach ($boxactivated as $box) {
1302 if (empty($user->conf->$confuserzone) || $box->fk_user == $user->id) {
1303 $boxidactivatedforuser[$box->id] = $box->id; // We keep only boxes to show for user
1304 }
1305
1306 if (!empty($box->lang)) {
1307 $langs->loadLangs(array($box->lang));
1308 $box->boxlabel = $langs->transnoentitiesnoconv($box->boxlabel);
1309 }
1310 }
1311
1312
1313 // Define selectboxlist
1314 $arrayboxtoactivatelabel = array();
1315 if (getDolUserString($confuserzone)) {
1316 $boxorder = '';
1317 $langs->load("boxes"); // Load label of boxes
1318 foreach ($boxactivated as $box) {
1319 if (!empty($boxidactivatedforuser[$box->id])) {
1320 continue; // Already visible for user
1321 }
1322
1323 $label = $langs->transnoentitiesnoconv($box->boxlabel);
1324 //if (preg_match('/graph/',$box->class)) $label.=' ('.$langs->trans("Graph").')';
1325 if (preg_match('/graph/', $box->class) && $conf->browser->layout != 'phone') {
1326 $label .= ' <span class="fas fa-chart-bar"></span>';
1327 }
1328 $arrayboxtoactivatelabel[$box->id] = array('label' => $label, 'data-html' => img_picto('', $box->boximg, 'class="pictofixedwidth valignmiddle"').'<span class="valignmiddle">'.$langs->trans($label).'</span>'); // We keep only boxes not shown for user, to show into combo list
1329 }
1330 foreach ($boxidactivatedforuser as $boxid) {
1331 if (empty($boxorder)) {
1332 $boxorder .= 'A:';
1333 }
1334 $boxorder .= $boxid.',';
1335 }
1336
1337 //var_dump($boxidactivatedforuser);
1338
1339 // Class Form must have been already loaded
1340 $widthforwidget = 'width200';
1341 $selectboxlist .= '<!-- Form with select box list -->'."\n";
1342 $selectboxlist .= '<form id="addbox" class="parentonrightofpage" name="addbox" method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
1343 $selectboxlist .= '<input type="hidden" name="token" value="'.newToken().'">';
1344 $selectboxlist .= '<input type="hidden" name="addbox" value="addbox">';
1345 $selectboxlist .= '<input type="hidden" name="userid" value="'.$user->id.'">';
1346 $selectboxlist .= '<input type="hidden" name="areacode" value="'.$areacode.'">';
1347 $selectboxlist .= '<input type="hidden" name="boxorder" value="'.$boxorder.'">';
1348 $selectboxlist .= Form::selectarray('boxcombo', $arrayboxtoactivatelabel, -1, $langs->trans("ChooseBoxToAdd").'...', 0, 0, '', 0, 0, 0, 'ASC', 'noborderfocus selectwidget max'.$widthforwidget.' hideonprint onrightofpage', 0, 'hidden selected', 0, 0);
1349 if (!empty($conf->use_javascript_ajax)) {
1350 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
1351 $selectboxlist .= ajax_combobox("boxcombo", array(), 0, 0, 'resolve', '-1', 'onrightofpage '.$widthforwidget);
1352 }
1353 if (empty($conf->use_javascript_ajax)) {
1354 $selectboxlist .= ' <input type="submit" class="button" value="'.$langs->trans("AddBox").'">';
1355 }
1356 $selectboxlist .= '</form>';
1357 }
1358
1359 // Javascript code for dynamic actions
1360 if (!empty($conf->use_javascript_ajax)) {
1361 $selectboxlist .= '<script nonce="'.getNonce().'" type="text/javascript">
1362
1363 // To update list of activated boxes
1364 function updateBoxOrder(closing) {
1365 var left_list = cleanSerialize(jQuery("#boxhalfleft").sortable("serialize"));
1366 var right_list = cleanSerialize(jQuery("#boxhalfright").sortable("serialize"));
1367 var boxorder = \'A:\' + left_list + \'-B:\' + right_list;
1368 if (boxorder==\'A:A-B:B\' && closing == 1) // There is no more boxes on screen, and we are after a delete of a box so we must hide title
1369 {
1370 jQuery.ajax({
1371 url: \''.DOL_URL_ROOT.'/core/ajax/box.php?closing=1&boxorder=\'+boxorder+\'&zone='.$areacode.'&userid=\'+'.$user->id.',
1372 async: false
1373 });
1374 // We force reload to be sure to get all boxes into list
1375 window.location.search=\'mainmenu='.GETPOST("mainmenu", "aZ09").'&leftmenu='.GETPOST('leftmenu', "aZ09").'&action=delbox&token='.newToken().'\';
1376 }
1377 else
1378 {
1379 jQuery.ajax({
1380 url: \''.DOL_URL_ROOT.'/core/ajax/box.php?closing=\'+closing+\'&boxorder=\'+boxorder+\'&zone='.$areacode.'&userid=\'+'.$user->id.',
1381 async: true
1382 });
1383 }
1384 }
1385
1386 jQuery(document).ready(function() {
1387 jQuery("#boxcombo").change(function() {
1388 var boxid=jQuery("#boxcombo").val();
1389 if (boxid > 0) {
1390 console.log("A box widget has been selected for addition, we call ajax page to add it.")
1391 var left_list = cleanSerialize(jQuery("#boxhalfleft").sortable("serialize"));
1392 var right_list = cleanSerialize(jQuery("#boxhalfright").sortable("serialize"));
1393 var boxorder = \'A:\' + left_list + \'-B:\' + right_list;
1394 jQuery.ajax({
1395 url: \''.DOL_URL_ROOT.'/core/ajax/box.php?boxorder=\'+boxorder+\'&boxid=\'+boxid+\'&zone='.$areacode.'&userid='.$user->id.'\'
1396 }).done(function() {
1397 window.location.search=\'mainmenu='.GETPOST("mainmenu", "aZ09").'&leftmenu='.GETPOST('leftmenu', "aZ09").'\';
1398 });
1399 }
1400 });';
1401 if (!count($arrayboxtoactivatelabel)) {
1402 $selectboxlist .= 'jQuery("#boxcombo").hide();';
1403 }
1404 $selectboxlist .= '
1405
1406 jQuery("#boxhalfleft, #boxhalfright").sortable({
1407 handle: \'.boxhandle\',
1408 revert: \'invalid\',
1409 items: \'.boxdraggable\',
1410 containment: \'document\',
1411 connectWith: \'#boxhalfleft, #boxhalfright\',
1412 stop: function(event, ui) {
1413 console.log("We moved box so we call updateBoxOrder with ajax actions");
1414 updateBoxOrder(1); /* 1 to avoid message after a move */
1415 }
1416 });
1417
1418 jQuery(".boxclose").click(function() {
1419 var self = this; // because JQuery can modify this
1420 var boxid = self.id.substring(8);
1421 if (boxid > 0) {
1422 var label = jQuery(\'#boxlabelentry\'+boxid).val();
1423 console.log("We close box "+boxid);
1424 jQuery(\'#boxto_\'+boxid).remove();
1425 jQuery(\'#boxcombo\').append(new Option(label, boxid));
1426 updateBoxOrder(1); /* 1 to avoid message after a remove */
1427 }
1428 });
1429
1430 });'."\n";
1431
1432 $selectboxlist .= '</script>'."\n";
1433 }
1434
1435 // Define boxlista and boxlistb
1436 $boxlista = '';
1437 $boxlistb = '';
1438 $nbboxactivated = count($boxidactivatedforuser);
1439
1440 if ($nbboxactivated) {
1441 // Load translation files required by the page
1442 $langs->loadLangs(array("boxes", "projects"));
1443
1444 $emptybox = new ModeleBoxes($db);
1445
1446 $boxlista .= "\n<!-- Box left container -->\n";
1447
1448 // Define $box_max_lines
1449 $box_max_lines = getDolUserInt('MAIN_SIZE_SHORTLIST_LIMIT', getDolGlobalInt('MAIN_SIZE_SHORTLIST_LIMIT', 5));
1450
1451 $ii = 0;
1452 foreach ($boxactivated as $key => $box) {
1453 if ((!empty($user->conf->$confuserzone) && $box->fk_user == 0) || (empty($user->conf->$confuserzone) && $box->fk_user != 0)) {
1454 continue;
1455 }
1456 if (empty($box->box_order) && $ii < ($nbboxactivated / 2)) {
1457 $box->box_order = 'A'.sprintf("%02d", ($ii + 1)); // When box_order was not yet set to Axx or Bxx and is still 0
1458 }
1459 if (preg_match('/^A/i', $box->box_order)) { // column A
1460 $ii++;
1461 //print 'box_id '.$boxactivated[$ii]->box_id.' ';
1462 //print 'box_order '.$boxactivated[$ii]->box_order.'<br>';
1463 // Show box
1464 $box->loadBox($box_max_lines);
1465 $boxlista .= $box->showBox(null, null, 1);
1466 }
1467 }
1468
1469 if ($conf->browser->layout != 'phone') {
1470 $emptybox->box_id = 'A';
1471 $emptybox->info_box_head = array();
1472 $emptybox->info_box_contents = array();
1473 $boxlista .= $emptybox->showBox(array(), array(), 1);
1474 }
1475 $boxlista .= "<!-- End box left container -->\n";
1476
1477 $boxlistb .= "\n<!-- Box right container -->\n";
1478
1479 $ii = 0;
1480 foreach ($boxactivated as $key => $box) {
1481 if ((!empty($user->conf->$confuserzone) && $box->fk_user == 0) || (empty($user->conf->$confuserzone) && $box->fk_user != 0)) {
1482 continue;
1483 }
1484 if (empty($box->box_order) && $ii < ($nbboxactivated / 2)) {
1485 $box->box_order = 'B'.sprintf("%02d", ($ii + 1)); // When box_order was not yet set to Axx or Bxx and is still 0
1486 }
1487 if (preg_match('/^B/i', $box->box_order)) { // colonne B
1488 $ii++;
1489 //print 'box_id '.$boxactivated[$ii]->box_id.' ';
1490 //print 'box_order '.$boxactivated[$ii]->box_order.'<br>';
1491 // Show box
1492 $box->loadBox($box_max_lines);
1493 $boxlistb .= $box->showBox(null, null, 1);
1494 }
1495 }
1496
1497 if ($conf->browser->layout != 'phone') {
1498 $emptybox->box_id = 'B';
1499 $emptybox->info_box_head = array();
1500 $emptybox->info_box_contents = array();
1501 $boxlistb .= $emptybox->showBox(array(), array(), 1);
1502 }
1503
1504 $boxlistb .= "<!-- End box right container -->\n";
1505 }
1506
1507 return array('selectboxlist' => count($boxactivated) ? $selectboxlist : '', 'boxactivated' => $boxactivated, 'boxlista' => $boxlista, 'boxlistb' => $boxlistb);
1508 }
1509
1510
1511 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1524 public function select_dictionary($htmlname, $dictionarytable, $keyfield = 'code', $labelfield = 'label', $selected = '', $useempty = 0, $moreattrib = '')
1525 {
1526 // phpcs:enable
1527 global $langs;
1528
1529 $langs->load("admin");
1530
1531 $sql = "SELECT rowid, ".$this->db->sanitize($keyfield).", ".$this->db->sanitize($labelfield);
1532 $sql .= " FROM ".$this->db->prefix().$dictionarytable;
1533 $sql .= $this->db->order($labelfield);
1534
1535 dol_syslog(get_class($this)."::select_dictionary", LOG_DEBUG);
1536 $result = $this->db->query($sql);
1537 if ($result) {
1538 $num = $this->db->num_rows($result);
1539 $i = 0;
1540 if ($num) {
1541 print '<select id="select'.$htmlname.'" class="flat selectdictionary" name="'.$htmlname.'"'.($moreattrib ? ' '.$moreattrib : '').'>';
1542 if ($useempty == 1 || ($useempty == 2 && $num > 1)) {
1543 print '<option value="-1">&nbsp;</option>';
1544 }
1545
1546 while ($i < $num) {
1547 $obj = $this->db->fetch_object($result);
1548 if ($selected == $obj->rowid || $selected == $obj->{$keyfield}) {
1549 print '<option value="'.$obj->{$keyfield}.'" selected>';
1550 } else {
1551 print '<option value="'.$obj->{$keyfield}.'">';
1552 }
1553 $label = ($langs->trans($dictionarytable.$obj->{$keyfield}) != $dictionarytable.$obj->{$labelfield} ? $langs->trans($dictionarytable.$obj->{$keyfield}) : $obj->{$labelfield});
1554 print $label;
1555 print '</option>';
1556 $i++;
1557 }
1558 print "</select>";
1559 } else {
1560 print $langs->trans("DictionaryEmpty");
1561 }
1562 } else {
1563 dol_print_error($this->db);
1564 }
1565 }
1566
1577 public function selectAutoManual($htmlname, $value = '', $option = 0, $disabled = false, $useempty = 0)
1578 {
1579 global $langs;
1580
1581 $automatic = "automatic";
1582 $manual = "manual";
1583 if ($option) {
1584 $automatic = "1";
1585 $manual = "0";
1586 }
1587
1588 $disabled = ($disabled ? ' disabled' : '');
1589
1590 $resultautomanual = '<select class="flat width100" id="'.$htmlname.'" name="'.$htmlname.'"'.$disabled.'>'."\n";
1591 if ($useempty) {
1592 $resultautomanual .= '<option value="-1"'.(($value < 0) ? ' selected' : '').'>&nbsp;</option>'."\n";
1593 }
1594 if (("$value" == 'automatic') || ($value == 1)) {
1595 $resultautomanual .= '<option value="'.$automatic.'" selected>'.$langs->trans("Automatic").'</option>'."\n";
1596 $resultautomanual .= '<option value="'.$manual.'">'.$langs->trans("Manual").'</option>'."\n";
1597 } else {
1598 $selected = (($useempty && $value != '0' && $value != 'manual') ? '' : ' selected');
1599 $resultautomanual .= '<option value="'.$automatic.'">'.$langs->trans("Automatic").'</option>'."\n";
1600 $resultautomanual .= '<option value="'.$manual.'"'.$selected.'>'.$langs->trans("Manual").'</option>'."\n";
1601 }
1602 $resultautomanual .= '</select>'."\n";
1603 return $resultautomanual;
1604 }
1605
1606
1617 public function selectGroupByField($object, $search_groupby, &$arrayofgroupby, $morecss = 'minwidth200 maxwidth250', $showempty = '1')
1618 {
1619 global $form;
1620
1621 $arrayofgroupbylabel = array();
1622 foreach ($arrayofgroupby as $key => $val) {
1623 $arrayofgroupbylabel[$key] = $val['label'];
1624 }
1625 $result = $form->selectarray('search_groupby', $arrayofgroupbylabel, $search_groupby, $showempty, 0, 0, '', 0, 0, 0, '', $morecss, 1);
1626
1627 return $result;
1628 }
1629
1640 public function selectXAxisField($object, $search_xaxis, &$arrayofxaxis, $showempty = '1', $morecss = 'minwidth250 maxwidth500')
1641 {
1642 global $form;
1643
1644 $arrayofxaxislabel = array();
1645 foreach ($arrayofxaxis as $key => $val) {
1646 $arrayofxaxislabel[$key] = $val['label'];
1647 }
1648 $result = $form->selectarray('search_xaxis', $arrayofxaxislabel, $search_xaxis, $showempty, 0, 0, '', 0, 0, 0, '', $morecss, 1);
1649
1650 return $result;
1651 }
1652}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
$propal type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition propal.php:280
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='', $placeholder='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:477
static selectarray($htmlname, $array, $id='', $show_empty=0, $key_in_label=0, $value_as_key=0, $moreparam='', $translate=0, $maxlen=0, $disabled=0, $sort='', $morecss='minwidth75', $addjscombo=1, $moreparamonempty='', $disablebademail=0, $nohtmlescape=0)
Return a HTML select string, built from an array of key+value.
Class to help generate other html components Only common components are here.
selectDay($selected='', $htmlname='dayid', $useempty=0, $morecss='minwidth50 maxwidth75imp valignmiddle', $addjscombo=false)
Return HTML combo list of day.
__construct($db)
Constructor.
static getBoxesArea($user, $areacode)
Get array with HTML tabs with widgets/boxes of a particular area including personalized choices of us...
select_revenue_stamp($selected='', $htmlname='revenuestamp', $country_code='')
Return list of revenue stamp for country.
select_ecotaxes($selected='', $htmlname='ecotaxe_id')
Return list of ecotaxes with label.
select_year($selected='', $htmlname='yearid', $useempty=0, $min_year=10, $max_year=5, $offset=0, $invert=0, $option='', $morecss='valignmiddle maxwidth75imp', $addjscombo=false)
Return HTML combo list of years.
selectAutoManual($htmlname, $value='', $option=0, $disabled=false, $useempty=0)
Return an html string with a select combo box to choose yes or no.
select_dayofweek($selected='', $htmlname='weekid', $useempty=0)
Return HTML combo list of week.
getHTMLScannerForm($jstoexecuteonadd='barcodescannerjs', $mode='all', $warehouseselect=0)
Return the HTML code for scanner tool.
select_dictionary($htmlname, $dictionarytable, $keyfield='code', $labelfield='label', $selected='', $useempty=0, $moreattrib='')
Return a HTML select list of a dictionary.
selectGroupByField($object, $search_groupby, &$arrayofgroupby, $morecss='minwidth200 maxwidth250', $showempty='1')
Return HTML select list to select a group by field.
selectXAxisField($object, $search_xaxis, &$arrayofxaxis, $showempty='1', $morecss='minwidth250 maxwidth500')
Return HTML select list to select a group by field.
select_month($selected='', $htmlname='monthid', $useempty=0, $longlabel=0, $morecss='minwidth50 maxwidth75imp valignmiddle', $addjscombo=false)
Return HTML combo list of month.
selectyear($selected='', $htmlname='yearid', $useempty=0, $min_year=10, $max_year=5, $offset=0, $invert=0, $option='', $morecss='valignmiddle width75', $addjscombo=false)
Return HTML combo list of years.
Class with static methods for building HTML components related to products Only components common to ...
static listBoxes($dbs, $mode, $zone, $user=null, $excludelist=array(), $includehidden=1)
Return array of boxes qualified for area and user.
Class ModeleBoxes.
monthArray($outputlangs, $short=0)
Return array of translated months or selected month.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
getDolUserInt($key, $default=0, $tmpuser=null)
Return Dolibarr user constant int value.
getDolUserString($key, $default='', $tmpuser=null)
Return Dolibarr user constant string value.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into JavaScript code.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
a disabled
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Definition html.lib.php:181
$conf db user
Active Directory does not allow anonymous connections.
Definition repair.php:141
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:140