diff --git a/ChangeLog b/ChangeLog index d4a8b55625f..646c1314b1f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ English Dolibarr ChangeLog For users: ---------- +NEW: Several security issues after a second private bug bounty campaign. For developers: diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index 8982376ded6..cf2bd2065a2 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -582,6 +582,10 @@ if ($resql) { $i++; } + if ($num == 0) { + print ''.$langs->trans("None").''; + } + print ""; print ""; print ''; diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index b75bce38ca9..9b4dbb0203d 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -84,12 +84,10 @@ if (!empty($canvas)) { // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('membercard', 'globalcard')); -// Security check -$result = restrictedArea($user, 'adherent', $id, '', '', 'socid', 'rowid', 0); - -if ($id > 0) { +// Fetch object +if ($id > 0 || !empty($ref)) { // Load member - $result = $object->fetch($id); + $result = $object->fetch($id, $ref); // Define variables to know what current user can do on users $canadduser = ($user->admin || $user->rights->user->user->creer); @@ -97,9 +95,9 @@ if ($id > 0) { if ($object->user_id) { // $User is the user who edits, $object->user_id is the id of the related user in the edited member $caneditfielduser = ((($user->id == $object->user_id) && $user->rights->user->self->creer) - || (($user->id != $object->user_id) && $user->rights->user->user->creer)); + || (($user->id != $object->user_id) && $user->rights->user->user->creer)); $caneditpassworduser = ((($user->id == $object->user_id) && $user->rights->user->self->password) - || (($user->id != $object->user_id) && $user->rights->user->user->password)); + || (($user->id != $object->user_id) && $user->rights->user->user->password)); } } @@ -110,6 +108,8 @@ if ($id) { $caneditfieldmember = $user->rights->adherent->creer; } +// Security check +$result = restrictedArea($user, 'adherent', $object->id, '', '', 'socid', 'rowid', 0); /* diff --git a/htdocs/adherents/document.php b/htdocs/adherents/document.php index 88e31ebffb6..c359f539547 100644 --- a/htdocs/adherents/document.php +++ b/htdocs/adherents/document.php @@ -42,9 +42,6 @@ $ref = GETPOST('ref', 'alphanohtml'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); -// Security check -$result = restrictedArea($user, 'adherent', $id); - // Get parameters $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); @@ -63,8 +60,6 @@ if (!$sortfield) { $sortfield = "name"; } - -$form = new Form($db); $object = new Adherent($db); $membert = new AdherentType($db); $result = $object->fetch($id, $ref); @@ -74,6 +69,33 @@ if ($result < 0) { } $upload_dir = $conf->adherent->dir_output."/".get_exdir(0, 0, 0, 1, $object, 'member'); +// Fetch object +if ($id > 0 || !empty($ref)) { + // Load member + $result = $object->fetch($id, $ref); + + // Define variables to know what current user can do on users + $canadduser = ($user->admin || $user->rights->user->user->creer); + // Define variables to know what current user can do on properties of user linked to edited member + if ($object->user_id) { + // $User is the user who edits, $object->user_id is the id of the related user in the edited member + $caneditfielduser = ((($user->id == $object->user_id) && $user->rights->user->self->creer) + || (($user->id != $object->user_id) && $user->rights->user->user->creer)); + $caneditpassworduser = ((($user->id == $object->user_id) && $user->rights->user->self->password) + || (($user->id != $object->user_id) && $user->rights->user->user->password)); + } +} + +// Define variables to determine what the current user can do on the members +$canaddmember = $user->rights->adherent->creer; +// Define variables to determine what the current user can do on the properties of a member +if ($id) { + $caneditfieldmember = $user->rights->adherent->creer; +} + +// Security check +$result = restrictedArea($user, 'adherent', $object->id, '', '', 'socid', 'rowid', 0); + /* * Actions diff --git a/htdocs/adherents/htpasswd.php b/htdocs/adherents/htpasswd.php index a1c105bd192..e1f580a3656 100644 --- a/htdocs/adherents/htpasswd.php +++ b/htdocs/adherents/htpasswd.php @@ -26,7 +26,16 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; +$status = GETPOST('status', 'int'); +$cotis = GETPOST('cotis', 'int'); + +$sortfield = GETPOST('sortfield', 'alphanohtml'); +$sortorder = GETPOST('sortorder', 'aZ09'); + // Security check +if (empty($conf->adherent->enabled)) { + accessforbidden(); +} if (!$user->rights->adherent->export) { accessforbidden(); } @@ -46,19 +55,10 @@ if (empty($sortorder)) { if (empty($sortfield)) { $sortfield = "d.login"; } -if (!isset($statut)) { - $statut = 1; -} - -if (!isset($cotis)) { - // by default, members must be up to date of subscription - $cotis = 1; -} - $sql = "SELECT d.login, d.pass, d.datefin"; $sql .= " FROM ".MAIN_DB_PREFIX."adherent as d "; -$sql .= " WHERE d.statut = ".$statut; +$sql .= " WHERE d.statut = ".((int) $status); if ($cotis == 1) { $sql .= " AND datefin > '".$db->idate($now)."'"; } @@ -70,6 +70,7 @@ if ($resql) { $num = $db->num_rows($resql); $i = 0; + $param = ''; print_barre_liste($langs->trans("HTPasswordExport"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', 0); print "
\n"; diff --git a/htdocs/adherents/ldap.php b/htdocs/adherents/ldap.php index 89baf2f5ec5..44d5ee5399b 100644 --- a/htdocs/adherents/ldap.php +++ b/htdocs/adherents/ldap.php @@ -32,7 +32,8 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; // Load translation files required by the page $langs->loadLangs(array("companies", "members", "ldap", "admin")); -$rowid = GETPOST('id', 'int'); +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alphanohtml'); $action = GETPOST('action', 'aZ09'); // Protection @@ -42,12 +43,34 @@ if ($user->socid > 0) { } $object = new Adherent($db); -$result = $object->fetch($rowid); -if (!$result) { - dol_print_error($db, "Failed to get adherent: ".$object->error); - exit; + +// Fetch object +if ($id > 0 || !empty($ref)) { + // Load member + $result = $object->fetch($id, $ref); + + // Define variables to know what current user can do on users + $canadduser = ($user->admin || $user->rights->user->user->creer); + // Define variables to know what current user can do on properties of user linked to edited member + if ($object->user_id) { + // $User is the user who edits, $object->user_id is the id of the related user in the edited member + $caneditfielduser = ((($user->id == $object->user_id) && $user->rights->user->self->creer) + || (($user->id != $object->user_id) && $user->rights->user->user->creer)); + $caneditpassworduser = ((($user->id == $object->user_id) && $user->rights->user->self->password) + || (($user->id != $object->user_id) && $user->rights->user->user->password)); + } } +// Define variables to determine what the current user can do on the members +$canaddmember = $user->rights->adherent->creer; +// Define variables to determine what the current user can do on the properties of a member +if ($id) { + $caneditfieldmember = $user->rights->adherent->creer; +} + +// Security check +$result = restrictedArea($user, 'adherent', $object->id, '', '', 'socid', 'rowid', 0); + /* * Actions diff --git a/htdocs/adherents/note.php b/htdocs/adherents/note.php index 26fec04a5e6..91946094a9a 100644 --- a/htdocs/adherents/note.php +++ b/htdocs/adherents/note.php @@ -33,9 +33,7 @@ $langs->loadLangs(array("companies", "members", "bills")); $action = GETPOST('action', 'aZ09'); $id = GETPOST('id', 'int'); - -// Security check -$result = restrictedArea($user, 'adherent', $id); +$ref = GETPOST('ref', 'alphanohtml'); $object = new Adherent($db); $result = $object->fetch($id); @@ -46,6 +44,34 @@ if ($result > 0) { $permissionnote = $user->rights->adherent->creer; // Used by the include of actions_setnotes.inc.php +// Fetch object +if ($id > 0 || !empty($ref)) { + // Load member + $result = $object->fetch($id, $ref); + + // Define variables to know what current user can do on users + $canadduser = ($user->admin || $user->rights->user->user->creer); + // Define variables to know what current user can do on properties of user linked to edited member + if ($object->user_id) { + // $User is the user who edits, $object->user_id is the id of the related user in the edited member + $caneditfielduser = ((($user->id == $object->user_id) && $user->rights->user->self->creer) + || (($user->id != $object->user_id) && $user->rights->user->user->creer)); + $caneditpassworduser = ((($user->id == $object->user_id) && $user->rights->user->self->password) + || (($user->id != $object->user_id) && $user->rights->user->user->password)); + } +} + +// Define variables to determine what the current user can do on the members +$canaddmember = $user->rights->adherent->creer; +// Define variables to determine what the current user can do on the properties of a member +if ($id) { + $caneditfieldmember = $user->rights->adherent->creer; +} + +// Security check +$result = restrictedArea($user, 'adherent', $object->id, '', '', 'socid', 'rowid', 0); + + /* * Actions */ diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index ecc0e1cfe47..54729e5ba8a 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -42,7 +42,9 @@ $langs->loadLangs(array("companies", "bills", "members", "users", "mails", 'othe $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); -$rowid = GETPOST('rowid', 'int') ?GETPOST('rowid', 'int') : GETPOST('id', 'int'); +$id = GETPOST('rowid', 'int') ?GETPOST('rowid', 'int') : GETPOST('id', 'int'); +$rowid = $id; +$ref = GETPOST('ref', 'alphanohtml'); $typeid = GETPOST('typeid', 'int'); $cancel = GETPOST('cancel'); @@ -66,10 +68,6 @@ if (!$sortorder) { $sortorder = "DESC"; } - -// Security check -$result = restrictedArea($user, 'adherent', $rowid, '', 'cotisation'); - $object = new Adherent($db); $extrafields = new ExtraFields($db); $adht = new AdherentType($db); @@ -82,29 +80,6 @@ $errmsg = ''; $defaultdelay = 1; $defaultdelayunit = 'y'; -if ($rowid) { - // Load member - $result = $object->fetch($rowid); - - // Define variables to know what current user can do on users - $canadduser = ($user->admin || $user->rights->user->user->creer); - // Define variables to know what current user can do on properties of user linked to edited member - if ($object->user_id) { - // $user is the user editing, $object->user_id is the user's id linked to the edited member - $caneditfielduser = ((($user->id == $object->user_id) && $user->rights->user->self->creer) - || (($user->id != $object->user_id) && $user->rights->user->user->creer)); - $caneditpassworduser = ((($user->id == $object->user_id) && $user->rights->user->self->password) - || (($user->id != $object->user_id) && $user->rights->user->user->password)); - } -} - -// Define variables to know what current user can do on members -$canaddmember = $user->rights->adherent->creer; -// Define variables to know what current user can do on properties of a member -if ($rowid) { - $caneditfieldmember = $user->rights->adherent->creer; -} - // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('subscription')); @@ -117,6 +92,33 @@ $datefrom = 0; $dateto = 0; $paymentdate = -1; +// Fetch object +if ($id > 0 || !empty($ref)) { + // Load member + $result = $object->fetch($id, $ref); + + // Define variables to know what current user can do on users + $canadduser = ($user->admin || $user->rights->user->user->creer); + // Define variables to know what current user can do on properties of user linked to edited member + if ($object->user_id) { + // $User is the user who edits, $object->user_id is the id of the related user in the edited member + $caneditfielduser = ((($user->id == $object->user_id) && $user->rights->user->self->creer) + || (($user->id != $object->user_id) && $user->rights->user->user->creer)); + $caneditpassworduser = ((($user->id == $object->user_id) && $user->rights->user->self->password) + || (($user->id != $object->user_id) && $user->rights->user->user->password)); + } +} + +// Define variables to determine what the current user can do on the members +$canaddmember = $user->rights->adherent->creer; +// Define variables to determine what the current user can do on the properties of a member +if ($id) { + $caneditfieldmember = $user->rights->adherent->creer; +} + +// Security check +$result = restrictedArea($user, 'adherent', $object->id, '', '', 'socid', 'rowid', 0); + /* * Actions diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index bf18a851efb..6b76fc3d502 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -496,11 +496,14 @@ while ($i < min($num, $limit)) { $adherent->morphy = $obj->morphy; $adherent->email = $obj->email; $adherent->typeid = $obj->type; + $adherent->datefin = $db->jdate($obj->datef); $typeid = ($obj->fk_type > 0 ? $obj->fk_type : $adherent->typeid); $adht = new AdherentType($db); $adht->fetch($typeid); + $adherent->need_subscription = $adht->subscription; + print ''; // Ref diff --git a/htdocs/adherents/vcard.php b/htdocs/adherents/vcard.php index a53cacd2212..902206c7874 100644 --- a/htdocs/adherents/vcard.php +++ b/htdocs/adherents/vcard.php @@ -30,71 +30,100 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/vcard.class.php'; -$adherent = new adherent($db); - - $id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alphanohtml'); + +$object = new adherent($db); + +// Fetch object +if ($id > 0 || !empty($ref)) { + // Load member + $result = $object->fetch($id, $ref); + + // Define variables to know what current user can do on users + $canadduser = ($user->admin || $user->rights->user->user->creer); + // Define variables to know what current user can do on properties of user linked to edited member + if ($object->user_id) { + // $User is the user who edits, $object->user_id is the id of the related user in the edited member + $caneditfielduser = ((($user->id == $object->user_id) && $user->rights->user->self->creer) + || (($user->id != $object->user_id) && $user->rights->user->user->creer)); + $caneditpassworduser = ((($user->id == $object->user_id) && $user->rights->user->self->password) + || (($user->id != $object->user_id) && $user->rights->user->user->password)); + } +} + +// Define variables to determine what the current user can do on the members +$canaddmember = $user->rights->adherent->creer; +// Define variables to determine what the current user can do on the properties of a member +if ($id) { + $caneditfieldmember = $user->rights->adherent->creer; +} // Security check -$result = restrictedArea($user, 'adherent', $id, '', '', 'socid', 'rowid', $objcanvas); +$result = restrictedArea($user, 'adherent', $object->id, '', '', 'socid', 'rowid', 0); -$result = $adherent->fetch($id); -if ($result <= 0) { - dol_print_error($adherent->error); - exit; -} +/* + * Actions + */ -$physicalperson = 1; +// None + + +/* + * View + */ $company = new Societe($db); -if ($adherent->socid) { - $result = $company->fetch($adherent->socid); +if ($object->socid) { + $result = $company->fetch($object->socid); } + + // We create VCard $v = new vCard(); $v->setProdId('Dolibarr '.DOL_VERSION); -$v->setUid('DOLIBARR-ADHERENTID-'.$adherent->id); -$v->setName($adherent->lastname, $adherent->firstname, "", $adherent->civility, ""); -$v->setFormattedName($adherent->getFullName($langs, 1)); +$v->setUid('DOLIBARR-ADHERENTID-'.$object->id); +$v->setName($object->lastname, $object->firstname, "", $object->civility, ""); +$v->setFormattedName($object->getFullName($langs, 1)); -$v->setPhoneNumber($adherent->phone_pro, "TYPE=WORK;VOICE"); -//$v->setPhoneNumber($adherent->phone_perso,"TYPE=HOME;VOICE"); -$v->setPhoneNumber($adherent->phone_mobile, "TYPE=CELL;VOICE"); -$v->setPhoneNumber($adherent->fax, "TYPE=WORK;FAX"); +$v->setPhoneNumber($object->phone_pro, "TYPE=WORK;VOICE"); +//$v->setPhoneNumber($object->phone_perso,"TYPE=HOME;VOICE"); +$v->setPhoneNumber($object->phone_mobile, "TYPE=CELL;VOICE"); +$v->setPhoneNumber($object->fax, "TYPE=WORK;FAX"); -$country = $adherent->country_code ? $adherent->country : ''; +$country = $object->country_code ? $object->country : ''; -$v->setAddress("", "", $adherent->address, $adherent->town, $adherent->state, $adherent->zip, $country, "TYPE=WORK;POSTAL"); -$v->setLabel("", "", $adherent->address, $adherent->town, $adherent->state, $adherent->zip, $country, "TYPE=WORK"); +$v->setAddress("", "", $object->address, $object->town, $object->state, $object->zip, $country, "TYPE=WORK;POSTAL"); +$v->setLabel("", "", $object->address, $object->town, $object->state, $object->zip, $country, "TYPE=WORK"); -$v->setEmail($adherent->email); -$v->setNote($adherent->note_public); -$v->setTitle($adherent->poste); +$v->setEmail($object->email); +$v->setNote($object->note_public); +$v->setTitle($object->poste); // Data from linked company if ($company->id) { $v->setURL($company->url, "TYPE=WORK"); - if (!$adherent->phone_pro) { + if (!$object->phone_pro) { $v->setPhoneNumber($company->phone, "TYPE=WORK;VOICE"); } - if (!$adherent->fax) { + if (!$object->fax) { $v->setPhoneNumber($company->fax, "TYPE=WORK;FAX"); } - if (!$adherent->zip) { + if (!$object->zip) { $v->setAddress("", "", $company->address, $company->town, $company->state, $company->zip, $company->country, "TYPE=WORK;POSTAL"); } // when company e-mail is empty, use only adherent e-mail if (empty(trim($company->email))) { // was set before, don't set twice - } elseif (empty(trim($adherent->email))) { + } elseif (empty(trim($object->email))) { // when adherent e-mail is empty, use only company e-mail $v->setEmail($company->email); - } elseif (strtolower(end(explode("@", $adherent->email))) == strtolower(end(explode("@", $company->email)))) { + } elseif (strtolower(end(explode("@", $object->email))) == strtolower(end(explode("@", $company->email)))) { // when e-mail domain of adherent and company are the same, use adherent e-mail at first (and company e-mail at second) - $v->setEmail($adherent->email); + $v->setEmail($object->email); // support by Microsoft Outlook (2019 and possible earlier) $v->setEmail($company->email, 'INTERNET'); @@ -103,7 +132,7 @@ if ($company->id) { $v->setEmail($company->email); // support by Microsoft Outlook (2019 and possible earlier) - $v->setEmail($adherent->email, 'INTERNET'); + $v->setEmail($object->email, 'INTERNET'); } // Si adherent lie a un tiers non de type "particulier" @@ -113,9 +142,9 @@ if ($company->id) { } // Personal informations -$v->setPhoneNumber($adherent->phone_perso, "TYPE=HOME;VOICE"); -if ($adherent->birth) { - $v->setBirthday($adherent->birth); +$v->setPhoneNumber($object->phone_perso, "TYPE=HOME;VOICE"); +if ($object->birth) { + $v->setBirthday($object->birth); } $db->close(); diff --git a/htdocs/admin/index.php b/htdocs/admin/index.php index d94c8a3fffd..a97717412a9 100644 --- a/htdocs/admin/index.php +++ b/htdocs/admin/index.php @@ -93,7 +93,7 @@ print '
'; // Show info setup module print img_picto('', 'cog', 'class="paddingright"').' '.$langs->trans("SetupDescription4", DOL_URL_ROOT.'/admin/modules.php?mainmenu=home', $langs->transnoentities("Setup"), $langs->transnoentities("Modules")); -if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only user module enabled +if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled $langs->load("errors"); $warnpicto = img_warning($langs->trans("WarningEnableYourModulesApplications"), 'style="padding-right: 6px;"'); print '
'.$warnpicto.$langs->trans("WarningEnableYourModulesApplications").'
'; diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 5cf852fdacb..9b9fcdea1fd 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -463,11 +463,13 @@ asort($orders); //var_dump($modules); $nbofactivatedmodules = count($conf->modules); -$moreinfo = $langs->trans("TitleNumberOfActivatedModules"); + +//$conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING = 1000; +/*$moreinfo = $langs->trans("TitleNumberOfActivatedModules"); $moreinfo2 = ''.($nbofactivatedmodules - 1).' / '.count($modules).''; -if ($nbofactivatedmodules <= 1) { +if ($nbofactivatedmodules <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { $moreinfo2 .= ' '.img_warning($langs->trans("YouMustEnableOneModule")); -} +}*/ print load_fiche_titre($langs->trans("ModulesSetup"), '', 'title_setup'); @@ -476,7 +478,9 @@ $deschelp = ''; if ($mode == 'common' || $mode == 'commonkanban') { $desc = $langs->trans("ModulesDesc", '{picto}'); $desc = str_replace('{picto}', img_picto('', 'switch_off'), $desc); - $deschelp = '
'.$desc."

\n"; + if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled + $deschelp = '
'.$desc."

\n"; + } } if ($mode == 'marketplace') { //$deschelp = '
'.$langs->trans("ModulesMarketPlaceDesc")."

\n"; @@ -488,7 +492,7 @@ if ($mode == 'develop') { $deschelp = '
'.$langs->trans("ModulesDevelopDesc")."

\n"; } -$head = modules_prepare_head(); +$head = modules_prepare_head($nbofactivatedmodules, count($modules)); if ($mode == 'common' || $mode == 'commonkanban') { @@ -521,7 +525,7 @@ if ($mode == 'common' || $mode == 'commonkanban') { $moreforfilter .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-list-alt imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.$param, '', 1, array('morecss'=>'reposition'.($mode == 'commonkanban' ? '' : ' btnTitleSelected'))); $moreforfilter .= ''; - $moreforfilter .= '
'.$moreinfo.' '.$moreinfo2.'
'; + //$moreforfilter .= '
'.$moreinfo.' '.$moreinfo2.'
'; $moreforfilter .= '
'; $moreforfilter .= '
'; diff --git a/htdocs/api/admin/explorer.php b/htdocs/api/admin/explorer.php deleted file mode 100644 index 53b9233c130..00000000000 --- a/htdocs/api/admin/explorer.php +++ /dev/null @@ -1,216 +0,0 @@ - - * Copyright (C) 2016 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 - * 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 . - * - * @deprecated Old explorer. Not using Swagger. See instead explorer in htdocs/api/index.php. - */ - -/** - * \defgroup api Module DolibarrApi - * \brief API loader - * Search files htdocs//class/api_.class.php - * \file htdocs/api/admin/explorer.php - */ - -use Luracast\Restler\Routes; - -require_once '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php'; -require_once DOL_DOCUMENT_ROOT.'/api/class/api_access.class.php'; - -// Load translation files required by the page -$langs->load("admin"); - - -/* - * View - */ - -// Enable and test if module Api is enabled -if (empty($conf->global->MAIN_MODULE_API)) { - dol_syslog("Call Dolibarr API interfaces with module REST disabled"); - print $langs->trans("WarningModuleNotActive", 'Api').'.

'; - print $langs->trans("ToActivateModule"); - exit; -} - - -$api = new DolibarrApi($db); - -$api->r->addAPIClass('Luracast\\Restler\\Resources'); //this creates resources.json at API Root -$api->r->setSupportedFormats('JsonFormat', 'XmlFormat'); -$api->r->addAuthenticationClass('DolibarrApiAccess', ''); - -$listofapis = array(); - -$modulesdir = dolGetModulesDirs(); -foreach ($modulesdir as $dir) { - /* - * Search available module - */ - //dol_syslog("Scan directory ".$dir." for API modules"); - - $handle = @opendir(dol_osencode($dir)); - if (is_resource($handle)) { - while (($file = readdir($handle)) !== false) { - if (is_readable($dir.$file) && preg_match("/^(mod.*)\.class\.php$/i", $file, $reg)) { - $modulename = $reg[1]; - - // Defined if module is enabled - $enabled = true; - $module = $part = $obj = strtolower(preg_replace('/^mod/i', '', $modulename)); - //if ($part == 'propale') $part='propal'; - if ($module == 'societe') { - $obj = 'thirdparty'; - } - if ($module == 'categorie') { - $part = 'categories'; - $obj = 'category'; - } - if ($module == 'facture') { - $part = 'compta/facture'; - $obj = 'facture'; - } - if ($module == 'ficheinter') { - $obj = 'fichinter'; - $part = 'fichinter'; - $module = 'fichinter'; - } - - if (empty($conf->$module->enabled)) { - $enabled = false; - } - - if ($enabled) { - /* - * If exists, load the API class for enable module - * - * Search files named api_.class.php into /htdocs//class directory - * - * @todo : take care of externals module! - * @todo : use getElementProperties() function ? - */ - $dir_part = DOL_DOCUMENT_ROOT.'/'.$part.'/class/'; - - $handle_part = @opendir(dol_osencode($dir_part)); - if (is_resource($handle_part)) { - while (($file_searched = readdir($handle_part)) !== false) { - if (is_readable($dir_part.$file_searched) && preg_match("/^api_(.*)\.class\.php$/i", $file_searched, $reg)) { - $classname = ucwords($reg[1]); - require_once $dir_part.$file_searched; - if (class_exists($classname)) { - dol_syslog("Found API classname=".$classname." into ".$dir); - $listofapis[] = $classname; - } - } - - /* - if (is_readable($dir_part.$file_searched) && preg_match("/^(api_.*)\.class\.php$/i",$file_searched,$reg)) - { - $classname=$reg[1]; - $classname = str_replace('Api_','',ucwords($reg[1])).'Api'; - //$classname = str_replace('Api_','',ucwords($reg[1])); - $classname = ucfirst($classname); - require_once $dir_part.$file_searched; - - // if (class_exists($classname)) - // { - // dol_syslog("Found API classname=".$classname); - // $api->r->addAPIClass($classname,''); - - // require_once DOL_DOCUMENT_ROOT.'/includes/restler/framework/Luracast/Restler/Routes.php'; - // $tmpclass = new ReflectionClass($classname); - // try { - // $classMetadata = CommentParser::parse($tmpclass->getDocComment()); - // } catch (Exception $e) { - // throw new RestException(500, "Error while parsing comments of `$classname` class. " . $e->getMessage()); - // } - - // //$listofapis[]=array('classname'=>$classname, 'fullpath'=>$file_searched); - // } - }*/ - } - } - } - } - } - } -} - -//var_dump($listofapis); -$listofapis = Routes::toArray(); // @todo api for "status" is lost here -//var_dump($listofapis); - - -llxHeader(); - -$linkback = ''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("ApiSetup"), $linkback, 'title_setup'); - -// Define $urlwithroot -$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); -$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file -//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current - -// Show message -print '
'; -$message = ''; -$url = ''.$urlwithroot.'/api/index.php/login?login='.urlencode($user->login).'&password=yourpassword[&reset=1]'; -$message .= $langs->trans("UrlToGetKeyToUseAPIs").':
'; -$message .= img_picto('', 'globe').' '.$url; -print $message; -print '
'; -print '
'; - -$oldclass = ''; - -print $langs->trans("ListOfAvailableAPIs").':
'; -foreach ($listofapis['v1'] as $key => $val) { - if ($key == 'login') { - continue; - } - if ($key == 'index') { - continue; - } - - if ($key) { - foreach ($val as $method => $val2) { - $newclass = $val2['className']; - - if (preg_match('/restler/i', $newclass)) { - continue; - } - - if ($oldclass != $newclass) { - print "\n
\n".$langs->trans("Class").': '.$newclass.'
'."\n"; - $oldclass = $newclass; - } - //print $key.' - '.$val['classname'].' - '.$val['fullpath']." - ".DOL_MAIN_URL_ROOT.'/api/index.php/'.strtolower(preg_replace('/Api$/','',$val['classname']))."/xxx
\n"; - $url = $urlwithroot.'/api/index.php/'.$key; - $url .= '?api_key=token'; - print img_picto('', 'globe').' '.$method.' '.$url."
\n"; - } - } -} - -print '
'; -print '
'; -print $langs->trans("OnlyActiveElementsAreExposed", DOL_URL_ROOT.'/admin/modules.php'); - - -llxFooter(); -$db->close(); diff --git a/htdocs/api/admin/explorer_withredoc.php b/htdocs/api/admin/explorer_withredoc.php new file mode 100644 index 00000000000..45dd31d57c9 --- /dev/null +++ b/htdocs/api/admin/explorer_withredoc.php @@ -0,0 +1,87 @@ + + * Copyright (C) 2016 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 + * 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 . + * + * @deprecated Old explorer. Not using Swagger. See instead explorer in htdocs/api/index.php. + */ + +/** + * \defgroup api Module DolibarrApi + * \brief API explorer using the swagger.json file + * \file htdocs/api/admin/explorer_withredoc.php + */ + +require_once '../../main.inc.php'; + +// Enable and test if module Api is enabled +if (empty($conf->global->MAIN_MODULE_API)) { + $langs->load("admin"); + dol_syslog("Call of Dolibarr API interfaces with module API REST are disabled"); + print $langs->trans("WarningModuleNotActive", 'Api').'.

'; + print $langs->trans("ToActivateModule"); + //session_destroy(); + exit(0); +} + +// Test if explorer is not disabled +if (!empty($conf->global->API_EXPLORER_DISABLED)) { + $langs->load("admin"); + dol_syslog("Call Dolibarr API interfaces with module REST disabled"); + print $langs->trans("WarningAPIExplorerDisabled").'.

'; + //session_destroy(); + exit(0); +} + +// Restrict API to some IPs +if (!empty($conf->global->API_RESTRICT_ON_IP)) { + $allowedip = explode(' ', $conf->global->API_RESTRICT_ON_IP); + $ipremote = getUserRemoteIP(); + if (!in_array($ipremote, $allowedip)) { + dol_syslog('Remote ip is '.$ipremote.', not into list '.$conf->global->API_RESTRICT_ON_IP); + print 'APIs are not allowed from the IP '.$ipremote; + header('HTTP/1.1 503 API not allowed from your IP '.$ipremote); + //session_destroy(); + exit(0); + } +} + +?> + + + + ReDoc + + + + + + + + + + '> + + + + + diff --git a/htdocs/api/admin/index.php b/htdocs/api/admin/index.php index 3743d61b639..1697318c5e8 100644 --- a/htdocs/api/admin/index.php +++ b/htdocs/api/admin/index.php @@ -139,18 +139,25 @@ $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domai // Show message $message = ''; -$url = $urlwithroot.'/api/index.php/login?login=auserlogin&password=thepassword[&reset=1]'; +//$url = $urlwithroot.'/api/index.php/login?login=auserlogin&password=thepassword[&reset=1]'; +$url = $urlwithroot.'/api/index.php/login?login=auserlogin&password=thepassword[&reset=1]'; $message .= ''.$langs->trans("UrlToGetKeyToUseAPIs").':
'; -$message .= img_picto('', 'globe').' '.$url; +$message .= ''; print $message; +print ajax_autoselect("urltogettoken"); print '
'; print '
'; // Explorer -print ''.$langs->trans("ApiExporerIs").':
'; +print ''.$langs->trans("ApiExporerIs").':
'; if (dol_is_dir(DOL_DOCUMENT_ROOT.'/includes/restler/framework/Luracast/Restler/explorer')) { $url = DOL_MAIN_URL_ROOT.'/api/index.php/explorer'; - print img_picto('', 'globe').' '.$url."
\n"; + print '
\n"; + print '

'.$langs->trans("SwaggerDescriptionFile").':
'; + $urlswagger = DOL_MAIN_URL_ROOT.'/api/index.php/explorer/swagger.json?DOLAPIKEY=youruserapikey'; + //$urlswaggerreal = DOL_MAIN_URL_ROOT.'/api/index.php/explorer/swagger.json?DOLAPIKEY='.$user->api_key; + print '
\n"; + print '
'; } else { $langs->load("errors"); print info_admin($langs->trans("ErrorNotAvailableWithThisDistribution"), 0, 0, 'error'); diff --git a/htdocs/api/index.php b/htdocs/api/index.php index 2ed7d2e08f8..89b5a696462 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -55,6 +55,12 @@ if (!empty($_SERVER['HTTP_DOLAPIENTITY'])) { define("DOLENTITY", (int) $_SERVER['HTTP_DOLAPIENTITY']); } +// When we request url to get the json file, we accept Cross site so we can include the descriptor into an external tool. +if (preg_match('/\/explorer\/swagger\.json/', $_SERVER["PHP_SELF"])) { + header('Access-Control-Allow-Origin: *'); + header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE'); + header('Access-Control-Allow-Headers: Content-Type, Authorization, api_key, DOLAPIKEY'); +} $res = 0; if (!$res && file_exists("../main.inc.php")) { @@ -89,7 +95,7 @@ if (!empty($conf->global->MAIN_NGINX_FIX)) { // Enable and test if module Api is enabled if (empty($conf->global->MAIN_MODULE_API)) { $langs->load("admin"); - dol_syslog("Call Dolibarr API interfaces with module REST disabled"); + dol_syslog("Call of Dolibarr API interfaces with module API REST are disabled"); print $langs->trans("WarningModuleNotActive", 'Api').'.

'; print $langs->trans("ToActivateModule"); //session_destroy(); diff --git a/htdocs/asterisk/wrapper.php b/htdocs/asterisk/wrapper.php index 77a00aed302..7313fdfd2d5 100644 --- a/htdocs/asterisk/wrapper.php +++ b/htdocs/asterisk/wrapper.php @@ -75,6 +75,7 @@ function llxFooter() print "\n".''."\n"; } + require_once '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; @@ -117,10 +118,10 @@ if (!isset($conf->global->ASTERISK_MAX_RETRY)) { } -$login = GETPOST('login'); -$password = GETPOST('password'); -$caller = GETPOST('caller'); -$called = GETPOST('called'); +$login = GETPOST('login', 'alphanohtml'); +$password = GETPOST('password', 'none'); +$caller = GETPOST('caller', 'alphanohtml'); +$called = GETPOST('called', 'alphanohtml'); // IP address of Asterisk server $strHost = $conf->global->ASTERISK_HOST; @@ -163,7 +164,7 @@ if ($resql) { if ($obj) { $found = $obj->name; } else { - $found = $notfound; + $found = 'Not found'; } $db->free($resql); } else { @@ -177,7 +178,7 @@ if (!empty($number)) { if ($pos === false) { $errno = 0; $errstr = 0; - $strCallerId = "Dolibarr call $found <".strtolower($number).">"; + $strCallerId = "Dolibarr caller $found <".strtolower($number).">"; $oSocket = @fsockopen($strHost, $port, $errno, $errstr, 10); if (!$oSocket) { print ''."\n"; @@ -211,7 +212,7 @@ if (!empty($number)) { } } } else { - print 'Bad parameters in URL. Must be '.$_SERVER['PHP_SELF'].'?caller=99999&called=99999&login=xxxxx&password=xxxxx'; + print 'Bad parameters in URL. Must be '.dol_escape_htmltag($_SERVER['PHP_SELF']).'?caller=99999&called=99999&login=xxxxx&password=xxxxx'; } // End of page diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index cecb4fff28a..bc384cfb882 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1324,9 +1324,9 @@ if (empty($reshook)) { // Terms of payment $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); } elseif ($action == 'setremisepercent' && $usercancreate) { - $result = $object->set_remise_percent($user, $_POST['remise_percent']); + $result = $object->set_remise_percent($user, price2num(GETPOST('remise_percent'))); } elseif ($action == 'setremiseabsolue' && $usercancreate) { - $result = $object->set_remise_absolue($user, $_POST['remise_absolue']); + $result = $object->set_remise_absolue($user, price2num(GETPOST('remise_absolue'))); } elseif ($action == 'setmode' && $usercancreate) { // Payment choice $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); @@ -1387,7 +1387,7 @@ if (empty($reshook)) { } elseif ($action == 'swapstatut') { // Toggle the status of a contact if ($object->fetch($id) > 0) { - $result = $object->swapContactStatus(GETPOST('ligne')); + $result = $object->swapContactStatus(GETPOST('ligne', 'int')); } else { dol_print_error($db); } diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 3674356af20..0460caf21f5 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -3843,7 +3843,7 @@ class PropaleLigne extends CommonObjectLine $sql .= ' pd.date_start, pd.date_end, pd.product_type'; $sql .= ' FROM '.MAIN_DB_PREFIX.'propaldet as pd'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pd.fk_product = p.rowid'; - $sql .= ' WHERE pd.rowid = '.$rowid; + $sql .= ' WHERE pd.rowid = '.((int) $rowid); $result = $this->db->query($sql); if ($result) { diff --git a/htdocs/comm/propal/contact.php b/htdocs/comm/propal/contact.php index 60d3836cfcb..3bbe232be6e 100644 --- a/htdocs/comm/propal/contact.php +++ b/htdocs/comm/propal/contact.php @@ -93,7 +93,7 @@ if ($action == 'addcontact' && $user->rights->propale->creer) { } elseif ($action == 'swapstatut' && $user->rights->propale->creer) { // Toggle the status of a contact if ($object->id > 0) { - $result = $object->swapContactStatus(GETPOST('ligne')); + $result = $object->swapContactStatus(GETPOST('ligne', 'int')); } } elseif ($action == 'deletecontact' && $user->rights->propale->creer) { // Deletes a contact diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index b4c63365bf8..f5ac2ebae7a 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -843,31 +843,31 @@ if ($resql) { if ($user->rights->societe->client->voir || $socid) { $langs->load("commercial"); $moreforfilter .= '
'; - $moreforfilter .= $langs->trans('ThirdPartiesOfSaleRepresentative').': '; - $moreforfilter .= $formother->select_salesrepresentatives($search_sale, 'search_sale', $user, 0, 1, 'maxwidth200'); + $tmptitle = $langs->trans('ThirdPartiesOfSaleRepresentative'); + $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$formother->select_salesrepresentatives($search_sale, 'search_sale', $user, 0, $tmptitle, 'maxwidth250'); $moreforfilter .= '
'; } // If the user can view prospects other than his' if ($user->rights->societe->client->voir || $socid) { $moreforfilter .= '
'; - $moreforfilter .= $langs->trans('LinkedToSpecificUsers').': '; - $moreforfilter .= $form->select_dolusers($search_user, 'search_user', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth200'); + $tmptitle = $langs->trans('LinkedToSpecificUsers'); + $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$form->select_dolusers($search_user, 'search_user', $tmptitle, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth250'); $moreforfilter .= '
'; } // If the user can view products if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire && ($user->rights->produit->lire || $user->rights->service->lire)) { include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; $moreforfilter .= '
'; - $moreforfilter .= $langs->trans('IncludingProductWithTag').': '; + $tmptitle = $langs->trans('IncludingProductWithTag'); $cate_arbo = $form->select_all_categories(Categorie::TYPE_PRODUCT, null, 'parent', null, null, 1); - $moreforfilter .= $form->selectarray('search_product_category', $cate_arbo, $search_product_category, 1, 0, 0, '', 0, 0, 0, 0, 'maxwidth300', 1); + $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"').$form->selectarray('search_product_category', $cate_arbo, $search_product_category, $tmptitle, 0, 0, '', 0, 0, 0, 0, 'maxwidth300', 1); $moreforfilter .= '
'; } if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) { require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; $moreforfilter .= '
'; - $moreforfilter .= $langs->trans('CustomersProspectsCategoriesShort').': '; - $moreforfilter .= $formother->select_categories('customer', $search_categ_cus, 'search_categ_cus', 1); + $tmptitle = $langs->trans('CustomersProspectsCategoriesShort'); + $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"').$formother->select_categories('customer', $search_categ_cus, 'search_categ_cus', 1, $tmptitle); $moreforfilter .= '
'; } $parameters = array(); @@ -1532,7 +1532,7 @@ if ($resql) { } // Amount HT if (!empty($arrayfields['p.total_ht']['checked'])) { - print ''.price($obj->total_ht)."\n"; + print ''.price($obj->total_ht)."\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1543,7 +1543,7 @@ if ($resql) { } // Amount VAT if (!empty($arrayfields['p.total_tva']['checked'])) { - print ''.price($obj->total_tva)."\n"; + print ''.price($obj->total_tva)."\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1554,7 +1554,7 @@ if ($resql) { } // Amount TTC if (!empty($arrayfields['p.total_ttc']['checked'])) { - print ''.price($obj->total_ttc)."\n"; + print ''.price($obj->total_ttc)."\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1563,9 +1563,9 @@ if ($resql) { } $totalarray['val']['p.total_ttc'] += $obj->total_ttc; } - // Amount invoiced + // Amount invoiced HT if (!empty($arrayfields['p.total_ht_invoiced']['checked'])) { - print ''.price($totalInvoicedHT)."\n"; + print ''.price($totalInvoicedHT)."\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1574,9 +1574,9 @@ if ($resql) { } $totalarray['val']['p.total_ht_invoiced'] += $totalInvoicedHT; } - // Amount invoiced + // Amount invoiced TTC if (!empty($arrayfields['p.total_invoiced']['checked'])) { - print ''.price($totalInvoicedTTC)."\n"; + print ''.price($totalInvoicedTTC)."\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1604,35 +1604,35 @@ if ($resql) { } // Amount HT if (!empty($arrayfields['p.multicurrency_total_ht']['checked'])) { - print ''.price($obj->multicurrency_total_ht)."\n"; + print ''.price($obj->multicurrency_total_ht)."\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount VAT if (!empty($arrayfields['p.multicurrency_total_tva']['checked'])) { - print ''.price($obj->multicurrency_total_tva)."\n"; + print ''.price($obj->multicurrency_total_tva)."\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount TTC if (!empty($arrayfields['p.multicurrency_total_ttc']['checked'])) { - print ''.price($obj->multicurrency_total_ttc)."\n"; + print ''.price($obj->multicurrency_total_ttc)."\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount invoiced if (!empty($arrayfields['p.multicurrency_total_ht_invoiced']['checked'])) { - print ''.price($multicurrency_totalInvoicedHT)."\n"; + print ''.price($multicurrency_totalInvoicedHT)."\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount invoiced if (!empty($arrayfields['p.multicurrency_total_invoiced']['checked'])) { - print ''.price($multicurrency_totalInvoicedTTC)."\n"; + print ''.price($multicurrency_totalInvoicedTTC)."\n"; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/comm/prospect/recap-prospect.php b/htdocs/comm/prospect/recap-prospect.php index 655dda87d0d..4656574fb47 100644 --- a/htdocs/comm/prospect/recap-prospect.php +++ b/htdocs/comm/prospect/recap-prospect.php @@ -33,7 +33,7 @@ if (!empty($conf->facture->enabled)) { } // Security check -$socid = $_GET["socid"]; +$socid = GETPOST("socid", 'int'); if ($user->socid > 0) { $action = ''; $socid = $user->socid; diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 98ada17e54f..66d45f6a278 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -24,6 +24,8 @@ * \brief Page to edit absolute discounts for a customer */ +if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET + require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index a46e7df6b75..8e0dc91756c 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -1370,7 +1370,7 @@ if (empty($reshook)) { } elseif ($action == 'swapstatut') { // bascule du statut d'un contact if ($object->id > 0) { - $result = $object->swapContactStatus(GETPOST('ligne')); + $result = $object->swapContactStatus(GETPOST('ligne', 'int')); } else { dol_print_error($db); } diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 14fc65cf18d..ea97dcbf233 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -4126,7 +4126,7 @@ class OrderLine extends CommonOrderLine $sql .= ' cd.date_start, cd.date_end'; $sql .= ' FROM '.MAIN_DB_PREFIX.'commandedet as cd'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid'; - $sql .= ' WHERE cd.rowid = '.$rowid; + $sql .= ' WHERE cd.rowid = '.((int) $rowid); $result = $this->db->query($sql); if ($result) { $objp = $this->db->fetch_object($result); diff --git a/htdocs/commande/contact.php b/htdocs/commande/contact.php index 0a576707e73..5e11c5cb030 100644 --- a/htdocs/commande/contact.php +++ b/htdocs/commande/contact.php @@ -75,14 +75,14 @@ if ($action == 'addcontact' && $user->rights->commande->creer) { } elseif ($action == 'swapstatut' && $user->rights->commande->creer) { // bascule du statut d'un contact if ($object->fetch($id)) { - $result = $object->swapContactStatus(GETPOST('ligne')); + $result = $object->swapContactStatus(GETPOST('ligne', 'int')); } else { dol_print_error($db); } } elseif ($action == 'deletecontact' && $user->rights->commande->creer) { // Efface un contact $object->fetch($id); - $result = $object->delete_contact($_GET["lineid"]); + $result = $object->delete_contact(GETPOST("lineid", 'int')); if ($result >= 0) { header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 117f7557db3..df79a9edffd 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -806,39 +806,39 @@ if ($resql) { if ($user->rights->societe->client->voir || $socid) { $langs->load("commercial"); $moreforfilter .= '
'; - $moreforfilter .= $langs->trans('ThirdPartiesOfSaleRepresentative').': '; - $moreforfilter .= $formother->select_salesrepresentatives($search_sale, 'search_sale', $user, 0, 1, 'maxwidth200'); + $tmptitle = $langs->trans('ThirdPartiesOfSaleRepresentative'); + $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$formother->select_salesrepresentatives($search_sale, 'search_sale', $user, 0, $tmptitle, 'maxwidth250'); $moreforfilter .= '
'; } // If the user can view other users if ($user->rights->user->user->lire) { $moreforfilter .= '
'; - $moreforfilter .= $langs->trans('LinkedToSpecificUsers').': '; - $moreforfilter .= $form->select_dolusers($search_user, 'search_user', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth200'); + $tmptitle = $langs->trans('LinkedToSpecificUsers'); + $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$form->select_dolusers($search_user, 'search_user', $tmptitle, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth250'); $moreforfilter .= '
'; } // If the user can view prospects other than his' if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire && ($user->rights->produit->lire || $user->rights->service->lire)) { include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; $moreforfilter .= '
'; - $moreforfilter .= $langs->trans('IncludingProductWithTag').': '; + $tmptitle = $langs->trans('IncludingProductWithTag'); $cate_arbo = $form->select_all_categories(Categorie::TYPE_PRODUCT, null, 'parent', null, null, 1); - $moreforfilter .= $form->selectarray('search_product_category', $cate_arbo, $search_product_category, 1, 0, 0, '', 0, 0, 0, 0, 'maxwidth300', 1); + $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"').$form->selectarray('search_product_category', $cate_arbo, $search_product_category, $tmptitle, 0, 0, '', 0, 0, 0, 0, 'maxwidth300', 1); $moreforfilter .= '
'; } if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) { require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; $moreforfilter .= '
'; - $moreforfilter .= $langs->trans('CustomersProspectsCategoriesShort').': '; - $moreforfilter .= $formother->select_categories('customer', $search_categ_cus, 'search_categ_cus', 1); + $tmptitle = $langs->trans('CustomersProspectsCategoriesShort'); + $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"').$formother->select_categories('customer', $search_categ_cus, 'search_categ_cus', 1, $tmptitle); $moreforfilter .= '
'; } if (!empty($conf->expedition->enabled) && !empty($conf->global->WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER)) { require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; $formproduct = new FormProduct($db); $moreforfilter .= '
'; - $moreforfilter .= $langs->trans('Warehouse').': '; - $moreforfilter .= $formproduct->selectWarehouses($search_warehouse, 'search_warehouse', '', 1); + $tmptitle = $langs->trans('Warehouse'); + $moreforfilter .= img_picto($tmptitle, 'warehouse', 'class="pictofixedwidth"').$formproduct->selectWarehouses($search_warehouse, 'search_warehouse', '', $tmptitle); $moreforfilter .= '
'; } $parameters = array(); @@ -1437,7 +1437,7 @@ if ($resql) { } // Amount HT if (!empty($arrayfields['c.total_ht']['checked'])) { - print ''.price($obj->total_ht)."\n"; + print ''.price($obj->total_ht)."\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1448,7 +1448,7 @@ if ($resql) { } // Amount VAT if (!empty($arrayfields['c.total_vat']['checked'])) { - print ''.price($obj->total_tva)."\n"; + print ''.price($obj->total_tva)."\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1459,7 +1459,7 @@ if ($resql) { } // Amount TTC if (!empty($arrayfields['c.total_ttc']['checked'])) { - print ''.price($obj->total_ttc)."\n"; + print ''.price($obj->total_ttc)."\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1488,21 +1488,21 @@ if ($resql) { } // Amount HT if (!empty($arrayfields['c.multicurrency_total_ht']['checked'])) { - print ''.price($obj->multicurrency_total_ht)."\n"; + print ''.price($obj->multicurrency_total_ht)."\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount VAT if (!empty($arrayfields['c.multicurrency_total_vat']['checked'])) { - print ''.price($obj->multicurrency_total_vat)."\n"; + print ''.price($obj->multicurrency_total_vat)."\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount TTC if (!empty($arrayfields['c.multicurrency_total_ttc']['checked'])) { - print ''.price($obj->multicurrency_total_ttc)."\n"; + print ''.price($obj->multicurrency_total_ttc)."\n"; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index 22121fa7664..965e0f6c94b 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -211,7 +211,6 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_thirdparty_user = ''; $search_num_releve = ''; $search_conciliated = ''; - $thirdparty = ''; $search_account = ""; if ($id > 0 || !empty($ref)) { @@ -992,9 +991,9 @@ if ($resql) { // Bank line $moreforfilter .= '
'; - $moreforfilter .= $langs->trans('RubriquesTransactions').' : '; + $tmptitle = $langs->trans('RubriquesTransactions'); $cate_arbo = $form->select_all_categories(Categorie::TYPE_BANK_LINE, $search_bid, 'parent', null, null, 1); - $moreforfilter .= $form->selectarray('search_bid', $cate_arbo, $search_bid, 1, 0, 0, '', 0, 0, 0, '', '', 1); + $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"').$form->selectarray('search_bid', $cate_arbo, $search_bid, $tmptitle, 0, 0, '', 0, 0, 0, '', '', 1); $moreforfilter .= '
'; } } @@ -1561,12 +1560,12 @@ if ($resql) { // Debit if (!empty($arrayfields['b.debit']['checked'])) { - print ''; + print ''; if ($objp->amount < 0) { print price($objp->amount * -1); $totalarray['totaldeb'] += $objp->amount; } - print "\n"; + print "\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1577,12 +1576,12 @@ if ($resql) { // Credit if (!empty($arrayfields['b.credit']['checked'])) { - print ''; + print ''; if ($objp->amount > 0) { print price($objp->amount); $totalarray['totalcred'] += $objp->amount; } - print "\n"; + print "\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1717,9 +1716,9 @@ if ($resql) { print ''.$langs->trans("Totalforthispage").''; } } elseif ($totalarray['totaldebfield'] == $i) { - print ''.price(-1 * $totalarray['totaldeb']).''; + print ''.price(-1 * $totalarray['totaldeb']).''; } elseif ($totalarray['totalcredfield'] == $i) { - print ''.price($totalarray['totalcred']).''; + print ''.price($totalarray['totalcred']).''; } elseif ($i == $posconciliatecol) { print ''; if ($user->rights->banque->consolidate && $action == 'reconcile') { diff --git a/htdocs/compta/bank/budget.php b/htdocs/compta/bank/budget.php index d3ffbb37916..3e40e45b58e 100644 --- a/htdocs/compta/bank/budget.php +++ b/htdocs/compta/bank/budget.php @@ -82,8 +82,8 @@ if ($result) { print ''; print "rowid\">$objp->label"; print ''.$objp->nombre.''; - print ''.price(abs($objp->somme)).""; - print ''.price(abs(price2num($objp->somme / $objp->nombre, 'MT'))).""; + print ''.price(abs($objp->somme)).""; + print ''.price(abs(price2num($objp->somme / $objp->nombre, 'MT'))).""; print ""; $i++; $total += abs($objp->somme); diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index be91d475d4d..dc71a1d2d27 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -346,7 +346,7 @@ if (empty($numref)) { $balancestart[$objp->numr] = $obj->amount; $db->free($resql); } - print ''.price($balancestart[$objp->numr], '', $langs, 1, -1, -1, $conf->currency).''; + print ''.price($balancestart[$objp->numr], '', $langs, 1, -1, -1, $conf->currency).''; // Calculate end amount $sql = "SELECT sum(b.amount) as amount"; @@ -359,7 +359,7 @@ if (empty($numref)) { $content[$objp->numr] = $obj->amount; $db->free($resql); } - print ''.price(($balancestart[$objp->numr] + $content[$objp->numr]), '', $langs, 1, -1, -1, $conf->currency).''; + print ''.price(($balancestart[$objp->numr] + $content[$objp->numr]), '', $langs, 1, -1, -1, $conf->currency).''; print ''; if ($user->rights->banque->consolidate && $action != 'editbankreceipt') { diff --git a/htdocs/compta/bank/various_payment/list.php b/htdocs/compta/bank/various_payment/list.php index 65542598351..dcc1f4aef97 100644 --- a/htdocs/compta/bank/various_payment/list.php +++ b/htdocs/compta/bank/various_payment/list.php @@ -671,7 +671,7 @@ if ($result) { if ($arrayfields['debit']['checked']) { print ''; if ($obj->sens == 0) { - print price($obj->amount); + print ''.price($obj->amount).''; $totalarray['val']['total_deb'] += $obj->amount; } if (!$i) { @@ -687,7 +687,7 @@ if ($result) { if ($arrayfields['credit']['checked']) { print ''; if ($obj->sens == 1) { - print price($obj->amount); + print ''.price($obj->amount).''; $totalarray['val']['total_cred'] += $obj->amount; } if (!$i) { diff --git a/htdocs/compta/cashcontrol/cashcontrol_list.php b/htdocs/compta/cashcontrol/cashcontrol_list.php index 3b97b967208..79ac1e1b708 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_list.php +++ b/htdocs/compta/cashcontrol/cashcontrol_list.php @@ -31,14 +31,17 @@ //if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on). //if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) //if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data -//if (! defined('NOIPCHECK')) define('NOIPCHECK','1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip //if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu //if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php //if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library -//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) +//if (! defined("NOLOGIN")) define("NOLOGIN", '1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too. +//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip //if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT','auto'); // Force lang to a particular value //if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE','aloginmodule'); // Force authentication handler //if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN',1); // The main.inc.php does not make a redirect if not logged, instead show simple error message +//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies +//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET +//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/compta/cashcontrol/class/cashcontrol.class.php'; @@ -66,7 +69,7 @@ $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); -if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { +if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action $offset = $limit * $page; @@ -83,11 +86,13 @@ $hookmanager->initHooks(array('cashcontrol')); // Note that conf->hooks_modules // Fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); +//$extrafields->fetch_name_optionals_label($object->table_element_line); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); // Default sort order (if not yet defined by previous GETPOST) if (!$sortfield) { + reset($object->fields); // Reset is required to avoid key() to return null. $sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition. } if (!$sortorder) { @@ -95,12 +100,16 @@ if (!$sortorder) { } // Initialize array of search criterias -$search_all = GETPOST("search_all", 'alpha'); +$search_all = GETPOST('search_all', 'alphanohtml') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'); $search = array(); foreach ($object->fields as $key => $val) { - if (GETPOST('search_'.$key, 'alpha')) { + if (GETPOST('search_'.$key, 'alpha') !== '') { $search[$key] = GETPOST('search_'.$key, 'alpha'); } + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int')); + $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int')); + } } // List of fields to search into when doing a "search in all" @@ -161,6 +170,10 @@ if (empty($reshook)) { if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers foreach ($object->fields as $key => $val) { $search[$key] = ''; + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = ''; + $search[$key.'_dtend'] = ''; + } } $toselect = ''; $search_array_options = array(); @@ -198,9 +211,7 @@ $title = $langs->trans('CashControl'); // Build and execute select // -------------------------------------------------------------------- $sql = 'SELECT '; -foreach ($object->fields as $key => $val) { - $sql .= 't.'.$key.', '; -} +$sql .= $object->getFieldList('t'); // Add fields from extrafields if (!empty($extrafields->attributes[$object->table_element]['label'])) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { @@ -210,24 +221,48 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { // 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 = preg_replace('/, $/', '', $sql); +$sql .= preg_replace('/^,/', '', $hookmanager->resPrint); +$sql = preg_replace('/,\s*$/', '', $sql); $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; } +// 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; if ($object->ismultientitymanaged == 1) { $sql .= " WHERE t.entity IN (".getEntity($object->element).")"; } else { $sql .= " WHERE 1 = 1"; } foreach ($search as $key => $val) { - if ($key == 'status' && $search[$key] == -1) { - continue; - } - $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); - if ($search[$key] != '') { - $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); + if (array_key_exists($key, $object->fields)) { + if ($key == 'status' && $search[$key] == -1) { + continue; + } + $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); + if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0)) { + if ($search[$key] == '-1' || $search[$key] === '0') { + $search[$key] = ''; + } + $mode_search = 2; + } + if ($search[$key] != '') { + $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); + } + } else { + if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') { + $columnName=preg_replace('/(_dtstart|_dtend)$/', '', $key); + if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) { + if (preg_match('/_dtstart$/', $key)) { + $sql .= " AND t." . $columnName . " >= '" . $db->idate($search[$key]) . "'"; + } + if (preg_match('/_dtend$/', $key)) { + $sql .= " AND t." . $columnName . " <= '" . $db->idate($search[$key]) . "'"; + } + } + } } } if ($search_all) { @@ -241,20 +276,20 @@ $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $objec $sql .= $hookmanager->resPrint; /* If a group by is required - $sql.= " GROUP BY " - foreach($object->fields as $key => $val) - { - $sql.='t.'.$key.', '; - } - // Add fields from extrafields - if (! empty($extrafields->attributes[$object->table_element]['label'])) { - foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) $sql.=($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : ''); - // Add where from hooks - $parameters=array(); - $reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters); // Note that $action and $object may have been modified by hook - $sql.=$hookmanager->resPrint; - $sql=preg_replace('/, $/','', $sql); - */ +$sql.= " GROUP BY "; +foreach($object->fields as $key => $val) { + $sql.='t.'.$key.', '; +} +// Add fields from extrafields +if (! empty($extrafields->attributes[$object->table_element]['label'])) { + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) $sql.=($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : ''); +} +// Add where 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=preg_replace('/,\s*$/','', $sql); +*/ $sql .= $db->order($sortfield, $sortorder); @@ -269,10 +304,12 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { } } // if total of record found is smaller than limit, no need to do paging and to restart another select with limits set. -if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords) { +if (is_numeric($nbtotalofrecords) && ($limit > $nbtotalofrecords || empty($limit))) { $num = $nbtotalofrecords; } else { - $sql .= $db->plimit($limit + 1, $offset); + if ($limit) { + $sql .= $db->plimit($limit + 1, $offset); + } $resql = $db->query($sql); if (!$resql) { @@ -284,10 +321,10 @@ if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords) { } // Direct jump if only one record found -if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all) { +if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) { $obj = $db->fetch_object($resql); $id = $obj->rowid; - header("Location: ".dol_buildpath('/compta/cashcontrol/cashcontrol_card.php', 1).'?id='.$id); + header("Location: ".DOL_URL_ROOT.'/compta/cashcontrol/cashcontrol_card.php?id='.$id); exit; } @@ -295,7 +332,7 @@ if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $ // Output page // -------------------------------------------------------------------- -llxHeader('', $title, $help_url); +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'classforhorizontalscrolloftabs'); // Example : Adding jquery code print '