diff --git a/.travis.yml b/.travis.yml index 5380ef54d3d..eef14f01386 100644 --- a/.travis.yml +++ b/.travis.yml @@ -72,10 +72,6 @@ jobs: if: type = pull_request OR type = push php: '8.1' env: DB=mysql - - stage: PHP Dev - if: type = push AND branch = develop - php: nightly - env: DB=mysql - stage: PHP Dev if: type = push AND branch = 17.0 php: nightly diff --git a/COPYRIGHT b/COPYRIGHT index d980219c420..d04c007ff65 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -31,7 +31,7 @@ NuSoap 0.9.5 LGPL 2.1+ Yes PEAR Mail_MIME 1.8.9 BSD Yes NuSoap dependency ParseDown 1.6 MIT License Yes Markdown parser PCLZip 2.8.4 LGPL-3+ Yes Library to zip/unzip files -PHPDebugBar 1.15.1 MIT License Yes Used only by the module "debugbar" for developers +PHPDebugBar 1.18.2 MIT License Yes Used only by the module "debugbar" for developers PHP-Imap 2.7.2 MIT License Yes Library to use IMAP with OAuth PHPSpreadSheet 1.8.2 LGPL-2.1+ Yes Read/Write XLS files, read ODS files php-iban 4.1.1 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php index 384f43223bc..98c8e5b923d 100644 --- a/htdocs/accountancy/bookkeeping/card.php +++ b/htdocs/accountancy/bookkeeping/card.php @@ -4,7 +4,6 @@ * Copyright (C) 2013-2022 Alexandre Spangaro * Copyright (C) 2017 Laurent Destailleur * Copyright (C) 2018-2020 Frédéric France - * Copyright (C) 2022 Waël Almoman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -45,7 +44,7 @@ $cancel = GETPOST('cancel', 'aZ09'); $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') $id = GETPOST('id', 'int'); // id of record -$mode = $mode = $action == 'create' ? "_tmp" : GETPOST('mode', 'aZ09'); // '' or '_tmp' +$mode = GETPOST('mode', 'aZ09'); // '' or '_tmp' $piece_num = GETPOST("piece_num", 'int'); // id of transaction (several lines share the same transaction id) $accountingaccount = new AccountingAccount($db); @@ -55,15 +54,10 @@ $accountingaccount_number = GETPOST('accountingaccount_number', 'alphanohtml'); $accountingaccount->fetch(null, $accountingaccount_number, true); $accountingaccount_label = $accountingaccount->label; -$journal_code = GETPOST('code_journal', 'alpha') ? GETPOST('code_journal', 'alpha') : "NULL"; +$journal_code = GETPOST('code_journal', 'alpha'); $accountingjournal->fetch(null, $journal_code); $journal_label = $accountingjournal->label; -$next_num_mvt = (int) GETPOST('next_num_mvt', 'alpha'); -$doc_ref = (string) GETPOST('doc_ref', 'alpha'); -$doc_date = (string) GETPOST('doc_date', 'alpha'); -$doc_date = $doc_date = dol_mktime(0, 0, 0, GETPOST('doc_datemonth', 'int'), GETPOST('doc_dateday', 'int'), GETPOST('doc_dateyear', 'int')); - $subledger_account = GETPOST('subledger_account', 'alphanohtml'); if ($subledger_account == -1) { $subledger_account = null; @@ -78,10 +72,6 @@ $save = GETPOST('save', 'alpha'); if (!empty($save)) { $action = 'add'; } -$valid = GETPOST('validate', 'alpha'); -if (!empty($valid)) { - $action = 'valid'; -} $update = GETPOST('update', 'alpha'); if (!empty($update)) { $action = 'confirm_update'; @@ -166,79 +156,64 @@ if ($action == "confirm_update") { } } } -} elseif ($action == 'add' || $action == 'valid') { +} elseif ($action == "add") { $error = 0; - if (array_sum($debit) != array_sum($credit)) { - $action = 'add'; + if ((floatval($debit) != 0.0) && (floatval($credit) != 0.0)) { + $error++; + setEventMessages($langs->trans('ErrorDebitCredit'), null, 'errors'); + $action = ''; + } + if (empty($accountingaccount_number) || $accountingaccount_number == '-1') { + $error++; + setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("AccountAccountingShort")), null, 'errors'); + $action = ''; } - foreach ($accountingaccount_number as $key => $value) { - $accountingaccount->fetch(null, $accountingaccount_number[$key], true); - $accountingaccount_label[$key] = $accountingaccount->label[$key]; + if (!$error) { + $object = new BookKeeping($db); - // if one added row is empty remove it before continue - if ($key < 1 && (empty($accountingaccount_number[$key]) || $accountingaccount_number[$key] == '-1') || (floatval($debit[$key]) == 0.0) && (floatval($credit[$key]) == 0.0)) { - continue; + $object->numero_compte = $accountingaccount_number; + $object->subledger_account = $subledger_account; + $object->subledger_label = $subledger_label; + $object->label_compte = $accountingaccount_label; + $object->label_operation = $label_operation; + $object->debit = $debit; + $object->credit = $credit; + $object->doc_date = (string) GETPOST('doc_date', 'alpha'); + $object->doc_type = (string) GETPOST('doc_type', 'alpha'); + $object->piece_num = $piece_num; + $object->doc_ref = (string) GETPOST('doc_ref', 'alpha'); + $object->code_journal = $journal_code; + $object->journal_label = $journal_label; + $object->fk_doc = GETPOSTINT('fk_doc'); + $object->fk_docdet = GETPOSTINT('fk_docdet'); + + if (floatval($debit) != 0.0) { + $object->montant = $debit; // deprecated + $object->amount = $debit; + $object->sens = 'D'; } - if ((floatval($debit[$key]) != 0.0) && (floatval($credit[$key]) != 0.0)) { - $error++; - setEventMessages($langs->trans('ErrorDebitCredit'), null, 'errors'); + if (floatval($credit) != 0.0) { + $object->montant = $credit; // deprecated + $object->amount = $credit; + $object->sens = 'C'; + } + + $result = $object->createStd($user, false, $mode); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } else { + if ($mode != '_tmp') { + setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); + } + + $debit = 0; + $credit = 0; + $action = ''; } - - if (empty($accountingaccount_number[$key]) || $accountingaccount_number[$key] == '-1') { - $error++; - setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("AccountAccountingShort")), null, 'errors'); - $action = ''; - } - - if (!$error) { - $object = new BookKeeping($db); - $object->numero_compte = $accountingaccount_number[$key]; - $object->subledger_account = $subledger_account[$key]; - $object->subledger_label = $subledger_label[$key]; - $object->label_compte = $accountingaccount_label[$key]; - $object->label_operation = $label_operation[$key]; - $object->debit = price2num($debit[$key]); - $object->credit = price2num($credit[$key]); - $object->doc_date = $doc_date; - $object->doc_type = (string) GETPOST('doc_type', 'alpha'); - $object->piece_num = $piece_num; - $object->doc_ref = $doc_ref; - $object->code_journal = $journal_code; - $object->journal_label = $journal_label; - $object->fk_doc = GETPOSTINT('fk_doc'); - $object->fk_docdet = GETPOSTINT('fk_docdet'); - - if (floatval($debit[$key]) != 0.0) { - $object->montant = $object->debit; // deprecated - $object->amount = $object->debit; - $object->sens = 'D'; - } - - if (floatval($credit[$key]) != 0.0) { - $object->montant = $object->credit; // deprecated - $object->amount = $object->credit; - $object->sens = 'C'; - } - - $result = $object->createStd($user, false, $mode); - if ($result < 0) { - $error++; - setEventMessages($object->error, $object->errors, 'errors'); - } - } - } - if (empty($error)) { - if ($mode != '_tmp') { - setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); - } - $debit = 0; - $credit = 0; - - $action = $action == 'add' ? '' : $action ; // stay in valid mode when not adding line } } elseif ($action == "confirm_delete") { $object = new BookKeeping($db); @@ -255,28 +230,17 @@ if ($action == "confirm_update") { } } $action = ''; -} elseif ($action == 'create') { +} elseif ($action == "confirm_create") { $error = 0; $object = new BookKeeping($db); - $next_num_mvt = !empty($next_num_mvt) ? $next_num_mvt : $object->getNextNumMvt('_tmp'); - $doc_ref = !empty($doc_ref) ? $doc_ref : $next_num_mvt; - - if (empty($doc_date)) { - $tmp_date = dol_getdate(dol_now()); - $_POST['doc_dateday'] = $tmp_date['mday']; - $_POST['doc_datemonth'] = $tmp_date['mon']; - $_POST['doc_dateyear'] = $tmp_date['year']; - unset($tmp_date); - } - if (!$journal_code || $journal_code == '-1') { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Journal")), null, 'errors'); $action = 'create'; $error++; } - if (empty($doc_ref)) { + if (!GETPOST('doc_ref', 'alpha')) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Piece")), null, 'errors'); $action = 'create'; $error++; @@ -288,8 +252,8 @@ if ($action == "confirm_update") { $object->credit = 0; $object->doc_date = $date_start = dol_mktime(0, 0, 0, GETPOST('doc_datemonth', 'int'), GETPOST('doc_dateday', 'int'), GETPOST('doc_dateyear', 'int')); $object->doc_type = GETPOST('doc_type', 'alpha'); - $object->piece_num = $next_num_mvt; - $object->doc_ref = $doc_ref; + $object->piece_num = GETPOST('next_num_mvt', 'alpha'); + $object->doc_ref = GETPOST('doc_ref', 'alpha'); $object->code_journal = $journal_code; $object->journal_label = $journal_label; $object->fk_doc = 0; @@ -338,7 +302,7 @@ if ($action == 'setjournal') { } if ($action == 'setdocref') { - $refdoc = $doc_ref; + $refdoc = GETPOST('doc_ref', 'alpha'); $result = $object->updateByMvt($piece_num, 'doc_ref', $refdoc, $mode); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); @@ -369,7 +333,7 @@ if ($action == 'valid') { $html = new Form($db); $formaccounting = new FormAccounting($db); -$title = $langs->trans($mode =="_tmp" ? "CreateMvts": "UpdateMvts"); +$title = $langs->trans("CreateMvts"); llxHeader('', $title); @@ -379,37 +343,28 @@ if ($action == 'delete') { print $formconfirm; } +if ($action == 'create') { + print load_fiche_titre($title); -$object = new BookKeeping($db); -$result = $object->fetchPerMvt($piece_num, $mode); -if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); -} + $object = new BookKeeping($db); + $next_num_mvt = $object->getNextNumMvt('_tmp'); -if (!empty($object->piece_num)) { - $backlink = ''.$langs->trans('BackToList').''; - - print load_fiche_titre($langs->trans($mode =="_tmp" ? "CreateMvts": "UpdateMvts"), $backlink); - - print '
'; if ($optioncss != '') { - print ''; + if (empty($next_num_mvt)) { + dol_print_error('', 'Failed to get next piece number'); } - $head = array(); - $h = 0; - $head[$h][0] = $_SERVER['PHP_SELF'].'?piece_num='.$object->piece_num.($mode ? '&mode='.$mode : ''); - $head[$h][1] = $langs->trans("Transaction"); - $head[$h][2] = 'transaction'; - $h++; - print dol_get_fiche_head($head, 'transaction', '', -1); + print ''; + if ($optioncss != '') { + print ''; + } + print ''; + print ''."\n"; + print ''."\n"; + print ''."\n"; - //dol_banner_tab($object, '', $backlink); + print dol_get_fiche_head(); - print '
'; - print '
'; - - print '
'; - print ''; + print '
'; /*print ''; print ''; @@ -419,7 +374,7 @@ if (!empty($object->piece_num)) { print ''; print ''; print ''; print ''; @@ -430,218 +385,298 @@ if (!empty($object->piece_num)) { print ''; print ''; - print ''; + print ''; print ''; /* print ''; print ''; - print ''; + print ''; print ''; */ print '
' . $langs->trans("NumPiece") . '
'.$langs->trans("Docdate").''; - print $html->selectDate($doc_date, 'doc_date', '', '', '', "create_mvt", 1, 1); + print $html->selectDate('', 'doc_date', '', '', '', "create_mvt", 1, 1); print '
'.$langs->trans("Piece").'
' . $langs->trans("Doctype") . '
'; - print '
'; - - print '
'; - - print '
'; - print ''; - - // Doc type - if (!empty($object->doc_type)) { - print ''; - print ''; - print ''; - print ''; - } - - // Date document creation - print ''; - print ''; - print ''; - print ''; - - // Don't show in tmp mode, inevitably empty - if ($mode != "_tmp") { - // Date document export - print ''; - print ''; - print ''; - print ''; - - // Date document validation - print ''; - print ''; - print ''; - print ''; - } - // Validate - /* - print ''; - print ''; - print ''; - print ''; - */ - - // check data - /* - print ''; - print ''; - if ($object->doc_type == 'customer_invoice') { - $sqlmid = 'SELECT rowid as ref'; - $sqlmid .= " FROM ".MAIN_DB_PREFIX."facture as fac"; - $sqlmid .= " WHERE fac.rowid=" . ((int) $object->fk_doc); - dol_syslog("accountancy/bookkeeping/card.php::sqlmid=" . $sqlmid, LOG_DEBUG); - $resultmid = $db->query($sqlmid); - if ($resultmid) { - $objmid = $db->fetch_object($resultmid); - $invoicestatic = new Facture($db); - $invoicestatic->fetch($objmid->ref); - $ref=$langs->trans("Invoice").' '.$invoicestatic->getNomUrl(1); - } else { - dol_print_error($db); - } - } - print ''; - print ''; - */ - print "
'.$langs->trans("Doctype").''.$object->doc_type.'
'.$langs->trans("DateCreation").''; - print $object->date_creation ? dol_print_date($object->date_creation, 'day') : ' '; - print '
'.$langs->trans("DateExport").''; - print $object->date_export ? dol_print_date($object->date_export, 'dayhour') : ' '; - print '
'.$langs->trans("DateValidation").''; - print $object->date_validation ? dol_print_date($object->date_validation, 'dayhour') : ' '; - print '
' . $langs->trans("Status") . ''; - if (empty($object->validated)) { - print ''; - print img_picto($langs->trans("Disabled"), 'switch_off'); - print ''; - } else { - print ''; - print img_picto($langs->trans("Activated"), 'switch_on'); - print ''; - } - print '
' . $langs->trans("Control") . '' . $ref .'
\n"; - print dol_get_fiche_end(); - print '
'; + print $form->buttonsSaveCancel("Create"); - print '
'; - - $result = $object->fetchAllPerMvt($piece_num, $mode); // This load $object->linesmvt + print ''; +} else { + $object = new BookKeeping($db); + $result = $object->fetchPerMvt($piece_num, $mode); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); - } else { - // List of movements - print load_fiche_titre($langs->trans("ListeMvts"), '', ''); + } - if ($optioncss != '') { - print ''; + if (!empty($object->piece_num)) { + $backlink = ''.$langs->trans('BackToList').''; + + if ($mode == '_tmp') { + print load_fiche_titre($langs->trans("CreateMvts"), $backlink); + } else { + print load_fiche_titre($langs->trans("UpdateMvts"), $backlink); } - print ''; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; + $head = array(); + $h = 0; + $head[$h][0] = $_SERVER['PHP_SELF'].'?piece_num='.$object->piece_num.($mode ? '&mode='.$mode : ''); + $head[$h][1] = $langs->trans("Transaction"); + $head[$h][2] = 'transaction'; + $h++; - if (count($object->linesmvt) > 0) { - print '
'; - print ''; + print dol_get_fiche_head($head, 'transaction', '', -1); - $total_debit = 0; - $total_credit = 0; + //dol_banner_tab($object, '', $backlink); - // Don't show in tmp mode, inevitably empty - if ($mode != "_tmp") { - // Date document export - print ''; - print ''; - print ''; - print ''; + print '
'; + print '
'; - // Date document validation - print '
'; - print ''; - print ''; - print ''; + print '
'; + print '
' . $langs->trans("DateExport") . ''; - print $object->date_export ? dol_print_date($object->date_export, 'dayhour') : ' '; - print '
' . $langs->trans("DateValidation") . ''; - print $object->date_validation ? dol_print_date($object->date_validation, 'dayhour') : ' '; - print '
'; + + // Account movement + print ''; + print ''; + print ''; + print ''; + + // Date + print ''; + print ''; - print ''; + // Journal + print ''; + print ''; - print_liste_field_titre("AccountAccountingShort"); - print_liste_field_titre("SubledgerAccount"); - print_liste_field_titre("LabelOperation"); - print_liste_field_titre("AccountingDebit", "", "", "", "", 'class="right"'); - print_liste_field_titre("AccountingCredit", "", "", "", "", 'class="right"'); - if (empty($object->date_validation)) { - print_liste_field_titre("Action", "", "", "", "", 'width="60"', "", "", 'center '); + // Ref document + print ''; + print ''; + + print '
'.$langs->trans("NumMvts").''.($mode == '_tmp' ? ''.$langs->trans("Draft").'' : $object->piece_num).'
'; + print ''; + if ($action != 'editdate') { + print ''; + } + print '
'; + print $langs->trans('Docdate'); + print 'piece_num).'&mode='.urlencode($mode).'">'.img_edit($langs->transnoentitiesnoconv('SetDate'), 1).'
'; + print '
'; + if ($action == 'editdate') { + print '
'; + if ($optioncss != '') { + print ''; } + print ''; + print ''; + print ''; + print $form->selectDate($object->doc_date ? $object->doc_date : - 1, 'doc_date', '', '', '', "setdate"); + print ''; + print '
'; + } else { + print $object->doc_date ? dol_print_date($object->doc_date, 'day') : ' '; + } + print '
'; + print ''; + if ($action != 'editjournal') { + print ''; + } + print '
'; + print $langs->trans('Codejournal'); + print 'piece_num).'&mode='.urlencode($mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'
'; + print '
'; + if ($action == 'editjournal') { + print '
'; + if ($optioncss != '') { + print ''; + } + print ''; + print ''; + print ''; + print $formaccounting->select_journal($object->code_journal, 'code_journal', 0, 0, array(), 1, 1); + print ''; + print '
'; + } else { + print $object->code_journal; + } + print '
'; + print ''; + if ($action != 'editdocref') { + print ''; + } + print '
'; + print $langs->trans('Piece'); + print 'piece_num).'&mode='.urlencode($mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'
'; + print '
'; + if ($action == 'editdocref') { + print '
'; + if ($optioncss != '') { + print ''; + } + print ''; + print ''; + print ''; + print ''; + print ''; + print '
'; + } else { + print $object->doc_ref; + } + print '
'; + + print '
'; + + print '
'; + + print '
'; + print ''; + + // Doc type + if (!empty($object->doc_type)) { + print ''; + print ''; + print ''; + print ''; + } + + // Date document creation + print ''; + print ''; + print ''; + print ''; + + // Don't show in tmp mode, inevitably empty + if ($mode != "_tmp") { + // Date document export + print ''; + print ''; + print ''; + print ''; + + // Date document validation + print ''; + print ''; + print ''; + print ''; + } + + // Validate + /* + print ''; + print ''; + print ''; + print ''; + */ - print "\n"; - - // In _tmp mode the first line is empty so we remove it - if ($mode == "_tmp") { - array_shift($object->linesmvt); + // check data + /* + print ''; + print ''; + if ($object->doc_type == 'customer_invoice') + { + $sqlmid = 'SELECT rowid as ref'; + $sqlmid .= " FROM ".MAIN_DB_PREFIX."facture as fac"; + $sqlmid .= " WHERE fac.rowid=" . ((int) $object->fk_doc); + dol_syslog("accountancy/bookkeeping/card.php::sqlmid=" . $sqlmid, LOG_DEBUG); + $resultmid = $db->query($sqlmid); + if ($resultmid) { + $objmid = $db->fetch_object($resultmid); + $invoicestatic = new Facture($db); + $invoicestatic->fetch($objmid->ref); + $ref=$langs->trans("Invoice").' '.$invoicestatic->getNomUrl(1); } + else dol_print_error($db); + } + print ''; + print ''; + */ + print "
'.$langs->trans("Doctype").''.$object->doc_type.'
'.$langs->trans("DateCreation").''; + print $object->date_creation ? dol_print_date($object->date_creation, 'day') : ' '; + print '
' . $langs->trans("DateExport") . ''; + print $object->date_export ? dol_print_date($object->date_export, 'dayhour') : ' '; + print '
' . $langs->trans("DateValidation") . ''; + print $object->date_validation ? dol_print_date($object->date_validation, 'dayhour') : ' '; + print '
' . $langs->trans("Status") . ''; + if (empty($object->validated)) { + print ''; + print img_picto($langs->trans("Disabled"), 'switch_off'); + print ''; } else { - print_liste_field_titre(""); + print ''; + print img_picto($langs->trans("Activated"), 'switch_on'); + print ''; } + print '
' . $langs->trans("Control") . '' . $ref .'
\n"; - // Add an empty line at the end to be able to add transaction - $line = new BookKeepingLine(); - $object->linesmvt[] = $line; + print '
'; - // Add a second line empty line if there is not yet - if (empty($object->linesmvt[1])) { - $line = new BookKeepingLine(); - $object->linesmvt[] = $line; + print dol_get_fiche_end(); + + print '
'; + + print '
'; + + $result = $object->fetchAllPerMvt($piece_num, $mode); // This load $object->linesmvt + + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } else { + // List of movements + print load_fiche_titre($langs->trans("ListeMvts"), '', ''); + + print '
'; + if ($optioncss != '') { + print ''; } + print ''; + print ''."\n"; + print ''."\n"; + print ''."\n"; + print ''."\n"; + print ''."\n"; + print ''."\n"; + print ''."\n"; - $count_line = count($object->linesmvt); - $num_line = 0; - foreach ($object->linesmvt as $key => $line) { - $num_line++; - print ''; - $total_debit += $line->debit; - $total_credit += $line->credit; + if (count($object->linesmvt) > 0) { + print '
'; + print ''; - if ($action == 'update' && $line->id == $id) { - print ''; - print ''; - print ''; + + print_liste_field_titre("AccountAccountingShort"); + print_liste_field_titre("SubledgerAccount"); + print_liste_field_titre("LabelOperation"); + print_liste_field_titre("AccountingDebit", "", "", "", "", 'class="right"'); + print_liste_field_titre("AccountingCredit", "", "", "", "", 'class="right"'); + if (empty($object->date_validation)) { + print_liste_field_titre("Action", "", "", "", "", 'width="60"', "", "", 'center '); + } else { + print_liste_field_titre(""); + } + + print "\n"; + + // Add an empty line if there is not yet + if (!empty($object->linesmvt[0])) { + $tmpline = $object->linesmvt[0]; + if (!empty($tmpline->numero_compte)) { + $line = new BookKeepingLine(); + $object->linesmvt[] = $line; } - // Add also input for subledger label - print '
subledger_label).'" placeholder="'.dol_escape_htmltag($langs->trans("SubledgerAccountLabel")).'" />'; - print ''; - print ''; - print ''; - print ''; - print ''; - } elseif (empty($line->numero_compte) || (empty($line->debit) && empty($line->credit))) { - if ($action == "" || $action == 'add') { - print ''; + } + + foreach ($object->linesmvt as $line) { + print ''; + $total_debit += $line->debit; + $total_credit += $line->credit; + + if ($action == 'update' && $line->id == $id) { + print ''; print ''; print ''; - print ''; - print ''; - print ''; - // Add button should not appear twice - if ($num_line === $count_line) { - print ''; + print ''; + print ''; + print ''; + print ''; + } elseif (empty($line->numero_compte) || (empty($line->debit) && empty($line->credit))) { + if ($action == "" || $action == 'add') { + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + } else { + print ''; + $resultfetch = $accountingaccount->fetch(null, $line->numero_compte, true); + print ''; + print $line->numero_compte.' ('.$langs->trans("AccountRemovedFromCurrentChartOfAccount").')'; } - } - } else { - print ''; - $resultfetch = $accountingaccount->fetch(null, $line->numero_compte, true); - print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print ''; - print ''; + } + print "\n"; + } + + $total_debit = price2num($total_debit, 'MT'); + $total_credit = price2num($total_credit, 'MT'); + + if ($total_debit != $total_credit) { + setEventMessages(null, array($langs->trans('MvtNotCorrectlyBalanced', $total_debit, $total_credit)), 'warnings'); + } + + print '
'; - print $formaccounting->select_account((GETPOSTISSET("accountingaccount_number") ? GETPOST("accountingaccount_number", "alpha") : $line->numero_compte), 'accountingaccount_number', 1, array(), 1, 1, ''); - print ''; - // TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because: - // It does not use the setup of "key pressed" to select a thirdparty and this hang browser on large databases. - // Also, it is not possible to use a value that is not in the list. - // Also, the label is not automatically filled when a value is selected. - if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) { - print $formaccounting->select_auxaccount((GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account), 'subledger_account', 1, 'maxwidth250', '', 'subledger_label'); - } else { - print 'subledger_account).'" placeholder="'.dol_escape_htmltag($langs->trans("SubledgerAccount")).'" />'; + $total_debit = 0; + $total_credit = 0; + + print '
label_operation).'" />debit)).'" />credit)).'" />'; - print ''."\n"; - print ''; - print '
'; - print $formaccounting->select_account((is_array($accountingaccount_number) ? $accountingaccount_number[$key] : $accountingaccount_number ), 'accountingaccount_number['.$key.']', 1, array(), 1, 1, ''); + print $formaccounting->select_account((GETPOSTISSET("accountingaccount_number") ? GETPOST("accountingaccount_number", "alpha") : $line->numero_compte), 'accountingaccount_number', 1, array(), 1, 1, 'minwidth200 maxwidth500'); print ''; // TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because: @@ -649,102 +684,124 @@ if (!empty($object->piece_num)) { // Also, it is not possible to use a value that is not in the list. // Also, the label is not automatically filled when a value is selected. if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) { - print $formaccounting->select_auxaccount((is_array($subledger_account) ? $subledger_account[$key] : $subledger_account ), 'subledger_account['.$key.']', 1, 'maxwidth250', '', 'subledger_label'); + print $formaccounting->select_auxaccount((GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account), 'subledger_account', 1, 'maxwidth250', '', 'subledger_label'); } else { - print ''; + print 'subledger_account).'" placeholder="'.dol_escape_htmltag($langs->trans("SubledgerAccount")).'">'; } - print '
'; + // Add also input for subledger label + print '
subledger_label).'" placeholder="'.dol_escape_htmltag($langs->trans("SubledgerAccountLabel")).'">'; print '
label_operation).'">debit)).'">credit)).'">'; + print ''."\n"; + print ''; + print ''; + print $formaccounting->select_account('', 'accountingaccount_number', 1, array(), 1, 1, 'minwidth200 maxwidth500'); + print ''; + // TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because: + // It does not use the setup of "key pressed" to select a thirdparty and this hang browser on large databases. + // Also, it is not possible to use a value that is not in the list. + // Also, the label is not automatically filled when a value is selected. + if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) { + print $formaccounting->select_auxaccount('', 'subledger_account', 1, 'maxwidth250', '', 'subledger_label'); + } else { + print ''; + } + print '
'; + print '
'; + if ($resultfetch > 0) { + print $accountingaccount->getNomUrl(0, 1, 1, '', 0); } else { - print ''; - if ($resultfetch > 0) { - print $accountingaccount->getNomUrl(0, 1, 1, '', 0); - } else { - print $line->numero_compte.' ('.$langs->trans("AccountRemovedFromCurrentChartOfAccount").')'; - } - print ''.length_accounta($line->subledger_account); - if ($line->subledger_label) { - print ' - '.$line->subledger_label.''; - } - print ''.$line->label_operation.''.($line->debit != 0 ? price($line->debit) : '').''.($line->credit != 0 ? price($line->credit) : '').''.length_accounta($line->subledger_account); + if ($line->subledger_label) { + print ' - '.$line->subledger_label.''; + } + print ''.$line->label_operation.''.($line->debit != 0 ? price($line->debit) : '').''.($line->credit != 0 ? price($line->credit) : '').''; - if (empty($line->date_export) && empty($line->date_validation)) { - print 'id . '&piece_num=' . urlencode($line->piece_num) . '&mode=' . urlencode($mode) . '&token=' . urlencode(newToken()) . '">'; - print img_edit('', 0, 'class="marginrightonly"'); - print '  '; - } else { - print ''; - print img_edit($langs->trans("ForbiddenTransactionAlreadyExported"), 0, 'class="marginrightonly"'); - print '  '; - } - - if (empty($line->date_validation)) { - $actiontodelete = 'delete'; - if ($mode == '_tmp' || $action != 'delmouv') { - $actiontodelete = 'confirm_delete'; + print ''; + if (empty($line->date_export) && empty($line->date_validation)) { + print 'id . '&piece_num=' . urlencode($line->piece_num) . '&mode=' . urlencode($mode) . '&token=' . urlencode(newToken()) . '">'; + print img_edit('', 0, 'class="marginrightonly"'); + print '  '; + } else { + print ''; + print img_edit($langs->trans("ForbiddenTransactionAlreadyExported"), 0, 'class="marginrightonly"'); + print '  '; } - print ''; - print img_delete(); - print ''; + if (empty($line->date_validation)) { + $actiontodelete = 'delete'; + if ($mode == '_tmp' || $action != 'delmouv') { + $actiontodelete = 'confirm_delete'; + } + + print ''; + print img_delete(); + print ''; + } else { + print ''; + print img_delete($langs->trans("ForbiddenTransactionAlreadyValidated")); + print ''; + } + + print '
'; + print '
'; + + if ($mode == '_tmp' && $action == '') { + print '
'; + print '
'; + if ($total_debit == $total_credit) { + print ''.$langs->trans("ValidTransaction").''; } else { - print ''; - print img_delete($langs->trans("ForbiddenTransactionAlreadyValidated")); - print ''; + print ''; } - print ''; + print '   '; + print ''.$langs->trans("Cancel").''; + + print "
"; } - print "\n"; } - $total_debit = price2num($total_debit, 'MT'); - $total_credit = price2num($total_credit, 'MT'); - - if ($total_debit != $total_credit) { - setEventMessages(null, array($langs->trans('MvtNotCorrectlyBalanced', $total_debit, $total_credit)), 'warnings'); - } - - print ''; - print '
'; - - if ($mode == '_tmp' && $action == '') { - print '
'; - print '
'; - if ($total_debit == $total_credit) { - print ''; - } else { - print ''; - } - - print '   '; - print ''.$langs->trans("Cancel").''; - - print "
"; - } + print ''; } - - print ''; + } else { + print load_fiche_titre($langs->trans("NoRecords")); } -} else { - print load_fiche_titre($langs->trans("NoRecords")); } print dol_get_fiche_end(); diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 0fbb2764ae6..217474db0c9 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -754,30 +754,33 @@ if ($action == 'export_fileconfirm' && $user->hasRight('accounting', 'mouvements } else { if (!empty($notifiedexportdate) || !empty($notifiedvalidationdate)) { if (is_array($object->lines)) { + dol_syslog("/accountancy/bookkeeping/list.php Function export_file Specify movements as exported", LOG_DEBUG); + // Specify as export : update field date_export or date_validated $db->begin(); + // TODO Merge update for each line into one gloacl using rowid IN (list of movement ids) foreach ($object->lines as $movement) { $now = dol_now(); - $sql = " UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping"; - $sql .= " SET"; - if (!empty($notifiedexportdate) && !empty($notifiedvalidationdate)) { - $sql .= " date_export = '".$db->idate($now)."'"; - $sql .= ", date_validated = '".$db->idate($now)."'"; - } elseif (!empty($notifiedexportdate)) { - $sql .= " date_export = '".$db->idate($now)."'"; - } elseif (!empty($notifiedvalidationdate)) { - $sql .= " date_validated = '".$db->idate($now)."'"; + $setfields = ''; + if (!empty($notifiedexportdate) && empty($movement->date_export)) { + $setfields .= ($setfields ? "," : "")." date_export = '".$db->idate($now)."'"; + } + if (!empty($notifiedvalidationdate) && empty($movement->date_validation)) { + $setfields .= ($setfields ? "," : "")." date_validated = '".$db->idate($now)."'"; } - $sql .= " WHERE rowid = ".((int) $movement->id); - dol_syslog("/accountancy/bookkeeping/list.php Function export_file Specify movements as exported", LOG_DEBUG); + if ($setfields) { + $sql = " UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping"; + $sql .= " SET ".$setfields; + $sql .= " WHERE rowid = ".((int) $movement->id); - $result = $db->query($sql); - if (!$result) { - $error++; - break; + $result = $db->query($sql); + if (!$result) { + $error++; + break; + } } } @@ -1014,17 +1017,17 @@ $newcardbutton = empty($hookmanager->resPrint) ? '' : $hookmanager->resPrint; if (empty($reshook)) { // Button re-export if (!empty($conf->global->ACCOUNTING_REEXPORT)) { - $newcardbutton .= ''.img_picto($langs->trans("ClickToHideAlreadyExportedLines"), 'switch_off', 'class="small size15x valignmiddle"'); + $newcardbutton .= ''.img_picto($langs->trans("ClickToHideAlreadyExportedLines"), 'switch_off', 'class="small size15x valignmiddle"'); $newcardbutton .= ''.$langs->trans("ClickToHideAlreadyExportedLines").''; $newcardbutton .= ''; } else { - $newcardbutton .= ''.img_picto($langs->trans("DocsAlreadyExportedAreExcluded"), 'switch_on', 'class="warning size15x valignmiddle"'); + $newcardbutton .= ''.img_picto($langs->trans("DocsAlreadyExportedAreExcluded"), 'switch_on', 'class="warning size15x valignmiddle"'); $newcardbutton .= ''.$langs->trans("DocsAlreadyExportedAreExcluded").''; $newcardbutton .= ''; } if ($user->hasRight('accounting', 'mouvements', 'export')) { - $newcardbutton .= dolGetButtonTitle($buttonLabel, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', 'fa fa-file-export paddingleft', $_SERVER["PHP_SELF"].'?action=export_file&token='.newToken().($param ? '&'.$param : ''), $user->hasRight('accounting', 'mouvements', 'export')); + $newcardbutton .= dolGetButtonTitle($buttonLabel, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', 'fa fa-file-export paddingleft', $_SERVER["PHP_SELF"].'?action=export_file&token='.newToken().($param ? '&'.$param : '').'&sortfield='.urlencode($sortfield).'&sortorder='.urlencode($sortorder), $user->hasRight('accounting', 'mouvements', 'export')); } $newcardbutton .= dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); @@ -1355,6 +1358,9 @@ while ($i < min($num, $limit)) { print ''; } print ''; + if (!$i) { + $totalarray['nbfield']++; + } } // Piece number @@ -1522,7 +1528,7 @@ while ($i < min($num, $limit)) { // Creation operation date if (!empty($arrayfields['t.date_creation']['checked'])) { - print ''.dol_print_date($line->date_creation, 'dayhour').''; + print ''.dol_print_date($line->date_creation, 'dayhour', 'tzuserrel').''; if (!$i) { $totalarray['nbfield']++; } @@ -1530,7 +1536,7 @@ while ($i < min($num, $limit)) { // Modification operation date if (!empty($arrayfields['t.tms']['checked'])) { - print ''.dol_print_date($line->date_modification, 'dayhour').''; + print ''.dol_print_date($line->date_modification, 'dayhour', 'tzuserrel').''; if (!$i) { $totalarray['nbfield']++; } @@ -1538,7 +1544,7 @@ while ($i < min($num, $limit)) { // Exported operation date if (!empty($arrayfields['t.date_export']['checked'])) { - print ''.dol_print_date($line->date_export, 'dayhour').''; + print ''.dol_print_date($line->date_export, 'dayhour', 'tzuserrel').''; if (!$i) { $totalarray['nbfield']++; } @@ -1546,7 +1552,7 @@ while ($i < min($num, $limit)) { // Validated operation date if (!empty($arrayfields['t.date_validated']['checked'])) { - print ''.dol_print_date($line->date_validation, 'dayhour').''; + print ''.dol_print_date($line->date_validation, 'dayhour', 'tzuserrel').''; if (!$i) { $totalarray['nbfield']++; } @@ -1570,11 +1576,11 @@ while ($i < min($num, $limit)) { print ''; } print ''; + if (!$i) { + $totalarray['nbfield']++; + } } - if (!$i) { - $totalarray['nbfield']++; - } print "\n"; diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 17ebe24546a..419369fe9d3 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -951,6 +951,10 @@ while ($i < min($num, $limit)) { if (!empty($arrayfields['t.date_export']['checked'])) { $colspanend++; } if (!empty($arrayfields['t.date_validating']['checked'])) { $colspanend++; } if (!empty($arrayfields['t.lettering_code']['checked'])) { $colspanend++; } + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + $colspan++; + $colspanend--; + } // Is it a break ? if ($accountg != $displayed_account_number || !isset($displayed_account_number)) { @@ -990,7 +994,9 @@ while ($i < min($num, $limit)) { print ''; if ($type == 'sub') { if ($line->subledger_account != "" && $line->subledger_account != '-1') { - print $line->subledger_label . ' : ' . length_accounta($line->subledger_account); + print empty($line->subledger_label) ? ''.$langs->trans("Unknown").'' : $line->subledger_label; + print ' : '; + print length_accounta($line->subledger_account); } else { // Should not happen: subledger account must be null or a non empty value print '' . $langs->trans("Unknown"); @@ -1033,6 +1039,9 @@ while ($i < min($num, $limit)) { print ''; } print ''; + if (!$i) { + $totalarray['nbfield']++; + } } // Piece number if (!empty($arrayfields['t.piece_num']['checked'])) { @@ -1216,9 +1225,9 @@ while ($i < min($num, $limit)) { print ''; } print ''; - } - if (!$i) { - $totalarray['nbfield']++; + if (!$i) { + $totalarray['nbfield']++; + } } // Comptabilise le sous-total diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index b725cafdacd..8c21b070d9f 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -37,7 +37,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; diff --git a/htdocs/accountancy/class/accountingjournal.class.php b/htdocs/accountancy/class/accountingjournal.class.php index f56932d4985..7c71d073629 100644 --- a/htdocs/accountancy/class/accountingjournal.class.php +++ b/htdocs/accountancy/class/accountingjournal.class.php @@ -388,12 +388,6 @@ class AccountingJournal extends CommonObject if (empty($type)) $type = 'view'; if (empty($in_bookkeeping)) $in_bookkeeping = 'notyet'; - // Hook - if (!is_object($hookmanager)) { - include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($this->db); - } - $data = array(); $hookmanager->initHooks(array('accountingjournaldao')); @@ -790,12 +784,6 @@ class AccountingJournal extends CommonObject global $conf, $langs, $hookmanager; require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php'; - // Hook - if (!is_object($hookmanager)) { - include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($this->db); - } - $error = 0; $hookmanager->initHooks(array('accountingjournaldao')); @@ -940,11 +928,6 @@ class AccountingJournal extends CommonObject $out = ''; // Hook - if (!is_object($hookmanager)) { - include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($this->db); - } - $hookmanager->initHooks(array('accountingjournaldao')); $parameters = array('journal_data' => &$journal_data, 'search_date_end' => &$search_date_end, 'sep' => &$sep, 'out' => &$out); $reshook = $hookmanager->executeHooks('exportCsv', $parameters, $this); // Note that $action and $object may have been diff --git a/htdocs/adherents/admin/website.php b/htdocs/adherents/admin/website.php index dd44ce0cece..6b7d12c122a 100644 --- a/htdocs/adherents/admin/website.php +++ b/htdocs/adherents/admin/website.php @@ -60,7 +60,7 @@ if ($action == 'update') { $amount = price2num(GETPOST('MEMBER_NEWFORM_AMOUNT'), 'MT', 2); $minamount = GETPOST('MEMBER_MIN_AMOUNT'); $publiccounters = GETPOST('MEMBER_COUNTERS_ARE_PUBLIC'); - $showtable = GETPOST('MEMBER_SHOW_TABLE');; + $showtable = GETPOST('MEMBER_SHOW_TABLE'); $showvoteallowed = GETPOST('MEMBER_SHOW_VOTE_ALLOWED'); $payonline = GETPOST('MEMBER_NEWFORM_PAYONLINE'); $forcetype = GETPOST('MEMBER_NEWFORM_FORCETYPE', 'int'); diff --git a/htdocs/adherents/canvas/actions_adherentcard_common.class.php b/htdocs/adherents/canvas/actions_adherentcard_common.class.php index 45d9c4f8fce..eda6f52deb3 100644 --- a/htdocs/adherents/canvas/actions_adherentcard_common.class.php +++ b/htdocs/adherents/canvas/actions_adherentcard_common.class.php @@ -61,20 +61,15 @@ abstract class ActionsAdherentCardCommon */ public function getObject($id) { - //$ret = $this->getInstanceDao(); + $object = new Adherent($this->db); - /*if (is_object($this->object) && method_exists($this->object,'fetch')) - { - if (!empty($id)) $this->object->fetch($id); - } - else - {*/ - $object = new Adherent($this->db); if (!empty($id)) { $object->fetch($id); } - $this->object = $object; - //} + + $this->object = $object; + + return $object; } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -83,7 +78,7 @@ abstract class ActionsAdherentCardCommon * * @param string $action Type of action * @param int $id Id - * @return string HTML output + * @return void */ public function assign_values(&$action, $id) { diff --git a/htdocs/adherents/canvas/default/actions_adherentcard_default.class.php b/htdocs/adherents/canvas/default/actions_adherentcard_default.class.php index b6f0489108a..58b414b2511 100644 --- a/htdocs/adherents/canvas/default/actions_adherentcard_default.class.php +++ b/htdocs/adherents/canvas/default/actions_adherentcard_default.class.php @@ -84,7 +84,6 @@ class ActionsAdherentCardDefault extends ActionsAdherentCardCommon public function assign_values(&$action, $id) { // phpcs:enable - global $limit, $offset, $sortfield, $sortorder; global $conf, $db, $langs, $user; global $form; diff --git a/htdocs/admin/stocktransfer.php b/htdocs/admin/stocktransfer.php index 02c73bb2a76..77e823d0457 100644 --- a/htdocs/admin/stocktransfer.php +++ b/htdocs/admin/stocktransfer.php @@ -356,8 +356,8 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { dol_print_error($db); } - print "\n"; - print "\n"; + print '
'."\n"; + print ''."\n"; print ''; print ''; print '\n"; @@ -396,7 +396,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified = 0; if ($modulequalified) { - print ''; print ''; diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 90bb35320c0..15db7d2ba0d 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -241,14 +241,41 @@ print '
'; print '
'; $installlock = DOL_DATA_ROOT.'/install.lock'; +$upgradeunlock = DOL_DATA_ROOT.'/upgrade.unlock'; +$installmoduleslock = DOL_DATA_ROOT.'/installmodules.lock'; + +// Is install (upgrade) locked print ''.$langs->trans("DolibarrSetup").': '; if (file_exists($installlock)) { - print img_picto('', 'tick').' '.$langs->trans("InstallAndUpgradeLockedBy", $installlock); + if (file_exists($upgradeunlock)) { + print img_picto('', 'tick').' '.$langs->trans("InstallLockedBy", $installlock); + } else { + print img_picto('', 'tick').' '.$langs->trans("InstallAndUpgradeLockedBy", $installlock); + } } else { print img_warning().' '.$langs->trans("WarningLockFileDoesNotExists", DOL_DATA_ROOT); } print '
'; +// Is upgrade unlocked +if (file_exists($installlock)) { // If install not locked, no need to show this. + if (file_exists($upgradeunlock)) { + print ''.$langs->trans("DolibarrUpgrade").': '; + print img_warning().' '.$langs->trans("UpgradeHasBeenUnlocked", $upgradeunlock); + print '
'; + } +} + +// Is addon install locked ? +print ''.$langs->trans("DolibarrAddonInstall").': '; +if (file_exists($installmoduleslock)) { + print img_picto('', 'tick').' '.$langs->trans("InstallAndUpgradeLockedBy", $installmoduleslock); +} else { + print $langs->trans("InstallOfAddonIsNotBlocked", DOL_DATA_ROOT); +} +print '
'; + + // File conf.php @@ -286,7 +313,7 @@ if (empty($dolibarr_main_restrict_os_commands)) { } else { print $dolibarr_main_restrict_os_commands; } -print ' ('.$langs->trans("RecommendedValueIs", 'mysqldump, mysql, pg_dump, pgrestore').')'; +print ' ('.$langs->trans("RecommendedValueIs", 'mysqldump, mysql, pg_dump, pgrestore, clamdscan').')'; print '
'; if (empty($conf->global->SECURITY_DISABLE_TEST_ON_OBFUSCATED_CONF)) { diff --git a/htdocs/asset/class/assetaccountancycodes.class.php b/htdocs/asset/class/assetaccountancycodes.class.php index 720dd1e745d..60b545ba6ce 100644 --- a/htdocs/asset/class/assetaccountancycodes.class.php +++ b/htdocs/asset/class/assetaccountancycodes.class.php @@ -116,11 +116,6 @@ class AssetAccountancyCodes extends CommonObject $asset_id = $asset_id > 0 ? $asset_id : 0; $asset_model_id = $asset_model_id > 0 ? $asset_model_id : 0; - if (!is_object($hookmanager)) { - require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($this->db); - } - $hookmanager->initHooks(array('assetaccountancycodesdao')); $parameters = array('asset_id' => $asset_id, 'asset_model_id' => $asset_model_id); $reshook = $hookmanager->executeHooks('fetchAccountancyCodes', $parameters, $this); // Note that $action and $object may have been modified by some hooks @@ -188,11 +183,6 @@ class AssetAccountancyCodes extends CommonObject $asset_id = $asset_id > 0 ? $asset_id : 0; $asset_model_id = $asset_model_id > 0 ? $asset_model_id : 0; - if (!is_object($hookmanager)) { - require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($this->db); - } - $hookmanager->initHooks(array('assetaccountancycodesdao')); $parameters = array('user' => $user, 'asset_id' => $asset_id, 'asset_model_id' => $asset_model_id); $reshook = $hookmanager->executeHooks('updateAccountancyCodes', $parameters, $this); // Note that $action and $object may have been modified by some hooks diff --git a/htdocs/asset/class/assetdepreciationoptions.class.php b/htdocs/asset/class/assetdepreciationoptions.class.php index 49efadca869..f2411ea4494 100644 --- a/htdocs/asset/class/assetdepreciationoptions.class.php +++ b/htdocs/asset/class/assetdepreciationoptions.class.php @@ -319,11 +319,6 @@ class AssetDepreciationOptions extends CommonObject $asset_id = $asset_id > 0 ? $asset_id : 0; $asset_model_id = $asset_model_id > 0 ? $asset_model_id : 0; - if (!is_object($hookmanager)) { - require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($this->db); - } - $hookmanager->initHooks(array('assetdepreciationoptionsdao')); $parameters = array('asset_id' => $asset_id, 'asset_model_id' => $asset_model_id); $reshook = $hookmanager->executeHooks('fetchDepreciationOptions', $parameters, $this); // Note that $action and $object may have been modified by some hooks @@ -392,11 +387,6 @@ class AssetDepreciationOptions extends CommonObject // Clean parameters $mode = strtolower(trim($mode)); - if (!is_object($hookmanager)) { - require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($this->db); - } - $hookmanager->initHooks(array('assetdepreciationoptionsdao')); $parameters = array('mode' => $mode); $reshook = $hookmanager->executeHooks('getGeneralDepreciationInfoForMode', $parameters, $this); // Note that $action and $object may have been modified by some hooks @@ -437,11 +427,6 @@ class AssetDepreciationOptions extends CommonObject $asset_id = $asset_id > 0 ? $asset_id : 0; $asset_model_id = $asset_model_id > 0 ? $asset_model_id : 0; - if (!is_object($hookmanager)) { - require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($this->db); - } - $hookmanager->initHooks(array('assetdepreciationoptionsdao')); $parameters = array('user' => $user, 'asset_id' => $asset_id, 'asset_model_id' => $asset_model_id); $reshook = $hookmanager->executeHooks('updateDepreciationOptions', $parameters, $this); // Note that $action and $object may have been modified by some hooks diff --git a/htdocs/asset/list.php b/htdocs/asset/list.php index d98165d28a2..4b3b530148d 100644 --- a/htdocs/asset/list.php +++ b/htdocs/asset/list.php @@ -639,7 +639,7 @@ if ($num == 0) { $colspan++; } } - print ''; + print ''; } diff --git a/htdocs/blockedlog/class/authority.class.php b/htdocs/blockedlog/class/authority.class.php index b3dd9b45f47..e274ff4175d 100644 --- a/htdocs/blockedlog/class/authority.class.php +++ b/htdocs/blockedlog/class/authority.class.php @@ -20,6 +20,11 @@ */ class BlockedLogAuthority { + /** + * DoliDB + * @var DoliDB + */ + public $db; /** * Id of the log @@ -45,6 +50,12 @@ class BlockedLogAuthority */ public $tms = 0; + /** + * Error message + * @var string + */ + public $error; + /** * Constructor * diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 5f1b081c46d..6762770d564 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -845,10 +845,12 @@ class Categorie extends CommonObject * @param int $offset Offset * @param string $sortfield Sort fields * @param string $sortorder Sort order ('ASC' or 'DESC'); + * @param array $filter Filter array. Example array('field'=>'valueforlike', 'customsql'=>...) + * @param string $filtermode Filter mode (AND or OR) * @return array|int -1 if KO, array of instance of object if OK * @see containsObject() */ - public function getObjectsInCateg($type, $onlyids = 0, $limit = 0, $offset = 0, $sortfield = '', $sortorder = 'ASC') + public function getObjectsInCateg($type, $onlyids = 0, $limit = 0, $offset = 0, $sortfield = '', $sortorder = 'ASC', $filter = array(), $filtermode = 'AND') { global $user; @@ -867,10 +869,24 @@ class Categorie extends CommonObject if (($type == 'customer' || $type == 'supplier') && $user->socid > 0) { $sql .= " AND o.rowid = ".((int) $user->socid); } + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + if ($key == 'o.rowid') { + $sqlwhere[] = $key." = ".((int) $value); + } elseif ($key == 'customsql') { + $sqlwhere[] = $value; + } + } + } + if (count($sqlwhere) > 0) { + $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")"; + } + $sql .= $this->db->order($sortfield, $sortorder); if ($limit > 0 || $offset > 0) { $sql .= $this->db->plimit($limit + 1, $offset); } - $sql .= $this->db->order($sortfield, $sortorder); dol_syslog(get_class($this)."::getObjectsInCateg", LOG_DEBUG); $resql = $this->db->query($sql); diff --git a/htdocs/comm/propal/agenda.php b/htdocs/comm/propal/agenda.php index 9b9e396ee26..42e15dca146 100644 --- a/htdocs/comm/propal/agenda.php +++ b/htdocs/comm/propal/agenda.php @@ -24,6 +24,7 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/propal.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index cae98408d44..5c4c4aae9f1 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -79,6 +79,7 @@ $cancel = GETPOST('cancel', 'alpha'); $origin = GETPOST('origin', 'alpha'); $originid = GETPOST('originid', 'int'); $confirm = GETPOST('confirm', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page $lineid = GETPOST('lineid', 'int'); $contactid = GETPOST('contactid', 'int'); $projectid = GETPOST('projectid', 'int'); @@ -1774,6 +1775,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; if ($origin != 'project' && $originid) { print ''; print ''; @@ -2449,6 +2451,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; print $form->selectDate($object->date, 're', '', '', 0, "editdate"); print ''; print ''; @@ -2476,6 +2479,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; print $form->selectDate($object->fin_validite, 'ech', '', '', '', "editecheance"); print ''; print ''; @@ -2836,6 +2840,7 @@ if ($action == 'create') { + '; @@ -2845,7 +2850,7 @@ if ($action == 'create') { print '
'; if (!empty($object->lines) || ($object->statut == Propal::STATUS_DRAFT && $usercancreate && $action != 'selectlines' && $action != 'editline')) { - print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."
'; + print '
'; print (empty($module->name) ? $name : $module->name); print "\n"; if (method_exists($module, 'info')) print $module->info($langs); diff --git a/htdocs/admin/system/phpinfo.php b/htdocs/admin/system/phpinfo.php index 301231b1e4c..36c64a826a6 100644 --- a/htdocs/admin/system/phpinfo.php +++ b/htdocs/admin/system/phpinfo.php @@ -252,6 +252,7 @@ foreach ($phparray as $key => $value) { if (!is_array($keyvalue)) { $keytoshow = $keyparam; $valtoshow = $keyvalue; + // Hide value of session cookies if (in_array($keyparam, array('HTTP_COOKIE', 'Cookie', "\$_SERVER['HTTP_COOKIE']", 'Authorization'))) { $valtoshow = ''.$langs->trans("Hidden").''; @@ -260,6 +261,10 @@ foreach ($phparray as $key => $value) { $keytoshow = $keyparam; $valtoshow = ''.$langs->trans("Hidden").''; } + if (preg_match('/'.preg_quote('$_SERVER[\'PHP_AUTH_PW', '/').'/i', $keyparam)) { + $keytoshow = $keyparam; + $valtoshow = ''.$langs->trans("Hidden").''; + } print '
'.$keytoshow.'
'.$langs->trans("NoRecordFound").'
'.$langs->trans("NoRecordFound").'
'; + print '
'; } if (!empty($object->lines)) { diff --git a/htdocs/commande/agenda.php b/htdocs/commande/agenda.php index 8eabb418ae9..a998229f776 100644 --- a/htdocs/commande/agenda.php +++ b/htdocs/commande/agenda.php @@ -24,6 +24,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/order.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index b0c257172a4..318ce32f115 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -84,6 +84,8 @@ $socid = GETPOST('socid', 'int'); $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'alpha'); $confirm = GETPOST('confirm', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); + $lineid = GETPOST('lineid', 'int'); $contactid = GETPOST('contactid', 'int'); $projectid = GETPOST('projectid', 'int'); @@ -1755,6 +1757,7 @@ if ($action == 'create' && $usercancreate) { print ''; print ''; print ''; + print ''; if (!empty($currency_tx)) { print ''; } @@ -2449,6 +2452,7 @@ if ($action == 'create' && $usercancreate) { print ''; print ''; print ''; + print ''; print $form->selectDate($object->date, 'order_', '', '', '', "setdate"); print ''; print ''; @@ -2470,6 +2474,7 @@ if ($action == 'create' && $usercancreate) { print ''; print ''; print ''; + print ''; print $form->selectDate($object->delivery_date ? $object->delivery_date : -1, 'liv_', 1, 1, '', "setdate_livraison", 1, 0); print ''; print ''; @@ -2763,7 +2768,9 @@ if ($action == 'create' && $usercancreate) { - '; + + + '; if (!empty($conf->use_javascript_ajax) && $object->statut == Commande::STATUS_DRAFT) { include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index af8d626eba1..4b3d0e6e94c 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -135,14 +135,14 @@ if (empty($entity)) { $error = 0; $listofchoices = array( - 'selectinvoices'=>array('label'=>'Invoices', 'lang'=>'bills', 'enabled' => isModEnabled('facture'), 'perms' => !empty($user->rights->facture->lire)), - 'selectsupplierinvoices'=>array('label'=>'BillsSuppliers', 'lang'=>'bills', 'enabled' => isModEnabled('supplier_invoice'), 'perms' => !empty($user->rights->fournisseur->facture->lire)), - 'selectexpensereports'=>array('label'=>'ExpenseReports', 'lang'=>'trips', 'enabled' => isModEnabled('expensereport'), 'perms' => !empty($user->rights->expensereport->lire)), - 'selectdonations'=>array('label'=>'Donations', 'lang'=>'donation', 'enabled' => isModEnabled('don'), 'perms' => !empty($user->rights->don->lire)), - 'selectsocialcontributions'=>array('label'=>'SocialContributions', 'enabled' => isModEnabled('tax'), 'perms' => !empty($user->rights->tax->charges->lire)), - 'selectpaymentsofsalaries'=>array('label'=>'SalariesPayments', 'lang'=>'salaries', 'enabled' => isModEnabled('salaries'), 'perms' => !empty($user->rights->salaries->read)), - 'selectvariouspayment'=>array('label'=>'VariousPayment', 'enabled' => isModEnabled('banque'), 'perms' => !empty($user->rights->banque->lire)), - 'selectloanspayment'=>array('label'=>'PaymentLoan', 'enabled' => isModEnabled('don'), 'perms' => !empty($user->rights->loan->read)), + 'selectinvoices'=>array('label'=>'Invoices', 'picto'=>'bill', 'lang'=>'bills', 'enabled' => isModEnabled('facture'), 'perms' => !empty($user->rights->facture->lire)), + 'selectsupplierinvoices'=>array('label'=>'BillsSuppliers', 'picto'=>'supplier_invoice', 'lang'=>'bills', 'enabled' => isModEnabled('supplier_invoice'), 'perms' => !empty($user->rights->fournisseur->facture->lire)), + 'selectexpensereports'=>array('label'=>'ExpenseReports', 'picto'=>'expensereport', 'lang'=>'trips', 'enabled' => isModEnabled('expensereport'), 'perms' => !empty($user->rights->expensereport->lire)), + 'selectdonations'=>array('label'=>'Donations', 'picto'=>'donation', 'lang'=>'donation', 'enabled' => isModEnabled('don'), 'perms' => !empty($user->rights->don->lire)), + 'selectsocialcontributions'=>array('label'=>'SocialContributions', 'picto'=>'bill', 'enabled' => isModEnabled('tax'), 'perms' => !empty($user->rights->tax->charges->lire)), + 'selectpaymentsofsalaries'=>array('label'=>'SalariesPayments', 'picto'=>'salary', 'lang'=>'salaries', 'enabled' => isModEnabled('salaries'), 'perms' => !empty($user->rights->salaries->read)), + 'selectvariouspayment'=>array('label'=>'VariousPayment', 'picto'=>'payment', 'enabled' => isModEnabled('banque'), 'perms' => !empty($user->rights->banque->lire)), + 'selectloanspayment'=>array('label'=>'PaymentLoan','picto'=>'loan', 'enabled' => isModEnabled('don'), 'perms' => !empty($user->rights->loan->read)), ); @@ -623,7 +623,9 @@ foreach ($listofchoices as $choice => $val) { $disabled = ' disabled'; } $checked = (((!GETPOSTISSET('search') && $action != 'searchfiles') || GETPOST($choice)) ? ' checked="checked"' : ''); - print '
'; + print '
'; } print ''; diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 73cb5d3bf02..6f08fb17054 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -55,6 +55,7 @@ $langs->loadLangs(array("banks", "bills", "categories", "companies", "compta", " $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); $object = new Account($db); $extrafields = new ExtraFields($db); @@ -380,6 +381,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; print dol_get_fiche_head(''); @@ -527,6 +529,12 @@ if ($action == 'create') { print ''; print ''; + $ibankey = FormBank::getIBANLabel($object); + $bickey = "BICNumber"; + if ($object->getCountryCode() == 'IN') { + $bickey = "SWIFT"; + } + // IBAN print ''; print ''; @@ -561,11 +569,6 @@ if ($action == 'create') { print ''; print ''; } - $ibankey = FormBank::getIBANLabel($object); - $bickey = "BICNumber"; - if ($object->getCountryCode() == 'IN') { - $bickey = "SWIFT"; - } if (isModEnabled('paymentbybanktransfer')) { print ''; @@ -903,6 +906,7 @@ if ($action == 'create') { print ''; print ''; print ''."\n\n"; + print ''; print dol_get_fiche_head(array(), 0, '', 0); diff --git a/htdocs/compta/bank/class/paymentvarious.class.php b/htdocs/compta/bank/class/paymentvarious.class.php index 705ff2d20ca..912f46e074a 100644 --- a/htdocs/compta/bank/class/paymentvarious.class.php +++ b/htdocs/compta/bank/class/paymentvarious.class.php @@ -828,4 +828,36 @@ class PaymentVarious extends CommonObject $return .= ''; return $return; } + + /** + * Return General accounting account with defined length (used for product and miscellaneous) + * + * @param string $account General accounting account + * @return string String with defined length + */ + public function lengthAccountg($account) + { + include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; + + /* + if (isModEnabled('accounting')) { + $accountingaccount = new AccountingAccount($db); + $accountingaccount->fetch('', $valuetoshow, 1); + }*/ + + return length_accountg($account); + } + + /** + * Return Auxiliary accounting account of thirdparties with defined length + * + * @param string $account Auxiliary accounting account + * @return string String with defined length + */ + public function lengthAccounta($account) + { + include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; + + return length_accounta($account); + } } diff --git a/htdocs/compta/bank/transfer.php b/htdocs/compta/bank/transfer.php index 5f33afbae7f..724e09554db 100644 --- a/htdocs/compta/bank/transfer.php +++ b/htdocs/compta/bank/transfer.php @@ -346,7 +346,7 @@ for ($i = 1 ; $i < $MAXLINES; $i++) { print ''; print ''; -}; +} print '
'.$langs->trans($ibankey).'
'.$form->textwithpicto($langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformation"), $langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformationHelp")).'
'; print '
'; diff --git a/htdocs/compta/bank/various_payment/card.php b/htdocs/compta/bank/various_payment/card.php index 1eb552fd711..7fbf2774e85 100644 --- a/htdocs/compta/bank/various_payment/card.php +++ b/htdocs/compta/bank/various_payment/card.php @@ -1,6 +1,7 @@ * Copyright (C) 2018-2020 Frédéric France + * Copyright (C) 2023 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -71,6 +72,8 @@ $object = new PaymentVarious($db); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('variouscard', 'globalcard')); +$permissiontoadd = $user->hasRight('banque', 'modifier'); + /** * Actions @@ -83,14 +86,8 @@ if ($reshook < 0) { } if (empty($reshook)) { - // Link to a project - if ($action == 'classin' && $user->rights->banque->modifier) { - $object->fetch($id); - $object->setProject(GETPOST('projectid')); - } - if ($cancel) { - if ($action != 'addlink') { + if ($action != 'addlink' && $action != 'setaccountancy_code' && $action != 'setsubledger_account') { $urltogo = $backtopage ? $backtopage : dol_buildpath('/compta/bank/various_payment/list.php', 1); header("Location: ".$urltogo); exit; @@ -101,6 +98,12 @@ if (empty($reshook)) { $action = ''; } + // Link to a project + if ($action == 'classin' && $permissiontoadd) { + $object->fetch($id); + $object->setProject(GETPOST('projectid', 'int')); + } + if ($action == 'add') { $error = 0; @@ -214,6 +217,22 @@ if (empty($reshook)) { } } + if ($action == 'setaccountancy_code') { + $db->begin(); + + $result = $object->fetch($id); + + $object->accountancy_code = GETPOST('accountancy_code', 'alpha'); + + $res = $object->update($user); + if ($res > 0) { + $db->commit(); + } else { + $db->rollback(); + setEventMessages($object->error, $object->errors, 'errors'); + } + } + if ($action == 'setsubledger_account') { $db->begin(); @@ -236,7 +255,7 @@ if ($action == 'confirm_clone' && $confirm != 'yes') { $action = ''; } -if ($action == 'confirm_clone' && $confirm == 'yes' && ($user->rights->banque->modifier)) { +if ($action == 'confirm_clone' && $confirm == 'yes' && $permissiontoadd) { $db->begin(); $originalId = $id; @@ -560,32 +579,25 @@ if ($id) { // Project if (isModEnabled('project')) { $langs->load("projects"); - $morehtmlref .= $langs->trans('Project').' '; - if ($user->rights->banque->modifier) { + //$morehtmlref .= '
'; + if ($permissiontoadd) { + $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"'); if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; - } - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref .= '
'; - $morehtmlref .= ''; - $morehtmlref .= ''; - $morehtmlref .= $formproject->select_projects(0, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref .= ''; - $morehtmlref .= '
'; - } else { - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); $morehtmlref .= $proj->getNomUrl(1); - } else { - $morehtmlref .= ''; + if ($proj->title) { + $morehtmlref .= ' - '.dol_escape_htmltag($proj->title).''; + } } } } + $morehtmlref .= ''; $linkback = ''.$langs->trans("BackToList").''; @@ -622,25 +634,24 @@ if ($id) { print ''.$langs->trans("Amount").''.price($object->amount, 0, $langs, 1, -1, -1, $conf->currency).''; - // Accountancy code - print ''; - print $langs->trans("AccountAccounting"); - print ''; + // Account of Chart of account + $editvalue = ''; if (isModEnabled('accounting')) { - $accountingaccount = new AccountingAccount($db); - $accountingaccount->fetch('', $object->accountancy_code, 1); - - print $accountingaccount->getNomUrl(0, 1, 1, '', 1); - } else { - print $object->accountancy_code; + $editvalue = $formaccounting->select_account($object->accountancy_code, 'accountancy_code', 1, null, 1, 1); } + + print ''; + print ''; + print $form->editfieldkey('AccountAccounting', 'accountancy_code', $object->accountancy_code, $object, (!$alreadyaccounted && $permissiontoadd), 'string', '', 0); + print ''; + print $form->editfieldval('AccountAccounting', 'accountancy_code', $object->accountancy_code, $object, (!$alreadyaccounted && $permissiontoadd), 'asis', $editvalue, 0, null, '', 1, 'lengthAccountg'); print ''; // Subledger account print ''; - print $form->editfieldkey('SubledgerAccount', 'subledger_account', $object->subledger_account, $object, (!$alreadyaccounted && $user->rights->banque->modifier), 'string', '', 0); + print $form->editfieldkey('SubledgerAccount', 'subledger_account', $object->subledger_account, $object, (!$alreadyaccounted && $permissiontoadd), 'string', '', 0); print ''; - print $form->editfieldval('SubledgerAccount', 'subledger_account', $object->subledger_account, $object, (!$alreadyaccounted && $user->rights->banque->modifier), 'string', '', 0); + print $form->editfieldval('SubledgerAccount', 'subledger_account', $object->subledger_account, $object, (!$alreadyaccounted && $permissiontoadd), 'string', '', 0, null, '', 1, 'lengthAccounta'); print ''; $bankaccountnotfound = 0; @@ -689,13 +700,13 @@ if ($id) { // Add button modify // Clone - if ($user->rights->banque->modifier) { + if ($permissiontoadd) { print '"; } // Delete if (empty($object->rappro) || $bankaccountnotfound) { - if (!empty($user->rights->banque->modifier)) { + if ($permissiontoadd) { if ($alreadyaccounted) { print ''; } else { diff --git a/htdocs/compta/bank/various_payment/document.php b/htdocs/compta/bank/various_payment/document.php index 43259727917..58e4d3680b9 100644 --- a/htdocs/compta/bank/various_payment/document.php +++ b/htdocs/compta/bank/various_payment/document.php @@ -100,7 +100,6 @@ if ($object->id) { // Project if (isModEnabled('project')) { $langs->load("projects"); - $morehtmlref .= $langs->trans('Project').' : '; if ($user->rights->banque->modifier && 0) { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; diff --git a/htdocs/compta/bank/various_payment/info.php b/htdocs/compta/bank/various_payment/info.php index ca31915d2f4..06f243a9847 100644 --- a/htdocs/compta/bank/various_payment/info.php +++ b/htdocs/compta/bank/various_payment/info.php @@ -60,7 +60,6 @@ $morehtmlref = '
'; // Project if (isModEnabled('project')) { $langs->load("projects"); - $morehtmlref .= $langs->trans('Project').' : '; if ($user->rights->banque->modifier && 0) { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; diff --git a/htdocs/compta/cashcontrol/cashcontrol_list.php b/htdocs/compta/cashcontrol/cashcontrol_list.php index 41aa42195dc..a050cf7ffec 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_list.php +++ b/htdocs/compta/cashcontrol/cashcontrol_list.php @@ -178,8 +178,8 @@ if (empty($reshook)) { // Mass actions $objectclass = 'CashControl'; $objectlabel = 'CashControl'; - //$uploaddir = ''; - //include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + $uploaddir = $conf->bank->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } @@ -376,15 +376,9 @@ $reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $param .= $hookmanager->resPrint; // List of mass actions available -$arrayofmassactions = array( -//'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), -//'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), -); -//if ($permissiontodelete) { -// $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); -//} -if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) { - $arrayofmassactions = array(); +$arrayofmassactions = array(); +if (!empty($permissiontodelete)) { + $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); } $massactionbutton = $form->selectMassAction('', $arrayofmassactions); @@ -585,7 +579,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { $object->cheque = $obj->cheque; - print $object->getKanbanView(''); + print $object->getKanbanView('', array('selected' => in_array($object->id, $arrayofselected))); if ($i == (min($num, $limit) - 1)) { print '
'; print ''; diff --git a/htdocs/compta/facture/agenda.php b/htdocs/compta/facture/agenda.php index b6bce2a160e..a7930660378 100644 --- a/htdocs/compta/facture/agenda.php +++ b/htdocs/compta/facture/agenda.php @@ -26,6 +26,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; // Load translation files required by the page $langs->loadLangs(array("facture", "other")); diff --git a/htdocs/compta/facture/card-rec.php b/htdocs/compta/facture/card-rec.php index ce7bf072073..a2a87d6d64a 100644 --- a/htdocs/compta/facture/card-rec.php +++ b/htdocs/compta/facture/card-rec.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2016 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Florian Henry - * Copyright (C) 2013 Juanjo Menent + * Copyright (C) 2013-2023 Juanjo Menent * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2015 Alexandre Spangaro @@ -437,6 +437,9 @@ if (empty($reshook)) { $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS', 2); $remise_percent = price2num(GETPOST('remise_percent'.$predef), '', 2); + if (empty($remise_percent)) { + $remise_percent = 0; + } // Extrafields $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line); @@ -784,6 +787,9 @@ if (empty($reshook)) { }*/ $remise_percent = price2num(GETPOST('remise_percent'), '', 2); + if (empty($remise_percent)) { + $remise_percent = 0; + } // Check minimum price $productid = GETPOST('productid', 'int'); diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index e8e92ebfada..58c7e35724d 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -86,6 +86,8 @@ $socid = GETPOST('socid', 'int'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); $cancel = GETPOST('cancel', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); + $lineid = GETPOST('lineid', 'int'); $userid = GETPOST('userid', 'int'); $search_ref = GETPOST('sf_ref', 'alpha') ? GETPOST('sf_ref', 'alpha') : GETPOST('search_ref', 'alpha'); @@ -3153,6 +3155,8 @@ if ($action == 'create') { if ($soc->id > 0) { print ''."\n"; } + print ''; + print ''; print ''; print ''; print ''; @@ -4688,6 +4692,7 @@ if ($action == 'create') { print '
'; print ''; print ''; + print ''; print ''; print ''; print '
'; @@ -4717,6 +4722,7 @@ if ($action == 'create') { print '
'; print ''; print ''; + print ''; $retained_warranty_fk_cond_reglement = GETPOST('retained_warranty_fk_cond_reglement', 'int'); $retained_warranty_fk_cond_reglement = !empty($retained_warranty_fk_cond_reglement) ? $retained_warranty_fk_cond_reglement : $object->retained_warranty_fk_cond_reglement; $retained_warranty_fk_cond_reglement = !empty($retained_warranty_fk_cond_reglement) ? $retained_warranty_fk_cond_reglement : $conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID; @@ -4752,6 +4758,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; print ''; print ''; print '
'; @@ -4832,6 +4839,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; print $formother->select_revenue_stamp('', 'revenuestamp_type', $mysoc->country_code); print ' → '; print ' '; @@ -5371,6 +5379,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; print ''; @@ -5409,6 +5418,7 @@ if ($action == 'create') { + '; if (!empty($conf->use_javascript_ajax) && $object->statut == 0) { diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index c39e432e535..a4e7bd52430 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1733,12 +1733,6 @@ class Facture extends CommonInvoice } } - - if (! is_object($hookmanager)) { - require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($origin->db); - } - $hookmanager->initHooks(array('invoicedao')); $parameters = array('objFrom' => $origin); @@ -3584,6 +3578,7 @@ class Facture extends CommonInvoice /** * Add an invoice line into database (linked to product/service or not). + * Note: ->thirdparty must be defined. * Les parametres sont deja cense etre juste et avec valeurs finales a l'appel * de cette methode. Aussi, pour le taux tva, il doit deja avoir ete defini * par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,produit) diff --git a/htdocs/compta/sociales/class/chargesociales.class.php b/htdocs/compta/sociales/class/chargesociales.class.php index c9e9b6e561b..34586a5468e 100644 --- a/htdocs/compta/sociales/class/chargesociales.class.php +++ b/htdocs/compta/sociales/class/chargesociales.class.php @@ -597,7 +597,7 @@ class ChargeSociales extends CommonObject $this->ref = $this->label; } - $label = img_picto('', 'tax').''.$langs->trans("SocialContribution").''; + $label = img_picto('', $this->picto, 'class="pictofixedwidth"').''.$langs->trans("SocialContribution").''; if (isset($this->paye)) { $label .= ' '.$this->getLibStatut(5); } diff --git a/htdocs/compta/sociales/list.php b/htdocs/compta/sociales/list.php index 297dc3f7de5..ed92d834488 100644 --- a/htdocs/compta/sociales/list.php +++ b/htdocs/compta/sociales/list.php @@ -45,6 +45,7 @@ $langs->loadLangs(array('compta', 'banks', 'bills', 'hrm', 'projects')); $action = GETPOST('action', 'aZ09'); $massaction = GETPOST('massaction', 'alpha'); $confirm = GETPOST('confirm', 'alpha'); +$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list $optioncss = GETPOST('optioncss', 'alpha'); $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'sclist'; $mode = GETPOST('mode', 'alpha'); @@ -126,6 +127,7 @@ if ($user->socid) { $socid = $user->socid; } $result = restrictedArea($user, 'tax', '', 'chargesociales', 'charges'); +$permissiontodelete = $user->rights->tax->charges->supprimer; /* @@ -170,7 +172,14 @@ if (empty($reshook)) { $search_type = ''; $search_account = ''; $search_array_options = array(); + $toselect = array(); } + + // Mass actions + $objectclass = 'ChargeSociales'; + $objectlabel = 'ChargeSociales'; + $uploaddir = $conf->tax->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } /* @@ -188,6 +197,8 @@ if (isModEnabled('project')) { llxHeader('', $langs->trans("SocialContributions")); +$arrayofselected = is_array($toselect) ? $toselect : array(); + $sql = "SELECT cs.rowid, cs.fk_type as type, cs.fk_user,"; $sql .= " cs.amount, cs.date_ech, cs.libelle as label, cs.paye, cs.periode, cs.fk_account,"; if (isModEnabled('project')) { @@ -378,6 +389,15 @@ if ($user->rights->tax->charges->creer) { $newcardbutton .= dolGetButtonTitle($langs->trans('MenuNewSocialContribution'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/compta/sociales/card.php?action=create'); } + +// List of mass actions available +$arrayofmassactions = array(); +if (!empty($permissiontodelete)) { + $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); +} +$massactionbutton = $form->selectMassAction('', $arrayofmassactions); +$moreforfilter = ''; + print ''; if ($optioncss != '') { print ''; @@ -394,7 +414,7 @@ print ''; $center = ''; -print_barre_liste($langs->trans("SocialContributions"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $center, $num, $nbtotalofrecords, 'bill', 0, $newcardbutton, '', $limit, 0, 0, 1); +print_barre_liste($langs->trans("SocialContributions"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'bill', 0, $newcardbutton, '', $limit, 0, 0, 1); if (empty($mysoc->country_id) && empty($mysoc->country_code)) { print '
'; @@ -408,8 +428,6 @@ if (empty($mysoc->country_id) && empty($mysoc->country_code)) { $db->close(); } -$moreforfilter = ''; -$massactionbutton = ''; $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); // This also change content of $arrayfields @@ -417,6 +435,10 @@ if ($massactionbutton) { $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); } +$objecttmp = new ChargeSociales($db); +$trackid = 'sc'.$object->id; +include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; + print '
'; print '
'."\n"; @@ -619,7 +641,7 @@ while ($i < $imaxinloop) { } // Output Kanban $chargesociale_static->fk_project = $projectstatic->getNomUrl(); - print $chargesociale_static->getKanbanView(''); + print $chargesociale_static->getKanbanView('', array('selected' => in_array($chargesociale_static->id, $arrayofselected))); if ($i == ($imaxinloop - 1)) { print ''; print ''; @@ -630,7 +652,15 @@ while ($i < $imaxinloop) { // Action column if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; + print ''; } // Line number @@ -774,7 +804,15 @@ while ($i < $imaxinloop) { // Action column if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; + print ''; } if (!$i) { $totalarray['nbfield']++; diff --git a/htdocs/contact/canvas/actions_contactcard_common.class.php b/htdocs/contact/canvas/actions_contactcard_common.class.php index 7e73d264480..3c82ae4f99b 100644 --- a/htdocs/contact/canvas/actions_contactcard_common.class.php +++ b/htdocs/contact/canvas/actions_contactcard_common.class.php @@ -86,7 +86,7 @@ abstract class ActionsContactCardCommon * * @param string $action Type of action * @param int $id Id - * @return string HTML output + * @return void */ public function assign_values(&$action, $id) { diff --git a/htdocs/contact/canvas/default/actions_contactcard_default.class.php b/htdocs/contact/canvas/default/actions_contactcard_default.class.php index f126b8c32a0..20be2b468b4 100644 --- a/htdocs/contact/canvas/default/actions_contactcard_default.class.php +++ b/htdocs/contact/canvas/default/actions_contactcard_default.class.php @@ -83,7 +83,6 @@ class ActionsContactCardDefault extends ActionsContactCardCommon public function assign_values(&$action, $id) { // phpcs:enable - global $limit, $offset, $sortfield, $sortorder; global $conf, $db, $langs, $user; global $form; diff --git a/htdocs/contrat/agenda.php b/htdocs/contrat/agenda.php index 1c3cc066038..4984e940bad 100644 --- a/htdocs/contrat/agenda.php +++ b/htdocs/contrat/agenda.php @@ -23,6 +23,7 @@ */ require "../main.inc.php"; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/contract.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 2817cfc406a..7a8fb3114fc 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -56,6 +56,7 @@ $langs->loadLangs(array("contracts", "orders", "companies", "bills", "products", $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); $cancel = GETPOST('cancel', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); $socid = GETPOST('socid', 'int'); $id = GETPOST('id', 'int'); @@ -1135,10 +1136,10 @@ if ($action == 'create') { print ''; print ''; - print ''; print ''."\n"; print ''; + print ''; print dol_get_fiche_head(); @@ -1350,6 +1351,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; } // Contract card @@ -1490,6 +1492,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; print ''; print ''; @@ -1808,7 +1811,7 @@ if ($action == 'create') { $moreparam = 'style="display: none;"'; } print ''; - print ''; + print ''; print "\n"; } @@ -1914,6 +1917,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; print ''; print ''; print ''; @@ -1973,6 +1977,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; print '
'; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($chargesociale_static->id, $arrayofselected)) { + $selected = 1; + } + print ''; + } + print ''; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($chargesociale_static->id, $arrayofselected)) { + $selected = 1; + } + print ''; + } + print '


'; @@ -2038,6 +2043,7 @@ if ($action == 'create') { + '; print '
'; diff --git a/htdocs/core/ajax/objectonoff.php b/htdocs/core/ajax/objectonoff.php index 77cd3234cd8..54344da699e 100644 --- a/htdocs/core/ajax/objectonoff.php +++ b/htdocs/core/ajax/objectonoff.php @@ -18,7 +18,7 @@ /** * \file htdocs/core/ajax/objectonoff.php * \brief File to set status for an object - * This Ajax service is called when option MAIN_DIRECT_STATUS_UPDATE is set. + * This Ajax service is oftenly called when option MAIN_DIRECT_STATUS_UPDATE is set. */ if (!defined('NOTOKENRENEWAL')) { @@ -53,15 +53,34 @@ $format = 'int'; $object = new GenericObject($db); -$tablename = $element; -if ($tablename == 'websitepage') { - $tablename = 'website_page'; -} +$tmparray = explode('@', $element); +if (empty($tmparray[1])) { + $subelement = ''; -$object->table_element = $tablename; + $object->module = $element; + $object->element = $element; + $object->table_element = $element; + + // Special case for compatibility + if ($object->table_element == 'websitepage') { + $object->table_element = 'website_page'; + } +} else { + $element = $tmparray[0]; + $subelement = $tmparray[1]; + + $object->module = $element; + $object->element = $subelement; + $object->table_element = $object->module.'_'.$object->element; +} $object->id = $id; $object->fields[$field] = array('type' => $format, 'enabled' => 1); +$module = $object->module; +$element = $object->element; + +//var_dump($object->module); var_dump($object->element); var_dump($object->table_element); + // Security check if (!empty($user->socid)) { $socid = $user->socid; @@ -70,12 +89,20 @@ if (!empty($user->socid)) { //$user->hasRight('societe', 'lire') = 0;$user->rights->fournisseur->lire = 0; //restrictedArea($user, 'societe', $id); -if (in_array($field, array('status'))) { - restrictedArea($user, $element, $id); +// We check permission. +// Check is done on $user->rights->element->create or $user->rights->element->subelement->create (because $action = 'set') +if (preg_match('/status$/', $field)) { + $module = $object->module; + $element = $object->element; + $usesublevelpermission = ($module != $element ? $element : ''); + if ($usesublevelpermission && !isset($user->rights->$module->$element)) { // There is no permission on object defined, we will check permission on module directly + $usesublevelpermission = ''; + } + restrictedArea($user, $object->module, $object, $object->table_element, $usesublevelpermission); } elseif ($element == 'product' && in_array($field, array('tosell', 'tobuy', 'tobatch'))) { // Special case for products - restrictedArea($user, 'produit|service', $id, 'product&product', '', '', 'rowid'); + restrictedArea($user, 'produit|service', $object, 'product&product', '', '', 'rowid'); } else { - httponly_accessforbidden("Bad value for combination of parameters element/field."); + httponly_accessforbidden("Bad value for combination of parameters element/field."); // This includes the exit. } @@ -89,7 +116,7 @@ print ''; print load_fiche_titre($langs->trans($title), $morehtmlright, '', 0, 0, 'showlinkedobjectblock'); @@ -8885,20 +8895,19 @@ class Form $res = @include dol_buildpath('core/tpl/objectlinked_lineimport.tpl.php'); } - print '
'; - - return $nbofdifferenttypes; } + + return $nbofdifferenttypes; } /** * Show block with links to link to other objects. * - * @param CommonObject $object Object we want to show links to - * @param array $restrictlinksto Restrict links to some elements, for exemple array('order') or array('supplier_order'). null or array() if no restriction. - * @param array $excludelinksto Do not show links of this type, for exemple array('order') or array('supplier_order'). null or array() if no exclusion. - * @return string <0 if KO, >0 if OK + * @param CommonObject $object Object we want to show links to + * @param array $restrictlinksto Restrict links to some elements, for exemple array('order') or array('supplier_order'). null or array() if no restriction. + * @param array $excludelinksto Do not show links of this type, for exemple array('order') or array('supplier_order'). null or array() if no exclusion. + * @return string HTML block */ public function showLinkToObjectBlock($object, $restrictlinksto = array(), $excludelinksto = array()) { @@ -10211,9 +10220,9 @@ class Form $out .= ''; } - return $out; - $this->db->free($resql); + + return $out; } else { dol_print_error($this->db); return ''; diff --git a/htdocs/core/class/html.formcompany.class.php b/htdocs/core/class/html.formcompany.class.php index e2a1cafcb3d..d2fda62ae97 100644 --- a/htdocs/core/class/html.formcompany.class.php +++ b/htdocs/core/class/html.formcompany.class.php @@ -989,15 +989,15 @@ class FormCompany extends Form // phpcs:enable $tax = get_localtax_by_third($local); - $num = $this->db->num_rows($tax); - $i = 0; - if ($num) { + if ($tax) { $valors = explode(":", $tax); + $nbvalues = count($valors); - if (count($valors) > 1) { + if ($nbvalues > 1) { //montar select print ''; + print ''; } } } diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php index e2f0e984ab1..28b4e21fdd4 100644 --- a/htdocs/core/class/html.formprojet.class.php +++ b/htdocs/core/class/html.formprojet.class.php @@ -58,7 +58,7 @@ class FormProjets // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Output a combo list with projects qualified for a third party / user + * Output a combo list with projects qualified for a third party / user * * @param int $socid Id third party (-1=all, 0=only projects not linked to a third party, id=projects not linked or linked to third party id) * @param string|Project $selected Id of preselected project or Project (or ''). Note: If you know the ref, you can also provide it into $selected_input_value to save one request in some cases. @@ -145,7 +145,7 @@ class FormProjets * @param int $htmlid Html id to use instead of htmlname * @param string $morecss More CSS * @param string $morefilter More filters (Must be a sql sanitized string) - * @return int Nb of project if OK, <0 if KO + * @return int|string|array HTML string or array of option or <0 if KO */ public function select_projects_list($socid = -1, $selected = '', $htmlname = 'projectid', $maxlength = 24, $option_only = 0, $show_empty = 1, $discard_closed = 0, $forcefocus = 0, $disabled = 0, $mode = 0, $filterkey = '', $nooutput = 0, $forceaddid = 0, $htmlid = '', $morecss = 'maxwidth500', $morefilter = '') { diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index 40dec1870a4..13afc43cb51 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -339,7 +339,7 @@ class FormSetup * Method used to test module builder convertion to this form usage * * @param array $params an array of arrays of params from old modulBuilder params - * @return void + * @return boolean */ public function addItemsFromParamsArray($params) { @@ -347,6 +347,7 @@ class FormSetup foreach ($params as $confKey => $param) { $this->addItemFromParams($confKey, $param); // todo manage error } + return true; } diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php index 3f3a038b88c..2257e563865 100644 --- a/htdocs/core/class/html.formticket.class.php +++ b/htdocs/core/class/html.formticket.class.php @@ -701,7 +701,7 @@ class FormTicket { global $langs, $user; - $selected = is_array($selected) ? $selected : (!empty($selected) ? array($selected) : array()); + $selected = is_array($selected) ? $selected : (!empty($selected) ? explode(',', $selected) : array()); $ticketstat = new Ticket($this->db); dol_syslog(get_class($this) . "::select_types_tickets " . implode(';', $selected) . ", " . $htmlname . ", " . $filtertype . ", " . $format . ", " . $multiselect, LOG_DEBUG); diff --git a/htdocs/core/customreports.php b/htdocs/core/customreports.php index 5273a37bc24..bea2b5a7349 100644 --- a/htdocs/core/customreports.php +++ b/htdocs/core/customreports.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2020-2023 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -98,7 +98,7 @@ $arrayoftype = array( 'proposal' => array('label' => 'Proposals', 'picto'=>'proposal', 'ObjectClassName' => 'Propal', 'enabled' => isModEnabled('propal'), 'ClassPath' => "/comm/propal/class/propal.class.php"), 'order' => array('label' => 'Orders', 'picto'=>'order', 'ObjectClassName' => 'Commande', 'enabled' => isModEnabled('commande'), 'ClassPath' => "/commande/class/commande.class.php"), 'invoice' => array('langs'=>'facture', 'label' => 'Invoices', 'picto'=>'bill', 'ObjectClassName' => 'Facture', 'enabled' => isModEnabled('facture'), 'ClassPath' => "/compta/facture/class/facture.class.php"), - 'invoice_template'=>array('langs'=>'facture', 'label' => 'PredefinedInvoices', 'picto'=>'bill', 'ObjectClassName' => 'FactureRec', 'enabled' => isModEnabled('facture'), 'ClassPath' => "/compta/class/facturerec.class.php", 'langs'=>'bills'), + 'invoice_template'=>array('label' => 'PredefinedInvoices', 'picto'=>'bill', 'ObjectClassName' => 'FactureRec', 'enabled' => isModEnabled('facture'), 'ClassPath' => "/compta/class/facturerec.class.php", 'langs'=>'bills'), 'contract' => array('label' => 'Contracts', 'picto'=>'contract', 'ObjectClassName' => 'Contrat', 'enabled' => isModEnabled('contrat'), 'ClassPath' => "/contrat/class/contrat.class.php", 'langs'=>'contracts'), 'contractdet' => array('label' => 'ContractLines', 'picto'=>'contract', 'ObjectClassName' => 'ContratLigne', 'enabled' => isModEnabled('contrat'), 'ClassPath' => "/contrat/class/contrat.class.php", 'langs'=>'contracts'), 'bom' => array('label' => 'BOM', 'picto'=>'bom', 'ObjectClassName' => 'Bom', 'enabled' => isModEnabled('bom')), diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index 593fa770536..e36fc547fa0 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -935,17 +935,17 @@ class DoliDBMysqli extends DoliDB if ($field_desc['null'] == 'not null' || $field_desc['null'] == 'NOT NULL') { // We will try to change format of column to NOT NULL. To be sure the ALTER works, we try to update fields that are NULL if ($field_desc['type'] == 'varchar' || $field_desc['type'] == 'text') { - $sqlbis = "UPDATE ".$table." SET ".$field_name." = '".$this->escape($field_desc['default'] ? $field_desc['default'] : '')."' WHERE ".$field_name." IS NULL"; + $sqlbis = "UPDATE ".$table." SET ".$field_name." = '".$this->escape(isset($field_desc['default']) ? $field_desc['default'] : '')."' WHERE ".$field_name." IS NULL"; $this->query($sqlbis); } elseif ($field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int') { - $sqlbis = "UPDATE ".$table." SET ".$field_name." = ".((int) $this->escape($field_desc['default'] ? $field_desc['default'] : 0))." WHERE ".$field_name." IS NULL"; + $sqlbis = "UPDATE ".$table." SET ".$field_name." = ".((int) $this->escape(isset($field_desc['default']) ? $field_desc['default'] : 0))." WHERE ".$field_name." IS NULL"; $this->query($sqlbis); } $sql .= " NOT NULL"; } - if ($field_desc['default'] != '') { + if (isset($field_desc['default']) && $field_desc['default'] != '') { if ($field_desc['type'] == 'double' || $field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int') { $sql .= " DEFAULT ".$this->escape($field_desc['default']); } elseif ($field_desc['type'] != 'text') { diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php index 069afeca4ff..610f9925546 100644 --- a/htdocs/core/db/pgsql.class.php +++ b/htdocs/core/db/pgsql.class.php @@ -1183,7 +1183,7 @@ class DoliDBPgsql extends DoliDB $sql = "ALTER TABLE ".$table." ADD ".$field_name." "; $sql .= $field_desc['type']; if (preg_match("/^[^\s]/i", $field_desc['value'])) { - if (!in_array($field_desc['type'], array('int', 'date', 'datetime')) && $field_desc['value']) { + if (!in_array($field_desc['type'], array('smallint', 'int', 'date', 'datetime')) && $field_desc['value']) { $sql .= "(".$field_desc['value'].")"; } } @@ -1225,23 +1225,25 @@ class DoliDBPgsql extends DoliDB { // phpcs:enable $sql = "ALTER TABLE ".$table; - $sql .= " MODIFY COLUMN ".$field_name." ".$field_desc['type']; - if (in_array($field_desc['type'], array('double', 'varchar')) && $field_desc['value']) { - $sql .= "(".$field_desc['value'].")"; + $sql .= " ALTER COLUMN '".$this->escape($field_name)."' TYPE ".$field_desc['type']; + if (preg_match("/^[^\s]/i", $field_desc['value'])) { + if (!in_array($field_desc['type'], array('smallint', 'int', 'date', 'datetime')) && $field_desc['value']) { + $sql .= "(".$field_desc['value'].")"; + } } if ($field_desc['null'] == 'not null' || $field_desc['null'] == 'NOT NULL') { // We will try to change format of column to NOT NULL. To be sure the ALTER works, we try to update fields that are NULL if ($field_desc['type'] == 'varchar' || $field_desc['type'] == 'text') { - $sqlbis = "UPDATE ".$table." SET ".$field_name." = '".$this->escape($field_desc['default'] ? $field_desc['default'] : '')."' WHERE ".$field_name." IS NULL"; + $sqlbis = "UPDATE ".$table." SET ".$this->escape($field_name)." = '".$this->escape(isset($field_desc['default']) ? $field_desc['default'] : '')."' WHERE ".$this->escape($field_name)." IS NULL"; $this->query($sqlbis); } elseif ($field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int') { - $sqlbis = "UPDATE ".$table." SET ".$field_name." = ".((int) $this->escape($field_desc['default'] ? $field_desc['default'] : 0))." WHERE ".$field_name." IS NULL"; + $sqlbis = "UPDATE ".$table." SET ".$this->escape($field_name)." = ".((int) $this->escape(isset($field_desc['default']) ? $field_desc['default'] : 0))." WHERE ".$this->escape($field_name)." IS NULL"; $this->query($sqlbis); } } - if ($field_desc['default'] != '') { + if (isset($field_desc['default']) && $field_desc['default'] != '') { if ($field_desc['type'] == 'double' || $field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int') { $sql .= " DEFAULT ".$this->escape($field_desc['default']); } elseif ($field_desc['type'] != 'text') { diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index fde2a988cf7..25aee10e2f3 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -696,8 +696,8 @@ function ajax_constantonoff($code, $input = array(), $entity = null, $revertonof * @param Object $object Object to set * @param string $code Name of property in object : 'status' or 'status_buy' for product by example * @param string $field Name of database field : 'tosell' or 'tobuy' for product by example - * @param string $text_on Text if on - * @param string $text_off Text if off + * @param string $text_on Text if on ('Text' or 'Text:css picto on') + * @param string $text_off Text if off ('Text' or 'Text:css picto on') * @param array $input Array of type->list of CSS element to switch. Example: array('disabled'=>array(0=>'cssid')) * @param string $morecss More CSS * @param string $htmlname Name of HTML component. Keep '' or use a different value if you need to use this component several time on same page for same property. @@ -710,6 +710,7 @@ function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input = if (empty($htmlname)) { $htmlname = $code; } + //var_dump($object->module); var_dump($object->element); $out = ''; - $out .= ''.img_picto($langs->trans($text_off), 'switch_off').''; - $out .= ''.img_picto($langs->trans($text_on), 'switch_on').''; + + $switchon = 'switch_on'; + $switchoff = 'switch_off'; + $tmparray = explode(':', $text_on); + if (!empty($tmparray[1])) { + $text_on = $tmparray[0]; + $switchon = $tmparray[1]; + } + $tmparray = explode(':', $text_off); + if (!empty($tmparray[1])) { + $text_off = $tmparray[0]; + $switchoff = $tmparray[1]; + } + + $out .= ''.img_picto($langs->trans($text_off), $switchoff).''; + $out .= ''.img_picto($langs->trans($text_on), $switchon).''; return $out; } diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index f35561d25a1..04874dd9d90 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -703,10 +703,10 @@ function currency_name($code_iso, $withcode = '', $outputlangs = null) } /** - * Retourne le nom traduit de la forme juridique + * Return the name translated of juridical status * - * @param string $code Code de la forme juridique - * @return string Nom traduit du pays + * @param string $code Code of juridical status + * @return string Value of the juridical status */ function getFormeJuridiqueLabel($code) { @@ -717,20 +717,24 @@ function getFormeJuridiqueLabel($code) } $sql = "SELECT libelle FROM ".MAIN_DB_PREFIX."c_forme_juridique"; - $sql .= " WHERE code='".$db->escape($code)."'"; + $sql .= " WHERE code = '".$db->escape($code)."'"; dol_syslog("Company.lib::getFormeJuridiqueLabel", LOG_DEBUG); + $resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); - if ($num) { $obj = $db->fetch_object($resql); + $label = ($obj->libelle != '-' ? $obj->libelle : ''); - return $label; + + return $langs->trans($label); } else { return $langs->trans("NotDefined"); } + } else { + return 'Error '.$db->lasterror(); } } @@ -1494,7 +1498,7 @@ function show_actions_todo($conf, $langs, $db, $filterobj, $objcon = '', $noprin */ function show_actions_done($conf, $langs, $db, $filterobj, $objcon = '', $noprint = 0, $actioncode = '', $donetodo = 'done', $filters = array(), $sortfield = 'a.datep,a.id', $sortorder = 'DESC', $module = '') { - global $user, $conf; + global $user, $conf, $hookmanager; global $form; global $param, $massactionbutton; @@ -1541,8 +1545,6 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon = '', $noprin $sql = ''; if (isModEnabled('agenda')) { - require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($db); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('agendadao')); @@ -2238,8 +2240,7 @@ function addEventTypeSQL(&$sql, $actioncode, $sqlANDOR = "AND") */ function addOtherFilterSQL(&$sql, $donetodo, $now, $filters) { - global $conf, $db; - // Condition on actioncode + global $db; if ($donetodo == 'todo') { $sql .= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep > '".$db->idate($now)."'))"; @@ -2266,12 +2267,10 @@ function addOtherFilterSQL(&$sql, $donetodo, $now, $filters) */ function addMailingEventTypeSQL($actioncode, $objcon, $filterobj) { - global $conf, $langs, $db; - // Add also event from emailings. TODO This should be replaced by an automatic event ? May be it's too much for very large emailing. - if (isModEnabled('mailing') && !empty($objcon->email) - && (empty($actioncode) || $actioncode == 'AC_OTH_AUTO' || $actioncode == 'AC_EMAILING')) { - $langs->load("mails"); + global $db; + // Add also event from emailings. TODO This should be replaced by an automatic event ? May be it's too much for very large emailing. + if (isModEnabled('mailing') && !empty($objcon->email) && (empty($actioncode) || $actioncode == 'AC_OTH_AUTO' || $actioncode == 'AC_EMAILING')) { $sql2 = "SELECT m.rowid as id, m.titre as label, mc.date_envoi as dp, mc.date_envoi as dp2, '100' as percent, 'mailing' as type"; $sql2 .= ", null as fk_element, '' as elementtype, null as contact_id"; $sql2 .= ", 'AC_EMAILING' as acode, '' as alabel, '' as apicto"; @@ -2292,6 +2291,9 @@ function addMailingEventTypeSQL($actioncode, $objcon, $filterobj) $sql2 .= " AND mc.statut = 1"; $sql2 .= " AND u.rowid = m.fk_user_valid"; $sql2 .= " AND mc.fk_mailing=m.rowid"; + return $sql2; + } else { + return ''; } } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 0c0a721a4ea..918046fc218 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4134,7 +4134,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'off', 'on', 'order', 'paiment', 'paragraph', 'play', 'pdf', 'phone', 'phoning', 'phoning_mobile', 'phoning_fax', 'playdisabled', 'previous', 'poll', 'pos', 'printer', 'product', 'propal', 'proposal', 'puce', 'stock', 'resize', 'service', 'stats', 'trip', - 'security', 'setup', 'share-alt', 'sign-out', 'split', 'stripe', 'stripe-s', 'switch_off', 'switch_on', 'switch_on_red', 'tools', 'unlink', 'uparrow', 'user', 'user-tie', 'vcard', 'wrench', + 'security', 'setup', 'share-alt', 'sign-out', 'split', 'stripe', 'stripe-s', 'switch_off', 'switch_on', 'switch_on_warning', 'switch_on_red', 'tools', 'unlink', 'uparrow', 'user', 'user-tie', 'vcard', 'wrench', 'github', 'google', 'jabber', 'microsoft', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'youtube', 'google-plus-g', 'whatsapp', 'chevron-left', 'chevron-right', 'chevron-down', 'chevron-top', 'commercial', 'companies', 'generic', 'home', 'hrm', 'members', 'products', 'invoicing', @@ -4180,7 +4180,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'member'=>'user-alt', 'meeting'=>'chalkboard-teacher', 'mrp'=>'cubes', 'next'=>'arrow-alt-circle-right', 'trip'=>'wallet', 'expensereport'=>'wallet', 'group'=>'users', 'movement'=>'people-carry', 'sign-out'=>'sign-out-alt', - 'switch_off'=>'toggle-off', 'switch_on'=>'toggle-on', 'switch_on_red'=>'toggle-on', 'check'=>'check', 'bookmark'=>'star', + 'switch_off'=>'toggle-off', 'switch_on'=>'toggle-on', 'switch_on_warning'=>'toggle-on', 'switch_on_red'=>'toggle-on', 'check'=>'check', 'bookmark'=>'star', 'bank'=>'university', 'close_title'=>'times', 'delete'=>'trash', 'filter'=>'filter', 'list-alt'=>'list-alt', 'calendarlist'=>'bars', 'calendar'=>'calendar-alt', 'calendarmonth'=>'calendar-alt', 'calendarweek'=>'calendar-week', 'calendarday'=>'calendar-day', 'calendarperuser'=>'table', 'intervention'=>'ambulance', 'invoice'=>'file-invoice-dollar', 'currency'=>'dollar-sign', 'multicurrency'=>'dollar-sign', 'order'=>'file-invoice', @@ -4264,7 +4264,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'members'=>'infobox-adherent', 'member'=>'infobox-adherent', 'money-bill-alt'=>'infobox-bank_account', 'order'=>'infobox-commande', 'user'=>'infobox-adherent', 'users'=>'infobox-adherent', - 'error'=>'pictoerror', 'warning'=>'pictowarning', 'switch_on'=>'font-status4', 'switch_on_red'=>'font-status8', + 'error'=>'pictoerror', 'warning'=>'pictowarning', 'switch_on'=>'font-status4', 'switch_on_warning'=>'font-status4 warning', 'switch_on_red'=>'font-status8', 'holiday'=>'infobox-holiday', 'info'=>'opacityhigh', 'invoice'=>'infobox-commande', 'knowledgemanagement'=>'infobox-contrat rotate90', 'loan'=>'infobox-bank_account', 'payment'=>'infobox-bank_account', 'payment_vat'=>'infobox-bank_account', 'poll'=>'infobox-adherent', 'pos'=>'infobox-bank_account', 'project'=>'infobox-project', 'projecttask'=>'infobox-project', @@ -6190,30 +6190,30 @@ function isOnlyOneLocalTax($local) /** * Get values of localtaxes (1 or 2) for company country for the common vat with the highest value * - * @param int $local LocalTax to get - * @return number Values of localtax + * @param int $local LocalTax to get + * @return string Values of localtax (Can be '20', '-19:-15:-9') */ function get_localtax_by_third($local) { global $db, $mysoc; - $sql = "SELECT t.localtax1, t.localtax2 "; - $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t inner join ".MAIN_DB_PREFIX."c_country as c ON c.rowid=t.fk_pays"; - $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND t.active = 1 AND t.taux=("; - $sql .= " SELECT max(tt.taux) FROM ".MAIN_DB_PREFIX."c_tva as tt inner join ".MAIN_DB_PREFIX."c_country as c ON c.rowid=tt.fk_pays"; - $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND tt.active = 1"; - $sql .= " )"; + + $sql = " SELECT t.localtax".$local." as localtax"; + $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t INNER JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = t.fk_pays"; + $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND t.active = 1 AND t.taux = ("; + $sql .= "SELECT MAX(tt.taux) FROM ".MAIN_DB_PREFIX."c_tva as tt INNER JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = tt.fk_pays"; + $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND tt.active = 1)"; + $sql .= " AND t.localtax".$local."_type <> '0'"; + $sql .= " ORDER BY t.rowid DESC"; $resql = $db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); - if ($local == 1) { - return $obj->localtax1; - } elseif ($local == 2) { - return $obj->localtax2; - } + return $obj->localtax; + } else { + return 'Error'; } - return 0; + return '0'; } @@ -6322,10 +6322,12 @@ function getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisi } $sql .= ", ".MAIN_DB_PREFIX."c_country as c"; - if ($mysoc->country_code == 'ES') { - $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($buyer->country_code)."'"; // local tax in spain use the buyer country ?? + if (!empty($mysoc) && $mysoc->country_code == 'ES') { + $countrycodetouse = ((empty($buyer) || empty($buyer->country_code)) ? $mysoc->country_code : $buyer->country_code); + $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($countrycodetouse)."'"; // local tax in spain use the buyer country ?? } else { - $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(empty($seller->country_code) ? $mysoc->country_code : $seller->country_code)."'"; + $countrycodetouse = ((empty($seller) || empty($seller->country_code)) ? $mysoc->country_code : $seller->country_code); + $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($countrycodetouse)."'"; } $sql .= " AND t.taux = ".((float) $vatratecleaned)." AND t.active = 1"; if ($vatratecode) { @@ -10888,8 +10890,8 @@ function dolGetStatus($statusLabel = '', $statusLabelShort = '', $html = '', $st * * @param string $label Label or tooltip of button. Also used as tooltip in title attribute. Can be escaped HTML content or full simple text. * @param string $text Optional : short label on button. Can be escaped HTML content or full simple text. - * @param string $actionType 'default', 'delete', 'danger' - * @param string $url Url for link + * @param string $actionType 'default', 'delete', 'danger', 'email', ... + * @param string|array $url Url for link or array of subbutton description * @param string $id Attribute id of button * @param int|boolean $userRight User action right * // phpcs:disable @@ -10916,7 +10918,26 @@ function dolGetButtonAction($label, $text = '', $actionType = 'default', $url = { global $hookmanager, $action, $object, $langs; - //var_dump($params); + // If $url is an array, we must build a dropdown button + if (is_array($url)) { + $out = '"; + + return $out; + } + + // If $url is a simple link if (!empty($params['isDropdown'])) $class = "dropdown-item"; else { diff --git a/htdocs/core/lib/modulebuilder.lib.php b/htdocs/core/lib/modulebuilder.lib.php index d706b7cabaa..26b5437aacc 100644 --- a/htdocs/core/lib/modulebuilder.lib.php +++ b/htdocs/core/lib/modulebuilder.lib.php @@ -529,3 +529,94 @@ function reWriteAllPermissions($file, $permissions, $key, $right, $action) return 1; } } + +/** + * Write all properties of the object in AsciiDoc format + * @param string $file path of the class + * @param string $objectname name of the objectClass + * @param string $destfile file where write table of properties + * @return int 1 if OK, -1 if KO + */ +function writePropsInAsciiDoc($file, $objectname, $destfile) +{ + + // stock all properties in array + $attributesUnique = array ('label', 'type', 'arrayofkeyval', 'notnull', 'default', 'index', 'foreignkey', 'position', 'enabled', 'visible', 'noteditable', 'alwayseditable', 'searchall', 'isameasure', 'css','cssview','csslist', 'help', 'showoncombobox', 'validate','comment','picto' ); + + $start = "public \$fields=array("; + $end = ");"; + $i = 1; + $keys = array(); + $lines = file($file); + // Search for start and end lines + foreach ($lines as $i => $line) { + if (strpos($line, $start) !== false) { + // Copy lines until the end on array + while (($line = $lines[++$i]) !== false) { + if (strpos($line, $end) !== false) { + break; + } + $keys[] = $line; + } + break; + } + } + // write the begin of table with specifics options + $table = "== DATA SPECIFICATIONS\n"; + $table .= "== Table of fields and their properties for object *$objectname* : \n"; + $table .= "[options='header',grid=rows,frame=topbot,width=100%,caption=Organisation]\n"; + $table .= "|===\n"; + $table .= "|code"; + // write all properties in the header of the table + foreach ($attributesUnique as $attUnique) { + $table .= "|".$attUnique; + } + $table .="\n"; + $countKeys = count($keys); + for ($j=0;$j<$countKeys;$j++) { + $string = $keys[$j]; + $string = trim($string, "'"); + $string = rtrim($string, ","); + + $array = []; + eval("\$array = [$string];"); + + // check if is array after cleaning string + if (!is_array($array)) { + return -1; + } + // name of field + $field = array_keys($array); + // all values of each property + $values = array_values($array); + + + // check each field has all properties and add it if missed + if (count($values[0]) <=22) { + foreach ($attributesUnique as $cle) { + if (!in_array($cle, array_keys($values[0]))) { + $values[0][$cle] = ''; + } + } + } + + //reorganize $values with order attributeUnique + $valuesRestructured = array(); + foreach ($attributesUnique as $key) { + if (array_key_exists($key, $values[0])) { + $valuesRestructured[$key] = $values[0][$key]; + } + } + // write all values of properties for each field + $table .= "|*".$field[0]."*|"; + $table .= implode("|", array_values($valuesRestructured))."\n"; + } + // end table + $table .= "|==="; + //write in file + $writeInFile = dolReplaceInFile($destfile, array('== DATA SPECIFICATIONS'=> $table)); + if ($writeInFile<0) { + return -1; + } + return 1; +} diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 25b34f0493d..2a38906e4de 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -1071,10 +1071,10 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t } //Check if Extrafields is totalizable - foreach ($extrafields->attributes['projet_task']['totalizable'] as $key=>$value){ - if ($arrayfields['ef.'.$key]['checked'] == 1){ + foreach ($extrafields->attributes['projet_task']['totalizable'] as $key=>$value) { + if ($arrayfields['ef.'.$key]['checked'] == 1) { print ''; diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 1f7b9404a7c..63202c693e4 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -485,7 +485,7 @@ function restrictedArea(User $user, $features, $object = 0, $tableandshare = '', $readok = 0; $nbko++; } - } elseif (!empty($feature2)) { // This is for permissions on 2 levels + } elseif (!empty($feature2)) { // This is for permissions on 2 levels (module->object->read) $tmpreadok = 1; foreach ($feature2 as $subfeature) { if ($subfeature == 'user' && $user->id == $objectid) { @@ -504,7 +504,7 @@ function restrictedArea(User $user, $features, $object = 0, $tableandshare = '', $readok = 0; // All tests are ko (we manage here the and, the or will be managed later using $nbko). $nbko++; } - } elseif (!empty($feature) && ($feature != 'user' && $feature != 'usergroup')) { // This is permissions on 1 level + } elseif (!empty($feature) && ($feature != 'user' && $feature != 'usergroup')) { // This is permissions on 1 level (module->read) if (empty($user->rights->$feature->lire) && empty($user->rights->$feature->read) && empty($user->rights->$feature->run)) { @@ -531,7 +531,7 @@ function restrictedArea(User $user, $features, $object = 0, $tableandshare = '', // Check write permission from module (we need to know write permission to create but also to delete drafts record or to upload files) $createok = 1; $nbko = 0; - $wemustcheckpermissionforcreate = (GETPOST('sendit', 'alpha') || GETPOST('linkit', 'alpha') || in_array(GETPOST('action', 'aZ09'), array('create', 'update', 'add_element_resource', 'confirm_delete_linked_resource')) || GETPOST('roworder', 'alpha', 2)); + $wemustcheckpermissionforcreate = (GETPOST('sendit', 'alpha') || GETPOST('linkit', 'alpha') || in_array(GETPOST('action', 'aZ09'), array('create', 'update', 'set', 'add_element_resource', 'confirm_delete_linked_resource')) || GETPOST('roworder', 'alpha', 2)); $wemustcheckpermissionfordeletedraft = ((GETPOST("action", "aZ09") == 'confirm_delete' && GETPOST("confirm", "aZ09") == 'yes') || GETPOST("action", "aZ09") == 'delete'); if ($wemustcheckpermissionforcreate || $wemustcheckpermissionfordeletedraft) { @@ -576,7 +576,7 @@ function restrictedArea(User $user, $features, $object = 0, $tableandshare = '', $createok = 0; $nbko++; } - } elseif (!empty($feature2)) { // This is for permissions on one level + } elseif (!empty($feature2)) { // This is for permissions on 2 levels (module->object->write) foreach ($feature2 as $subfeature) { if ($subfeature == 'user' && $user->id == $objectid && $user->rights->user->self->creer) { continue; // User can edit its own card @@ -599,7 +599,7 @@ function restrictedArea(User $user, $features, $object = 0, $tableandshare = '', break; } } - } elseif (!empty($feature)) { // This is for permissions on 2 levels ('creer' or 'write') + } elseif (!empty($feature)) { // This is for permissions on 1 levels (module->write) //print '
feature='.$feature.' creer='.$user->rights->$feature->creer.' write='.$user->rights->$feature->write; exit; if (empty($user->rights->$feature->creer) && empty($user->rights->$feature->write) diff --git a/htdocs/core/lib/xcal.lib.php b/htdocs/core/lib/xcal.lib.php index 1bf83410088..57cbb0188a5 100644 --- a/htdocs/core/lib/xcal.lib.php +++ b/htdocs/core/lib/xcal.lib.php @@ -30,7 +30,7 @@ * @param string $desc Description of export * @param array $events_array Array of events ("uid","startdate","duration","enddate","title","summary","category","email","url","desc","author") * @param string $outputfile Output file - * @return int < 0 if ko, Nb of events in file if ok + * @return int < 0 if KO, Nb of events in file if OK */ function build_calfile($format, $title, $desc, $events_array, $outputfile) { @@ -43,6 +43,8 @@ function build_calfile($format, $title, $desc, $events_array, $outputfile) return -1; } + $nbevents = 0; + // Note: A cal file is an UTF8 encoded file $calfileh = fopen($outputfile, "w"); @@ -144,6 +146,8 @@ function build_calfile($format, $title, $desc, $events_array, $outputfile) */ if ($type === "event") { + $nbevents++; + fwrite($calfileh, "BEGIN:VEVENT\n"); fwrite($calfileh, "UID:".$uid."\n"); @@ -247,6 +251,8 @@ function build_calfile($format, $title, $desc, $events_array, $outputfile) // Output the vCard/iCal VJOURNAL object if ($type === "journal") { + $nbevents++; + fwrite($calfileh, "BEGIN:VJOURNAL\n"); fwrite($calfileh, "UID:".$uid."\n"); @@ -289,6 +295,8 @@ function build_calfile($format, $title, $desc, $events_array, $outputfile) dol_syslog("xcal.lib.php::build_calfile Failed to open file ".$outputfile." for writing"); return -2; } + + return $nbevents; } /** @@ -303,7 +311,7 @@ function build_calfile($format, $title, $desc, $events_array, $outputfile) * @param string $filter (optional) Filter * @param string $url Url (If empty, forge URL for agenda RSS export) * @param string $langcode Language code to show in header - * @return int < 0 if ko, Nb of events in file if ok + * @return int < 0 if KO, Nb of events in file if OK */ function build_rssfile($format, $title, $desc, $events_array, $outputfile, $filter = '', $url = '', $langcode = '') { @@ -317,6 +325,8 @@ function build_rssfile($format, $title, $desc, $events_array, $outputfile, $filt return -1; } + $nbevents = 0; + $fichier = fopen($outputfile, "w"); if ($fichier) { @@ -362,6 +372,8 @@ function build_rssfile($format, $title, $desc, $events_array, $outputfile, $filt } if ($eventqualified) { + $nbevents++; + if (is_object($event) && get_class($event) == 'WebsitePage') { // Convert object into an array $tmpevent = array(); @@ -426,6 +438,8 @@ function build_rssfile($format, $title, $desc, $events_array, $outputfile, $filt fclose($fichier); dolChmod($outputfile); } + + return $nbevents; } /** @@ -437,8 +451,6 @@ function build_rssfile($format, $title, $desc, $events_array, $outputfile, $filt */ function format_cal($format, $string) { - global $conf; - $newstring = $string; if ($format === "vcal") { diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index 417744bc49d..8be5531965c 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -481,11 +481,11 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left -- HRM - Holiday insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5000__+MAX_llx_menu__, 'hrm', 'hrm', 15__+MAX_llx_menu__, '/holiday/list.php?mainmenu=hrm&leftmenu=hrm', 'CPTitreMenu', 0, 'holiday', '$user->rights->holiday->read', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5001__+MAX_llx_menu__, 'hrm', '', 5000__+MAX_llx_menu__, '/holiday/card.php?mainmenu=hrm&action=create', 'New', 1, 'holiday', '$user->rights->holiday->write', '', 0, 1, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5001__+MAX_llx_menu__, 'hrm', '', 5000__+MAX_llx_menu__, '/holiday/card_group.php?mainmenu=hrm&action=create', 'NewHolidayForGroup', 1, 'holiday', '$user->rights->holiday->write', '', 0, 1, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5002__+MAX_llx_menu__, 'hrm', '', 5000__+MAX_llx_menu__, '/holiday/list.php?mainmenu=hrm&leftmenu=hrm', 'List', 1, 'holiday', '$user->rights->holiday->read', '', 0, 1, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5003__+MAX_llx_menu__, 'hrm', '', 5002__+MAX_llx_menu__, '/holiday/list.php?mainmenu=hrm&search_statut=2&leftmenu=hrm', 'ListToApprove', 2, 'trips', '$user->rights->holiday->read', '', 0, 1, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5004__+MAX_llx_menu__, 'hrm', '', 5000__+MAX_llx_menu__, '/holiday/define_holiday.php?mainmenu=hrm', 'MenuConfCP', 1, 'holiday', '$user->rights->holiday->define_holiday', '', 0, 2, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5005__+MAX_llx_menu__, 'hrm', '', 5000__+MAX_llx_menu__, '/holiday/view_log.php?mainmenu=hrm', 'MenuLogCP', 1, 'holiday', '$user->rights->holiday->define_holiday', '', 0, 3, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5002__+MAX_llx_menu__, 'hrm', '', 5000__+MAX_llx_menu__, '/holiday/card_group.php?mainmenu=hrm&action=create', 'NewHolidayForGroup', 1, 'holiday', '$user->rights->holiday->write', '', 0, 1, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5003__+MAX_llx_menu__, 'hrm', '', 5000__+MAX_llx_menu__, '/holiday/list.php?mainmenu=hrm&leftmenu=hrm', 'List', 1, 'holiday', '$user->rights->holiday->read', '', 0, 1, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5004__+MAX_llx_menu__, 'hrm', '', 5002__+MAX_llx_menu__, '/holiday/list.php?mainmenu=hrm&search_statut=2&leftmenu=hrm', 'ListToApprove', 2, 'trips', '$user->rights->holiday->read', '', 0, 1, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5005__+MAX_llx_menu__, 'hrm', '', 5000__+MAX_llx_menu__, '/holiday/define_holiday.php?mainmenu=hrm', 'MenuConfCP', 1, 'holiday', '$user->rights->holiday->define_holiday', '', 0, 2, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5006__+MAX_llx_menu__, 'hrm', '', 5000__+MAX_llx_menu__, '/holiday/view_log.php?mainmenu=hrm', 'MenuLogCP', 1, 'holiday', '$user->rights->holiday->define_holiday', '', 0, 3, __ENTITY__); -- HRM - Trips and expenses (old module) insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->deplacement->enabled', __HANDLER__, 'left', 2100__+MAX_llx_menu__, 'accountancy', 'tripsandexpenses', 15__+MAX_llx_menu__, '/compta/deplacement/index.php?mainmenu=accountancy&leftmenu=tripsandexpenses', 'TripsAndExpenses', 0, 'trips', '$user->rights->deplacement->lire', '', 0, 5, __ENTITY__); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 59c49f7fc7f..7c51180fe68 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1734,8 +1734,8 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef $langs->load('accountancy'); $journallabel = ''; if ($objp->label) { - $journallabelwithoutspan = $langs->transnoentities($objp->label); - $journallabel = '('.$langs->transnoentities($objp->label).')'; // Label of bank account in llx_accounting_journal + $journallabelwithoutspan = $langs->trans($objp->label); + $journallabel = '('.$langs->trans($objp->label).')'; // Label of bank account in llx_accounting_journal } $key = $langs->trans("AccountingJournalType".$objp->nature); // $objp->nature is 1, 2, 3 ... diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php index b6e38438a69..449bd69f17d 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -207,7 +207,7 @@ class pdf_eagle extends ModelePdfStockTransfer // Load traductions files required by page $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies", "propal", "deliveries", "sendings", "productbatch", "stocks", "stocktransfer@stocktransfer")); - $nblines = count($object->lines); + $nblines = is_array($object->lines) ? count($object->lines) : 0; // Loop on each lines to detect if there is at least one image to show $realpatharray = array(); @@ -287,7 +287,7 @@ class pdf_eagle extends ModelePdfStockTransfer $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks // Set nblines with the new facture lines content after hook - $nblines = count($object->lines); + $nblines = is_array($object->lines) ? count($object->lines) : 0; $pdf = pdf_getInstance($this->format); $default_font_size = pdf_getPDFFontSize($outputlangs); @@ -777,7 +777,7 @@ class pdf_eagle extends ModelePdfStockTransfer /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y @@ -971,17 +971,11 @@ class pdf_eagle extends ModelePdfStockTransfer $pdf->SetFont('', 'B', $default_font_size + 2); $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); - $title = $outputlangs->transnoentities("StockTransferSheet"); + $title = $outputlangs->transnoentities("StockTransferSheet").' '.$object->ref; $pdf->MultiCell($w, 4, $title, '', 'R'); $pdf->SetFont('', '', $default_font_size + 1); - $posy += 5; - - $pdf->SetXY($posx, $posy); - $pdf->SetTextColor(0, 0, 60); - $pdf->MultiCell($w, 4, $outputlangs->transnoentities("Ref")." : ".$object->ref, '', 'R'); - // Date prévue depart if (!empty($object->date_prevue_depart)) { $posy += 4; diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php index c705e4c9b41..8b0a032c4c9 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php @@ -209,7 +209,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes $outputlangsbis->loadLangs(array("main", "dict", "companies", "bills", "products", "orders", "deliveries")); } - $nblines = count($object->lines); + $nblines = is_array($object->lines) ? count($object->lines) : 0; $hidetop = 0; if (!empty($conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE)) { @@ -1551,7 +1551,7 @@ class pdf_eagle_proforma extends ModelePDFCommandes // Adapt dynamically the width of subprice, if text is too long. $tmpwidth = 0; - $nblines = count($object->lines); + $nblines = is_array($object->lines) ? count($object->lines) : 0; for ($i = 0; $i < $nblines; $i++) { $tmpwidth2 = dol_strlen(dol_string_nohtmltag(pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails))); $tmpwidth = max($tmpwidth, $tmpwidth2); diff --git a/htdocs/core/tpl/advtarget.tpl.php b/htdocs/core/tpl/advtarget.tpl.php index 55d5c5ed24a..2e0b800e022 100644 --- a/htdocs/core/tpl/advtarget.tpl.php +++ b/htdocs/core/tpl/advtarget.tpl.php @@ -336,12 +336,7 @@ if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) { $std_soc = new Societe($db); $action_search = 'query'; - // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($db); - $hookmanager->initHooks(array('thirdpartycard')); - - $parameters = array(); + $parameters = array('advtarget'=>1); if (!empty($advTarget->id)) { $parameters = array('array_query' => $advTarget->filtervalue); } diff --git a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php index bc10b6cf0ee..39f0e37c206 100644 --- a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php +++ b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php @@ -94,7 +94,6 @@ class InterfaceNotification extends DolibarrTriggers global $conf, $action; global $hookmanager; - if (!is_object($hookmanager)) { include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; $hookmanager = new HookManager($this->db); diff --git a/htdocs/datapolicy/class/datapolicy.class.php b/htdocs/datapolicy/class/datapolicy.class.php index 7bbe8d7c1a6..e83730c89e2 100644 --- a/htdocs/datapolicy/class/datapolicy.class.php +++ b/htdocs/datapolicy/class/datapolicy.class.php @@ -44,7 +44,7 @@ class DataPolicy /** * getAllContactNotInformed * - * @return number + * @return integer */ public function getAllContactNotInformed() { @@ -75,12 +75,14 @@ class DataPolicy $this->error = $this->db->error(); return -1; } + + return 1; } /** * getAllCompaniesNotInformed * - * @return number + * @return integer */ public function getAllCompaniesNotInformed() { @@ -110,12 +112,14 @@ class DataPolicy $this->error = $this->db->error(); return -1; } + + return 1; } /** * getAllAdherentsNotInformed * - * @return number + * @return integer */ public function getAllAdherentsNotInformed() { @@ -145,6 +149,8 @@ class DataPolicy $this->error = $this->db->error(); return -1; } + + return 1; } /** diff --git a/htdocs/debugbar/class/DataCollector/DolRequestDataCollector.php b/htdocs/debugbar/class/DataCollector/DolRequestDataCollector.php index a74669e5238..d7e8f9a858a 100644 --- a/htdocs/debugbar/class/DataCollector/DolRequestDataCollector.php +++ b/htdocs/debugbar/class/DataCollector/DolRequestDataCollector.php @@ -51,7 +51,13 @@ class DolRequestDataCollector extends RequestDataCollector } //var_dump($arrayofvalues); } - + if ($var == '_SERVER') { + foreach ($arrayofvalues as $key => $val) { + if (preg_match('/^PHP_AUTH_PW/', $key)) { + $arrayofvalues[$key] = '*****hidden*****'; + } + } + } $data["$".$var] = $this->getDataFormatter()->formatVar($arrayofvalues); } } diff --git a/htdocs/debugbar/class/DebugBar.php b/htdocs/debugbar/class/DebugBar.php index 47ad6ea5fce..bf293ea6e5f 100644 --- a/htdocs/debugbar/class/DebugBar.php +++ b/htdocs/debugbar/class/DebugBar.php @@ -24,7 +24,6 @@ dol_include_once('/debugbar/class/autoloader.php'); use \DebugBar\DebugBar; -use \DebugBar\DataCollector\PhpInfoCollector; dol_include_once('/debugbar/class/DataCollector/DolMessagesCollector.php'); dol_include_once('/debugbar/class/DataCollector/DolRequestDataCollector.php'); @@ -71,7 +70,7 @@ class DolibarrDebugBar extends DebugBar /** * Returns a JavascriptRenderer for this instance * - * @return DebugBar\JavascriptRenderer String content + * @return \DebugBar\JavascriptRenderer String content */ public function getRenderer() { @@ -80,6 +79,7 @@ class DolibarrDebugBar extends DebugBar $renderer->disableVendor('fontawesome'); // We already have fontawesome loaded globally by the main.inc.php $renderer->disableVendor('highlightjs'); // We don't need this $renderer->setEnableJqueryNoConflict(false); // We don't need no conflict + return $renderer; } } diff --git a/htdocs/delivery/class/delivery.class.php b/htdocs/delivery/class/delivery.class.php index 975ee6cbfb6..61309a1cfae 100644 --- a/htdocs/delivery/class/delivery.class.php +++ b/htdocs/delivery/class/delivery.class.php @@ -281,7 +281,6 @@ class Delivery extends CommonObject // phpcs:enable $error = 0; $idprod = $fk_product; - $j = 0; $sql = "INSERT INTO ".MAIN_DB_PREFIX."deliverydet (fk_delivery, fk_origin_line,"; $sql .= " fk_product, description, qty)"; @@ -304,9 +303,11 @@ class Delivery extends CommonObject $result = $line->insertExtraFields(); } - if ($error == 0) { + if (!$error) { return 1; } + + return -1; } /** @@ -317,8 +318,6 @@ class Delivery extends CommonObject */ public function fetch($id) { - global $conf; - $sql = "SELECT l.rowid, l.fk_soc, l.date_creation, l.date_valid, l.ref, l.ref_customer, l.fk_user_author,"; $sql .= " l.total_ht, l.fk_statut, l.fk_user_valid, l.note_private, l.note_public"; $sql .= ", l.date_delivery, l.fk_address, l.model_pdf"; @@ -396,7 +395,8 @@ class Delivery extends CommonObject */ public function valid($user, $notrigger = 0) { - global $conf, $langs; + global $conf; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; dol_syslog(get_class($this)."::valid begin"); @@ -521,8 +521,10 @@ class Delivery extends CommonObject } } } + + return -1; } else { - $this->error = "Non autorise"; + $this->error = "NotAllowed"; dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); return -1; } @@ -532,9 +534,9 @@ class Delivery extends CommonObject /** * Creating the delivery slip from an existing shipment * - * @param User $user User who creates - * @param int $sending_id Id of the expedition that serves as a model - * @return integer + * @param User $user User who creates + * @param int $sending_id Id of the expedition that serves as a model + * @return integer <=0 if KO, >0 if OK */ public function create_from_sending($user, $sending_id) { @@ -543,6 +545,9 @@ class Delivery extends CommonObject $expedition = new Expedition($this->db); $result = $expedition->fetch($sending_id); + if ($result <= 0) { + return $result; + } $this->lines = array(); @@ -638,7 +643,7 @@ class Delivery extends CommonObject * Delete line * * @param int $lineid Line id - * @return integer|null + * @return integer <0 if KO, 0 if nothing done, >0 if OK */ public function deleteline($lineid) { @@ -651,9 +656,11 @@ class Delivery extends CommonObject return 1; } else { - return 0; + return -1; } } + + return 0; } /** @@ -737,7 +744,7 @@ class Delivery extends CommonObject */ public function getTooltipContentArray($params) { - global $conf, $langs; + global $langs; $datas = []; @@ -944,8 +951,6 @@ class Delivery extends CommonObject */ public function initAsSpecimen() { - global $user, $langs, $conf; - $now = dol_now(); // Load array of products prodids @@ -994,13 +999,11 @@ class Delivery extends CommonObject /** * Renvoie la quantite de produit restante a livrer pour une commande * - * @return array Product remaining to be delivered + * @return array|int Product remaining to be delivered or <0 if KO * TODO use new function */ public function getRemainingDelivered() { - global $langs; - // Get the linked object $this->fetchObjectLinked('', '', $this->id, $this->element); //var_dump($this->linkedObjectsIds); @@ -1098,7 +1101,7 @@ class Delivery extends CommonObject */ public function generateDocument($modele, $outputlangs = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0) { - global $conf, $user, $langs; + global $conf, $langs; $langs->load("deliveries"); $outputlangs->load("products"); diff --git a/htdocs/document.php b/htdocs/document.php index eccf49de0be..21ab1b8b054 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -278,10 +278,6 @@ if (!file_exists($fullpath_original_file_osencoded)) { } // Hooks -if (!is_object($hookmanager)) { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($this->db); -} $hookmanager->initHooks(array('document')); $parameters = array('ecmfile' => $ecmfile, 'modulepart' => $modulepart, 'original_file' => $original_file, 'entity' => $entity, 'refname' => $refname, 'fullpath_original_file' => $fullpath_original_file, diff --git a/htdocs/don/card.php b/htdocs/don/card.php index a077c703fda..2c3e3ec6e11 100644 --- a/htdocs/don/card.php +++ b/htdocs/don/card.php @@ -52,6 +52,7 @@ $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'alpha'); $confirm = GETPOST('confirm', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); $socid = GETPOST('socid', 'int'); $amount = price2num(GETPOST('amount', 'alphanohtml'), 'MT'); $donation_date = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); @@ -405,6 +406,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; print dol_get_fiche_head(''); @@ -579,7 +581,7 @@ if (!empty($id) && $action == 'edit') { print ''; print ''; print ''; - + print ''; print dol_get_fiche_head($head, $hselected, $langs->trans("Donation"), 0, 'donation'); @@ -732,6 +734,7 @@ if (!empty($id) && $action != 'edit') { $morehtmlref .= ''; $morehtmlref .= ''; $morehtmlref .= ''; + $morehtmlref .= ''; $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', 0, 0, 1, 0, 1, 0, 0, '', 1, 0, 'maxwidth500'); $morehtmlref .= ''; $morehtmlref .= ''; diff --git a/htdocs/don/class/paymentdonation.class.php b/htdocs/don/class/paymentdonation.class.php index 1aceca10c16..1769033df28 100644 --- a/htdocs/don/class/paymentdonation.class.php +++ b/htdocs/don/class/paymentdonation.class.php @@ -134,7 +134,7 @@ class PaymentDonation extends CommonObject $now = dol_now(); // Validate parameters - if (!$this->datepaid) { + if (!$this->datep) { $this->error = 'ErrorBadValueForParameterCreatePaymentDonation'; return -1; } @@ -193,7 +193,7 @@ class PaymentDonation extends CommonObject $sql .= " fk_typepayment, num_payment, note, ext_payment_id, ext_payment_site,"; $sql .= " fk_user_creat, fk_bank)"; $sql .= " VALUES (".((int) $this->chid).", '".$this->db->idate($now)."',"; - $sql .= " '".$this->db->idate($this->datepaid)."',"; + $sql .= " '".$this->db->idate($this->datep)."',"; $sql .= " ".((float) price2num($totalamount)).","; $sql .= " ".((int) $this->paymenttype).", '".$this->db->escape($this->num_payment)."', '".$this->db->escape($this->note_public)."', "; $sql .= " ".($this->ext_payment_id ? "'".$this->db->escape($this->ext_payment_id)."'" : "null").", ".($this->ext_payment_site ? "'".$this->db->escape($this->ext_payment_site)."'" : "null").","; @@ -588,10 +588,9 @@ class PaymentDonation extends CommonObject if ($mode == 'payment_donation') { $amount = $total; } - // Insert payment into llx_bank $bank_line_id = $acc->addline( - $this->datepaid, + $this->datep, $this->paymenttype, // Payment mode id or code ("CHQ or VIR for example") $label, $amount, diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php index cf1a570f04f..e9015c08acb 100644 --- a/htdocs/ecm/class/ecmfiles.class.php +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -155,6 +155,31 @@ class EcmFiles extends CommonObject */ public $section_id; + public $fields = array( + 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), + 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>20, 'notnull'=>1, 'visible'=>-1, 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'validate'=>'1', 'comment'=>"contains hash from filename+filepath"), + 'label' => array('type'=>'varchar(128)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>0, 'visible'=>-1, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>"Help text", 'showoncombobox'=>'2', 'validate'=>'1', 'comment'=>"contains hash of file content"), + 'share' => array('type'=>'varchar(128)', 'label'=>'Share', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>-1, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>"Help text", 'showoncombobox'=>'2', 'validate'=>'1', 'comment' => "contains hash for file sharing"), + 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => 1, 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 50, 'index' => 1), + 'filepath' => array('type'=>'varchar(255)', 'label'=>'FilePath', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>0, 'searchall'=>0, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>"Help text", 'showoncombobox'=>'2', 'validate'=>'1','comment'=> "relative to dolibarr document dir. Example module/def"), + 'filename' => array('type'=>'varchar(255)', 'label'=>'FileName', 'enabled'=>'1', 'position'=>70, 'notnull'=>0, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>"Help text", 'showoncombobox'=>'2', 'validate'=>'1','comment'=>"file name only without any directory"), + 'src_object_type' => array('type'=>'varchar(64)', 'label'=>'SourceType', 'enabled'=>'1', 'position'=>80, 'notnull'=>0, 'visible'=>0, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>"Help text", 'showoncombobox'=>'2', 'validate'=>'1','comment'=> "Source object type ('proposal', 'invoice', ...)"), + 'src_object_id' => array('type' => 'integer', 'label' => 'SourceID', 'default' => 1, 'enabled' => 1, 'visible' => 0, 'notnull' => 1, 'position' => 90, 'index' => 1, 'comment' => "Source object id"), + 'fullpath_orig' => array('type'=>'varchar(750)', 'label'=>'FullPathOrig', 'enabled'=>'1', 'position'=>100, 'notnull'=>0, 'visible'=>0, 'searchall'=>0, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>"Help text", 'showoncombobox'=>'2', 'validate'=>'1','comment'=>"full path of original filename, when file is uploaded from a local computer"), + 'description' => array('type' => 'text', 'label' => 'Description', 'enabled' => 1, 'visible' => 0, 'position' => 110), + 'keywords' => array('type'=>'varchar(750)', 'label'=>'Keywords', 'enabled'=>'1', 'position'=>120, 'notnull'=>0, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>"Help text", 'showoncombobox'=>'2', 'validate'=>'1','comment'=>"list of keywords, separated with comma. Must be limited to most important keywords."), + 'cover' => array('type' => 'text', 'label' => 'Cover', 'enabled' => 1, 'visible' => 0, 'position' => 130, 'comment'=>"is this file a file to use for a cover"), + 'position' => array('type' => 'integer', 'label' => 'Position', 'default' => 1, 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 140, 'index' => 1, 'comment' => "position of file among others"), + 'gen_or_uploaded' => array('type'=>'varchar(12)', 'label'=>'GenOrUpload', 'enabled'=>'1', 'position'=>150, 'notnull'=>0, 'visible'=>-1, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>"Help text", 'showoncombobox'=>'2', 'validate'=>'1','comment'=>"'generated' or 'uploaded'"), + 'extraparams' => array('type'=>'varchar(255)', 'label'=>'ExtraParams', 'enabled'=>'1', 'position'=>160, 'notnull'=>0, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>"Help text", 'showoncombobox'=>'2', 'validate'=>'1', 'comment' => "for stocking other parameters with json format"), + 'date_c' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 170), + 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 175), + 'fk_user_c' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>'1', 'position'=>510, 'notnull'=>1, 'visible'=>-2, 'foreignkey'=>'user.rowid',), + 'fk_user_m' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,), + 'note_public' => array('type' => 'text', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 155), + 'note_private' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160), + 'acl' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160, 'comment' => "for future permission 'per file'"), + ); /** diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 7dd54308af4..168e7461427 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -55,6 +55,7 @@ $langs->loadLangs(array("trips", "bills", "mails")); $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'alpha'); $confirm = GETPOST('confirm', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); $id = GETPOST('id', 'int'); $date_start = dol_mktime(0, 0, 0, GETPOST('date_debutmonth', 'int'), GETPOST('date_debutday', 'int'), GETPOST('date_debutyear', 'int')); @@ -1407,6 +1408,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; print dol_get_fiche_head(''); @@ -1545,6 +1547,7 @@ if ($action == 'create') { print "\n"; print ''; print ''; + print ''; print dol_get_fiche_head($head, 'card', $langs->trans("ExpenseReport"), 0, 'trip'); @@ -2027,6 +2030,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; print '
'; print '
'; - if ($value == 1){ + if ($value == 1) { print $totalarray['totalizable'][$key]['total']; } print '
'; diff --git a/htdocs/expensereport/class/paymentexpensereport.class.php b/htdocs/expensereport/class/paymentexpensereport.class.php index 0d056a1f9e4..4fe23ae589c 100644 --- a/htdocs/expensereport/class/paymentexpensereport.class.php +++ b/htdocs/expensereport/class/paymentexpensereport.class.php @@ -111,9 +111,8 @@ class PaymentExpenseReport extends CommonObject $error = 0; $now = dol_now(); - // Validate parameters - if (!$this->datepaid) { + if (!$this->datep) { $this->error = 'ErrorBadValueForParameterCreatePaymentExpenseReport'; return -1; } @@ -170,7 +169,7 @@ class PaymentExpenseReport extends CommonObject $sql = "INSERT INTO ".MAIN_DB_PREFIX."payment_expensereport (fk_expensereport, datec, datep, amount,"; $sql .= " fk_typepayment, num_payment, note, fk_user_creat, fk_bank)"; $sql .= " VALUES ($this->fk_expensereport, '".$this->db->idate($now)."',"; - $sql .= " '".$this->db->idate($this->datepaid)."',"; + $sql .= " '".$this->db->idate($this->datep)."',"; $sql .= " ".price2num($totalamount).","; $sql .= " ".((int) $this->fk_typepayment).", '".$this->db->escape($this->num_payment)."', '".$this->db->escape($this->note_public)."', ".((int) $user->id).","; $sql .= " 0)"; // fk_bank is ID of transaction into ll_bank @@ -531,7 +530,7 @@ class PaymentExpenseReport extends CommonObject // Insert payment into llx_bank $bank_line_id = $acc->addline( - $this->datepaid, + $this->datep, $this->fk_typepayment, // Payment mode id or code ("CHQ or VIR for example") $label, -$amount, diff --git a/htdocs/expensereport/payment/payment.php b/htdocs/expensereport/payment/payment.php index 6456bf80d7f..20b49b1533c 100644 --- a/htdocs/expensereport/payment/payment.php +++ b/htdocs/expensereport/payment/payment.php @@ -107,8 +107,8 @@ if ($action == 'add_payment') { // Create a line of payments $payment = new PaymentExpenseReport($db); $payment->fk_expensereport = $expensereport->id; - $payment->datepaid = $datepaid; - $payment->amounts = $amounts; // Tableau de montant + $payment->datep = $datepaid; + $payment->amounts = $amounts; // Tableau de montant $payment->total = $total; $payment->fk_typepayment = GETPOST("fk_typepayment", 'int'); $payment->num_payment = GETPOST("num_payment", 'alphanothtml'); diff --git a/htdocs/fichinter/agenda.php b/htdocs/fichinter/agenda.php index 4b4ef9a7215..451f0a533f5 100644 --- a/htdocs/fichinter/agenda.php +++ b/htdocs/fichinter/agenda.php @@ -25,6 +25,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/fichinter.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index 0f18d024671..31ae0ccaf65 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -62,6 +62,8 @@ $contratid = (int) GETPOST('contratid', 'int'); $action = GETPOST('action', 'alpha'); $cancel = GETPOST('cancel', 'alpha'); $confirm = GETPOST('confirm', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); + $mesg = GETPOST('msg', 'alpha'); $origin = GETPOST('origin', 'alpha'); $originid = (GETPOST('originid', 'int') ?GETPOST('originid', 'int') : GETPOST('origin_id', 'int')); // For backward compatibility @@ -890,6 +892,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; print dol_get_fiche_head(''); @@ -1043,6 +1046,7 @@ if ($action == 'create') { print ''; print ''; print ''; // We go back to create action + print ''; print dol_get_fiche_head(''); @@ -1308,6 +1312,7 @@ if ($action == 'create') { } else { print ''; } + print ''; // Intervention lines $sql = 'SELECT ft.rowid, ft.description, ft.fk_fichinter, ft.duree, ft.rang,'; diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index 45a78d2914d..4c217f8b0ef 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -1589,16 +1589,17 @@ class FichinterLigne extends CommonObjectLine */ public function fetch($rowid) { + dol_syslog("FichinterLigne::fetch", LOG_DEBUG); + $sql = 'SELECT ft.rowid, ft.fk_fichinter, ft.description, ft.duree, ft.rang, ft.date'; $sql .= ' FROM '.MAIN_DB_PREFIX.'fichinterdet as ft'; $sql .= ' WHERE ft.rowid = '.((int) $rowid); - dol_syslog("FichinterLigne::fetch", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) { - $objp = $this->db->fetch_object($result); + $resql = $this->db->query($sql); + if ($resql) { + $objp = $this->db->fetch_object($resql); $this->rowid = $objp->rowid; - $this->id = $objp->rowid; + $this->id = $objp->rowid; $this->fk_fichinter = $objp->fk_fichinter; $this->date = $this->db->jdate($objp->date); $this->datei = $this->db->jdate($objp->date); // For backward compatibility @@ -1606,7 +1607,10 @@ class FichinterLigne extends CommonObjectLine $this->duration = $objp->duree; $this->rang = $objp->rang; - $this->db->free($result); + $this->db->free($resql); + + $this->fetch_optionals(); + return 1; } else { $this->error = $this->db->error().' sql='.$sql; @@ -1623,8 +1627,6 @@ class FichinterLigne extends CommonObjectLine */ public function insert($user, $notrigger = 0) { - global $langs, $conf; - $error = 0; dol_syslog("FichinterLigne::insert rang=".$this->rang); @@ -1714,8 +1716,6 @@ class FichinterLigne extends CommonObjectLine */ public function update($user, $notrigger = 0) { - global $langs, $conf; - $error = 0; if (empty($this->date) && !empty($this->datei)) { // For backward compatibility diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 68a4193520a..20622132c00 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -260,25 +260,25 @@ class CommandeFournisseur extends CommonOrder 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>35), 'ref_supplier' =>array('type'=>'varchar(255)', 'label'=>'RefOrderSupplierShort', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'searchall'=>1), 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Project', 'enabled'=>"isModEnabled('project')", 'visible'=>-1, 'position'=>45), - 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>60), - 'date_approve' =>array('type'=>'datetime', 'label'=>'DateApprove', 'enabled'=>1, 'visible'=>-1, 'position'=>62), - 'date_approve2' =>array('type'=>'datetime', 'label'=>'DateApprove2', 'enabled'=>1, 'visible'=>3, 'position'=>64), + 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>710), + 'date_approve' =>array('type'=>'datetime', 'label'=>'DateApprove', 'enabled'=>1, 'visible'=>-1, 'position'=>720), + 'date_approve2' =>array('type'=>'datetime', 'label'=>'DateApprove2', 'enabled'=>1, 'visible'=>3, 'position'=>725), 'date_commande' =>array('type'=>'date', 'label'=>'OrderDateShort', 'enabled'=>1, 'visible'=>1, 'position'=>70), 'date_livraison' =>array('type'=>'datetime', 'label'=>'DeliveryDate', 'enabled'=>'empty($conf->global->ORDER_DISABLE_DELIVERY_DATE)', 'visible'=>1, 'position'=>74), - 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>3, 'position'=>75), + 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>3, 'position'=>41), 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>3, 'notnull'=>-1, 'position'=>80), - 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>3, 'position'=>85), - 'fk_user_approve' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserApproval', 'enabled'=>1, 'visible'=>3, 'position'=>90), - 'fk_user_approve2' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserApproval2', 'enabled'=>1, 'visible'=>3, 'position'=>95), + 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>3, 'position'=>711), + 'fk_user_approve' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserApproval', 'enabled'=>1, 'visible'=>3, 'position'=>721), + 'fk_user_approve2' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserApproval2', 'enabled'=>1, 'visible'=>3, 'position'=>726), 'source' =>array('type'=>'smallint(6)', 'label'=>'Source', 'enabled'=>1, 'visible'=>3, 'notnull'=>1, 'position'=>100), - 'billed' =>array('type'=>'smallint(6)', 'label'=>'Billed', 'enabled'=>1, 'visible'=>1, 'position'=>110), - 'total_tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>1, 'position'=>130, 'isameasure'=>1), - 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>3, 'position'=>135, 'isameasure'=>1), - 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>3, 'position'=>140, 'isameasure'=>1), - 'total_ht' =>array('type'=>'double(24,8)', 'label'=>'TotalHT', 'enabled'=>1, 'visible'=>1, 'position'=>145, 'isameasure'=>1), - 'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'TotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>150, 'isameasure'=>1), - 'note_public' =>array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>155, 'searchall'=>1), - 'note_private' =>array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>160, 'searchall'=>1), + 'billed' =>array('type'=>'smallint(6)', 'label'=>'Billed', 'enabled'=>1, 'visible'=>1, 'position'=>710), + 'total_ht' =>array('type'=>'double(24,8)', 'label'=>'AmountHT', 'enabled'=>1, 'visible'=>1, 'position'=>130, 'isameasure'=>1), + 'total_tva' =>array('type'=>'double(24,8)', 'label'=>'AmountVAT', 'enabled'=>1, 'visible'=>1, 'position'=>135, 'isameasure'=>1), + 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'LT1', 'enabled'=>1, 'visible'=>3, 'position'=>140, 'isameasure'=>1), + 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'LT2', 'enabled'=>1, 'visible'=>3, 'position'=>145, 'isameasure'=>1), + 'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'AmountTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>150, 'isameasure'=>1), + 'note_public' =>array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>750, 'searchall'=>1), + 'note_private' =>array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>760, 'searchall'=>1), 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'ModelPDF', 'enabled'=>1, 'visible'=>0, 'position'=>165), 'fk_input_method' =>array('type'=>'integer', 'label'=>'OrderMode', 'enabled'=>1, 'visible'=>3, 'position'=>170), 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>3, 'position'=>175), @@ -294,7 +294,7 @@ class CommandeFournisseur extends CommonOrder 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountVAT', 'enabled'=>'isModEnabled("multicurrency")', 'visible'=>-1, 'position'=>235), 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountTTC', 'enabled'=>'isModEnabled("multicurrency")', 'visible'=>-1, 'position'=>240), 'date_creation' =>array('type'=>'datetime', 'label'=>'Date creation', 'enabled'=>1, 'visible'=>-1, 'position'=>500), - 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'isModEnabled("societe")', 'visible'=>1, 'notnull'=>1, 'position'=>46), + 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'isModEnabled("societe")', 'visible'=>1, 'notnull'=>1, 'position'=>50), 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'position'=>1000, 'index'=>1), 'tms'=>array('type'=>'datetime', 'label'=>"DateModificationShort", 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>501), 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>0, 'position'=>700), diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 6f326a75250..64ac75ce0e9 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -190,15 +190,17 @@ $checkedtypetiers = 0; // Definition of array of fields for columns $arrayfields = array( - 's.name_alias'=>array('label'=>"AliasNameShort", 'position'=>47, 'checked'=>0), - 's.town'=>array('label'=>"Town", 'enabled'=>1, 'position'=>47, 'checked'=>1), - 's.zip'=>array('label'=>"Zip", 'enabled'=>1, 'position'=>47, 'checked'=>1), - 'state.nom'=>array('label'=>"StateShort", 'enabled'=>1, 'position'=>48), - 'country.code_iso'=>array('label'=>"Country", 'enabled'=>1, 'position'=>49), - 'typent.code'=>array('label'=>"ThirdPartyType", 'enabled'=>$checkedtypetiers, 'position'=>50), - 'u.login'=>array('label'=>"AuthorRequest", 'enabled'=>1, 'position'=>51), - 'cf.note_public'=>array('label'=>'NotePublic', 'checked'=>0, 'enabled'=>(!getDolGlobalInt('MAIN_LIST_HIDE_PUBLIC_NOTES')), 'position'=>100), - 'cf.note_private'=>array('label'=>'NotePrivate', 'checked'=>0, 'enabled'=>(!getDolGlobalInt('MAIN_LIST_HIDE_PRIVATE_NOTES')), 'position'=>110), + 'u.login'=>array('label'=>"AuthorRequest", 'enabled'=>1, 'position'=>41), + 's.name_alias'=>array('label'=>"AliasNameShort", 'position'=>51, 'checked'=>0), + 's.town'=>array('label'=>"Town", 'enabled'=>1, 'position'=>55, 'checked'=>1), + 's.zip'=>array('label'=>"Zip", 'enabled'=>1, 'position'=>56, 'checked'=>1), + 'state.nom'=>array('label'=>"StateShort", 'enabled'=>1, 'position'=>57), + 'country.code_iso'=>array('label'=>"Country", 'enabled'=>1, 'position'=>58), + 'typent.code'=>array('label'=>"ThirdPartyType", 'enabled'=>$checkedtypetiers, 'position'=>59), + 'cf.total_localtax1'=>array('label'=>$langs->transcountry("AmountLT1", $mysoc->country_code), 'checked'=>0, 'enabled'=>($mysoc->localtax1_assuj == "1"), 'position'=>140), + 'cf.total_localtax2'=>array('label'=>$langs->transcountry("AmountLT2", $mysoc->country_code), 'checked'=>0, 'enabled'=>($mysoc->localtax2_assuj == "1"), 'position'=>145), + 'cf.note_public'=>array('label'=>'NotePublic', 'checked'=>0, 'enabled'=>(!getDolGlobalInt('MAIN_LIST_HIDE_PUBLIC_NOTES')), 'position'=>750), + 'cf.note_private'=>array('label'=>'NotePrivate', 'checked'=>0, 'enabled'=>(!getDolGlobalInt('MAIN_LIST_HIDE_PRIVATE_NOTES')), 'position'=>760), ); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field @@ -766,6 +768,7 @@ $sql .= ' s.rowid as socid, s.nom as name, s.name_alias as alias, s.town, s.zip, $sql .= " typent.code as typent_code,"; $sql .= " state.code_departement as state_code, state.nom as state_name,"; $sql .= " cf.rowid, cf.ref, cf.ref_supplier, cf.fk_statut, cf.billed, cf.total_ht, cf.total_tva, cf.total_ttc, cf.fk_user_author, cf.date_commande as date_commande, cf.date_livraison as date_livraison,cf.date_valid, cf.date_approve,"; +$sql .= ' cf.localtax1 as total_localtax1, cf.localtax2 as total_localtax2,'; $sql .= ' cf.fk_multicurrency, cf.multicurrency_code, cf.multicurrency_tx, cf.multicurrency_total_ht, cf.multicurrency_total_tva, cf.multicurrency_total_ttc,'; $sql .= ' cf.date_creation as date_creation, cf.tms as date_update,'; $sql .= ' cf.note_public, cf.note_private,'; @@ -1774,7 +1777,7 @@ if ($resql) { $totalarray['nbfield']++; } } - //alias + // Alias if (!empty($arrayfields['s.name_alias']['checked'])) { print ''; } @@ -1374,6 +1374,7 @@ while ($i < $imaxinloop) { $product_static->ref_fourn = empty($obj->ref_supplier) ? '' : $obj->ref_supplier; // deprecated $product_static->ref_supplier = empty($obj->ref_supplier) ? '' : $obj->ref_supplier; $product_static->label = $obj->label; + $product_static->barcode = $obj->barcode; $product_static->finished = $obj->finished; $product_static->type = $obj->fk_product_type; $product_static->status_buy = $obj->tobuy; diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php index bfe12d7efe2..f22e688327a 100644 --- a/htdocs/product/reassort.php +++ b/htdocs/product/reassort.php @@ -151,6 +151,10 @@ $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_stock as s ON p.rowid = s.fk_produ if (!empty($conf->global->PRODUCT_USE_UNITS)) { $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_units as u on p.fk_unit = u.rowid'; } +// Add table from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; $sql .= " WHERE p.entity IN (".getEntity('product').")"; if (!empty($search_categ) && $search_categ != '-1') { $sql .= " AND "; @@ -207,10 +211,12 @@ $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $objec $sql .= $hookmanager->resPrint; $sql .= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,"; $sql .= " p.fk_product_type, p.tms, p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock"; -// Add fields from hooks + +// Add GROUP BY from hooks $parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldSelect', $parameters, $object); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; + $sql_having = ''; if ($search_toolowstock) { $sql_having .= " HAVING SUM(".$db->ifsql('s.reel IS NULL', '0', 's.reel').") < p.seuil_stock_alerte"; @@ -226,6 +232,19 @@ if ($search_stock_physique != '') { } $sql_having .= $natural_search_physique; } + +// Add HAVING from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook +if (!empty($hookmanager->resPrint)) { + if (!empty($sql_having)) { + $sql_having .= " AND"; + } else { + $sql_having .= " HAVING"; + } + $sql_having .= $hookmanager->resPrint; +} + if (!empty($sql_having)) { $sql .= $sql_having; } @@ -515,7 +534,7 @@ if ($resql) { print img_warning($langs->trans("StockLowerThanLimit", $objp->seuil_stock_alerte)).' '; } if ($objp->stock_physique < 0) { print ''; } - print price2num($product->stock_theorique, 'MS', 0, $langs, 1, 0); + print price(price2num($product->stock_theorique, 'MS'), 0, $langs, 1, 0); if ($objp->stock_physique < 0) { print ''; } print ''; } diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php index c823379ce31..d24b5282d11 100644 --- a/htdocs/product/reassortlot.php +++ b/htdocs/product/reassortlot.php @@ -126,6 +126,9 @@ if (!empty($canvas)) { $objcanvas->getCanvas('product', 'list', $canvas); } +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('productreassortlotlist')); + // Security check if ($user->socid) { $socid = $user->socid; @@ -222,11 +225,19 @@ $sql .= ' e.ref as warehouse_ref, e.lieu as warehouse_lieu, e.fk_parent as wareh $sql .= ' pb.batch, pb.eatby as oldeatby, pb.sellby as oldsellby,'; $sql .= ' pl.rowid as lotid, pl.eatby, pl.sellby,'; $sql .= ' SUM(pb.qty) as stock_physique, COUNT(pb.rowid) as nbinbatchtable'; +// Add fields from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; $sql .= ' FROM '.MAIN_DB_PREFIX.'product as p'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_stock as ps on p.rowid = ps.fk_product'; // Detail for each warehouse $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'entrepot as e on ps.fk_entrepot = e.rowid'; // Link on unique key $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_batch as pb on pb.fk_product_stock = ps.rowid'; // Detail for each lot on each warehouse $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_lot as pl on pl.fk_product = p.rowid AND pl.batch = pb.batch'; // Link on unique key +// Add table from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; $sql .= " WHERE p.entity IN (".getEntity('product').") AND e.entity IN (".getEntity('stock').")"; if (!empty($search_categ) && $search_categ != '-1') { $sql .= " AND "; @@ -315,6 +326,10 @@ foreach ($search as $key => $val) { } } } +// Add where from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; $sql .= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,"; $sql .= " p.fk_product_type, p.tms,"; @@ -323,6 +338,10 @@ $sql .= " ps.fk_entrepot, ps.reel,"; $sql .= " e.ref, e.lieu, e.fk_parent,"; $sql .= " pb.batch, pb.eatby, pb.sellby,"; $sql .= " pl.rowid, pl.eatby, pl.sellby"; +// Add GROUP BY from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; $sql_having = ''; if ($search_toolowstock) { $sql_having .= " HAVING SUM(".$db->ifsql('ps.reel IS NULL', '0', 'ps.reel').") < p.seuil_stock_alerte"; // Not used yet @@ -337,6 +356,17 @@ if ($search_stock_physique != '') { } $sql_having .= $natural_search_physique; } +// Add HAVING from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook +if (!empty($hookmanager->resPrint)) { + if (!empty($sql_having)) { + $sql_having .= " AND"; + } else { + $sql_having .= " HAVING"; + } + $sql_having .= $hookmanager->resPrint; +} if (!empty($sql_having)) { $sql .= $sql_having; } @@ -563,6 +593,9 @@ print ''; print ''; print ''; print ''; +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; // Action column if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { print ''; + // Fields values from hook + $parameters = array('obj'=>$objp); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $product); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Action column if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { print ''; diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 36bc7b87961..bc31f211a63 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -1551,56 +1551,26 @@ if ($action == 'create' && $user->rights->projet->creer) { } } + // Buttons Create + if (empty($conf->global->PROJECT_HIDE_CREATE_OBJECT_BUTTON)) { + $arrayforbutaction = array( + 10 => array('lang'=>'propal', 'enabled'=>isModEnabled("propal"), 'perm'=>$user->hasRight('propal', 'creer'), 'label' => 'AddProp', 'url'=>'/comm/propal/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid), + 20 => array('lang'=>'orders', 'enabled'=>isModEnabled("commande"), 'perm'=>$user->hasRight('commande', 'creer'), 'label' => 'CreateOrder', 'url'=>'/commande/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid), + 30 => array('lang'=>'bills', 'enabled'=>isModEnabled("facture"), 'perm'=>$user->hasRight('facture', 'creer'), 'label' => 'CreateBill', 'url'=>'/compta/facture/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid), + 40 => array('lang'=>'supplier_proposal', 'enabled'=>isModEnabled("supplier_proposal"), 'perm'=>$user->hasRight('supplier_proposal', 'creer'), 'label' => 'AddSupplierProposal', 'url'=>'/supplier_proposal/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid), + 50 => array('lang'=>'suppliers', 'enabled'=>isModEnabled("supplier_order"), 'perm'=>$user->hasRight('fournisseur', 'commande', 'creer'), 'label' => 'AddSupplierOrder', 'url'=>'/fourn/commande/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid), + 60 => array('lang'=>'suppliers', 'enabled'=>isModEnabled("supplier_invoice"), 'perm'=>$user->hasRight('fournisseur', 'facture', 'creer'), 'label' => 'AddSupplierInvoice', 'url'=>'/fourn/facture/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid), + 70 => array('lang'=>'interventions', 'enabled'=>isModEnabled("ficheinter"), 'perm'=>$user->hasRight('fichinter', 'creer'), 'label' => 'AddIntervention', 'url'=>'/fichinter/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid), + 80 => array('lang'=>'contrats', 'enabled'=>isModEnabled("contrat"), 'perm'=>$user->hasRight('contrat', 'creer'), 'label' => 'AddContract', 'url'=>'/contrat/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid), + 90 => array('lang'=>'trips', 'enabled'=>isModEnabled("expensereport"), 'perm'=>$user->hasRight('expensereport', 'creer'), 'label' => 'AddTrip', 'url'=>'/expensereport/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid), + 100 => array('lang'=>'donations', 'enabled'=>isModEnabled("don"), 'perm'=>$user->hasRight('don', 'creer'), 'label' => 'AddDonation', 'url'=>'/don/card.php?action=create&projectid='.$object->id.'&socid='.$object->socid), + ); - if (!empty($conf->global->PROJECT_SHOW_CREATE_OBJECT_BUTTON)) { - print'"; + $params = array('backtopage' => $_SERVER["PHP_SELF"].'?id='.$object->id); + + print dolGetButtonAction($langs->trans("Create"), '', 'default', $arrayforbutaction, '', 1, $params); } + // Clone if ($user->rights->projet->creer) { if ($userWrite > 0) { diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index a848bf4e708..35e47f64604 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -1536,7 +1536,7 @@ if (isset($totalarray['totaldurationeffectivefield']) || isset($totalarray['tota print ''; } elseif ($totalarray['totalbudget_amountfield'] == $i) { print ''; - } else if (!empty($totalarray['pos'][$i])) { + } elseif (!empty($totalarray['pos'][$i])) { print ''; - }else { + } else { print ''; } } diff --git a/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php index a415cb5c940..1837d9a6839 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php @@ -213,6 +213,7 @@ class doc_generic_recruitmentjobposition_odt extends ModelePDFRecruitmentJobPosi { // phpcs:enable global $user, $langs, $conf, $mysoc, $hookmanager; + global $action; if (empty($srctemplatepath)) { dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING); @@ -220,12 +221,7 @@ class doc_generic_recruitmentjobposition_odt extends ModelePDFRecruitmentJobPosi } // Add odtgeneration hook - if (!is_object($hookmanager)) { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($this->db); - } $hookmanager->initHooks(array('odtgeneration')); - global $action; if (!is_object($outputlangs)) { $outputlangs = $langs; diff --git a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php index 8ee6043f870..1c066112f45 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php @@ -175,6 +175,7 @@ class pdf_standard_recruitmentjobposition extends ModelePDFRecruitmentJobPositio { // phpcs:enable global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines; + global $action; dol_syslog("write_file outputlangs->defaultlang=".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null')); @@ -281,13 +282,8 @@ class pdf_standard_recruitmentjobposition extends ModelePDFRecruitmentJobPositio if (file_exists($dir)) { // Add pdfgeneration hook - if (!is_object($hookmanager)) { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($this->db); - } $hookmanager->initHooks(array('pdfgeneration')); $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); - global $action; $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks // Set nblines with the new facture lines content after hook diff --git a/htdocs/resource/agenda.php b/htdocs/resource/agenda.php index d05b5070be3..b9c4090aedd 100644 --- a/htdocs/resource/agenda.php +++ b/htdocs/resource/agenda.php @@ -31,6 +31,7 @@ // Load Dolibarr environment require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/resource.lib.php'; require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php'; diff --git a/htdocs/salaries/list.php b/htdocs/salaries/list.php index 7ef8db376b7..50107bc477e 100644 --- a/htdocs/salaries/list.php +++ b/htdocs/salaries/list.php @@ -726,7 +726,7 @@ if ($num == 0) { }*/ $colspan = 9; if (isModEnabled("banque")) { $colspan++; } - print ''; + print ''; } diff --git a/htdocs/societe/canvas/company/actions_card_company.class.php b/htdocs/societe/canvas/company/actions_card_company.class.php index 7aa46178235..1e034d46322 100644 --- a/htdocs/societe/canvas/company/actions_card_company.class.php +++ b/htdocs/societe/canvas/company/actions_card_company.class.php @@ -88,7 +88,7 @@ class ActionsCardCompany extends ActionsCardCommon { // phpcs:enable global $conf, $langs, $user, $mysoc; - global $form, $formadmin, $formcompany; + global $form, $formcompany; $ret = $this->getObject($id, $ref); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index a56fad2c086..368ceec6dfc 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2415,7 +2415,7 @@ class Societe extends CommonObject * @param int $mode 0=Array with properties, 1=Array of id. * @param string $sortfield List of sort fields, separated by comma. Example: 't1.fielda,t2.fieldb' * @param string $sortorder Sort order, separated by comma. Example: 'ASC,DESC'; - * @return array Array of sales representatives of third party + * @return array|int Array of sales representatives of third party or <0 if KO */ public function getSalesRepresentatives(User $user, $mode = 0, $sortfield = null, $sortorder = null) { diff --git a/htdocs/societe/price.php b/htdocs/societe/price.php index af2898a8556..dafe53a19d8 100644 --- a/htdocs/societe/price.php +++ b/htdocs/societe/price.php @@ -321,7 +321,7 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { // VAT print ''; // Price base @@ -329,7 +329,7 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print $langs->trans('PriceBase'); print ''; print ''; print ''; diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index 732c4a57326..c6ee16c5128 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -151,7 +151,7 @@ class Stripe extends CommonObject * @param string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect * @param int $status Status (0=test, 1=live) * @param int $createifnotlinkedtostripe 1=Create the stripe customer and the link if the thirdparty is not yet linked to a stripe customer - * @return \Stripe\StripeCustomer|null Stripe Customer or null if not found + * @return \Stripe\Customer|null Stripe Customer or null if not found */ public function customerStripe(Societe $object, $key = '', $status = 0, $createifnotlinkedtostripe = 0) { @@ -783,12 +783,12 @@ class Stripe extends CommonObject /** * Get the Stripe card of a company payment mode (option to create it on Stripe if not linked yet is no more available on new Stripe API) * - * @param \Stripe\StripeCustomer $cu Object stripe customer. + * @param \Stripe\Customer $cu Object stripe customer. * @param CompanyPaymentMode $object Object companypaymentmode to check, or create on stripe (create on stripe also update the societe_rib table for current entity) * @param string $stripeacc ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect * @param int $status Status (0=test, 1=live) * @param int $createifnotlinkedtostripe 1=Create the stripe card and the link if the card is not yet linked to a stripe card. Deprecated with new Stripe API and SCA. - * @return \Stripe\StripeCard|\Stripe\PaymentMethod|null Stripe Card or null if not found + * @return \Stripe\Card|\Stripe\PaymentMethod|null Stripe Card or null if not found */ public function cardStripe($cu, CompanyPaymentMode $object, $stripeacc = '', $status = 0, $createifnotlinkedtostripe = 0) { @@ -935,7 +935,7 @@ class Stripe extends CommonObject /** * Get the Stripe SEPA of a company payment mode * - * @param \Stripe\StripeCustomer $cu Object stripe customer. + * @param \Stripe\Customer $cu Object stripe customer. * @param CompanyPaymentMode $object Object companypaymentmode to check, or create on stripe (create on stripe also update the societe_rib table for current entity) * @param string $stripeacc ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect * @param int $status Status (0=test, 1=live) diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 9baa56d8193..79520727955 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -63,6 +63,9 @@ $ref = GETPOST('ref', 'alpha'); $socid = GETPOST('socid', 'int'); $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); +$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); + $origin = GETPOST('origin', 'alpha'); $originid = GETPOST('originid', 'int'); $confirm = GETPOST('confirm', 'alpha'); @@ -1251,6 +1254,7 @@ if ($action == 'create') { print ''; print ''; } + print ''; print dol_get_fiche_head(); @@ -1688,6 +1692,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; print $form->selectDate($object->delivery_date, 'liv_', '', '', '', "editdate_livraison"); print ''; print ''; @@ -1889,6 +1894,7 @@ if ($action == 'create') { + '; if (!empty($conf->use_javascript_ajax) && $object->statut == SupplierProposal::STATUS_DRAFT) { diff --git a/htdocs/takepos/admin/terminal.php b/htdocs/takepos/admin/terminal.php index e2e3bd87048..dbbe7cfe46a 100644 --- a/htdocs/takepos/admin/terminal.php +++ b/htdocs/takepos/admin/terminal.php @@ -167,7 +167,8 @@ if (isModEnabled("banque")) { print ''; print ''; print ''; print ''; print ''; } } diff --git a/htdocs/takepos/ajax/ajax.php b/htdocs/takepos/ajax/ajax.php index 87357d10091..5b75ef04275 100644 --- a/htdocs/takepos/ajax/ajax.php +++ b/htdocs/takepos/ajax/ajax.php @@ -62,6 +62,10 @@ $hookmanager->initHooks(array('takeposproductsearch')); // new context for produ */ if ($action == 'getProducts') { + $tosell = GETPOSTISSET('tosell') ? GETPOST('tosell', 'int') : ''; + $limit = GETPOSTISSET('limit') ? GETPOST('limit', 'int') : 0; + $offset = GETPOSTISSET('offset') ? GETPOST('offset', 'int') : 0; + top_httphead('application/json'); $object = new Categorie($db); @@ -70,7 +74,11 @@ if ($action == 'getProducts') { } $result = $object->fetch($category); if ($result > 0) { - $prods = $object->getObjectsInCateg("product", 0, 0, 0, getDolGlobalString('TAKEPOS_SORTPRODUCTFIELD'), 'ASC'); + $filter = array(); + if ($tosell != '') { + $filter = array('customsql' => 'o.tosell = '.((int) $tosell)); + } + $prods = $object->getObjectsInCateg("product", 0, $limit, $offset, getDolGlobalString('TAKEPOS_SORTPRODUCTFIELD'), 'ASC', $filter); // Removed properties we don't need $res = array(); if (is_array($prods) && count($prods) > 0) { diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index bbbf9e0cd33..84ec7439ca3 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -322,7 +322,12 @@ function LoadProducts(position, issubcat) { }); idata=0; //product data counter - $.getJSON('/takepos/ajax/ajax.php?action=getProducts&token=&category='+currentcat, function(data) { + var limit = 0; + if (maxproduct >= 1) { + limit = maxproduct-1; + } + // Only show products for sale (tosell=1) + $.getJSON('/takepos/ajax/ajax.php?action=getProducts&token=&category='+currentcat+'&tosell=1&limit='+limit+'&offset=0', function(data) { console.log("Call ajax.php (in LoadProducts) to get Products of category "+currentcat+" then loop on result to fill image thumbs"); console.log(data); while (ishow < maxproduct) { @@ -342,10 +347,7 @@ function LoadProducts(position, issubcat) { $("#proprice"+ishow).html(""); $("#prodiv"+ishow).data("rowid",""); $("#prodiv"+ishow).attr("class","wrapper2 divempty"); - $("#prowatermark"+ishow).hide(); - ishow++; //Next product to show after print data product - } - else if ((data[idata]['status']) == "1") { // Only show products with status=1 (for sell) + } else { transnoentities('Ref').': ')."' + data[idata]['ref']"; $titlestring .= " + ' - ".dol_escape_js($langs->trans("Barcode").': ')."' + data[idata]['barcode']"; @@ -376,8 +378,7 @@ function LoadProducts(position, issubcat) { console.log($('#prodiv4').data('rowid')); $("#prodiv"+ishow).data("iscat", 0); $("#prodiv"+ishow).attr("class","wrapper2"); - $("#prowatermark"+ishow).hide(); - ishow++; //Next product to show after print data product + resPrint; ?> } - //console.log("Hide the prowatermark for ishow="+ishow); + $("#prowatermark"+ishow).hide(); + ishow++; //Next product to show after print data product idata++; //Next data everytime } }); @@ -414,15 +416,22 @@ function MoreProducts(moreorless) { if (pageproducts==0) return; //Return if no less pages pageproducts=pageproducts-1; } - $.getJSON('/takepos/ajax/ajax.php?action=getProducts&token=&category='+currentcat, function(data) { + + ishow=0; //product to show counter + idata=0; //product data counter + var limit = 0; + if (maxproduct >= 1) { + limit = maxproduct-1; + } + var offset = * pageproducts; + // Only show products for sale (tosell=1) + $.getJSON('/takepos/ajax/ajax.php?action=getProducts&token=&category='+currentcat+'&tosell=1&limit='+limit+'&offset='+offset, function(data) { console.log("Call ajax.php (in MoreProducts) to get Products of category "+currentcat); - if (typeof (data[(maxproduct * pageproducts)]) == "undefined" && moreorless=="more"){ // Return if no more pages + if (typeof (data[0]) == "undefined" && moreorless=="more"){ // Return if no more pages pageproducts=pageproducts-1; return; } - idata= * pageproducts; //product data counter - ishow=0; //product to show counter while (ishow < maxproduct) { if (typeof (data[idata]) == "undefined") { @@ -434,10 +443,7 @@ function MoreProducts(moreorless) { $("#proprice"+ishow).html(""); $("#proimg"+ishow).attr("src","genimg/empty.png"); $("#prodiv"+ishow).data("rowid",""); - ishow++; //Next product to show after print data product - } - else if ((data[idata]['status']) == "1") { - //Only show products with status=1 (for sell) + } else { $("#prodivdesc"+ishow).show(); @@ -454,9 +460,9 @@ function MoreProducts(moreorless) { $("#proimg"+ishow).attr("src","genimg/index.php?query=pro&id="+data[idata]['id']); $("#prodiv"+ishow).data("rowid",data[idata]['id']); $("#prodiv"+ishow).data("iscat",0); - ishow++; //Next product to show after print data product } $("#prowatermark"+ishow).hide(); + ishow++; //Next product to show after print data product idata++; //Next data everytime } }); diff --git a/htdocs/theme/eldy/dropdown.inc.php b/htdocs/theme/eldy/dropdown.inc.php index b3f91901575..034b9974c23 100644 --- a/htdocs/theme/eldy/dropdown.inc.php +++ b/htdocs/theme/eldy/dropdown.inc.php @@ -501,6 +501,43 @@ div.quickaddblock:focus { background: ; } + +/* for the dropdown on action buttons */ +dropdown-holder { + position: relative; + display: inline-block; +} + +.dropdown-content { + display: none; + position: absolute; + z-index: 1; + width: 300px; + right:10px; /* will be set with js */ + background: #fff; + border: 1px solid #bbb; + text-align: +} + +.dropdown-content a { + margin-right: auto !important; + margin-left: auto !important; +} +.dropdown-content .butAction { + background: none; + color: #000 !important; +} +.dropdown-content .butAction:hover { + box-shadow: none; + text-decoration: underline; +} + +.dropdown-holder.open .dropdown-content { + display: block; +} + + + /* smartphone */ @media only screen and (max-width: 767px) { diff --git a/htdocs/theme/md/dropdown.inc.php b/htdocs/theme/md/dropdown.inc.php index eb1fd668361..a0d010a4461 100644 --- a/htdocs/theme/md/dropdown.inc.php +++ b/htdocs/theme/md/dropdown.inc.php @@ -435,6 +435,41 @@ a.dropdown-item { } +/* for the dropdown on action buttons */ +dropdown-holder { + position: relative; + display: inline-block; +} + +.dropdown-content { + display: none; + position: absolute; + z-index: 1; + width: 300px; + right:10px; /* will be set with js */ + background: #fff; + border: 1px solid #bbb; + text-align: +} + +.dropdown-content a { + margin-right: auto !important; + margin-left: auto !important; +} +.dropdown-content .butAction { + background: none; + color: #000 !important; +} +.dropdown-content .butAction:hover { + box-shadow: none; + text-decoration: underline; +} + +.dropdown-holder.open .dropdown-content { + display: block; +} + + /* smartphone */ @media only screen and (max-width: 767px) { diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php index 8e2114f9bae..08ffcc5cbb5 100755 --- a/htdocs/ticket/card.php +++ b/htdocs/ticket/card.php @@ -5,6 +5,7 @@ * Copyright (C) 2021 Frédéric France * Copyright (C) 2021 Alexandre Spangaro * Copyright (C) 2022 Charlene Benke + * Copyright (C) 2023 Benjamin Falière * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -961,6 +962,9 @@ if ($action == 'create' || $action == 'presend') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetThirdParty'), 0).' '; } $morehtmlref .= $form->form_thirdparty($url_page_current.'?track_id='.$object->track_id, $object->socid, $action == 'editcustomer' ? 'editcustomer' : 'none', '', 1, 0, 0, array(), 1); + if (!empty($object->socid)) { + $morehtmlref .= ' - '.img_picto($langs->trans("Tickets"), 'ticket', 'class="pictofixedwidth"').' '.$langs->trans("TicketHistory").''; + } } // Project diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 59357fec734..6c504e43729 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -1383,7 +1383,7 @@ class Ticket extends CommonObject public function LibStatut($status, $mode = 0, $notooltip = 0, $progress = 0) { // phpcs:enable - global $langs; + global $langs, $hookmanager; $labelStatus = $this->statuts[$status]; $labelStatusShort = $this->statuts_short[$status]; @@ -1411,6 +1411,18 @@ class Ticket extends CommonObject $mode = 0; } + $parameters = array( + 'status' => $status, + 'mode' => $mode, + ); + + // Note that $action and $object may have been modified by hook + $reshook = $hookmanager->executeHooks('LibStatut', $parameters, $this); + + if ($reshook > 0) { + return $hookmanager->resPrint; + } + $params = array(); if ($notooltip) { $params = array('tooltip' => 'no'); diff --git a/htdocs/user/virtualcard.php b/htdocs/user/virtualcard.php index 55d63c3d40a..ee47afffc0e 100644 --- a/htdocs/user/virtualcard.php +++ b/htdocs/user/virtualcard.php @@ -129,7 +129,9 @@ print '
'; print '
'; -print ''.$langs->trans("UserPublicPageDesc").'

'; +if (!getDolUserInt('USER_ENABLE_PUBLIC', 0, $object)) { + print ''.$langs->trans("UserPublicPageDesc").'

'; +} $param = '&id='.((int) $object->id); $param .= '&dol_openinpopup=1'; diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 2192532772c..3d54742b38d 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2016-2023 Laurent Destailleur * Copyright (C) 2020 Nicolas ZABOURI * * This program is free software; you can redistribute it and/or modify @@ -2504,6 +2504,14 @@ $tempdir = $conf->website->dir_output.'/'.$websitekey.'/'; // Generate web site sitemaps if ($action == 'generatesitemaps' && $usercanedit) { + // Define $domainname + if ($website->virtualhost) { + $domainname = $website->virtualhost; + } + if (! preg_match('/^http/i', $domainname)) { + $domainname = 'https://'.$domainname; + } + $domtree = new DOMDocument('1.0', 'UTF-8'); $root = $domtree->createElementNS('http://www.sitemaps.org/schemas/sitemap/0.9', 'urlset'); @@ -2511,6 +2519,7 @@ if ($action == 'generatesitemaps' && $usercanedit) { $domtree->formatOutput = true; + $addrsswrapper = 0; $xmlname = 'sitemap.xml'; $sql = "SELECT wp.rowid, wp.type_container , wp.pageurl, wp.lang, wp.fk_page, wp.tms as tms,"; @@ -2539,6 +2548,11 @@ if ($action == 'generatesitemaps' && $usercanedit) { $shortlangcode = substr($object->lang, 0, 2); // Use short lang code of website } + // Is it a blog post for the RSS wrapper ? + if ($objp->type_container == 'blogpost') { + $addrsswrapper = 1; + } + // Forge $pageurl, adding language prefix if it is an alternative language $pageurl = $objp->pageurl.'.php'; if ($objp->fk_default_home == $objp->rowid) { @@ -2549,24 +2563,18 @@ if ($action == 'generatesitemaps' && $usercanedit) { } } - if ($objp->virtualhost) { - $domainname = $objp->virtualhost; - } - if (! preg_match('/^http/i', $domainname)) { - $domainname = 'https://'.$domainname; - } //$pathofpage = $dolibarr_main_url_root.'/'.$pageurl.'.php'; // URL of sitemaps must end with trailing slash if page is '' $loc = $domtree->createElement('loc', $domainname.'/'.$pageurl); $lastmod = $domtree->createElement('lastmod', dol_print_date($db->jdate($objp->tms), 'dayrfc', 'gmt')); - $changefreq = $domtree->createElement('changefreq', 'weekly'); // TODO Manage other values $priority = $domtree->createElement('priority', '1'); $url->appendChild($loc); $url->appendChild($lastmod); // Add suggested frequency for refresh if (!empty($conf->global->WEBSITE_SITEMAPS_ADD_WEEKLY_FREQ)) { + $changefreq = $domtree->createElement('changefreq', 'weekly'); // TODO Manage other values $url->appendChild($changefreq); } // Add higher priority for home page @@ -2655,7 +2663,31 @@ if ($action == 'generatesitemaps' && $usercanedit) { $root->appendChild($url); $i++; } + + // Adding a RSS feed into a sitemap should nto be required. The RSS contains pages that are already included into + // the sitemap and RSS feeds are not shown into index. + if ($addrsswrapper && getDolGlobalInt('WEBSITE_ADD_RSS_FEED_INTO_SITEMAP')) { + $url = $domtree->createElement('url'); + + $pageurl = 'wrapper.php?rss=1'; + + // URL of sitemaps must end with trailing slash if page is '' + $loc = $domtree->createElement('loc', $domainname.'/'.$pageurl); + $lastmod = $domtree->createElement('lastmod', dol_print_date($db->jdate(dol_now()), 'dayrfc', 'gmt')); + + $url->appendChild($loc); + $url->appendChild($lastmod); + // Add suggested frequency for refresh + if (!empty($conf->global->WEBSITE_SITEMAPS_ADD_WEEKLY_FREQ)) { + $changefreq = $domtree->createElement('changefreq', 'weekly'); // TODO Manage other values + $url->appendChild($changefreq); + } + + $root->appendChild($url); + } + $domtree->appendChild($root); + if ($domtree->save($tempdir.$xmlname)) { dolChmod($tempdir.$xmlname); setEventMessages($langs->trans("SitemapGenerated", $xmlname), null, 'mesgs'); diff --git a/htdocs/website/samples/wrapper.php b/htdocs/website/samples/wrapper.php index 621dee927cb..a32e2094fc7 100644 --- a/htdocs/website/samples/wrapper.php +++ b/htdocs/website/samples/wrapper.php @@ -2,7 +2,7 @@ // BEGIN PHP File wrapper.php - DO NOT MODIFY - It is just a copy of file website/samples/wrapper.php $websitekey = basename(__DIR__); if (strpos($_SERVER["PHP_SELF"], 'website/samples/wrapper.php')) { - die("Sample file for website module. Can be called directly."); + die("Sample file for website module. Can't be called directly."); } if (!defined('USEDOLIBARRSERVER') && !defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; diff --git a/scripts/cron/cron_run_jobs.php b/scripts/cron/cron_run_jobs.php index c7a9d19fb5c..29c8025758c 100755 --- a/scripts/cron/cron_run_jobs.php +++ b/scripts/cron/cron_run_jobs.php @@ -92,7 +92,7 @@ $hookmanager->initHooks(array('cli')); $now = dol_now(); @set_time_limit(0); -print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." - userlogin=".$userlogin." - ".dol_print_date($now, 'dayhourrfc')." *****\n"; +print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." - userlogin=".$userlogin." - ".dol_print_date($now, 'dayhourrfc')." - ".gethostname()." *****\n"; // Check module cron is activated if (empty($conf->cron->enabled)) { diff --git a/test/phpunit/AllTests.php b/test/phpunit/AllTests.php index ec419ad9987..1d5f6eccb37 100644 --- a/test/phpunit/AllTests.php +++ b/test/phpunit/AllTests.php @@ -112,6 +112,8 @@ class AllTests $suite->addTestSuite('CodingSqlTest'); require_once dirname(__FILE__).'/CodingPhpTest.php'; $suite->addTestSuite('CodingPhpTest'); + require_once dirname(__FILE__).'/DoliDBTest.php'; + $suite->addTestSuite('DoliDBTest'); require_once dirname(__FILE__).'/SecurityTest.php'; $suite->addTestSuite('SecurityTest'); diff --git a/test/phpunit/DoliDBTest.php b/test/phpunit/DoliDBTest.php new file mode 100644 index 00000000000..03a45c6c28d --- /dev/null +++ b/test/phpunit/DoliDBTest.php @@ -0,0 +1,169 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file test/phpunit/DoliDBTest.php + * \ingroup test + * \brief PHPUnit test + * \remarks To run this script as CLI: phpunit filename.php + */ + +global $conf,$user,$langs,$db; +//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver +//require_once 'PHPUnit/Autoload.php'; +require_once dirname(__FILE__).'/../../htdocs/master.inc.php'; +require_once dirname(__FILE__).'/../../htdocs/core/class/discount.class.php'; + +if (empty($user->id)) { + print "Load permissions for admin user nb 1\n"; + $user->fetch(1); + $user->getrights(); +} +$conf->global->MAIN_DISABLE_ALL_MAILS=1; + + +/** + * Class for PHPUnit tests + * + * @backupGlobals disabled + * @backupStaticAttributes enabled + * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased. + */ +class DoliDBTest extends PHPUnit\Framework\TestCase +{ + protected $savconf; + protected $savuser; + protected $savlangs; + protected $savdb; + + /** + * Constructor + * We save global variables into local variables + * + * @return DiscountTest + */ + public function __construct() + { + parent::__construct(); + + //$this->sharedFixture + global $conf,$user,$langs,$db; + $this->savconf=$conf; + $this->savuser=$user; + $this->savlangs=$langs; + $this->savdb=$db; + + print __METHOD__." db->type=".$db->type." user->id=".$user->id; + //print " - db ".$db->db; + print "\n"; + } + + /** + * setUpBeforeClass + * + * @return void + */ + public static function setUpBeforeClass(): void + { + global $conf,$user,$langs,$db; + $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. + + print __METHOD__."\n"; + } + + /** + * tearDownAfterClass + * + * @return void + */ + public static function tearDownAfterClass(): void + { + global $conf,$user,$langs,$db; + $db->rollback(); + + print __METHOD__."\n"; + } + + /** + * Init phpunit tests + * + * @return void + */ + protected function setUp(): void + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + print __METHOD__."\n"; + //print $db->getVersion()."\n"; + } + /** + * End phpunit tests + * + * @return void + */ + protected function tearDown(): void + { + print __METHOD__."\n"; + } + + /** + * testDDLUpdateField + * + * @return int + */ + public function testDDLUpdateField() + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + print __METHOD__.' db->type = '.$db->type."\n"; + + $savtype = ''; + $savnull = ''; + $resql = $db->DDLDescTable($db->prefix().'c_paper_format', 'code'); + while ($obj = $resql->fetch_object()) { + if ($obj->Field == 'code') { + $savtype = $obj->Type; + $savnull = $obj->Null; + } + } + + // Set new field + $field_desc = array('type'=>'varchar', 'value'=>'17', 'null'=>'NOT NULL'); + + $result = $db->DDLUpdateField($db->prefix().'c_paper_format', 'code', $field_desc); + $this->assertEquals(1, $result); + print __METHOD__." result=".$result."\n"; + + // TODO Use $savtype and $savnull instead of hard coded + $field_desc = array('type'=>'varchar', 'value'=>'16', 'null'=>'NOT NULL'); + + $result = $db->DDLUpdateField($db->prefix().'c_paper_format', 'code', $field_desc); + $this->assertEquals(1, $result); + print __METHOD__." result=".$result."\n"; + + return $result; + } +} diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index f398aef1050..57b640cd606 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -80,6 +80,7 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase protected $savuser; protected $savlangs; protected $savdb; + protected $savmysoc; /** * Constructor @@ -92,11 +93,12 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase parent::__construct(); //$this->sharedFixture - global $conf,$user,$langs,$db; + global $conf,$user,$langs,$db,$mysoc; $this->savconf=$conf; $this->savuser=$user; $this->savlangs=$langs; $this->savdb=$db; + $this->savmysoc=$mysoc; print __METHOD__." db->type=".$db->type." user->id=".$user->id; //print " - db ".$db->db; @@ -142,17 +144,18 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase } /** - * Init phpunit tests + * Init phpunit tests. Restore variables before each test. * * @return void */ protected function setUp(): void { - global $conf,$user,$langs,$db; + global $conf,$user,$langs,$db,$mysoc; $conf=$this->savconf; $user=$this->savuser; $langs=$this->savlangs; $db=$this->savdb; + $mysoc=$this->savmysoc; print __METHOD__."\n"; } @@ -1233,7 +1236,6 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase // We do same tests but with option SERVICE_ARE_ECOMMERCE_200238EC on. $conf->global->SERVICE_ARE_ECOMMERCE_200238EC = 1; - // Test RULE 1 (FR-US) $vat=get_default_tva($companyfr, $companyus, 0); $this->assertEquals(0, $vat, 'RULE 1 ECOMMERCE_200238EC'); @@ -1256,7 +1258,7 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase } /** - * testGetDefaultTva + * testGetDefaultLocalTax * * @return void */ @@ -1343,6 +1345,27 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase } + /** + * testGetLocalTaxByThird + * + * @return void + */ + public function testGetLocalTaxByThird() + { + global $mysoc; + + $mysoc->country_code = 'ES'; + + $result = get_localtax_by_third(1); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('5.2', $result); + + $result = get_localtax_by_third(2); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('-19:-15:-9', $result); + } + + /** * testDolExplodeIntoArray * diff --git a/test/phpunit/NumberingModulesTest.php b/test/phpunit/NumberingModulesTest.php index b2b6285f9e3..e5d31df1cf7 100644 --- a/test/phpunit/NumberingModulesTest.php +++ b/test/phpunit/NumberingModulesTest.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2012-2023 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -152,6 +152,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1915); // we use year 1915 to be sure to not have existing invoice for this year (usefull only if numbering is {0000@1} $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -165,8 +167,11 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $result=$localobject->is_erasable(); print __METHOD__." is_erasable=".$result."\n"; $this->assertGreaterThanOrEqual(1, $result, 'Test for is_erasable, 1st invoice'); // Can be deleted + $localobject2=new Facture($this->savdb); $localobject2->initAsSpecimen(); + $localobject2->fetch_thirdparty(); + $localobject2->date=dol_mktime(12, 0, 0, 1, 1, 1916); // we use following year for second invoice (there is no reset into mask) $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject2, 'last'); @@ -193,6 +198,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1910); // we use year 1910 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -200,15 +207,21 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $result3=$localobject->validate($user, $result); print __METHOD__." result=".$result."\n"; $this->assertEquals('1910-0001', $result, 'Test for {yyyy}-{0000@1} 1st invoice'); // counter must start to 1 + $localobject2=new Facture($this->savdb); $localobject2->initAsSpecimen(); + $localobject2->fetch_thirdparty(); + $localobject2->date=dol_mktime(12, 0, 0, 1, 1, 1910); // we use same year for second invoice (and there is a reset required) $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject2); print __METHOD__." result=".$result."\n"; $this->assertEquals('1910-0002', $result, 'Test for {yyyy}-{0000@1} 2nd invoice, same day'); // counter must be now 2 + $localobject3=new Facture($this->savdb); $localobject3->initAsSpecimen(); + $localobject3->fetch_thirdparty(); + $localobject3->date=dol_mktime(12, 0, 0, 1, 1, 1911); // we use next year for third invoice (and there is a reset required) $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject3); @@ -218,8 +231,11 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase // Same but we add month after year $conf->global->FACTURE_MERCURE_MASK_CREDIT='{yyyy}{mm}-{0000@1}'; $conf->global->FACTURE_MERCURE_MASK_INVOICE='{yyyy}{mm}-{0000@1}'; + $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1920); // we use year 1920 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -230,8 +246,11 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $result=$localobject->is_erasable(); print __METHOD__." is_erasable=".$result."\n"; $this->assertGreaterThanOrEqual(1, $result); // Can be deleted + $localobject2=new Facture($this->savdb); $localobject2->initAsSpecimen(); + $localobject2->fetch_thirdparty(); + $localobject2->date=dol_mktime(12, 0, 0, 1, 1, 1921); // we use following year for second invoice (and there is a reset required) $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject2); @@ -251,6 +270,7 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $conf->global->FACTURE_MERCURE_MASK_INVOICE='{mm}{yy}-{0000@1}'; $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1925); // we use year 1925 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -261,8 +281,10 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $result=$localobject->is_erasable(); // This call get getNextNumRef with param 'last' print __METHOD__." is_erasable=".$result."\n"; $this->assertGreaterThanOrEqual(1, $result); // Can be deleted + $localobject2=new Facture($this->savdb); $localobject2->initAsSpecimen(); + $localobject2->fetch_thirdparty(); $localobject2->date=dol_mktime(12, 0, 0, 1, 1, 1925); // we use same year 1925 for second invoice (and there is a reset required) $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject2); @@ -276,8 +298,10 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $result=$localobject->is_erasable(); print __METHOD__." is_erasable=".$result."\n"; $this->assertLessThanOrEqual(0, $result); // Case 1 can not be deleted (because there is an invoice 2) + $localobject3=new Facture($this->savdb); $localobject3->initAsSpecimen(); + $localobject3->fetch_thirdparty(); $localobject3->date=dol_mktime(12, 0, 0, 1, 1, 1926); // we use following year for third invoice (and there is a reset required) $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject3); @@ -295,6 +319,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1930); // we use year 1930 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject, 'last'); @@ -311,6 +337,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1930); // we use same year but fiscal month after $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject, 'last'); @@ -324,6 +352,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1931); // we use same fiscal year but different year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -334,6 +364,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1931); // we use different fiscal year but same year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -348,6 +380,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1940); // we use year 1940 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -358,6 +392,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1940); // we use same year but fiscal month after $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -368,6 +404,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1941); // we use same fiscal year but different year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -378,6 +416,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1941); // we use different discal year but same year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -392,6 +432,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1950); // we use year 1950 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -402,6 +444,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1950); // we use same year but fiscal month after $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -412,6 +456,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1951); // we use same fiscal year but different year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -422,6 +468,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1951); // we use different discal year but same year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -436,6 +484,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1960); // we use year 1960 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -446,6 +496,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1960); // we use same year but fiscal month after $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -456,6 +508,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1961); // we use same fiscal year but different year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -466,6 +520,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1961); // we use different discal year but same year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -480,6 +536,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1970); // we use year 1970 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -490,6 +548,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1970); // we use same year but fiscal month after $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -500,6 +560,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1971); // we use same fiscal year but different year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -510,6 +572,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1971); // we use different fiscal year but same year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -523,6 +587,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1980); // we use year 1980 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -533,6 +599,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1980); // we use year 1980 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -543,6 +611,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 2, 1, 1980); // we use year 1980 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -553,6 +623,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1981); // we use year 1981 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -572,6 +644,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1982); // we use year 1982 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($tmpthirdparty, $localobject);
'; print $obj->alias; diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 30e6ceda91e..5408b8f980a 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -74,6 +74,8 @@ $action = GETPOST('action', 'aZ09'); $confirm = GETPOST("confirm"); $ref = GETPOST('ref', 'alpha'); $cancel = GETPOST('cancel', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); + $lineid = GETPOST('lineid', 'int'); $projectid = GETPOST('projectid', 'int'); $origin = GETPOST('origin', 'alpha'); @@ -2156,6 +2158,7 @@ if ($action == 'create') { if (!empty($currency_tx)) { print ''; } + print ''; print dol_get_fiche_head(); @@ -3721,6 +3724,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; if (!empty($conf->use_javascript_ajax) && $object->statut == FactureFournisseur::STATUS_DRAFT) { include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; diff --git a/htdocs/includes/maximebf/debugbar/composer.json b/htdocs/includes/maximebf/debugbar/composer.json index e68fc461f1c..50793eb6f6c 100644 --- a/htdocs/includes/maximebf/debugbar/composer.json +++ b/htdocs/includes/maximebf/debugbar/composer.json @@ -17,12 +17,13 @@ } ], "require": { - "php": ">=5.6", - "psr/log": "^1.0", - "symfony/var-dumper": "^2.6|^3|^4" + "php": "^7.1|^8", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^4|^5|^6" }, "require-dev": { - "phpunit/phpunit": "^5" + "phpunit/phpunit": ">=7.5.20 <10.0", + "twig/twig": "^1.38|^2.7|^3.0" }, "autoload": { "psr-4": { @@ -36,7 +37,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.15-dev" + "dev-master": "1.18-dev" } } } diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/MonologCollector.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/MonologCollector.php index f24b296d574..49eb37c27f5 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/MonologCollector.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/MonologCollector.php @@ -57,9 +57,9 @@ class MonologCollector extends AbstractProcessingHandler implements DataCollecto } /** - * @param array $record + * @param array|\Monolog\LogRecord $record */ - protected function write(array $record) + protected function write($record): void { $this->records[] = array( 'message' => $record['formatted'], diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/NamespacedTwigProfileCollector.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/NamespacedTwigProfileCollector.php new file mode 100644 index 00000000000..02e7306e232 --- /dev/null +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/NamespacedTwigProfileCollector.php @@ -0,0 +1,204 @@ + + * $env = new \Twig\Environment($loader); // Or from a PSR11-container + * $profile = new \Twig\Profiler\Profile(); + * $env->addExtension(new \Twig\Extension\ProfilerExtension($profile)); + * $debugbar->addCollector(new ModernTwigProfileCollector($profile, $env)); + * // or: $debugbar->addCollector(new ModernTwigProfileCollector($profile, $loader)); + * + */ +class NamespacedTwigProfileCollector extends DataCollector implements Renderable, AssetProvider +{ + /** + * @var Profile + */ + private $profile; + + /** + * @var LoaderInterface|Environment|null + */ + private $loader; + + /** + * @var int + */ + private $templateCount; + + /** + * @var int + */ + private $blockCount; + + /** + * @var int + */ + private $macroCount; + /** + * @var array[] { + * @var string $name + * @var int $render_time + * @var string $render_time_str + * @var string $memory_str + * @var string $xdebug_link + * } + */ + private $templates; + + /** + * TwigProfileCollector constructor. + * + * @param Profile $profile + * @param LoaderInterface|Environment $loaderOrEnv + */ + public function __construct(Profile $profile, $loaderOrEnv = null) + { + $this->profile = $profile; + if ($loaderOrEnv instanceof Environment) { + $loaderOrEnv = $loaderOrEnv->getLoader(); + } + $this->loader = $loaderOrEnv; + } + + /** + * Returns a hash where keys are control names and their values + * an array of options as defined in {@see \DebugBar\JavascriptRenderer::addControl()} + * + * @return array + */ + public function getWidgets() + { + return [ + 'twig' => [ + 'icon' => 'leaf', + 'widget' => 'PhpDebugBar.Widgets.TemplatesWidget', + 'map' => 'twig', + 'default' => json_encode(['templates' => []]), + ], + 'twig:badge' => [ + 'map' => 'twig.badge', + 'default' => 0, + ], + ]; + } + + /** + * @return array + */ + public function getAssets() + { + return [ + 'css' => 'widgets/templates/widget.css', + 'js' => 'widgets/templates/widget.js', + ]; + } + + /** + * Called by the DebugBar when data needs to be collected + * + * @return array Collected data + */ + public function collect() + { + $this->templateCount = $this->blockCount = $this->macroCount = 0; + $this->templates = []; + $this->computeData($this->profile); + + return [ + 'nb_templates' => $this->templateCount, + 'nb_blocks' => $this->blockCount, + 'nb_macros' => $this->macroCount, + 'templates' => $this->templates, + 'accumulated_render_time' => $this->profile->getDuration(), + 'accumulated_render_time_str' => $this->getDataFormatter()->formatDuration($this->profile->getDuration()), + 'memory_usage_str' => $this->getDataFormatter()->formatBytes($this->profile->getMemoryUsage()), + 'callgraph' => $this->getHtmlCallGraph(), + 'badge' => implode( + '/', + [ + $this->templateCount, + $this->blockCount, + $this->macroCount, + ] + ), + ]; + } + + /** + * Returns the unique name of the collector + * + * @return string + */ + public function getName() + { + return 'twig'; + } + + public function getHtmlCallGraph() + { + $dumper = new HtmlDumper(); + return $dumper->dump($this->profile); + } + + /** + * Get an Xdebug Link to a file + * + * @return array { + * @var string url + * @var bool ajax + * } + */ + public function getXdebugLink($template, $line = 1) + { + if (is_null($this->loader)) { + return null; + } + $file = $this->loader->getSourceContext($template)->getPath(); + + return parent::getXdebugLink($file, $line); + } + + private function computeData(Profile $profile) + { + $this->templateCount += ($profile->isTemplate() ? 1 : 0); + $this->blockCount += ($profile->isBlock() ? 1 : 0); + $this->macroCount += ($profile->isMacro() ? 1 : 0); + if ($profile->isTemplate()) { + $this->templates[] = [ + 'name' => $profile->getName(), + 'render_time' => $profile->getDuration(), + 'render_time_str' => $this->getDataFormatter()->formatDuration($profile->getDuration()), + 'memory_str' => $this->getDataFormatter()->formatBytes($profile->getMemoryUsage()), + 'xdebug_link' => $this->getXdebugLink($profile->getTemplate()), + ]; + } + foreach ($profile as $p) { + $this->computeData($p); + } + } +} diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/SwiftMailer/SwiftLogCollector.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/SwiftMailer/SwiftLogCollector.php index fdef79a0bdc..e8c2fcd92f0 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/SwiftMailer/SwiftLogCollector.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/SwiftMailer/SwiftLogCollector.php @@ -34,7 +34,16 @@ class SwiftLogCollector extends MessagesCollector implements Swift_Plugins_Logge public function dump() { - return implode(PHP_EOL, $this->_log); + $dump = ''; + foreach ($this->messages as $message) { + if (!$message['is_string']) { + continue; + } + + $dump .= $message['message'] . PHP_EOL; + } + + return $dump; } public function getName() diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TimeableTwigExtensionProfiler.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TimeableTwigExtensionProfiler.php index 3611d2d8efa..30238cc20a4 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TimeableTwigExtensionProfiler.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TimeableTwigExtensionProfiler.php @@ -57,4 +57,4 @@ class TimeableTwigExtensionProfiler extends \Twig_Extension_Profiler $this->timeDataCollector->stopMeasure($profile->getName()); } } -} \ No newline at end of file +} diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigEnvironment.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigEnvironment.php index cdaae7a4525..9e98c191115 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigEnvironment.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigEnvironment.php @@ -24,6 +24,8 @@ use Twig_TokenStream; /** * Wrapped a Twig Environment to provide profiling features + * + * @deprecated */ class TraceableTwigEnvironment extends Twig_Environment { diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigTemplate.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigTemplate.php index 648f7baf4da..1d57d2a518a 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigTemplate.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigTemplate.php @@ -15,6 +15,8 @@ use Twig_TemplateInterface; /** * Wraps a Twig_Template to add profiling features + * + * @deprecated */ class TraceableTwigTemplate extends Twig_Template implements Twig_TemplateInterface { diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TwigCollector.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TwigCollector.php index c571d835bcc..bb48ab79a36 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TwigCollector.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/Twig/TwigCollector.php @@ -26,6 +26,8 @@ use DebugBar\DataCollector\Renderable; * $env = new TraceableTwigEnvironment(new Twig_Environment($loader)); * $debugbar->addCollector(new TwigCollector($env)); * + * + * @deprecated use DebugBar\Bridge\TwigProfileCollector instead */ class TwigCollector extends DataCollector implements Renderable, AssetProvider { diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/TwigProfileCollector.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/TwigProfileCollector.php index efd3a7d523e..ce68fcbb403 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/TwigProfileCollector.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/Bridge/TwigProfileCollector.php @@ -34,6 +34,8 @@ use DebugBar\DataCollector\Renderable; * $debugbar->addCollector(new TwigProfileCollector($profile, $env)); * // or: $debugbar->addCollector(new TwigProfileCollector($profile, $loader)); * + * + * @deprecated Use `\Debugbar\Bridge\NamespacedTwigProfileCollector` instead for Twig 2.x and 3.x */ class TwigProfileCollector extends DataCollector implements Renderable, AssetProvider { diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/AggregatedCollector.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/AggregatedCollector.php index c1fd96aef26..56c9dc7aa47 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/AggregatedCollector.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/AggregatedCollector.php @@ -48,7 +48,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess /** * @param DataCollectorInterface $collector */ - public function addCollector(DataCollectorInterface $collector) + public function addCollector(DataCollectorInterface $collector) : void { $this->collectors[$collector->getName()] = $collector; } @@ -56,7 +56,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess /** * @return array */ - public function getCollectors() + public function getCollectors() : array { return $this->collectors; } @@ -66,7 +66,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess * * @param string $property */ - public function setMergeProperty($property) + public function setMergeProperty($property) : void { $this->mergeProperty = $property; } @@ -74,7 +74,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess /** * @return string */ - public function getMergeProperty() + public function getMergeProperty() : string { return $this->mergeProperty; } @@ -87,7 +87,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess * * @param bool|string $sort */ - public function setSort($sort) + public function setSort($sort) : void { $this->sort = $sort; } @@ -103,7 +103,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess /** * @return array */ - public function collect() + public function collect() : array { $aggregate = array(); foreach ($this->collectors as $collector) { @@ -123,7 +123,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess * @param array $data * @return array */ - protected function sort($data) + protected function sort($data) : array { if (is_string($this->sort)) { $p = $this->sort; @@ -142,7 +142,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess /** * @return string */ - public function getName() + public function getName() : string { return $this->name; } @@ -155,7 +155,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess * @param mixed $value * @throws DebugBarException */ - public function offsetSet($key, $value) + public function offsetSet($key, $value): void { throw new DebugBarException("AggregatedCollector[] is read-only"); } @@ -164,6 +164,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess * @param mixed $key * @return mixed */ + #[\ReturnTypeWillChange] public function offsetGet($key) { return $this->collectors[$key]; @@ -173,7 +174,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess * @param mixed $key * @return bool */ - public function offsetExists($key) + public function offsetExists($key): bool { return isset($this->collectors[$key]); } @@ -182,7 +183,7 @@ class AggregatedCollector implements DataCollectorInterface, ArrayAccess * @param mixed $key * @throws DebugBarException */ - public function offsetUnset($key) + public function offsetUnset($key): void { throw new DebugBarException("AggregatedCollector[] is read-only"); } diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/ExceptionsCollector.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/ExceptionsCollector.php index 285bc971102..3fcac398016 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/ExceptionsCollector.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/ExceptionsCollector.php @@ -21,6 +21,10 @@ class ExceptionsCollector extends DataCollector implements Renderable protected $exceptions = array(); protected $chainExceptions = false; + // The HTML var dumper requires debug bar users to support the new inline assets, which not all + // may support yet - so return false by default for now. + protected $useHtmlVarDumper = false; + /** * Adds an exception to be profiled in the debug bar * @@ -65,6 +69,30 @@ class ExceptionsCollector extends DataCollector implements Renderable return $this->exceptions; } + /** + * Sets a flag indicating whether the Symfony HtmlDumper will be used to dump variables for + * rich variable rendering. + * + * @param bool $value + * @return $this + */ + public function useHtmlVarDumper($value = true) + { + $this->useHtmlVarDumper = $value; + return $this; + } + + /** + * Indicates whether the Symfony HtmlDumper will be used to dump variables for rich variable + * rendering. + * + * @return mixed + */ + public function isHtmlVarDumperUsed() + { + return $this->useHtmlVarDumper; + } + public function collect() { return array( @@ -102,6 +130,11 @@ class ExceptionsCollector extends DataCollector implements Renderable $lines = array("Cannot open the file ($filePath) in which the exception occurred "); } + $traceHtml = null; + if ($this->isHtmlVarDumperUsed()) { + $traceHtml = $this->getVarDumper()->renderVar($e->getTrace()); + } + return array( 'type' => get_class($e), 'message' => $e->getMessage(), @@ -109,6 +142,7 @@ class ExceptionsCollector extends DataCollector implements Renderable 'file' => $filePath, 'line' => $e->getLine(), 'stack_trace' => $e->getTraceAsString(), + 'stack_trace_html' => $traceHtml, 'surrounding_lines' => $lines, 'xdebug_link' => $this->getXdebugLink($filePath, $e->getLine()) ); diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/MemoryCollector.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/MemoryCollector.php index 894f8870adc..1a34f3bddb0 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/MemoryCollector.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/MemoryCollector.php @@ -67,7 +67,7 @@ class MemoryCollector extends DataCollector implements Renderable $this->updatePeakUsage(); return array( 'peak_usage' => $this->peakUsage, - 'peak_usage_str' => $this->getDataFormatter()->formatBytes($this->peakUsage) + 'peak_usage_str' => $this->getDataFormatter()->formatBytes($this->peakUsage, 0) ); } diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/MessagesCollector.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/MessagesCollector.php index f26d3716ca2..8859e7d0175 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/MessagesCollector.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/MessagesCollector.php @@ -183,11 +183,37 @@ class MessagesCollector extends AbstractLogger implements DataCollectorInterface * @param $message * @param array $context */ - public function log($level, $message, array $context = array()) + public function log($level, $message, array $context = array()): void { + // For string messages, interpolate the context following PSR-3 + if (is_string($message)) { + $message = $this->interpolate($message, $context); + } $this->addMessage($message, $level); } + /** + * Interpolates context values into the message placeholders. + * + * @param $message + * @param array $context + * @return string + */ + function interpolate($message, array $context = array()) + { + // build a replacement array with braces around the context keys + $replace = array(); + foreach ($context as $key => $val) { + // check that the value can be cast to string + if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) { + $replace['{' . $key . '}'] = $val; + } + } + + // interpolate replacement values into the message and return + return strtr($message, $replace); + } + /** * Deletes all messages */ diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/PDOCollector.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/PDOCollector.php index e1eb35ad0bc..77e36307095 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/PDOCollector.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/PDOCollector.php @@ -21,10 +21,10 @@ class PDOCollector extends DataCollector implements Renderable, AssetProvider protected $sqlQuotationChar = '<>'; /** - * @param TraceablePDO $pdo + * @param \PDO $pdo * @param TimeDataCollector $timeCollector */ - public function __construct(TraceablePDO $pdo = null, TimeDataCollector $timeCollector = null) + public function __construct(\PDO $pdo = null, TimeDataCollector $timeCollector = null) { $this->timeCollector = $timeCollector; if ($pdo !== null) { @@ -65,11 +65,14 @@ class PDOCollector extends DataCollector implements Renderable, AssetProvider * @param TraceablePDO $pdo * @param string $name Optional connection name */ - public function addConnection(TraceablePDO $pdo, $name = null) + public function addConnection(\PDO $pdo, $name = null) { if ($name === null) { $name = spl_object_hash($pdo); } + if (!($pdo instanceof TraceablePDO)) { + $pdo = new TraceablePDO($pdo); + } $this->connections[$name] = $pdo; } diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TraceablePDO.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TraceablePDO.php index e448a794ad3..753964a343c 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TraceablePDO.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TraceablePDO.php @@ -23,13 +23,13 @@ class TraceablePDO extends PDO $this->pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, [TraceablePDOStatement::class, [$this]]); } - /** - * Initiates a transaction - * - * @link http://php.net/manual/en/pdo.begintransaction.php - * @return bool TRUE on success or FALSE on failure. - */ - public function beginTransaction() + /** + * Initiates a transaction + * + * @link http://php.net/manual/en/pdo.begintransaction.php + * @return bool TRUE on success or FALSE on failure. + */ + public function beginTransaction() : bool { return $this->pdo->beginTransaction(); } @@ -40,7 +40,7 @@ class TraceablePDO extends PDO * @link http://php.net/manual/en/pdo.commit.php * @return bool TRUE on success or FALSE on failure. */ - public function commit() + public function commit() : bool { return $this->pdo->commit(); } @@ -51,6 +51,7 @@ class TraceablePDO extends PDO * @link http://php.net/manual/en/pdo.errorinfo.php * @return array PDO::errorInfo returns an array of error information */ + #[\ReturnTypeWillChange] public function errorCode() { return $this->pdo->errorCode(); @@ -62,7 +63,7 @@ class TraceablePDO extends PDO * @link http://php.net/manual/en/pdo.errorinfo.php * @return array PDO::errorInfo returns an array of error information */ - public function errorInfo() + public function errorInfo() : array { return $this->pdo->errorInfo(); } @@ -77,6 +78,7 @@ class TraceablePDO extends PDO * return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE. * Please read the section on Booleans for more information */ + #[\ReturnTypeWillChange] public function exec($statement) { return $this->profileCall('exec', $statement, func_get_args()); @@ -90,6 +92,7 @@ class TraceablePDO extends PDO * @return mixed A successful call returns the value of the requested PDO attribute. * An unsuccessful call returns null. */ + #[\ReturnTypeWillChange] public function getAttribute($attribute) { return $this->pdo->getAttribute($attribute); @@ -101,7 +104,7 @@ class TraceablePDO extends PDO * @link http://php.net/manual/en/pdo.intransaction.php * @return bool TRUE if a transaction is currently active, and FALSE if not. */ - public function inTransaction() + public function inTransaction() : bool { return $this->pdo->inTransaction(); } @@ -114,36 +117,41 @@ class TraceablePDO extends PDO * @return string If a sequence name was not specified for the name parameter, PDO::lastInsertId * returns a string representing the row ID of the last row that was inserted into the database. */ + #[\ReturnTypeWillChange] public function lastInsertId($name = null) { return $this->pdo->lastInsertId($name); } - /** - * Prepares a statement for execution and returns a statement object - * - * @link http://php.net/manual/en/pdo.prepare.php - * @param string $statement This must be a valid SQL statement template for the target DB server. - * @param array $driver_options [optional] This array holds one or more key=>value pairs to - * set attribute values for the PDOStatement object that this method returns. - * @return TraceablePDOStatement|bool If the database server successfully prepares the statement, - * PDO::prepare returns a PDOStatement object. If the database server cannot successfully prepare - * the statement, PDO::prepare returns FALSE or emits PDOException (depending on error handling). - */ + /** + * Prepares a statement for execution and returns a statement object + * + * @link http://php.net/manual/en/pdo.prepare.php + * @param string $statement This must be a valid SQL statement template for the target DB server. + * @param array $driver_options [optional] This array holds one or more key=>value pairs to + * set attribute values for the PDOStatement object that this method returns. + * @return TraceablePDOStatement|bool If the database server successfully prepares the statement, + * PDO::prepare returns a PDOStatement object. If the database server cannot successfully prepare + * the statement, PDO::prepare returns FALSE or emits PDOException (depending on error handling). + */ + #[\ReturnTypeWillChange] public function prepare($statement, $driver_options = []) { return $this->pdo->prepare($statement, $driver_options); } - /** - * Executes an SQL statement, returning a result set as a PDOStatement object - * - * @link http://php.net/manual/en/pdo.query.php - * @param string $statement - * @return TraceablePDOStatement|bool PDO::query returns a PDOStatement object, or FALSE on - * failure. - */ - public function query($statement) + /** + * Executes an SQL statement, returning a result set as a PDOStatement object + * + * @link http://php.net/manual/en/pdo.query.php + * @param string $statement + * @param int $fetchMode + * @param mixed ...$fetchModeArgs + * @return TraceablePDOStatement|bool PDO::query returns a PDOStatement object, or FALSE on + * failure. + */ + #[\ReturnTypeWillChange] + public function query($statement, $fetchMode = null, ...$fetchModeArgs) { return $this->profileCall('query', $statement, func_get_args()); } @@ -158,6 +166,7 @@ class TraceablePDO extends PDO * @return string|bool A quoted string that is theoretically safe to pass into an SQL statement. * Returns FALSE if the driver does not support quoting in this way. */ + #[\ReturnTypeWillChange] public function quote($string, $parameter_type = PDO::PARAM_STR) { return $this->pdo->quote($string, $parameter_type); @@ -169,7 +178,7 @@ class TraceablePDO extends PDO * @link http://php.net/manual/en/pdo.rollback.php * @return bool TRUE on success or FALSE on failure. */ - public function rollBack() + public function rollBack() : bool { return $this->pdo->rollBack(); } @@ -182,7 +191,7 @@ class TraceablePDO extends PDO * @param mixed $value * @return bool TRUE on success or FALSE on failure. */ - public function setAttribute($attribute, $value) + public function setAttribute($attribute, $value) : bool { return $this->pdo->setAttribute($attribute, $value); } @@ -195,6 +204,7 @@ class TraceablePDO extends PDO * @param array $args * @return mixed The result of the call */ + #[\ReturnTypeWillChange] protected function profileCall($method, $sql, array $args) { $trace = new TracedStatement($sql); @@ -226,7 +236,7 @@ class TraceablePDO extends PDO * * @param TracedStatement $stmt */ - public function addExecutedStatement(TracedStatement $stmt) + public function addExecutedStatement(TracedStatement $stmt) : void { $this->executedStatements[] = $stmt; } @@ -234,9 +244,9 @@ class TraceablePDO extends PDO /** * Returns the accumulated execution time of statements * - * @return int + * @return float */ - public function getAccumulatedStatementsDuration() + public function getAccumulatedStatementsDuration() : float { return array_reduce($this->executedStatements, function ($v, $s) { return $v + $s->getDuration(); }); } @@ -246,7 +256,7 @@ class TraceablePDO extends PDO * * @return int */ - public function getMemoryUsage() + public function getMemoryUsage() : int { return array_reduce($this->executedStatements, function ($v, $s) { return $v + $s->getMemoryUsage(); }); } @@ -256,7 +266,7 @@ class TraceablePDO extends PDO * * @return int */ - public function getPeakMemoryUsage() + public function getPeakMemoryUsage() : int { return array_reduce($this->executedStatements, function ($v, $s) { $m = $s->getEndMemory(); return $m > $v ? $m : $v; }); } @@ -266,7 +276,7 @@ class TraceablePDO extends PDO * * @return TracedStatement[] */ - public function getExecutedStatements() + public function getExecutedStatements() : array { return $this->executedStatements; } @@ -276,7 +286,7 @@ class TraceablePDO extends PDO * * @return TracedStatement[] */ - public function getFailedExecutedStatements() + public function getFailedExecutedStatements() : array { return array_filter($this->executedStatements, function ($s) { return !$s->isSuccess(); }); } diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TraceablePDOStatement.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TraceablePDOStatement.php index d125b19a2eb..011bbfe4351 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TraceablePDOStatement.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TraceablePDOStatement.php @@ -39,6 +39,7 @@ class TraceablePDOStatement extends PDOStatement * @param mixed $driverdata [optional] Optional parameter(s) for the driver. * @return bool TRUE on success or FALSE on failure. */ + #[\ReturnTypeWillChange] public function bindColumn($column, &$param, $type = null, $maxlen = null, $driverdata = null) { $this->boundParameters[$column] = $param; @@ -61,7 +62,7 @@ class TraceablePDOStatement extends PDOStatement * @param mixed $driver_options [optional] * @return bool TRUE on success or FALSE on failure. */ - public function bindParam($parameter, &$variable, $data_type = PDO::PARAM_STR, $length = null, $driver_options = null) + public function bindParam($parameter, &$variable, $data_type = PDO::PARAM_STR, $length = null, $driver_options = null) : bool { $this->boundParameters[$parameter] = $variable; $args = array_merge([$parameter, &$variable], array_slice(func_get_args(), 2)); @@ -80,7 +81,7 @@ class TraceablePDOStatement extends PDOStatement * constants. * @return bool TRUE on success or FALSE on failure. */ - public function bindValue($parameter, $value, $data_type = PDO::PARAM_STR) + public function bindValue($parameter, $value, $data_type = PDO::PARAM_STR) : bool { $this->boundParameters[$parameter] = $value; return call_user_func_array(['parent', 'bindValue'], func_get_args()); @@ -96,7 +97,7 @@ class TraceablePDOStatement extends PDOStatement * @throws PDOException * @return bool TRUE on success or FALSE on failure. */ - public function execute($input_parameters = null) + public function execute($input_parameters = null) : bool { $preparedId = spl_object_hash($this); $boundParameters = $this->boundParameters; diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TracedStatement.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TracedStatement.php index c4eef46aaeb..9111489b0ea 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TracedStatement.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TracedStatement.php @@ -27,12 +27,14 @@ class TracedStatement protected $exception; + protected $preparedId; + /** * @param string $sql * @param array $params - * @param string $preparedId + * @param null|string $preparedId */ - public function __construct($sql, array $params = [], $preparedId = null) + public function __construct(string $sql, array $params = [], ?string $preparedId = null) { $this->sql = $sql; $this->parameters = $this->checkParameters($params); @@ -43,7 +45,7 @@ class TracedStatement * @param null $startTime * @param null $startMemory */ - public function start($startTime = null, $startMemory = null) + public function start($startTime = null, $startMemory = null) : void { $this->startTime = $startTime ?: microtime(true); $this->startMemory = $startMemory ?: memory_get_usage(false); @@ -55,7 +57,7 @@ class TracedStatement * @param float $endTime * @param int $endMemory */ - public function end(\Exception $exception = null, $rowCount = 0, $endTime = null, $endMemory = null) + public function end(\Exception $exception = null, int $rowCount = 0, float $endTime = null, int $endMemory = null) : void { $this->endTime = $endTime ?: microtime(true); $this->duration = $this->endTime - $this->startTime; @@ -71,10 +73,10 @@ class TracedStatement * @param array $params * @return array */ - public function checkParameters($params) + public function checkParameters(array $params) : array { foreach ($params as &$param) { - if (!mb_check_encoding($param, 'UTF-8')) { + if (!mb_check_encoding($param ?? '', 'UTF-8')) { $param = '[BINARY DATA]'; } } @@ -86,7 +88,7 @@ class TracedStatement * * @return string */ - public function getSql() + public function getSql() : string { return $this->sql; } @@ -97,7 +99,7 @@ class TracedStatement * @param string $quotationChar * @return string */ - public function getSqlWithParams($quotationChar = '<>') + public function getSqlWithParams(string $quotationChar = '<>') : string { if (($l = strlen($quotationChar)) > 1) { $quoteLeft = substr($quotationChar, 0, $l / 2); @@ -123,7 +125,11 @@ class TracedStatement } $matchRule = "/({$marker}(?!\w))(?=(?:[^$quotationChar]|[$quotationChar][^$quotationChar]*[$quotationChar])*$)/"; - for ($i = 0; $i <= mb_substr_count($sql, $k); $i++) { + $count = mb_substr_count($sql, $k); + if ($count < 1) { + $count = mb_substr_count($sql, $matchRule); + } + for ($i = 0; $i <= $count; $i++) { $sql = preg_replace($matchRule, $v, $sql, 1); } } @@ -138,7 +144,7 @@ class TracedStatement * * @return int */ - public function getRowCount() + public function getRowCount() : int { return $this->rowCount; } @@ -148,11 +154,11 @@ class TracedStatement * * @return array */ - public function getParameters() + public function getParameters() : array { $params = []; foreach ($this->parameters as $name => $param) { - $params[$name] = htmlentities($param, ENT_QUOTES, 'UTF-8', false); + $params[$name] = htmlentities($param?:"", ENT_QUOTES, 'UTF-8', false); } return $params; } @@ -160,9 +166,9 @@ class TracedStatement /** * Returns the prepared statement id * - * @return string + * @return null|string */ - public function getPreparedId() + public function getPreparedId() : ?string { return $this->preparedId; } @@ -172,7 +178,7 @@ class TracedStatement * * @return boolean */ - public function isPrepared() + public function isPrepared() : bool { return $this->preparedId !== null; } @@ -180,7 +186,7 @@ class TracedStatement /** * @return float */ - public function getStartTime() + public function getStartTime() : float { return $this->startTime; } @@ -188,7 +194,7 @@ class TracedStatement /** * @return float */ - public function getEndTime() + public function getEndTime() : float { return $this->endTime; } @@ -198,7 +204,7 @@ class TracedStatement * * @return float */ - public function getDuration() + public function getDuration() : float { return $this->duration; } @@ -206,7 +212,7 @@ class TracedStatement /** * @return int */ - public function getStartMemory() + public function getStartMemory() : int { return $this->startMemory; } @@ -214,7 +220,7 @@ class TracedStatement /** * @return int */ - public function getEndMemory() + public function getEndMemory() : int { return $this->endMemory; } @@ -224,7 +230,7 @@ class TracedStatement * * @return int */ - public function getMemoryUsage() + public function getMemoryUsage() : int { return $this->memoryDelta; } @@ -234,7 +240,7 @@ class TracedStatement * * @return boolean */ - public function isSuccess() + public function isSuccess() : bool { return $this->exception === null; } @@ -244,8 +250,8 @@ class TracedStatement * * @return \Exception */ - public function getException() - { + public function getException() : \Exception + { return $this->exception; } @@ -264,7 +270,7 @@ class TracedStatement * * @return string */ - public function getErrorMessage() + public function getErrorMessage() : string { return $this->exception !== null ? $this->exception->getMessage() : ''; } diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PhpInfoCollector.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PhpInfoCollector.php index 57e9e45f47f..15a3f22dc38 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PhpInfoCollector.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PhpInfoCollector.php @@ -29,7 +29,7 @@ class PhpInfoCollector extends DataCollector implements Renderable public function collect() { return array( - 'version' => PHP_VERSION, + 'version' => implode('.', [PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION]), 'interface' => PHP_SAPI ); } diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/TimeDataCollector.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/TimeDataCollector.php index 27a2e1a2df2..5794ccd7cb3 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/TimeDataCollector.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/TimeDataCollector.php @@ -134,6 +134,7 @@ class TimeDataCollector extends DataCollector implements Renderable * @param string $label * @param \Closure $closure * @param string|null $collector + * @return mixed */ public function measure($label, \Closure $closure, $collector = null) { @@ -142,6 +143,7 @@ class TimeDataCollector extends DataCollector implements Renderable $result = $closure(); $params = is_array($result) ? $result : array(); $this->stopMeasure($name, $params); + return $result; } /** diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/DataFormatter.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/DataFormatter.php index 7ffb19892c8..d933f3466ea 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/DataFormatter.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/DataFormatter.php @@ -15,6 +15,10 @@ use Symfony\Component\VarDumper\Dumper\CliDumper; class DataFormatter implements DataFormatterInterface { + public $cloner; + + public $dumper; + /** * DataFormatter constructor. */ @@ -54,8 +58,10 @@ class DataFormatter implements DataFormatterInterface { if ($seconds < 0.001) { return round($seconds * 1000000) . 'μs'; - } elseif ($seconds < 1) { + } elseif ($seconds < 0.1) { return round($seconds * 1000, 2) . 'ms'; + } elseif ($seconds < 1) { + return round($seconds * 1000) . 'ms'; } return round($seconds, 2) . 's'; } @@ -76,6 +82,6 @@ class DataFormatter implements DataFormatterInterface $base = log($size) / log(1024); $suffixes = array('B', 'KB', 'MB', 'GB', 'TB'); - return $sign . round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)]; + return $sign . round(pow(1024, $base - floor($base)), $precision) . $suffixes[(int) floor($base)]; } } diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/DataFormatterInterface.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/DataFormatterInterface.php index cb7b426e70b..e4b464b7ed8 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/DataFormatterInterface.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/DataFormatterInterface.php @@ -18,7 +18,7 @@ interface DataFormatterInterface /** * Transforms a PHP variable to a string representation * - * @param mixed $var + * @param mixed $data * @return string */ function formatVar($data); diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/DebugBarVarDumper.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/DebugBarVarDumper.php index 7b92ddf0a34..768879957fa 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/DebugBarVarDumper.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/DebugBarVarDumper.php @@ -4,7 +4,7 @@ namespace DebugBar\DataFormatter; use DebugBar\DataCollector\AssetProvider; use DebugBar\DataFormatter\VarDumper\DebugBarHtmlDumper; -use DebugBar\DataFormatter\VarDumper\SeekingData; +use Symfony\Component\VarDumper\Cloner\Data\SeekingData; use Symfony\Component\VarDumper\Cloner\Data; use Symfony\Component\VarDumper\Cloner\VarCloner; @@ -254,8 +254,6 @@ class DebugBarVarDumper implements AssetProvider public function renderCapturedVar($capturedData, $seekPath = array()) { $data = unserialize($capturedData); - // The seek method was added in Symfony 3.2; emulate the behavior via SeekingData for older - // Symfony versions. if (!method_exists($data, 'seek')) { $data = new SeekingData($data->getRawData()); } @@ -285,7 +283,7 @@ class DebugBarVarDumper implements AssetProvider */ public function getAssets() { $dumper = $this->getDumper(); - $dumper->setDumpHeader(null); // this will cause the default dump header to regenerate + $dumper->resetDumpHeader(); // this will cause the default dump header to regenerate return array( 'inline_head' => array( 'html_var_dumper' => $dumper->getDumpHeaderByDebugBar(), diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/VarDumper/DebugBarHtmlDumper.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/VarDumper/DebugBarHtmlDumper.php index 0ff4919c18b..136d1ae8f0c 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/VarDumper/DebugBarHtmlDumper.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/VarDumper/DebugBarHtmlDumper.php @@ -10,6 +10,14 @@ use Symfony\Component\VarDumper\Dumper\HtmlDumper; */ class DebugBarHtmlDumper extends HtmlDumper { + /** + * Resets an HTML header. + */ + public function resetDumpHeader() + { + $this->dumpHeader = null; + } + public function getDumpHeaderByDebugBar() { // getDumpHeader is protected: return str_replace('pre.sf-dump', '.phpdebugbar pre.sf-dump', $this->getDumpHeader()); diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/VarDumper/SeekingData.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/VarDumper/SeekingData.php deleted file mode 100644 index be71ebfc9ce..00000000000 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DataFormatter/VarDumper/SeekingData.php +++ /dev/null @@ -1,103 +0,0 @@ -getRawData(); - $item = $thisData[$this->position][$this->key]; - - if (!$item instanceof Stub || !$item->position) { - return; - } - $keys = array($key); - - switch ($item->type) { - case Stub::TYPE_OBJECT: - $keys[] = "\0+\0".$key; - $keys[] = "\0*\0".$key; - $keys[] = "\0~\0".$key; - $keys[] = "\0$item->class\0$key"; - case Stub::TYPE_ARRAY: - case Stub::TYPE_RESOURCE: - break; - default: - return; - } - - $data = null; - $children = $thisData[$item->position]; - - foreach ($keys as $key) { - if (isset($children[$key]) || array_key_exists($key, $children)) { - $data = clone $this; - $data->key = $key; - $data->position = $item->position; - break; - } - } - - return $data; - } - - /** - * {@inheritdoc} - */ - public function dump(DumperInterface $dumper) - { - // Override the base class dump to use the position and key - $refs = array(0); - $class = new \ReflectionClass($this); - $dumpItem = $class->getMethod('dumpItem'); - $dumpItem->setAccessible(true); - $data = $this->getRawData(); - $args = array($dumper, new Cursor(), &$refs, $data[$this->position][$this->key]); - $dumpItem->invokeArgs($this, $args); - } -} diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/DebugBar.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/DebugBar.php index af900a801e8..b3999b476b5 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/DebugBar.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/DebugBar.php @@ -471,21 +471,25 @@ class DebugBar implements ArrayAccess // -------------------------------------------- // ArrayAccess implementation + #[\ReturnTypeWillChange] public function offsetSet($key, $value) { throw new DebugBarException("DebugBar[] is read-only"); } + #[\ReturnTypeWillChange] public function offsetGet($key) { return $this->getCollector($key); } + #[\ReturnTypeWillChange] public function offsetExists($key) { return $this->hasCollector($key); } + #[\ReturnTypeWillChange] public function offsetUnset($key) { throw new DebugBarException("DebugBar[] is read-only"); diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/JavascriptRenderer.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/JavascriptRenderer.php index 7f7ed84e0dd..b61d74fd43e 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/JavascriptRenderer.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/JavascriptRenderer.php @@ -82,6 +82,8 @@ class JavascriptRenderer protected $openHandlerUrl; + protected $cspNonce; + /** * @param \DebugBar\DebugBar $debugBar * @param string $baseUrl @@ -183,6 +185,9 @@ class JavascriptRenderer if (array_key_exists('open_handler_url', $options)) { $this->setOpenHandlerUrl($options['open_handler_url']); } + if (array_key_exists('csp_nonce', $options)) { + $this->setCspNonce($options['csp_nonce']); + } } /** @@ -606,6 +611,28 @@ class JavascriptRenderer return $this->openHandlerUrl; } + /** + * Sets the CSP Nonce (or remove it by setting to null) + * + * @param string|null $nonce + * @return $this + */ + public function setCspNonce($nonce = null) + { + $this->cspNonce = $nonce; + return $this; + } + + /** + * Get the CSP Nonce + * + * @return string|null + */ + public function getCspNonce() + { + return $this->cspNonce; + } + /** * Add assets stored in files to render in the head * @@ -692,8 +719,8 @@ class JavascriptRenderer } foreach ($additionalAssets as $assets) { - $basePath = isset($assets['base_path']) ? $assets['base_path'] : null; - $baseUrl = isset($assets['base_url']) ? $assets['base_url'] : null; + $basePath = isset($assets['base_path']) ? $assets['base_path'] : ''; + $baseUrl = isset($assets['base_url']) ? $assets['base_url'] : ''; $root = $this->getRelativeRoot($relativeTo, $this->makeUriRelativeTo($basePath, $this->basePath), $this->makeUriRelativeTo($baseUrl, $this->baseUrl)); @@ -719,7 +746,7 @@ class JavascriptRenderer $cssFiles = array_unique($cssFiles); $jsFiles = array_unique($jsFiles); - return $this->filterAssetArray(array($cssFiles, $jsFiles, $inlineCss, $inlineJs, $inlineHead), $type); + return $this->filterAssetArray(array($cssFiles, $jsFiles, $inlineCss, $inlineJs, $inlineHead), $type ?? ''); } /** @@ -762,7 +789,9 @@ class JavascriptRenderer return $uris; } - if ($uri && (substr($uri, 0, 1) === '/' || preg_match('/^([a-zA-Z]+:\/\/|[a-zA-Z]:\/|[a-zA-Z]:\\\)/', $uri))) { + $uri = $uri ?? ''; + + if (substr($uri, 0, 1) === '/' || preg_match('/^([a-zA-Z]+:\/\/|[a-zA-Z]:\/|[a-zA-Z]:\\\)/', $uri)) { return $uri; } return rtrim($root, '/') . "/$uri"; @@ -775,10 +804,10 @@ class JavascriptRenderer * @param string $type 'css', 'js', 'inline_css', 'inline_js', 'inline_head', or null for all * @return array */ - protected function filterAssetArray($array, $type = null) + protected function filterAssetArray($array, $type = '') { $types = array('css', 'js', 'inline_css', 'inline_js', 'inline_head'); - $typeIndex = is_null($type) ? false : array_search(strtolower($type), $types); + $typeIndex = array_search(strtolower($type ?? ''), $types); return $typeIndex !== false ? $array[$typeIndex] : $array; } @@ -905,6 +934,8 @@ class JavascriptRenderer list($cssFiles, $jsFiles, $inlineCss, $inlineJs, $inlineHead) = $this->getAssets(null, self::RELATIVE_URL); $html = ''; + $nonce = $this->getNonceAttribute(); + foreach ($cssFiles as $file) { $html .= sprintf('' . "\n", $file); } @@ -918,7 +949,7 @@ class JavascriptRenderer } foreach ($inlineJs as $content) { - $html .= sprintf('' . "\n", $content); + $html .= sprintf('' . "\n", $nonce, $content); } foreach ($inlineHead as $content) { @@ -926,7 +957,7 @@ class JavascriptRenderer } if ($this->enableJqueryNoConflict && !$this->useRequireJs) { - $html .= '' . "\n"; + $html .= '' . "\n"; } return $html; @@ -1013,10 +1044,12 @@ class JavascriptRenderer $suffix = !$initialize ? '(ajax)' : null; $js .= $this->getAddDatasetCode($this->debugBar->getCurrentRequestId(), $this->debugBar->getData(), $suffix); + $nonce = $this->getNonceAttribute(); + if ($this->useRequireJs){ - return "\n"; + return "\n"; } else { - return "\n"; + return "\n"; } } @@ -1149,4 +1182,17 @@ class JavascriptRenderer ); return $js; } + + /** + * If a nonce it set, create the correct attribute + * @return string + */ + protected function getNonceAttribute() + { + if ($nonce = $this->getCspNonce()) { + return ' nonce="' . $nonce .'"'; + } + + return ''; + } } diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/debugbar.css b/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/debugbar.css index 502d2482954..606e51dab0e 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/debugbar.css +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/debugbar.css @@ -116,11 +116,10 @@ div.phpdebugbar-closed, div.phpdebugbar-minimized{ } /* -------------------------------------- */ -div.phpdebugbar-header, a.phpdebugbar-restore-btn { +a.phpdebugbar-restore-btn { background: #efefef url(data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2020%2020%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Ccircle%20fill%3D%22%23000%22%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%229%22%2F%3E%3Cpath%20d%3D%22M6.039%208.342c.463%200%20.772.084.927.251.154.168.191.455.11.862-.084.424-.247.727-.487.908-.241.182-.608.272-1.1.272h-.743l.456-2.293h.837zm-2.975%204.615h1.22l.29-1.457H5.62c.461%200%20.84-.047%201.139-.142.298-.095.569-.254.812-.477.205-.184.37-.387.497-.608.127-.222.217-.466.27-.734.13-.65.032-1.155-.292-1.518-.324-.362-.84-.543-1.545-.543H4.153l-1.089%205.479zM9.235%206.02h1.21l-.289%201.458h1.079c.679%200%201.147.115%201.405.347.258.231.335.607.232%201.125l-.507%202.55h-1.23l.481-2.424c.055-.276.035-.464-.06-.565-.095-.1-.298-.15-.608-.15H9.98L9.356%2011.5h-1.21l1.089-5.48M15.566%208.342c.464%200%20.773.084.928.251.154.168.19.455.11.862-.084.424-.247.727-.488.908-.24.182-.607.272-1.1.272h-.742l.456-2.293h.836zm-2.974%204.615h1.22l.29-1.457h1.046c.461%200%20.84-.047%201.139-.142.298-.095.569-.254.812-.477.205-.184.37-.387.497-.608.127-.222.217-.466.27-.734.129-.65.032-1.155-.292-1.518-.324-.362-.84-.543-1.545-.543H13.68l-1.089%205.479z%22%20fill%3D%22%23FFF%22%2F%3E%3C%2Fsvg%3E) no-repeat 5px 4px / 20px 20px; } div.phpdebugbar-header { - padding-left: 29px; min-height: 26px; line-height: 16px; } diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/debugbar.js b/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/debugbar.js index 09c3caebdc6..66658d25938 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/debugbar.js +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/debugbar.js @@ -477,6 +477,10 @@ if (typeof(PhpDebugBar) == 'undefined') { this.$dragCapture = $('
').addClass(csscls('drag-capture')).appendTo(this.$el); this.$resizehdle = $('
').addClass(csscls('resize-handle')).appendTo(this.$el); this.$header = $('
').addClass(csscls('header')).appendTo(this.$el); + this.$headerBtn = $('').addClass(csscls('restore-btn')).appendTo(this.$header); + this.$headerBtn.click(function() { + self.close(); + }); this.$headerLeft = $('
').addClass(csscls('header-left')).appendTo(this.$header); this.$headerRight = $('
').addClass(csscls('header-right')).appendTo(this.$header); var $body = this.$body = $('
').addClass(csscls('body')).appendTo(this.$el); @@ -944,6 +948,7 @@ if (typeof(PhpDebugBar) == 'undefined') { var self = this; this.openHandler.load(id, function(data) { self.addDataSet(data, id, suffix, show); + self.resize(); callback && callback(data); }); }, @@ -1160,7 +1165,7 @@ if (typeof(PhpDebugBar) == 'undefined') { var self = this; var proxied = window.fetch; - if (proxied === undefined && proxied.polyfill !== undefined) { + if (proxied !== undefined && proxied.polyfill !== undefined) { return; } @@ -1169,8 +1174,6 @@ if (typeof(PhpDebugBar) == 'undefined') { promise.then(function (response) { self.handle(response); - }, function (e) { - self.handle(response); }); return promise; @@ -1204,7 +1207,9 @@ if (typeof(PhpDebugBar) == 'undefined') { var xhr = this; this.addEventListener("readystatechange", function() { var skipUrl = self.debugbar.openHandler ? self.debugbar.openHandler.get('url') : null; - if (xhr.readyState == 4 && url.indexOf(skipUrl) !== 0) { + var href = (typeof url === 'string') ? url : url.href; + + if (xhr.readyState == 4 && href.indexOf(skipUrl) !== 0) { self.handle(xhr); } }, false); diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/widgets.js b/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/widgets.js index b4a583dfc52..a0cd2888ba6 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/widgets.js +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/widgets.js @@ -216,11 +216,11 @@ if (typeof(PhpDebugBar) == 'undefined') { }); // ------------------------------------------------------------------ - + /** * An extension of KVListWidget where the data represents a list * of variables - * + * * Options: * - data */ @@ -353,7 +353,7 @@ if (typeof(PhpDebugBar) == 'undefined') { this.$list.$el.appendTo(this.$el); this.$toolbar = $('
').addClass(csscls('toolbar')).appendTo(this.$el); - $('') + $('') .on('change', function() { self.set('search', this.value); }) .appendTo(this.$toolbar); @@ -468,7 +468,7 @@ if (typeof(PhpDebugBar) == 'undefined') { m.appendTo(li); this.$el.append(li); - + if (measure.params && !$.isEmptyObject(measure.params)) { var table = $('
Params
').addClass(csscls('params')).appendTo(li); for (var key in measure.params) { @@ -518,7 +518,7 @@ if (typeof(PhpDebugBar) == 'undefined') { }); // ------------------------------------------------------------------ - + /** * Widget for the displaying exceptions * @@ -550,20 +550,26 @@ if (typeof(PhpDebugBar) == 'undefined') { } if (e.surrounding_lines) { var pre = createCodeBlock(e.surrounding_lines.join(""), 'php').addClass(csscls('file')).appendTo(li); - li.click(function() { - if (pre.is(':visible')) { - pre.hide(); - } else { - pre.show(); - } - }); + if (!e.stack_trace_html) { + // This click event makes the var-dumper hard to use. + li.click(function () { + if (pre.is(':visible')) { + pre.hide(); + } else { + pre.show(); + } + }); + } } - if (e.stack_trace) { - e.stack_trace.split("\n").forEach(function(trace) { - var $traceLine = $('
'); - $('').addClass(csscls('filename')).text(trace).appendTo($traceLine); - $traceLine.appendTo(li); - }); + if (e.stack_trace_html) { + var $trace = $('').addClass(csscls('filename')).html(e.stack_trace_html); + $trace.appendTo(li); + } else if (e.stack_trace) { + e.stack_trace.split("\n").forEach(function (trace) { + var $traceLine = $('
'); + $('').addClass(csscls('filename')).text(trace).appendTo($traceLine); + $traceLine.appendTo(li); + }); } }}); this.$list.$el.appendTo(this.$el); @@ -578,6 +584,6 @@ if (typeof(PhpDebugBar) == 'undefined') { } }); - + })(PhpDebugBar.$); diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/widgets/templates/widget.css b/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/widgets/templates/widget.css index 29f6ab979bc..1cd7df41c07 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/widgets/templates/widget.css +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/widgets/templates/widget.css @@ -11,6 +11,7 @@ div.phpdebugbar-widgets-templates div.phpdebugbar-widgets-status { div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-render-time, div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-memory, div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-param-count, +div.phpdebugbar-widgets-templates a.phpdebugbar-widgets-editor-link, div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-type { float: right; margin-left: 8px; @@ -19,6 +20,7 @@ div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-type { div.phpdebugbar-widgets-templates div.phpdebugbar-widgets-status span.phpdebugbar-widgets-render-time, div.phpdebugbar-widgets-templates div.phpdebugbar-widgets-status span.phpdebugbar-widgets-memory, div.phpdebugbar-widgets-templates div.phpdebugbar-widgets-status span.phpdebugbar-widgets-param-count, +div.phpdebugbar-widgets-templates div.phpdebugbar-widgets-status a.phpdebugbar-widgets-editor-link, div.phpdebugbar-widgets-templates div.phpdebugbar-widgets-status span.phpdebugbar-widgets-type { color: #555; } @@ -26,12 +28,17 @@ div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-render-time:before, div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-memory:before, div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-param-count:before, div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-type:before, +div.phpdebugbar-widgets-templates a.phpdebugbar-widgets-editor-link:before, div.phpdebugbar-widgets-templates a.phpdebugbar-widgets-editor-link:before { font-family: PhpDebugbarFontAwesome; margin-right: 4px; font-size: 12px; } +div.phpdebugbar-widgets-templates a.phpdebugbar-widgets-editor-link:hover +{ + color: #ffffff; +} div.phpdebugbar-widgets-templates span.phpdebugbar-widgets-render-time:before { content: "\f017"; } diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/widgets/templates/widget.js b/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/widgets/templates/widget.js index 8763e7eda68..056e9c4196d 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/widgets/templates/widget.js +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/Resources/widgets/templates/widget.js @@ -39,6 +39,9 @@ if (typeof(tpl.type) != 'undefined' && tpl.type) { $('').addClass(csscls('type')).text(tpl.type).appendTo(li); } + if (typeof(tpl.editorLink) != 'undefined' && tpl.editorLink) { + $('').addClass(csscls('editor-link')).text('file').appendTo(li); + } if (tpl.params && !$.isEmptyObject(tpl.params)) { var table = $('
Params
').addClass(csscls('params')).appendTo(li); for (var key in tpl.params) { diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/Storage/FileStorage.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/Storage/FileStorage.php index 98923e272b3..41c2be55a3c 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/Storage/FileStorage.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/Storage/FileStorage.php @@ -62,7 +62,7 @@ class FileStorage implements StorageInterface //Sort the files, newest first usort($files, function ($a, $b) { - return $a['time'] < $b['time']; + return $a['time'] <=> $b['time']; }); //Load the metadata and filter the results. diff --git a/htdocs/includes/maximebf/debugbar/src/DebugBar/Storage/RedisStorage.php b/htdocs/includes/maximebf/debugbar/src/DebugBar/Storage/RedisStorage.php index f145369660b..fe79082dc14 100644 --- a/htdocs/includes/maximebf/debugbar/src/DebugBar/Storage/RedisStorage.php +++ b/htdocs/includes/maximebf/debugbar/src/DebugBar/Storage/RedisStorage.php @@ -15,13 +15,15 @@ namespace DebugBar\Storage; */ class RedisStorage implements StorageInterface { + /** @var \Predis\Client|\Redis */ protected $redis; + /** @var string */ protected $hash; /** - * @param \Predis\Client $redis Redis Client - * @param string $hash + * @param \Predis\Client|\Redis $redis Redis Client + * @param string $hash */ public function __construct($redis, $hash = 'phpdebugbar') { @@ -34,9 +36,9 @@ class RedisStorage implements StorageInterface */ public function save($id, $data) { - $this->redis->hset("$this->hash:meta", $id, serialize($data['__meta'])); + $this->redis->hSet("$this->hash:meta", $id, serialize($data['__meta'])); unset($data['__meta']); - $this->redis->hset("$this->hash:data", $id, serialize($data)); + $this->redis->hSet("$this->hash:data", $id, serialize($data)); } /** @@ -44,19 +46,25 @@ class RedisStorage implements StorageInterface */ public function get($id) { - return array_merge(unserialize($this->redis->hget("$this->hash:data", $id)), - array('__meta' => unserialize($this->redis->hget("$this->hash:meta", $id)))); + return array_merge(unserialize($this->redis->hGet("$this->hash:data", $id)), + array('__meta' => unserialize($this->redis->hGet("$this->hash:meta", $id)))); } /** * {@inheritdoc} */ - public function find(array $filters = array(), $max = 20, $offset = 0) + public function find(array $filters = [], $max = 20, $offset = 0) { - $results = array(); + $results = []; $cursor = "0"; + $isPhpRedis = get_class($this->redis) === 'Redis'; + do { - list($cursor, $data) = $this->redis->hscan("$this->hash:meta", $cursor); + if ($isPhpRedis) { + $data = $this->redis->hScan("$this->hash:meta", $cursor); + } else { + [$cursor, $data] = $this->redis->hScan("$this->hash:meta", $cursor); + } foreach ($data as $meta) { if ($meta = unserialize($meta)) { @@ -66,11 +74,11 @@ class RedisStorage implements StorageInterface } } } while($cursor); - - usort($results, function ($a, $b) { - return $a['utime'] < $b['utime']; + + usort($results, static function ($a, $b) { + return $b['utime'] <=> $a['utime']; }); - + return array_slice($results, $offset, $max); } @@ -92,6 +100,7 @@ class RedisStorage implements StorageInterface */ public function clear() { - $this->redis->del($this->hash); + $this->redis->del("$this->hash:data"); + $this->redis->del("$this->hash:meta"); } } diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index 9bfdc55a7b0..30af80d1f8e 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -561,3 +561,6 @@ ALTER TABLE llx_bank ADD COLUMN amount_main_currency double(24,8) NULL; ALTER TABLE llx_commande_fournisseurdet MODIFY COLUMN ref varchar(128); ALTER TABLE llx_facture_fourn_det MODIFY COLUMN ref varchar(128); + +UPDATE llx_c_tva SET localtax2 = '-19:-15:-9' WHERE localtax2 = '-19' AND localtax2_type = '5' AND fk_pays = 4 AND taux = 21; + diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 2c72878d40e..f189c96939d 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -349,8 +349,8 @@ ACCOUNTING_ENABLE_AUTOLETTERING=Enable the automatic lettering when transferring ## Export NotExportLettering=Do not export the lettering when generating the file -NotifiedExportDate=Flag exported lines as Exported (to modify a line, you will need to delete the whole transaction and re-transfert it into accounting) -NotifiedValidationDate=Validate and Lock the exported entries (same effect than the "%s" feature, modification and deletion of the lines will DEFINITELY not be possible) +NotifiedExportDate=Flag not yet exported lines as Exported (to modify a line flagged as exported, you will need to delete the whole transaction and re-transfert it into accounting) +NotifiedValidationDate=Validate and Lock the exported entries not yet already locked (same effect than the "%s" feature, modification and deletion of the lines will DEFINITELY not be possible) NotifiedExportFull=Export documents ? DateValidationAndLock=Date validation and lock ConfirmExportFile=Confirmation of the generation of the accounting export file ? diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 0214b73292d..484e207e347 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -51,6 +51,8 @@ ClientSortingCharset=Client collation WarningModuleNotActive=Module %s must be enabled WarningOnlyPermissionOfActivatedModules=Only permissions related to activated modules are shown here. You can activate other modules in the Home->Setup->Modules page. DolibarrSetup=Dolibarr install or upgrade +DolibarrUpgrade=Dolibarr upgrade +DolibarrAddonInstall=Installation of Addon/External modules (uploaded or generated) InternalUsers=Internal users ExternalUsers=External users UserInterface=User interface @@ -2264,6 +2266,8 @@ DatabasePasswordNotObfuscated=Database password is NOT obfuscated in conf file APIsAreNotEnabled=APIs modules are not enabled YouShouldSetThisToOff=You should set this to 0 or off InstallAndUpgradeLockedBy=Install and upgrades are locked by the file %s +InstallLockedBy=Install/Reinstall is locked by the file %s +InstallOfAddonIsNotBlocked=Installations of addons are not locked. Create a file installmodules.lock into directory %s to block installations of external addons/modules. OldImplementation=Old implementation PDF_SHOW_LINK_TO_ONLINE_PAYMENT=If some online payment modules are enabled (Paypal, Stripe, ...), add a link on the PDF to make the online payment DashboardDisableGlobal=Disable globally all the thumbs of open objects diff --git a/htdocs/langs/en_US/salaries.lang b/htdocs/langs/en_US/salaries.lang index d5f5b7e7544..e94669516a8 100644 --- a/htdocs/langs/en_US/salaries.lang +++ b/htdocs/langs/en_US/salaries.lang @@ -24,4 +24,4 @@ SalariesStatistics=Salary statistics SalariesAndPayments=Salaries and payments ConfirmDeleteSalaryPayment=Do you want to delete this salary payment ? FillFieldFirst=Fill employee field first -UpdateAmountWithLastSalary=Set amount with last salary +UpdateAmountWithLastSalary=Set amount of last salary diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index ea360315fba..8f539c507b4 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -354,7 +354,7 @@ if (!defined('NOSESSION')) { } -// Init the 5 global objects, this include will make the 'new Xxx()' and set properties for: $conf, $db, $langs, $user, $mysoc +// Init the 6 global objects, this include will make the 'new Xxx()' and set properties for: $conf, $db, $langs, $user, $mysoc, $hookmanager require_once 'master.inc.php'; // If software has been locked. Only login $conf->global->MAIN_ONLY_LOGIN_ALLOWED is allowed. @@ -2454,27 +2454,39 @@ function top_menu_user($hideloginname = 0, $urllogout = '') } jQuery(document).ready(function() { jQuery(document).on("click", function(event) { + // console.log("Click somewhere on screen"); if (!$(event.target).closest("#topmenu-login-dropdown").length) { closeTopMenuLoginDropdown(); } }); - '; + + jQuery(".butAction.dropdown-toggle").on("click", function(event) { + console.log("Click on .butAction.dropdown-toggle"); + var parentholder = jQuery(".butAction.dropdown-toggle").closest(".dropdown"); + var offset = parentholder.offset(); + var left = offset.left; + var right = $(document).width() - offset.left - parentholder.width(); + parentholder.toggleClass("open"); + parentholder.children(".dropdown-content").css({"right": right+"px", "left": "auto"}); + }); + '; + if ($conf->theme != 'md') { $btnUser .= ' jQuery("#topmenu-login-dropdown .dropdown-toggle").on("click", function(event) { - console.log("toggle login dropdown"); + console.log("Click on #topmenu-login-dropdown .dropdown-toggle"); event.preventDefault(); jQuery("#topmenu-login-dropdown").toggleClass("open"); }); jQuery("#topmenulogincompanyinfo-btn").on("click", function() { - console.log("Clik on topmenulogincompanyinfo-btn"); + console.log("Clik on #topmenulogincompanyinfo-btn"); jQuery("#topmenulogincompanyinfo").slideToggle(); }); jQuery("#topmenuloginmoreinfo-btn").on("click", function() { - console.log("Clik on topmenuloginmoreinfo-btn"); + console.log("Clik on #topmenuloginmoreinfo-btn"); jQuery("#topmenuloginmoreinfo").slideToggle(); });'; } @@ -2515,6 +2527,7 @@ function top_menu_quickadd() } }); $("#topmenu-quickadd-dropdown .dropdown-toggle").on("click", function(event) { + console.log("Click on #topmenu-quickadd-dropdown .dropdown-toggle"); openQuickAddDropDown(); }); // Key map shortcut @@ -2762,7 +2775,7 @@ function top_menu_bookmark() }); jQuery("#topmenu-bookmark-dropdown .dropdown-toggle").on("click", function(event) { - console.log("toggle bookmark dropdown"); + console.log("Click on #topmenu-bookmark-dropdown .dropdown-toggle"); openBookMarkDropDown(); }); @@ -2904,7 +2917,7 @@ function top_menu_search() // Open drop down jQuery("#topmenu-global-search-dropdown .dropdown-toggle").on("click", function(event) { - console.log("toggle search dropdown"); + console.log("click on toggle #topmenu-global-search-dropdown .dropdown-toggle"); openGlobalSearchDropDown(); }); diff --git a/htdocs/master.inc.php b/htdocs/master.inc.php index 2a90d1e1743..e7e532d666d 100644 --- a/htdocs/master.inc.php +++ b/htdocs/master.inc.php @@ -35,6 +35,8 @@ // Include the conf.php and functions.lib.php and security.lib.php. This defined the constants like DOL_DOCUMENT_ROOT, DOL_DATA_ROOT, DOL_URL_ROOT... // This file may have been already required by main.inc.php. But may not by scripts. So, here the require_once must be kept. require_once 'filefunc.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/conf.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; if (!function_exists('is_countable')) { @@ -53,8 +55,6 @@ if (!function_exists('is_countable')) { * Create $conf object */ -require_once DOL_DOCUMENT_ROOT.'/core/class/conf.class.php'; - $conf = new Conf(); // Set properties specific to database @@ -174,6 +174,11 @@ if (!defined('NOREQUIREUSER')) { $user = new User($db); } +/* + * Create the global $hookmanager object + */ +$hookmanager = new HookManager($db); + /* * Load object $conf @@ -241,10 +246,6 @@ if (!defined('NOREQUIRETRAN')) { } -// Create the global $hookmanager object -include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; -$hookmanager = new HookManager($db); - if (!defined('MAIN_LABEL_MENTION_NPR')) { define('MAIN_LABEL_MENTION_NPR', 'NPR'); diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 30d2c1dd842..c0c29ea2864 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -862,6 +862,14 @@ if ($dirins && $action == 'initdoc' && !empty($module)) { dolReplaceInFile($destfile, $arrayreplacement); + // add table of properties + $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; + $destdir = $dirins.'/'.strtolower($module); + $objects = dolGetListOfObjectClasses($destdir); + foreach ($objects as $path=>$obj) { + writePropsInAsciiDoc($path, $obj, $destfile); + } + // Delete old documentation files $FILENAMEDOC = $modulelowercase.'.html'; $FILENAMEDOCPDF = $modulelowercase.'.pdf'; diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 2a9b583b9e9..b54eff6a0e3 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -82,7 +82,7 @@ class MyObject extends CommonObject * 'date', 'datetime', 'timestamp', 'duration', * 'boolean', 'checkbox', 'radio', 'array', * 'mail', 'phone', 'url', 'password', 'ip' - * Note: Filter must be a Dolibarr filter syntax string. Example: "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.status:!=:0) or (t.nature:is:NULL)" + * Note: Filter must be a Dolibarr Universal Filter syntax string. Example: "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.status:!=:0) or (t.nature:is:NULL)" * 'label' the translation key. * 'picto' is code of a picto to show before value in forms * 'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM' or 'isModEnabled("multicurrency")' ...) @@ -260,7 +260,7 @@ class MyObject extends CommonObject } // Example to show how to set values of fields definition dynamically - /*if ($user->rights->mymodule->myobject->read) { + /*if ($user->hasRights->('mymodule', 'myobject', 'read')) { $this->fields['myfield']['visible'] = 1; $this->fields['myfield']['noteditable'] = 0; }*/ diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php b/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php index bcd437ad21d..0da8c7b3150 100644 --- a/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php +++ b/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php @@ -225,6 +225,7 @@ class doc_generic_myobject_odt extends ModelePDFMyObject { // phpcs:enable global $user, $langs, $conf, $mysoc, $hookmanager; + global $action; if (empty($srctemplatepath)) { dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING); @@ -232,12 +233,7 @@ class doc_generic_myobject_odt extends ModelePDFMyObject } // Add odtgeneration hook - if (!is_object($hookmanager)) { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($this->db); - } $hookmanager->initHooks(array('odtgeneration')); - global $action; if (!is_object($outputlangs)) { $outputlangs = $langs; diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php b/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php index 21397085729..6b66dea857e 100644 --- a/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php +++ b/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php @@ -270,10 +270,6 @@ class pdf_standard_myobject extends ModelePDFMyObject if (file_exists($dir)) { // Add pdfgeneration hook - if (!is_object($hookmanager)) { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($this->db); - } $hookmanager->initHooks(array('pdfgeneration')); $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); global $action; diff --git a/htdocs/product/agenda.php b/htdocs/product/agenda.php index b780f1b3229..84dcbbf2ab9 100644 --- a/htdocs/product/agenda.php +++ b/htdocs/product/agenda.php @@ -31,6 +31,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; diff --git a/htdocs/product/canvas/product/actions_card_product.class.php b/htdocs/product/canvas/product/actions_card_product.class.php index 56ebab13344..d9a20ac7f3e 100644 --- a/htdocs/product/canvas/product/actions_card_product.class.php +++ b/htdocs/product/canvas/product/actions_card_product.class.php @@ -77,7 +77,6 @@ class ActionsCardProduct public function assign_values(&$action, $id = 0, $ref = '') { // phpcs:enable - global $limit, $offset, $sortfield, $sortorder; global $conf, $langs, $user, $mysoc, $canvas; global $form, $formproduct; diff --git a/htdocs/product/canvas/service/actions_card_service.class.php b/htdocs/product/canvas/service/actions_card_service.class.php index 021de9b215e..e639568459e 100644 --- a/htdocs/product/canvas/service/actions_card_service.class.php +++ b/htdocs/product/canvas/service/actions_card_service.class.php @@ -81,9 +81,8 @@ class ActionsCardService public function assign_values(&$action, $id = 0, $ref = '') { // phpcs:enable - global $limit, $offset, $sortfield, $sortorder; global $conf, $langs, $user, $mysoc, $canvas; - global $form, $formproduct; + global $form; $tmpobject = new Product($this->db); if (!empty($id) || !empty($ref)) { diff --git a/htdocs/product/card.php b/htdocs/product/card.php index b42384e934d..9141810d9c8 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -2199,7 +2199,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { $arrayselected[] = $cat->id; } } - if (GETPOSTISSET('categories', 'array')) { + if (GETPOSTISARRAY('categories')) { foreach (GETPOST('categories', 'array') as $cat) { $arrayselected[] = $cat; } diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 86b2abfa8f2..0d7b4675bcf 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -5687,10 +5687,6 @@ class Product extends CommonObject $this->stock_theorique += ($stock_commande_fournisseur - $stock_reception_fournisseur); } - if (!is_object($hookmanager)) { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($this->db); - } $hookmanager->initHooks(array('productdao')); $parameters = array('id'=>$this->id, 'includedraftpoforvirtual' => $includedraftpoforvirtual); // Note that $action and $object may have been modified by some hooks diff --git a/htdocs/product/dynamic_price/class/price_parser.class.php b/htdocs/product/dynamic_price/class/price_parser.class.php index 412d015f8b9..47e290677c6 100644 --- a/htdocs/product/dynamic_price/class/price_parser.class.php +++ b/htdocs/product/dynamic_price/class/price_parser.class.php @@ -124,15 +124,15 @@ class PriceParser */ public function parseExpression($product, $expression, $values) { - global $user; - global $hookmanager; + global $user, $hookmanager, $extrafields; + $action = 'PARSEEXPRESSION'; - if ($result = $hookmanager->executeHooks('doDynamiPrice', array( - 'expression' =>$expression, - 'product' => $product, - 'values' => $values + if ($reshook = $hookmanager->executeHooks('doDynamiPrice', array( + 'expression' => &$expression, + 'product' => &$product, + 'values' => &$values ), $this, $action)) { - return $result; + return $hookmanager->resArray['return']; } //Check if empty $expression = trim($expression); @@ -154,8 +154,12 @@ class PriceParser "pmp" => $product->pmp, )); - //Retrieve all extrafield for product and add it to values - $extrafields = new ExtraFields($this->db); + // Retrieve all extrafields if not already not know (should not happen) + if (! is_object($extrafields)) { + $extrafields = new ExtraFields($this->db); + $extrafields->fetch_name_optionals_label(); + } + $product->fetch_optionals(); if (is_array($extrafields->attributes[$product->table_element]['label'])) { foreach ($extrafields->attributes[$product->table_element]['label'] as $key => $label) { diff --git a/htdocs/product/list.php b/htdocs/product/list.php index e227d88ebc8..670e77ad4d7 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2019 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2012-2016 Marcos García - * Copyright (C) 2013-2019 Juanjo Menent + * Copyright (C) 2013-2023 Juanjo Menent * Copyright (C) 2013-2015 Raphaël Doursenaud * Copyright (C) 2013 Jean Heimburger * Copyright (C) 2013 Cédric Salvador @@ -574,7 +574,7 @@ if ($search_accountancy_code_buy_export) { $sql .= natural_search($alias_product_perentity . '.accountancy_code_buy_export', $search_accountancy_code_buy_export); } if (!empty($conf->global->PRODUCT_USE_UNITS) && $search_units) { - $sql .= natural_search('cu.rowid', $search_units); + $sql .= natural_search('cu.rowid', $search_units); } // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; @@ -1026,7 +1026,7 @@ if (!empty($arrayfields['p.volume_units']['checked'])) { // Unit if (!empty($arrayfields['cu.label']['checked'])) { print '
'; - print $form->selectUnits($search_units, 'search_units', 1); + print $form->selectUnits($search_units, 'search_units', 1); print '   '; @@ -602,6 +635,10 @@ print_liste_field_titre("PhysicalStock", $_SERVER["PHP_SELF"], "stock_physique", print_liste_field_titre(''); print_liste_field_titre("ProductStatusOnSell", $_SERVER["PHP_SELF"], "p.tosell", "", $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre("ProductStatusOnBuy", $_SERVER["PHP_SELF"], "p.tobuy", "", $param, '', $sortfield, $sortorder, 'right '); +// Hook fields +$parameters = array('param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); +$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { print_liste_field_titre(''); } @@ -741,6 +778,11 @@ while ($i < $imaxinloop) { print ''.$product_static->LibStatut($objp->tobuy, 5, 1).''.convertSecondToTime($totalarray['totalbilled'], $plannedworkloadoutputformat).''.price($totalarray['totalbudgetamount'], 0, $langs, 1, 0, 0, $conf->currency).''; if (isset($totalarray['type']) && $totalarray['type'][$i] == 'duration') { print (!empty($totalarray['val'][$totalarray['pos'][$i]])?convertSecondToTime($totalarray['val'][$totalarray['pos'][$i]], 'allhourmin'):0); @@ -1544,7 +1544,7 @@ if (isset($totalarray['totaldurationeffectivefield']) || isset($totalarray['tota print price(!empty($totalarray['val'][$totalarray['pos'][$i]])?$totalarray['val'][$totalarray['pos'][$i]]:0); } print '
'.$langs->trans("NoRecordFound").'
'.$langs->trans("NoRecordFound").'
'.$langs->trans("VATRate").''; - print $form->load_tva("tva_tx", $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, '', false, 1); + print $form->load_tva("tva_tx", GETPOST("tva_tx", "alpha"), $mysoc, '', $object->id, 0, '', false, 1); print '
'; - print $form->selectPriceBaseType($object->price_base_type, "price_base_type"); + print $form->selectPriceBaseType(GETPOST("price_base_type", "aZ09"), "price_base_type"); print '
'.$langs->trans("CashDeskBankAccountForSell").''; print img_picto('', 'bank_account', 'class="pictofixedwidth"'); - $form->select_comptes(getDolGlobalInt('CASHDESK_ID_BANKACCOUNT_CASH'.$terminaltouse), 'CASHDESK_ID_BANKACCOUNT_CASH'.$terminaltouse, 0, "courant=2", 1); + print $form->select_comptes(getDolGlobalInt('CASHDESK_ID_BANKACCOUNT_CASH'.$terminaltouse), 'CASHDESK_ID_BANKACCOUNT_CASH'.$terminaltouse, 0, "courant=2", 1, '', 0, '', 1); + print ' '; if (getDolGlobalInt('CASHDESK_ID_BANKACCOUNT_CASH'.$terminaltouse)) { $atleastonefound++; } @@ -175,7 +176,8 @@ if (isModEnabled("banque")) { print '
'.$langs->trans("CashDeskBankAccountForCheque").''; print img_picto('', 'bank_account', 'class="pictofixedwidth"'); - $form->select_comptes(getDolGlobalInt('CASHDESK_ID_BANKACCOUNT_CHEQUE'.$terminaltouse), 'CASHDESK_ID_BANKACCOUNT_CHEQUE'.$terminaltouse, 0, "courant=1", 1); + print $form->select_comptes(getDolGlobalInt('CASHDESK_ID_BANKACCOUNT_CHEQUE'.$terminaltouse), 'CASHDESK_ID_BANKACCOUNT_CHEQUE'.$terminaltouse, 0, "courant=1", 1, '', 0, '', 1); + print ' '; if (getDolGlobalInt('CASHDESK_ID_BANKACCOUNT_CHEQUE'.$terminaltouse)) { $atleastonefound++; } @@ -183,7 +185,8 @@ if (isModEnabled("banque")) { print '
'.$langs->trans("CashDeskBankAccountForCB").''; print img_picto('', 'bank_account', 'class="pictofixedwidth"'); - $form->select_comptes(getDolGlobalInt('CASHDESK_ID_BANKACCOUNT_CB'.$terminaltouse), 'CASHDESK_ID_BANKACCOUNT_CB'.$terminaltouse, 0, "courant=1", 1); + print $form->select_comptes(getDolGlobalInt('CASHDESK_ID_BANKACCOUNT_CB'.$terminaltouse), 'CASHDESK_ID_BANKACCOUNT_CB'.$terminaltouse, 0, "courant=1", 1, '', 0, '', 1); + print ' '; if (getDolGlobalInt('CASHDESK_ID_BANKACCOUNT_CB'.$terminaltouse)) { $atleastonefound++; } @@ -230,7 +233,8 @@ if (isModEnabled("banque")) { print '
'.$langs->trans("CashDeskBankAccountForSumup").''; print img_picto('', 'bank_account', 'class="pictofixedwidth"'); - $form->select_comptes(getDolGlobalInt('CASHDESK_ID_BANKACCOUNT_SUMUP'.$terminaltouse), 'CASHDESK_ID_BANKACCOUNT_SUMUP'.$terminaltouse, 0, "courant=1", 1); + print $form->select_comptes(getDolGlobalInt('CASHDESK_ID_BANKACCOUNT_SUMUP'.$terminaltouse), 'CASHDESK_ID_BANKACCOUNT_SUMUP'.$terminaltouse, 0, "courant=1", 1, '', 0, '', 1); + print ' '; if (getDolGlobalInt('CASHDESK_ID_BANKACCOUNT_SUMUP'.$terminaltouse)) { $atleastonefound++; } @@ -249,7 +253,8 @@ if (isModEnabled("banque")) { } $cour = preg_match('/^LIQ.*/', $modep->code) ? 2 : 1; print img_picto('', 'bank_account', 'class="pictofixedwidth"'); - $form->select_comptes(getDolGlobalInt($name), $name, 0, "courant=".$cour, 1); + print $form->select_comptes(getDolGlobalInt($name), $name, 0, "courant=".$cour, 1, '', 0, '', 1); + print ' '; print '