Merge remote-tracking branch 'upstream/develop' into workstation
This commit is contained in:
commit
7ff542552b
20
ChangeLog
20
ChangeLog
@ -199,8 +199,7 @@ NEW: add option "If the feature to manage kits of module Stock is used, show det
|
||||
|
||||
For developers:
|
||||
---------------
|
||||
NEW: add substitution key __MEMBER_TYPE__
|
||||
NEW: add substitution key __TYPE__
|
||||
NEW: add __MEMBER_TYPE__ and __TYPE__ substitution key
|
||||
NEW: add function dolButtonToOpenUrlInDialogPopup() to be able to open page into a popup
|
||||
NEW: show line number on intervention card (via MAIN_VIEW_LINE_NUMBER)
|
||||
NEW: add some fields to link website page to an other object
|
||||
@ -212,12 +211,9 @@ NEW: can add event to log into blockedlog module with a constant
|
||||
NEW: add property cssview when declaring fields of an object
|
||||
NEW: can use dynamic code into the 'enabled' property of DAO fields
|
||||
NEW: field ref_ext in llx_commandedet
|
||||
NEW: field ref_ext for Attributes and Combinations
|
||||
NEW: fields ref_ext for Attributes and Combinations
|
||||
NEW: OAuth SCOPE for Admin SDK
|
||||
NEW: retrieve discount from invoice from API
|
||||
NEW: standardizes API thirdparties by email like other object
|
||||
NEW: Thirdparty REST API: endpoint to set price level
|
||||
NEW: use new category API for project list view
|
||||
NEW: Triggers Attributes and Attributes values
|
||||
NEW: add incoterms data into the substitution array
|
||||
NEW: add send context for ticket
|
||||
@ -234,11 +230,12 @@ NEW: API can update a payment
|
||||
NEW: API get member by thirdparty
|
||||
NEW: API get thirdparty by barcode
|
||||
NEW: API get users by email / login
|
||||
NEW: allow to edit field "demand reason" through API
|
||||
NEW: fetch contact by email with REST API
|
||||
NEW: get state by REST API
|
||||
NEW: get state dictionary by REST API
|
||||
NEW: improve Product API for product variants
|
||||
NEW: get state dictionnary by REST API
|
||||
NEW: improve Product API for variant products
|
||||
NEW: retrieve discount from invoice from API
|
||||
NEW: Thirdparty REST API: endpoint to set price level
|
||||
NEW: use new category API for project list view
|
||||
|
||||
HOOKs
|
||||
NEW: add hook on propal card
|
||||
@ -256,7 +253,7 @@ Following changes may create regressions for some external modules, but were nec
|
||||
* All properties ->titre have been renamed into ->title
|
||||
* Property $paiementid in API 'api_supplier_invoices.php' has been renamed into into $payment_mode_id
|
||||
* Property 'num_paiement' has been renamed 'num_payment' everywhere for better code consistency.
|
||||
* The deprecated subsitution key __SIGNATURE__ has been removed. Use __USER_SIGNATURE__ if you used the old syntax in your email templates.
|
||||
* The deprecated subsitution key __SIGNATURE__ has been removed. Replace it with __USER_SIGNATURE__ if you used the old syntax in your email templates.
|
||||
* The hidden option HOLIDAY_MORE_PUBLIC_HOLIDAYS has been removed. Use instead the dictionary table if you need to define custom days of holiday.
|
||||
* If you build a class that implement CommonObject to use the incoterm properties or methods (->fk_incoterm, ->label_incoterm, ->location_incoterm),
|
||||
you must now also include declaration of the Trait 'CommonIncoterm' in your class. All incoterm functions were moved into this Trait.
|
||||
@ -269,6 +266,7 @@ Following changes may create regressions for some external modules, but were nec
|
||||
* Context for hook showSocinfoOnPrint has been moved from "showsocinfoonprint" to "main"
|
||||
* Library htdocs/includes/phpoffice/phpexcel as been removed (replaced with htdocs/includes/phpoffice/PhpSpreadsheet)
|
||||
* Databse transaction in your triggers must be correctly balanced (one close for one open). If not, an error will be returned by the trigger, even if trigger did return error code.
|
||||
* Dolibarr v13 is still compatible with any PHP version between 5.6.0 and 7.4.*; Unit tests are OK with PHP 8.0 but some warnings or troubles may appears with PHP 8.0.
|
||||
|
||||
|
||||
***** ChangeLog for 12.0.4 compared to 12.0.3 *****
|
||||
|
||||
@ -532,6 +532,7 @@ if ($action == 'edit')
|
||||
print '<span class="opacitymedium">'.$langs->trans("EMailsDesc")."</span><br>\n";
|
||||
print "<br>\n";
|
||||
|
||||
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre"><td class="titlefieldmiddle">'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
|
||||
|
||||
@ -552,10 +553,12 @@ if ($action == 'edit')
|
||||
}
|
||||
|
||||
print '</table>';
|
||||
print '</div>';
|
||||
|
||||
if (empty($conf->global->MAIN_DISABLE_ALL_MAILS)) {
|
||||
print '<br>';
|
||||
|
||||
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre"><td class="titlefieldmiddle">'.$langs->trans("MAIN_MAIL_SENDMODE").'</td><td></td></tr>';
|
||||
|
||||
@ -663,6 +666,7 @@ if ($action == 'edit')
|
||||
}
|
||||
|
||||
print '</table>';
|
||||
print '</div>';
|
||||
|
||||
if ($conf->global->MAIN_MAIL_SENDMODE == 'mail' && empty($conf->global->MAIN_HIDE_WARNING_TO_ENCOURAGE_SMTP_SETUP)) {
|
||||
print info_admin($langs->trans("WarningPHPMail").'<br>'.$langs->trans("WarningPHPMailA").'<br>'.$langs->trans("WarningPHPMailB").'<br>'.$langs->trans("WarningPHPMailC").'<br><br>'.$langs->trans("WarningPHPMailD"), 0, 0, 'warning');
|
||||
@ -670,11 +674,12 @@ if ($action == 'edit')
|
||||
|
||||
print '<br>';
|
||||
|
||||
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre"><td class="titlefieldmiddle">'.$langs->trans("OtherOptions").'</td><td></td></tr>';
|
||||
|
||||
// From
|
||||
print '<tr class="oddeven"><td>'.$langs->trans("MAIN_MAIL_EMAIL_FROM", ini_get('sendmail_from') ?ini_get('sendmail_from') : $langs->transnoentities("Undefined")).'</td>';
|
||||
print '<tr class="oddeven"><td class="fieldrequired">'.$langs->trans("MAIN_MAIL_EMAIL_FROM", ini_get('sendmail_from') ?ini_get('sendmail_from') : $langs->transnoentities("Undefined")).'</td>';
|
||||
print '<td>'.$conf->global->MAIN_MAIL_EMAIL_FROM;
|
||||
if (!empty($conf->global->MAIN_MAIL_EMAIL_FROM) && !isValidEmail($conf->global->MAIN_MAIL_EMAIL_FROM)) print img_warning($langs->trans("ErrorBadEMail"));
|
||||
print '</td></tr>';
|
||||
@ -746,6 +751,7 @@ if ($action == 'edit')
|
||||
print '<tr class="oddeven"><td>'.$langs->trans("MAIN_MAIL_ENABLED_USER_DEST_SELECT").'</td><td>'.yn($conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT).'</td></tr>';
|
||||
|
||||
print '</table>';
|
||||
print '</div>';
|
||||
}
|
||||
|
||||
print dol_get_fiche_end();
|
||||
|
||||
@ -1870,11 +1870,6 @@ function email_admin_prepare_head()
|
||||
}
|
||||
}
|
||||
|
||||
$head[$h][0] = DOL_URL_ROOT."/admin/mails_templates.php";
|
||||
$head[$h][1] = $langs->trans("EMailTemplates");
|
||||
$head[$h][2] = 'templates';
|
||||
$h++;
|
||||
|
||||
if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) {
|
||||
$head[$h][0] = DOL_URL_ROOT."/admin/mails_senderprofile_list.php";
|
||||
$head[$h][1] = $langs->trans("EmailSenderProfiles");
|
||||
@ -1882,6 +1877,11 @@ function email_admin_prepare_head()
|
||||
$h++;
|
||||
}
|
||||
|
||||
$head[$h][0] = DOL_URL_ROOT."/admin/mails_templates.php";
|
||||
$head[$h][1] = $langs->trans("EMailTemplates");
|
||||
$head[$h][2] = 'templates';
|
||||
$h++;
|
||||
|
||||
complete_head_from_modules($conf, $langs, null, $head, $h, 'email_admin', 'remove');
|
||||
|
||||
return $head;
|
||||
|
||||
@ -686,7 +686,7 @@ function checkVal($out = '', $check = 'alphanohtml', $filter = null, $options =
|
||||
$out = dol_string_nohtmltag($out, 0);
|
||||
}
|
||||
break;
|
||||
case 'alphawithlgt': // No " and no ../ but we keep < > tags. Can be used for email string like "Name <email>"
|
||||
case 'alphawithlgt': // No " and no ../ but we keep balanced < > tags with no special chars inside. Can be used for email string like "Name <email>"
|
||||
if (!is_array($out)) {
|
||||
// '"' is dangerous because param in url can close the href= or src= and add javascript functions.
|
||||
// '../' is dangerous because it allows dir transversals
|
||||
@ -5762,7 +5762,7 @@ function picto_required()
|
||||
* @param string $stringtoclean String to clean
|
||||
* @param integer $removelinefeed 1=Replace all new lines by 1 space, 0=Only ending new lines are removed others are replaced with \n, 2=Ending new lines are removed but others are kept with a same number of \n than nb of <br> when there is both "...<br>\n..."
|
||||
* @param string $pagecodeto Encoding of input/output string
|
||||
* @param integer $strip_tags 0=Use internal strip, 1=Use strip_tags() php function (bugged when text contains a < char that is not for a html tag)
|
||||
* @param integer $strip_tags 0=Use internal strip, 1=Use strip_tags() php function (bugged when text contains a < char that is not for a html tag or when tags is not closed like '<img onload=aaa')
|
||||
* @param integer $removedoublespaces Replace double space into one space
|
||||
* @return string String cleaned
|
||||
*
|
||||
@ -5783,10 +5783,10 @@ function dol_string_nohtmltag($stringtoclean, $removelinefeed = 1, $pagecodeto =
|
||||
} else {
|
||||
$pattern = "/<[^<>]+>/";
|
||||
// Example of $temp: <a href="/myurl" title="<u>A title</u>">0000-021</a>
|
||||
$temp = preg_replace($pattern, "", $temp); // pass 1
|
||||
// $temp after pass 1: <a href="/myurl" title="A title">0000-021
|
||||
$temp = preg_replace($pattern, "", $temp); // pass 2
|
||||
// $temp after pass 2: 0000-021
|
||||
$temp = preg_replace($pattern, "", $temp); // pass 1 - $temp after pass 1: <a href="/myurl" title="A title">0000-021
|
||||
$temp = preg_replace($pattern, "", $temp); // pass 2 - $temp after pass 2: 0000-021
|
||||
// removed '<' into non closing html tags like '<a'
|
||||
$temp = preg_replace('/<(\w+)/', '\1', $temp);
|
||||
}
|
||||
|
||||
$temp = dol_html_entity_decode($temp, ENT_COMPAT, $pagecodeto);
|
||||
|
||||
@ -1118,6 +1118,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr
|
||||
$projectstatic->ref = $lines[$i]->projectref;
|
||||
$projectstatic->title = $lines[$i]->projectlabel;
|
||||
$projectstatic->public = $lines[$i]->public;
|
||||
$projectstatic->status = $lines[$i]->projectstatus;
|
||||
|
||||
$taskstatic->id = $lines[$i]->id;
|
||||
$taskstatic->ref = ($lines[$i]->ref ? $lines[$i]->ref : $lines[$i]->id);
|
||||
@ -1491,6 +1492,7 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$
|
||||
$projectstatic->title = $lines[$i]->projectlabel;
|
||||
$projectstatic->public = $lines[$i]->public;
|
||||
$projectstatic->thirdparty_name = $lines[$i]->thirdparty_name;
|
||||
$projectstatic->status = $lines[$i]->projectstatus;
|
||||
|
||||
$taskstatic->id = $lines[$i]->id;
|
||||
$taskstatic->ref = ($lines[$i]->ref ? $lines[$i]->ref : $lines[$i]->id);
|
||||
|
||||
@ -197,15 +197,25 @@ class modSociete extends DolibarrModules
|
||||
$this->rights[$r][3] = 0; // La permission est-elle une permission par defaut
|
||||
$this->rights[$r][4] = 'export';
|
||||
|
||||
// 262 : Resteindre l'acces des commerciaux
|
||||
// 262 : Restrict access to sales representative
|
||||
$r++;
|
||||
$this->rights[$r][0] = 262;
|
||||
$this->rights[$r][1] = 'Read all third parties by internal users (otherwise only if commercial contact). Not effective for external users (limited to themselves).';
|
||||
$this->rights[$r][1] = 'Read all third parties (and their objects) by internal users (otherwise only if commercial contact). Not effective for external users (limited to themselves).';
|
||||
$this->rights[$r][2] = 'r';
|
||||
$this->rights[$r][3] = 0;
|
||||
$this->rights[$r][4] = 'client';
|
||||
$this->rights[$r][5] = 'voir';
|
||||
|
||||
/*
|
||||
$r++;
|
||||
$this->rights[$r][0] = 263;
|
||||
$this->rights[$r][1] = 'Read all third parties (without their objects) by internal users (otherwise only if commercial contact). Not effective for external users (limited to themselves).';
|
||||
$this->rights[$r][2] = 'r';
|
||||
$this->rights[$r][3] = 0;
|
||||
$this->rights[$r][4] = 'client';
|
||||
$this->rights[$r][5] = 'readallthirdparties_advance';
|
||||
*/
|
||||
|
||||
$r++;
|
||||
$this->rights[$r][0] = 281; // id de la permission
|
||||
$this->rights[$r][1] = 'Read contacts'; // libelle de la permission
|
||||
|
||||
@ -820,11 +820,17 @@ IMG;
|
||||
// Export to PDF using LibreOffice
|
||||
if ($conf->global->MAIN_ODT_AS_PDF == 'libreoffice')
|
||||
{
|
||||
dol_mkdir($conf->user->dir_temp); // We must be sure the directory exists and is writable
|
||||
|
||||
// We delete and recreate a subdir because the soffice may have change pemrissions on it
|
||||
dol_delete_dir_recursive($conf->user->dir_temp.'/odtaspdf');
|
||||
dol_mkdir($conf->user->dir_temp.'/odtaspdf');
|
||||
|
||||
// Install prerequisites: apt install soffice libreoffice-common libreoffice-writer
|
||||
// using windows libreoffice that must be in path
|
||||
// using linux/mac libreoffice that must be in path
|
||||
// Note PHP Config "fastcgi.impersonate=0" must set to 0 - Default is 1
|
||||
$command ='soffice --headless -env:UserInstallation=file:"//'.$conf->user->dir_temp.'" --convert-to pdf --outdir '. escapeshellarg(dirname($name)). " ".escapeshellarg($name);
|
||||
$command ='soffice --headless -env:UserInstallation=file:\''.$conf->user->dir_temp.'/odtaspdf\' --convert-to pdf --outdir '. escapeshellarg(dirname($name)). " ".escapeshellarg($name);
|
||||
}
|
||||
elseif (preg_match('/unoconv/', $conf->global->MAIN_ODT_AS_PDF))
|
||||
{
|
||||
|
||||
@ -349,7 +349,7 @@ UpdateServerOffline=Update server offline
|
||||
WithCounter=Manage a counter
|
||||
GenericMaskCodes=You may enter any numbering mask. In this mask, the following tags could be used:<br><b>{000000}</b> corresponds to a number which will be incremented on each %s. Enter as many zeros as the desired length of the counter. The counter will be completed by zeros from the left in order to have as many zeros as the mask. <br><b>{000000+000}</b> same as previous but an offset corresponding to the number to the right of the + sign is applied starting on first %s. <br><b>{000000@x}</b> same as previous but the counter is reset to zero when month x is reached (x between 1 and 12, or 0 to use the early months of fiscal year defined in your configuration, or 99 to reset to zero every month). If this option is used and x is 2 or higher, then sequence {yy}{mm} or {yyyy}{mm} is also required. <br><b>{dd}</b> day (01 to 31).<br><b>{mm}</b> month (01 to 12).<br><b>{yy}</b>, <b>{yyyy}</b> or <b>{y}</b> year over 2, 4 or 1 numbers. <br>
|
||||
GenericMaskCodes2=<b>{cccc}</b> the client code on n characters<br><b>{cccc000}</b> the client code on n characters is followed by a counter dedicated for customer. This counter dedicated to customer is reset at same time than global counter.<br><b>{tttt}</b> The code of third party type on n characters (see menu Home - Setup - Dictionary - Types of third parties). If you add this tag, the counter will be different for each type of third party.<br>
|
||||
GenericMaskCodes3=All other characters in the mask will remain intact (except * or ? in 13th position in EAN13).<br>Spaces are not allowed.<br>In EAN13 the last character after the last } in 13th position<br> should be * or ? it will be replaced by the calculated key.<br>
|
||||
GenericMaskCodes3=All other characters in the mask will remain intact (except * or ? in 13th position in EAN13).<br>Spaces are not allowed.<br>In EAN13, the last character after the last } in 13th position should be * or ? . It will be replaced by the calculated key.<br>
|
||||
GenericMaskCodes4a=<u>Example on the 99th %s of the third party TheCompany, with date 2007-01-31:</u><br>
|
||||
GenericMaskCodes4b=<u>Example on third party created on 2007-03-01:</u><br>
|
||||
GenericMaskCodes4c=<u>Example on product created on 2007-03-01:</u><br>
|
||||
@ -805,7 +805,8 @@ PermissionAdvanced253=Create/modify internal/external users and permissions
|
||||
Permission254=Create/modify external users only
|
||||
Permission255=Modify other users password
|
||||
Permission256=Delete or disable other users
|
||||
Permission262=Extend access to all third parties (not only third parties for which that user is a sale representative).<br>Not effective for external users (always limited to themselves for proposals, orders, invoices, contracts, etc.).<br>Not effective for projects (only rules on project permissions, visibility and assignment matters).
|
||||
Permission262=Extend access to all third parties AND their objects (not only third parties for which the user is a sale representative).<br>Not effective for external users (always limited to themselves for proposals, orders, invoices, contracts, etc.).<br>Not effective for projects (only rules on project permissions, visibility and assignment matters).
|
||||
Permission263=Extend access to all third parties WITHOUT their objects (not only third parties for which the user is a sale representative).<br>Not effective for external users (always limited to themselves for proposals, orders, invoices, contracts, etc.).<br>Not effective for projects (only rules on project permissions, visibility and assignment matters).
|
||||
Permission271=Read CA
|
||||
Permission272=Read invoices
|
||||
Permission273=Issue invoices
|
||||
|
||||
@ -83,8 +83,6 @@ Workstations=Workstations
|
||||
WorkstationsDescription=Workstations management
|
||||
WorkstationSetup = Workstations setup
|
||||
WorkstationSetupPage = Workstations setup page
|
||||
WorkstationAbout = About Workstation
|
||||
WorkstationAboutPage = Workstations about page
|
||||
WorkstationList=Workstation list
|
||||
WorkstationCreate=Add new workstation
|
||||
ConfirmEnableWorkstation=Are you sure you want to enable workstation <b>%s</b> ?
|
||||
|
||||
@ -62,7 +62,7 @@ EnhancedValueOfWarehouses=Warehouses value
|
||||
UserWarehouseAutoCreate=Create a user warehouse automatically when creating a user
|
||||
AllowAddLimitStockByWarehouse=Manage also value for minimum and desired stock per pairing (product-warehouse) in addition to the value for minimum and desired stock per product
|
||||
RuleForWarehouse=Rule for warehouses
|
||||
WarehouseAskWarehouseDuringPropal=Set a warehouse on Sale propal
|
||||
WarehouseAskWarehouseDuringPropal=Set a warehouse on Commercial proposals
|
||||
WarehouseAskWarehouseDuringOrder=Set a warehouse on Sale orders
|
||||
UserDefaultWarehouse=Set a warehouse on Users
|
||||
MainDefaultWarehouse=Default warehouse
|
||||
|
||||
@ -51,6 +51,8 @@ if (!empty($_SERVER['MAIN_SHOW_TUNING_INFO']))
|
||||
|
||||
/**
|
||||
* Security: WAF layer for SQL Injection and XSS Injection (scripts) protection (Filters on GET, POST, PHP_SELF).
|
||||
* Warning: Such a protection can't be enough. It is not reliable as it will alwyas be possible to bypass this. Good protection can
|
||||
* only be guaranted by escaping data during output.
|
||||
*
|
||||
* @param string $val Value brut found int $_GET, $_POST or PHP_SELF
|
||||
* @param string $type 1=GET, 0=POST, 2=PHP_SELF, 3=GET without sql reserved keywords (the less tolerant test)
|
||||
@ -120,6 +122,19 @@ function testSqlAndScriptInject($val, $type)
|
||||
$inj += preg_match('/on(keydown|keypress|keyup|load|loadeddata|loadedmetadata|loadstart|offline|online|pagehide|pageshow)\s*=/i', $val);
|
||||
$inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|resize|reset|scroll|search|seeking|select|show|stalled|start|submit|suspend)\s*=/i', $val);
|
||||
$inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting)\s*=/i', $val);
|
||||
|
||||
// We refuse html into html because some hacks try to obfuscate evil strings by inserting HTML into HTML. Example: <img on<a>error=alert(1) to bypass test on onerror
|
||||
$tmpval = preg_replace('/<[^<]+>/', '', $val);
|
||||
// List of dom events is on https://www.w3schools.com/jsref/dom_obj_event.asp
|
||||
$inj += preg_match('/onmouse([a-z]*)\s*=/i', $tmpval); // onmousexxx can be set on img or any html tag like <img title='...' onmouseover=alert(1)>
|
||||
$inj += preg_match('/ondrag([a-z]*)\s*=/i', $tmpval); //
|
||||
$inj += preg_match('/ontouch([a-z]*)\s*=/i', $tmpval); //
|
||||
$inj += preg_match('/on(abort|afterprint|beforeprint|beforeunload|blur|canplay|canplaythrough|change|click|contextmenu|copy|cut)\s*=/i', $tmpval);
|
||||
$inj += preg_match('/on(dblclick|drop|durationchange|ended|error|focus|focusin|focusout|hashchange|input|invalid)\s*=/i', $tmpval);
|
||||
$inj += preg_match('/on(keydown|keypress|keyup|load|loadeddata|loadedmetadata|loadstart|offline|online|pagehide|pageshow)\s*=/i', $tmpval);
|
||||
$inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|resize|reset|scroll|search|seeking|select|show|stalled|start|submit|suspend)\s*=/i', $tmpval);
|
||||
$inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting)\s*=/i', $tmpval);
|
||||
|
||||
//$inj += preg_match('/on[A-Z][a-z]+\*=/', $val); // To lock event handlers onAbort(), ...
|
||||
$inj += preg_match('/:|:|:/i', $val); // refused string ':' encoded (no reason to have it encoded) to lock 'javascript:...'
|
||||
$inj += preg_match('/javascript\s*:/i', $val);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2005-2010 Regis Houssin <regis.houssin@inodbox.com>
|
||||
* Copyright (C) 2010 François Legastelois <flegastelois@teclib.com>
|
||||
* Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
|
||||
* Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
|
||||
*
|
||||
* 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
|
||||
@ -504,19 +504,19 @@ $moreforfilter .= '<div class="divsearchfield">';
|
||||
$moreforfilter .= '<div class="inline-block hideonsmartphone"></div>';
|
||||
$includeonly = 'hierarchyme';
|
||||
if (empty($user->rights->user->user->lire)) $includeonly = array($user->id);
|
||||
$moreforfilter .= img_picto($langs->trans('User'), 'user').$form->select_dolusers($search_usertoprocessid ? $search_usertoprocessid : $usertoprocess->id, 'search_usertoprocessid', $user->rights->user->user->lire ? 0 : 0, null, 0, $includeonly, null, 0, 0, 0, '', 0, '', 'maxwidth200 marginleftonly');
|
||||
$moreforfilter .= img_picto($langs->trans('Filter').' '.$langs->trans('User'), 'user').$form->select_dolusers($search_usertoprocessid ? $search_usertoprocessid : $usertoprocess->id, 'search_usertoprocessid', $user->rights->user->user->lire ? 0 : 0, null, 0, $includeonly, null, 0, 0, 0, '', 0, '', 'maxwidth200 marginleftonly');
|
||||
$moreforfilter .= '</div>';
|
||||
|
||||
if (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT))
|
||||
{
|
||||
$moreforfilter .= '<div class="divsearchfield">';
|
||||
$moreforfilter .= '<div class="inline-block"></div>';
|
||||
$moreforfilter .= img_picto($langs->trans('Project'), 'project').'<input type="text" size="4" name="search_project_ref" class="marginleftonly" value="'.dol_escape_htmltag($search_project_ref).'">';
|
||||
$moreforfilter .= img_picto($langs->trans('Filter').' '.$langs->trans('Project'), 'project').'<input type="text" size="4" name="search_project_ref" class="marginleftonly" value="'.dol_escape_htmltag($search_project_ref).'">';
|
||||
$moreforfilter .= '</div>';
|
||||
|
||||
$moreforfilter .= '<div class="divsearchfield">';
|
||||
$moreforfilter .= '<div class="inline-block"></div>';
|
||||
$moreforfilter .= img_picto($langs->trans('ThirdParty'), 'company').'<input type="text" size="4" name="search_thirdparty" class="marginleftonly" value="'.dol_escape_htmltag($search_thirdparty).'">';
|
||||
$moreforfilter .= img_picto($langs->trans('Filter').' '.$langs->trans('ThirdParty'), 'company').'<input type="text" size="4" name="search_thirdparty" class="marginleftonly" value="'.dol_escape_htmltag($search_thirdparty).'">';
|
||||
$moreforfilter .= '</div>';
|
||||
}
|
||||
|
||||
@ -594,7 +594,7 @@ if (!empty($arrayfields['t.progress']['checked']))
|
||||
if ($usertoprocess->id == $user->id) print '<td class="right maxwidth100">'.$langs->trans("TimeSpentByYou").'</td>';
|
||||
else print '<td class="right maxwidth100">'.$langs->trans("TimeSpentByUser").'</td>';*/
|
||||
print '<th class="right maxwidth100">'.$langs->trans("TimeSpent").'<br><span class="opacitymedium">'.$langs->trans("Everybody").'</span></th>';
|
||||
print '<th class="right maxwidth100">'.$langs->trans("TimeSpent").($usertoprocess->firstname ? '<br><span class="opacitymedium">'.dol_trunc($usertoprocess->firstname, 10).'</span>' : '').'</th>';
|
||||
print '<th class="right maxwidth100">'.$langs->trans("TimeSpent").($usertoprocess->firstname ? '<br>'.$usertoprocess->getNomUrl(-2).'<span class="opacitymedium paddingleft">'.dol_trunc($usertoprocess->firstname, 10).'</span>' : '').'</th>';
|
||||
print '<th class="center leftborder">'.$langs->trans("HourStart").'</td>';
|
||||
|
||||
// By default, we can edit only tasks we are assigned to
|
||||
|
||||
@ -429,19 +429,19 @@ $moreforfilter .= '<div class="divsearchfield">';
|
||||
$moreforfilter .= '<div class="inline-block hideonsmartphone"></div>';
|
||||
$includeonly = 'hierachyme';
|
||||
if (empty($user->rights->user->user->lire)) $includeonly = array($user->id);
|
||||
$moreforfilter .= img_picto($langs->trans('User'), 'user').$form->select_dolusers($search_usertoprocessid ? $search_usertoprocessid : $usertoprocess->id, 'search_usertoprocessid', $user->rights->user->user->lire ? 0 : 0, null, 0, $includeonly, null, 0, 0, 0, '', 0, '', 'maxwidth200');
|
||||
$moreforfilter .= img_picto($langs->trans('Filter').' '.$langs->trans('User'), 'user').$form->select_dolusers($search_usertoprocessid ? $search_usertoprocessid : $usertoprocess->id, 'search_usertoprocessid', $user->rights->user->user->lire ? 0 : 0, null, 0, $includeonly, null, 0, 0, 0, '', 0, '', 'maxwidth200');
|
||||
$moreforfilter .= '</div>';
|
||||
|
||||
if (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT))
|
||||
{
|
||||
$moreforfilter .= '<div class="divsearchfield">';
|
||||
$moreforfilter .= '<div class="inline-block"></div>';
|
||||
$moreforfilter .= img_picto($langs->trans('Project'), 'project').'<input type="text" size="4" name="search_project_ref" class="marginleftonly" value="'.dol_escape_htmltag($search_project_ref).'">';
|
||||
$moreforfilter .= img_picto($langs->trans('Filter').' '.$langs->trans('Project'), 'project').'<input type="text" size="4" name="search_project_ref" class="marginleftonly" value="'.dol_escape_htmltag($search_project_ref).'">';
|
||||
$moreforfilter .= '</div>';
|
||||
|
||||
$moreforfilter .= '<div class="divsearchfield">';
|
||||
$moreforfilter .= '<div class="inline-block"></div>';
|
||||
$moreforfilter .= img_picto($langs->trans('ThirdParty'), 'company').'<input type="text" size="4" name="search_thirdparty" class="marginleftonly" value="'.dol_escape_htmltag($search_thirdparty).'">';
|
||||
$moreforfilter .= img_picto($langs->trans('Filter').' '.$langs->trans('ThirdParty'), 'company').'<input type="text" size="4" name="search_thirdparty" class="marginleftonly" value="'.dol_escape_htmltag($search_thirdparty).'">';
|
||||
$moreforfilter .= '</div>';
|
||||
}
|
||||
|
||||
@ -488,7 +488,7 @@ print '<td align="right" class="maxwidth75">'.$langs->trans("ProgressDeclared").
|
||||
if ($usertoprocess->id == $user->id) print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpentByYou").'</td>';
|
||||
else print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpentByUser").'</td>';*/
|
||||
print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpent").'<br><span class="opacitymedium">'.$langs->trans("Everybody").'</span></td>';
|
||||
print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpent").($usertoprocess->firstname ? '<br><span class="opacitymedium">'.dol_trunc($usertoprocess->firstname, 10).'</span>' : '').'</td>';
|
||||
print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpent").($usertoprocess->firstname ? '<br>'.$usertoprocess->getNomUrl(-2).'<span class="opacitymedium paddingleft">'.dol_trunc($usertoprocess->firstname, 10).'</span>' : '').'</td>';
|
||||
|
||||
foreach ($TWeek as $week_number)
|
||||
{
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2005-2010 Regis Houssin <regis.houssin@inodbox.com>
|
||||
* Copyright (C) 2010 François Legastelois <flegastelois@teclib.com>
|
||||
* Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
|
||||
* Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
|
||||
*
|
||||
* 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
|
||||
@ -559,19 +559,19 @@ $moreforfilter .= '<div class="divsearchfield">';
|
||||
$moreforfilter .= '<div class="inline-block hideonsmartphone"></div>';
|
||||
$includeonly = 'hierarchyme';
|
||||
if (empty($user->rights->user->user->lire)) $includeonly = array($user->id);
|
||||
$moreforfilter .= img_picto($langs->trans('User'), 'user').$form->select_dolusers($search_usertoprocessid ? $search_usertoprocessid : $usertoprocess->id, 'search_usertoprocessid', $user->rights->user->user->lire ? 0 : 0, null, 0, $includeonly, null, 0, 0, 0, '', 0, '', 'maxwidth200');
|
||||
$moreforfilter .= img_picto($langs->trans('Filter').' '.$langs->trans('User'), 'user').$form->select_dolusers($search_usertoprocessid ? $search_usertoprocessid : $usertoprocess->id, 'search_usertoprocessid', $user->rights->user->user->lire ? 0 : 0, null, 0, $includeonly, null, 0, 0, 0, '', 0, '', 'maxwidth200');
|
||||
$moreforfilter .= '</div>';
|
||||
|
||||
if (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT))
|
||||
{
|
||||
$moreforfilter .= '<div class="divsearchfield">';
|
||||
$moreforfilter .= '<div class="inline-block"></div>';
|
||||
$moreforfilter .= img_picto($langs->trans('Project'), 'project').'<input type="text" size="4" name="search_project_ref" class="marginleftonly" value="'.dol_escape_htmltag($search_project_ref).'">';
|
||||
$moreforfilter .= img_picto($langs->trans('Filter').' '.$langs->trans('Project'), 'project').'<input type="text" size="4" name="search_project_ref" class="marginleftonly" value="'.dol_escape_htmltag($search_project_ref).'">';
|
||||
$moreforfilter .= '</div>';
|
||||
|
||||
$moreforfilter .= '<div class="divsearchfield">';
|
||||
$moreforfilter .= '<div class="inline-block"></div>';
|
||||
$moreforfilter .= img_picto($langs->trans('ThirdParty'), 'company').'<input type="text" size="4" name="search_thirdparty" class="marginleftonly" value="'.dol_escape_htmltag($search_thirdparty).'">';
|
||||
$moreforfilter .= img_picto($langs->trans('Filter').' '.$langs->trans('ThirdParty'), 'company').'<input type="text" size="4" name="search_thirdparty" class="marginleftonly" value="'.dol_escape_htmltag($search_thirdparty).'">';
|
||||
$moreforfilter .= '</div>';
|
||||
}
|
||||
|
||||
@ -652,7 +652,7 @@ if (!empty($arrayfields['t.progress']['checked']))
|
||||
if ($usertoprocess->id == $user->id) print '<td class="maxwidth75 right">'.$langs->trans("TimeSpentByYou").'</td>';
|
||||
else print '<td class="maxwidth75 right">'.$langs->trans("TimeSpentByUser").'</td>';*/
|
||||
print '<th class="maxwidth75 right">'.$langs->trans("TimeSpent").'<br><span class="opacitymedium">'.$langs->trans("Everybody").'</span></th>';
|
||||
print '<th class="maxwidth75 right">'.$langs->trans("TimeSpent").($usertoprocess->firstname ? '<br><span class="opacitymedium">'.dol_trunc($usertoprocess->firstname, 10).'</span>' : '').'</th>';
|
||||
print '<th class="maxwidth75 right">'.$langs->trans("TimeSpent").($usertoprocess->firstname ? '<br>'.$usertoprocess->getNomUrl(-2).'<span class="opacitymedium paddingleft">'.dol_trunc($usertoprocess->firstname, 10).'</span>' : '').'</th>';
|
||||
|
||||
for ($idw = 0; $idw < 7; $idw++)
|
||||
{
|
||||
|
||||
@ -436,9 +436,11 @@ if (!empty($search_categ_sup)) $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_f
|
||||
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."c_stcomm as st ON s.fk_stcomm = st.id";
|
||||
// We'll need this table joined to the select in order to filter by sale
|
||||
if ($search_sale == -2) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = s.rowid";
|
||||
elseif ($search_sale || (!$user->rights->societe->client->voir && !$socid)) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
|
||||
//elseif ($search_sale || (empty($user->rights->societe->client->voir) && (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || empty($user->rights->societe->client->readallthirdparties_advance)) && !$socid)) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
|
||||
elseif ($search_sale || (empty($user->rights->societe->client->voir) && !$socid)) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
|
||||
$sql .= " WHERE s.entity IN (".getEntity('societe').")";
|
||||
if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
|
||||
//if (empty($user->rights->societe->client->voir) && (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || empty($user->rights->societe->client->readallthirdparties_advance)) && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
|
||||
if (empty($user->rights->societe->client->voir) && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
|
||||
if ($search_sale && $search_sale != -2) $sql .= " AND s.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
|
||||
if (!$user->rights->fournisseur->lire) $sql .= " AND (s.fournisseur <> 1 OR s.client <> 0)"; // client=0, fournisseur=0 must be visible
|
||||
if ($search_sale == -2) $sql .= " AND sc.fk_user IS NULL";
|
||||
|
||||
@ -2577,6 +2577,9 @@ img.userphotosmall { /* size for user photo in lists */
|
||||
img.userphoto[alt="Gravatar avatar"], img.photouserphoto.dropdown-user-image[alt="Gravatar avatar"] {
|
||||
background: #fff;
|
||||
}
|
||||
form[name="addtime"] img.userphoto {
|
||||
border: 1px solid #444;
|
||||
}
|
||||
.span-icon-user {
|
||||
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/object_user.png', 1); ?>);
|
||||
background-repeat: no-repeat;
|
||||
|
||||
@ -2568,6 +2568,9 @@ img.userphotosmall { /* size for user photo in lists */
|
||||
img.userphoto[alt="Gravatar avatar"] {
|
||||
background: #fff;
|
||||
}
|
||||
form[name="addtime"] img.userphoto {
|
||||
border: 1px solid #444;
|
||||
}
|
||||
.span-icon-user {
|
||||
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/object_user.png', 1); ?>);
|
||||
background-repeat: no-repeat;
|
||||
|
||||
@ -2398,53 +2398,54 @@ class User extends CommonObject
|
||||
$label .= '<div class="centpercent">';
|
||||
$label .= img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("User").'</u>';
|
||||
$label .= ' '.$this->getLibStatut(4);
|
||||
$label .= '<br><b>'.$langs->trans('Name').':</b> '.$this->getFullName($langs, '');
|
||||
$label .= '<br><b>'.$langs->trans('Name').':</b> '.dol_string_nohtmltag($this->getFullName($langs, ''));
|
||||
if (!empty($this->login)) {
|
||||
$label .= '<br><b>'.$langs->trans('Login').':</b> '.$this->login;
|
||||
$label .= '<br><b>'.$langs->trans('Login').':</b> '.dol_string_nohtmltag($this->login);
|
||||
}
|
||||
if (!empty($this->job)) {
|
||||
$label .= '<br><b>'.$langs->trans("Job").':</b> '.$this->job;
|
||||
$label .= '<br><b>'.$langs->trans("Job").':</b> '.dol_string_nohtmltag($this->job);
|
||||
}
|
||||
$label .= '<br><b>'.$langs->trans("Email").':</b> '.$this->email;
|
||||
$label .= '<br><b>'.$langs->trans("Email").':</b> '.dol_string_nohtmltag($this->email);
|
||||
if (!empty($this->phone)) {
|
||||
$label .= '<br><b>'.$langs->trans("Phone").':</b> '.$this->phone;
|
||||
$label .= '<br><b>'.$langs->trans("Phone").':</b> '.dol_string_nohtmltag($this->phone);
|
||||
}
|
||||
if (!empty($this->admin)) {
|
||||
$label .= '<br><b>'.$langs->trans("Administrator").'</b>: '.yn($this->admin);
|
||||
}
|
||||
$company = '';
|
||||
if (!empty($this->socid)) { // Add thirdparty for external users
|
||||
$thirdpartystatic = new Societe($db);
|
||||
$thirdpartystatic->fetch($this->socid);
|
||||
if (empty($hidethirdpartylogo)) {
|
||||
$companylink = ' '.$thirdpartystatic->getNomUrl(2, (($option == 'nolink') ? 'nolink' : '')); // picto only of company
|
||||
}
|
||||
$company = ' ('.$langs->trans("Company").': '.$thirdpartystatic->name.')';
|
||||
$company = ' ('.$langs->trans("Company").': '.dol_string_nohtmltag($thirdpartystatic->name).')';
|
||||
}
|
||||
$type = ($this->socid ? $langs->trans("External").$company : $langs->trans("Internal"));
|
||||
$label .= '<br><b>'.$langs->trans("Type").':</b> '.$type;
|
||||
$label .= '<br><b>'.$langs->trans("Type").':</b> '.dol_string_nohtmltag($type);
|
||||
$label .= '</div>';
|
||||
if ($infologin > 0) {
|
||||
$label .= '<br>';
|
||||
$label .= '<br><u>'.$langs->trans("Session").'</u>';
|
||||
$label .= '<br><b>'.$langs->trans("IPAddress").'</b>: '.$_SERVER["REMOTE_ADDR"];
|
||||
$label .= '<br><b>'.$langs->trans("IPAddress").'</b>: '.dol_string_nohtmltag(getUserRemoteIP());
|
||||
if (!empty($conf->global->MAIN_MODULE_MULTICOMPANY)) {
|
||||
$label .= '<br><b>'.$langs->trans("ConnectedOnMultiCompany").':</b> '.$conf->entity.' (user entity '.$this->entity.')';
|
||||
$label .= '<br><b>'.$langs->trans("ConnectedOnMultiCompany").':</b> '.$conf->entity.' (User entity '.$this->entity.')';
|
||||
}
|
||||
$label .= '<br><b>'.$langs->trans("AuthenticationMode").':</b> '.$_SESSION["dol_authmode"].(empty($dolibarr_main_demo) ? '' : ' (demo)');
|
||||
$label .= '<br><b>'.$langs->trans("AuthenticationMode").':</b> '.dol_string_nohtmltag($_SESSION["dol_authmode"].(empty($dolibarr_main_demo) ? '' : ' (demo)'));
|
||||
$label .= '<br><b>'.$langs->trans("ConnectedSince").':</b> '.dol_print_date($this->datelastlogin, "dayhour", 'tzuser');
|
||||
$label .= '<br><b>'.$langs->trans("PreviousConnexion").':</b> '.dol_print_date($this->datepreviouslogin, "dayhour", 'tzuser');
|
||||
$label .= '<br><b>'.$langs->trans("CurrentTheme").':</b> '.$conf->theme;
|
||||
$label .= '<br><b>'.$langs->trans("CurrentMenuManager").':</b> '.$menumanager->name;
|
||||
$label .= '<br><b>'.$langs->trans("CurrentTheme").':</b> '.dol_string_nohtmltag($conf->theme);
|
||||
$label .= '<br><b>'.$langs->trans("CurrentMenuManager").':</b> '.dol_string_nohtmltag($menumanager->name);
|
||||
$s = picto_from_langcode($langs->getDefaultLang());
|
||||
$label .= '<br><b>'.$langs->trans("CurrentUserLanguage").':</b> '.($s ? $s.' ' : '').$langs->getDefaultLang();
|
||||
$label .= '<br><b>'.$langs->trans("Browser").':</b> '.$conf->browser->name.($conf->browser->version ? ' '.$conf->browser->version : '').' ('.$_SERVER['HTTP_USER_AGENT'].')';
|
||||
$label .= '<br><b>'.$langs->trans("Layout").':</b> '.$conf->browser->layout;
|
||||
$label .= '<br><b>'.$langs->trans("Screen").':</b> '.$_SESSION['dol_screenwidth'].' x '.$_SESSION['dol_screenheight'];
|
||||
$label .= '<br><b>'.$langs->trans("CurrentUserLanguage").':</b> '.dol_string_nohtmltag(($s ? $s.' ' : '').$langs->getDefaultLang());
|
||||
$label .= '<br><b>'.$langs->trans("Browser").':</b> '.dol_string_nohtmltag($conf->browser->name.($conf->browser->version ? ' '.$conf->browser->version : '').' ('.$_SERVER['HTTP_USER_AGENT'].')');
|
||||
$label .= '<br><b>'.$langs->trans("Layout").':</b> '.dol_string_nohtmltag($conf->browser->layout);
|
||||
$label .= '<br><b>'.$langs->trans("Screen").':</b> '.dol_string_nohtmltag($_SESSION['dol_screenwidth'].' x '.$_SESSION['dol_screenheight']);
|
||||
if ($conf->browser->layout == 'phone') {
|
||||
$label .= '<br><b>'.$langs->trans("Phone").':</b> '.$langs->trans("Yes");
|
||||
}
|
||||
if (!empty($_SESSION["disablemodules"])) {
|
||||
$label .= '<br><b>'.$langs->trans("DisabledModules").':</b> <br>'.join(', ', explode(',', $_SESSION["disablemodules"]));
|
||||
$label .= '<br><b>'.$langs->trans("DisabledModules").':</b> <br>'.dol_string_nohtmltag(join(', ', explode(',', $_SESSION["disablemodules"])));
|
||||
}
|
||||
}
|
||||
if ($infologin < 0) {
|
||||
@ -2508,12 +2509,12 @@ class User extends CommonObject
|
||||
}
|
||||
if ($withpictoimg > -2 && $withpictoimg != 2) {
|
||||
if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
|
||||
$result .= '<span class=" nopadding usertext'.((!isset($this->statut) || $this->statut) ? '' : ' strikefordisabled').($morecss ? ' '.$morecss : '').'">';
|
||||
$result .= '<span class="nopadding usertext'.((!isset($this->statut) || $this->statut) ? '' : ' strikefordisabled').($morecss ? ' '.$morecss : '').'">';
|
||||
}
|
||||
if ($mode == 'login') {
|
||||
$result .= dol_trunc($this->login, $maxlen);
|
||||
$result .= dol_string_nohtmltag(dol_trunc($this->login, $maxlen));
|
||||
} else {
|
||||
$result .= $this->getFullName($langs, '', ($mode == 'firstelselast' ? 3 : ($mode == 'firstname' ? 2 : -1)), $maxlen);
|
||||
$result .= dol_string_nohtmltag($this->getFullName($langs, '', ($mode == 'firstelselast' ? 3 : ($mode == 'firstname' ? 2 : -1)), $maxlen));
|
||||
}
|
||||
if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
|
||||
$result .= '</span>';
|
||||
|
||||
@ -128,7 +128,7 @@ if ($resql)
|
||||
print '<table class="noborder centpercent">';
|
||||
print '<tr class="liste_titre"><td colspan="3">'.$langs->trans("LastUsersCreated", min($num, $max)).'</td>';
|
||||
print '<td class="right" colspan="2"><a class="commonlink" href="'.DOL_URL_ROOT.'/user/list.php?sortfield=u.datec&sortorder=DESC">'.$langs->trans("FullList").'</td>';
|
||||
print '</tr>';
|
||||
print '</tr>'."\n";
|
||||
$i = 0;
|
||||
|
||||
while ($i < $num && $i < $max)
|
||||
|
||||
@ -186,7 +186,11 @@ class SecurityTest extends PHPUnit\Framework\TestCase
|
||||
|
||||
$_SERVER["PHP_SELF"]='/DIR WITH SPACE/htdocs/admin/index.php?mainmenu=home&leftmenu=setup&username=weservices';
|
||||
$result=testSqlAndScriptInject($_SERVER["PHP_SELF"], 2);
|
||||
$this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject 1a');
|
||||
$this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject expected 0a');
|
||||
|
||||
$test = 'This is a < inside string with < and > also and tag like <a> before the >';
|
||||
$result=testSqlAndScriptInject($test, 0);
|
||||
$this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject expected 0b');
|
||||
|
||||
// Should detect XSS
|
||||
$expectedresult=1;
|
||||
@ -275,6 +279,10 @@ class SecurityTest extends PHPUnit\Framework\TestCase
|
||||
$test="on<!-- ab\nc -->error=alert(1)";
|
||||
$result=testSqlAndScriptInject($test, 0);
|
||||
$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject jjj');
|
||||
|
||||
$test="<img src=x one<a>rror=alert(document.location)";
|
||||
$result=testSqlAndScriptInject($test, 0);
|
||||
$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject kkk');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -299,7 +307,9 @@ class SecurityTest extends PHPUnit\Framework\TestCase
|
||||
$_GET["param5"]="a_1-b";
|
||||
$_POST["param6"]=""><svg onload='console.log("123")'>";
|
||||
$_GET["param7"]='"c:\this is a path~1\aaan" abc<bad>def</bad>';
|
||||
$_POST["param8"]="Hacker<svg onload='console.log("123")'"; // html tag is not closed so it is not detected as html tag but is still harmfull
|
||||
$_POST["param8a"]="Hacker<svg onload='console.log("123")'"; // html tag is not closed so it is not detected as html tag but is still harmfull
|
||||
$_POST['param8b']='<img src=x onerror=alert(document.location) t='; // this is html obfuscated by non closing tag
|
||||
$_POST['param8c']='< with space after is ok';
|
||||
$_POST["param9"]='is_object($object) ? ($object->id < 10 ? round($object->id / 2, 2) : (2 * $user->id) * (int) substr($mysoc->zip, 1, 2)) : \'objnotdefined\'';
|
||||
$_POST["param10"]='is_object($object) ? ($object->id < 10 ? round($object->id / 2, 2) : (2 * $user->id) * (int) substr($mysoc->zip, 1, 2)) : \'<abc>objnotdefined\'';
|
||||
$_POST["param11"]=' Name <email@email.com> ';
|
||||
@ -363,10 +373,18 @@ class SecurityTest extends PHPUnit\Framework\TestCase
|
||||
print __METHOD__." result=".$result."\n";
|
||||
$this->assertEquals('"c:\this is a path~1\aaan" abcdef', $result);
|
||||
|
||||
// With alphanohtml, we must convert the html entities like n
|
||||
$result=GETPOST("param8", 'alphanohtml');
|
||||
// With alphanohtml, we must convert the html entities like n and disable all entities
|
||||
$result=GETPOST("param8a", 'alphanohtml');
|
||||
print __METHOD__." result=".$result."\n";
|
||||
$this->assertEquals("Hacker<svg onload='console.log(123)'", $result);
|
||||
$this->assertEquals("Hackersvg onload='console.log(123)'", $result);
|
||||
|
||||
$result=GETPOST("param8b", 'alphanohtml');
|
||||
print __METHOD__." result=".$result."\n";
|
||||
$this->assertEquals('img src=x onerror=alert(document.location) t=', $result, 'Test a string with non closing html tag with alphanohtml');
|
||||
|
||||
$result=GETPOST("param8c", 'alphanohtml');
|
||||
print __METHOD__." result=".$result."\n";
|
||||
$this->assertEquals($_POST['param8c'], $result, 'Test a string with non closing html tag with alphanohtml');
|
||||
|
||||
$result=GETPOST("param9", 'alphanohtml');
|
||||
print __METHOD__." result=".$result."\n";
|
||||
@ -574,10 +592,10 @@ class SecurityTest extends PHPUnit\Framework\TestCase
|
||||
$this->assertEquals(400, $tmp['http_code'], 'GET url to '.$url.' that is a local URL'); // Test we receive an error because localtest.me is not an external URL
|
||||
|
||||
/*$url = 'localtest.me';
|
||||
$tmp = getURLContent($url, 'GET', '', 0, array(), array('http', 'https'), 0); // Only external URL
|
||||
print __METHOD__." url=".$url."\n";
|
||||
$this->assertEquals(400, $tmp['http_code'], 'GET url to '.$url.' that resolves to a local URL'); // Test we receive an error because localtest.me is not an external URL
|
||||
*/
|
||||
$tmp = getURLContent($url, 'GET', '', 0, array(), array('http', 'https'), 0); // Only external URL
|
||||
print __METHOD__." url=".$url."\n";
|
||||
$this->assertEquals(400, $tmp['http_code'], 'GET url to '.$url.' that resolves to a local URL'); // Test we receive an error because localtest.me is not an external URL
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user