From 797bab47417ad3f1673b09a0470a25ce6e870f79 Mon Sep 17 00:00:00 2001 From: Abbes Bahfir Date: Wed, 11 Sep 2019 18:42:46 +0100 Subject: [PATCH 01/27] fix: repetition --- htdocs/core/class/ldap.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index 1d1a6122288..266b41867e8 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -609,7 +609,7 @@ class Ldap } if ($result <= 0) { - $this->error = ldap_errno($this->connection)." ".ldap_error($this->connection)." ".$this->error; + $this->error = ldap_errno($this->connection)." ".$this->error; dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR); //print_r($info); return -1; From 5183a1ec7a19cd553fd9fa728a911df3310174b9 Mon Sep 17 00:00:00 2001 From: Abbes Bahfir Date: Wed, 11 Sep 2019 22:45:02 +0100 Subject: [PATCH 02/27] New : Use of posixAccount and posixGroup objectclass for users and groups in LDAP --- htdocs/admin/ldap_groups.php | 8 +++++++ htdocs/admin/ldap_users.php | 33 +++++++++++++++++++++++++++ htdocs/langs/en_US/admin.lang | 7 ++++++ htdocs/langs/fr_FR/admin.lang | 7 ++++++ htdocs/user/class/user.class.php | 18 +++++++++++++-- htdocs/user/class/usergroup.class.php | 5 +++- 6 files changed, 75 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/ldap_groups.php b/htdocs/admin/ldap_groups.php index 450fec88ad0..6dcc26a23e0 100644 --- a/htdocs/admin/ldap_groups.php +++ b/htdocs/admin/ldap_groups.php @@ -58,6 +58,7 @@ if ($action == 'setvalue' && $user->admin) //if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_NAME',$_POST["fieldname"],'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_DESCRIPTION', GETPOST("fielddescription"), 'chaine', 0, '', $conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_GROUPMEMBERS', GETPOST("fieldgroupmembers"), 'chaine', 0, '', $conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_FIELD_GROUPID', GETPOST("fieldgroupid"), 'chaine', 0, '', $conf->entity)) $error++; // This one must be after the others $valkey=''; @@ -170,6 +171,13 @@ print ''.$langs->trans("LDAPFieldGroupMembersExample").''; print 'global->LDAP_KEY_GROUPS && $conf->global->LDAP_KEY_GROUPS==$conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS)?' checked':'').">"; print ''; +// Group id +print ''.$langs->trans("LDAPFieldGroupid").''; +print ''; +print ''.$langs->trans("LDAPFieldGroupidExample").''; +print ' '; +print ''; + print ''; print info_admin($langs->trans("LDAPDescValues")); diff --git a/htdocs/admin/ldap_users.php b/htdocs/admin/ldap_users.php index 4148d81f438..394451c9472 100644 --- a/htdocs/admin/ldap_users.php +++ b/htdocs/admin/ldap_users.php @@ -5,6 +5,7 @@ * Copyright (C) 2005 Regis Houssin * Copyright (C) 2006-2011 Laurent Destailleur * Copyright (C) 2011-2016 Juanjo Menent + * Copyright (C) 2019 Abbes Bahfir * * 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 @@ -73,6 +74,10 @@ if ($action == 'setvalue' && $user->admin) if (! dolibarr_set_const($db, 'LDAP_FIELD_DESCRIPTION', GETPOST("fielddescription"), 'chaine', 0, '', $conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_SID', GETPOST("fieldsid"), 'chaine', 0, '', $conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_TITLE', GETPOST("fieldtitle"), 'chaine', 0, '', $conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_FIELD_GROUPID', GETPOST("fieldgroupid"), 'chaine', 0, '', $conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_FIELD_USERID', GETPOST("fielduserid"), 'chaine', 0, '', $conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_FIELD_HOMEDIRECTORY', GETPOST("fieldhomedirectory"), 'chaine', 0, '', $conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_FIELD_HOMEDIRECTORYPREFIX', GETPOST("fieldhomedirectoryprefix"), 'chaine', 0, '', $conf->entity)) $error++; // This one must be after the others $valkey=''; @@ -301,6 +306,34 @@ print ''.$langs->trans("LDAPFieldSidExample").''; print 'global->LDAP_KEY_USERS && $conf->global->LDAP_KEY_USERS==$conf->global->LDAP_FIELD_SID)?' checked':'').">"; print ''; +// Group id +print ''.$langs->trans("LDAPFieldGroupid").''; +print ''; +print ''.$langs->trans("LDAPFieldGroupidExample").''; +print ' '; +print ''; + +// Userid +print ''.$langs->trans("LDAPFieldUserid").''; +print ''; +print ''.$langs->trans("LDAPFieldUseridExample").''; +print ' '; +print ''; + +// Home Directory +print ''.$langs->trans("LDAPFieldHomedirectory").''; +print ''; +print ''.$langs->trans("LDAPFieldHomedirectoryExample").''; +print ' '; +print ''; + +// Home Directory Prefix +print ''.$langs->trans("LDAPFieldHomedirectoryprefix").''; +print ''; +print ''; +print ' '; +print ''; + print ''; print info_admin($langs->trans("LDAPDescValues")); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index a8f7f9643ce..3eb9f24112d 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1458,6 +1458,13 @@ LDAPFieldSidExample=Example: objectsid LDAPFieldEndLastSubscription=Date of subscription end LDAPFieldTitle=Job position LDAPFieldTitleExample=Example: title +LDAPFieldGroupid=Group id +LDAPFieldGroupidExample=Exemple : gidnumber +LDAPFieldUserid=User id +LDAPFieldUseridExample=Exemple : uidnumber +LDAPFieldHomedirectory=Home directory prefix +LDAPFieldHomedirectoryExample=Exemple : homedirectory +LDAPFieldHomedirectoryprefix=Home directory prefix LDAPSetupNotComplete=LDAP setup not complete (go on others tabs) LDAPNoUserOrPasswordProvidedAccessIsReadOnly=No administrator or password provided. LDAP access will be anonymous and in read only mode. LDAPDescContact=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr contacts. diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index 20cdc9175d6..ff684f01cb9 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -1458,6 +1458,13 @@ LDAPFieldSidExample=Exemple : objectsid LDAPFieldEndLastSubscription=Date de fin de validité adhésion LDAPFieldTitle=Poste/fonction LDAPFieldTitleExample=Exemple: title +LDAPFieldGroupid=Groupe id +LDAPFieldGroupidExample=Exemple : gidnumber +LDAPFieldUserid=User id +LDAPFieldUseridExample=Exemple : uidnumber +LDAPFieldHomedirectory=Répertoire d'accueil +LDAPFieldHomedirectoryExample=Exemple : homedirectory +LDAPFieldHomedirectoryprefix=Préfixe du répertoire d'accueil LDAPSetupNotComplete=Configuration LDAP incomplète (à compléter sur les autres onglets) LDAPNoUserOrPasswordProvidedAccessIsReadOnly=Administrateur ou mot de passe non renseigné. Les accès LDAP seront donc anonymes et en lecture seule. LDAPDescContact=Cette page permet de définir le nom des attributs de l'arbre LDAP pour chaque information des contacts Dolibarr. diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 4d78aa1b892..aa4aec74251 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -13,6 +13,7 @@ * Copyright (C) 2018 charlene Benke * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2019 Frédéric France + * Copyright (C) 2019 Abbes Bahfir * * 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 @@ -35,6 +36,7 @@ */ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT .'/user/class/usergroup.class.php'; /** * Class to manage Dolibarr users @@ -2655,8 +2657,20 @@ class User extends CommonObject if ($this->phone_mobile) $info["phpgwCellTelephoneNumber"] = $this->phone_mobile; } - return $info; - } + $info[$conf->global->LDAP_FIELD_USERID] = $this->id; + $info[$conf->global->LDAP_FIELD_GROUPID] = '1'; + $usergroup = new UserGroup($this->db); + $groupslist = $usergroup->listGroupsForUser($this->id); + if(!empty($groupslist)){ + foreach ($groupslist as $groupforuser) { + $info[$conf->global->LDAP_FIELD_GROUPID] = $groupforuser->id;//Select first group in list + break; + } + } + $info[$conf->global->LDAP_FIELD_HOMEDIRECTORY]="{$conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX}/$this->firstname"; + + return $info; + } /** diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index d51d82c8d13..c0cd4d9227f 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -6,6 +6,7 @@ * Copyright (C) 2014 Juanjo Menent * Copyright (C) 2014 Alexis Algoud * Copyright (C) 2018 Nicolas ZABOURI + * Copyright (C) 2019 Abbes Bahfir * * 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 @@ -978,7 +979,9 @@ class UserGroup extends CommonObject $valueofldapfield[] = $muser->_load_ldap_dn($info2); } $info[$conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS] = (!empty($valueofldapfield)?$valueofldapfield:''); - } + + } + $info[$conf->global->LDAP_FIELD_GROUPID]=$this->id; return $info; } From e5878c105a001d1215a31c121b10caee5452da02 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 11 Sep 2019 21:48:17 +0000 Subject: [PATCH 03/27] Fixing style errors. --- htdocs/user/class/usergroup.class.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index c0cd4d9227f..4e8cdf5824b 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -979,7 +979,6 @@ class UserGroup extends CommonObject $valueofldapfield[] = $muser->_load_ldap_dn($info2); } $info[$conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS] = (!empty($valueofldapfield)?$valueofldapfield:''); - } $info[$conf->global->LDAP_FIELD_GROUPID]=$this->id; return $info; From 195ac8e8f6d70b60495cc6c2b99d4af2465dfab0 Mon Sep 17 00:00:00 2001 From: Abbes Bahfir Date: Thu, 12 Sep 2019 11:18:22 +0100 Subject: [PATCH 04/27] fix : Tests for attributes exsitence in Use of posixAccount and posixGroup objectclass for users and groups in LDAP --- htdocs/user/class/user.class.php | 20 +++++++++++--------- htdocs/user/class/usergroup.class.php | 4 +++- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index aa4aec74251..ae1d9afa062 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2657,17 +2657,19 @@ class User extends CommonObject if ($this->phone_mobile) $info["phpgwCellTelephoneNumber"] = $this->phone_mobile; } - $info[$conf->global->LDAP_FIELD_USERID] = $this->id; - $info[$conf->global->LDAP_FIELD_GROUPID] = '1'; - $usergroup = new UserGroup($this->db); - $groupslist = $usergroup->listGroupsForUser($this->id); - if(!empty($groupslist)){ - foreach ($groupslist as $groupforuser) { - $info[$conf->global->LDAP_FIELD_GROUPID] = $groupforuser->id;//Select first group in list - break; + if (!empty($conf->global->LDAP_FIELD_USERID))$info[$conf->global->LDAP_FIELD_USERID] = $this->id; + if(!empty($info[$conf->global->LDAP_FIELD_GROUPID])){ + $usergroup = new UserGroup($this->db); + $groupslist = $usergroup->listGroupsForUser($this->id); + $info[$conf->global->LDAP_FIELD_GROUPID] = '1'; + if(!empty($groupslist)){ + foreach ($groupslist as $groupforuser) { + $info[$conf->global->LDAP_FIELD_GROUPID] = $groupforuser->id;//Select first group in list + break; + } } } - $info[$conf->global->LDAP_FIELD_HOMEDIRECTORY]="{$conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX}/$this->firstname"; + if (!empty($this->firstname) && !empty($conf->global->LDAP_FIELD_HOMEDIRECTORY) && !empty($conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX)) $info[$conf->global->LDAP_FIELD_HOMEDIRECTORY]="{$conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX}/$this->firstname"; return $info; } diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index c0cd4d9227f..f2194b1d8b7 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -981,7 +981,9 @@ class UserGroup extends CommonObject $info[$conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS] = (!empty($valueofldapfield)?$valueofldapfield:''); } - $info[$conf->global->LDAP_FIELD_GROUPID]=$this->id; + if(!empty($info[$conf->global->LDAP_FIELD_GROUPID])){ + $info[$conf->global->LDAP_FIELD_GROUPID]=$this->id; + } return $info; } From a12bd6aec8ed782c38a5a7aced80473f37921652 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 12 Sep 2019 18:55:07 +0200 Subject: [PATCH 05/27] better translation --- htdocs/langs/en_US/orders.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/orders.lang b/htdocs/langs/en_US/orders.lang index 256bd2a7d4d..c170e4c1248 100644 --- a/htdocs/langs/en_US/orders.lang +++ b/htdocs/langs/en_US/orders.lang @@ -152,7 +152,7 @@ OrderCreated=Your orders have been created OrderFail=An error happened during your orders creation CreateOrders=Create orders ToBillSeveralOrderSelectCustomer=To create an invoice for several orders, click first onto customer, then choose "%s". -OptionToSetOrderBilledNotEnabled=Option (from module Workflow) to set order to 'Billed' automatically when invoice is validated is off, so you will have to set status of order to 'Billed' manually. +OptionToSetOrderBilledNotEnabled=Option from module Workflow, to set order to 'Billed' automatically when invoice is validated, is not enabled, so you will have to set the status of orders to 'Billed' manually after the invoice has been generated. IfValidateInvoiceIsNoOrderStayUnbilled=If invoice validation is 'No', the order will remain to status 'Unbilled' until the invoice is validated. CloseReceivedSupplierOrdersAutomatically=Close order to status "%s" automatically if all products are received. SetShippingMode=Set shipping mode From 1439310a15197dc0383f27749744cc35c9b503f1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 12 Sep 2019 21:08:46 +0200 Subject: [PATCH 06/27] Fix margin --- htdocs/includes/ckeditor/ckeditor/contents.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/includes/ckeditor/ckeditor/contents.css b/htdocs/includes/ckeditor/ckeditor/contents.css index 7bd09d5552a..933afb9c6f3 100644 --- a/htdocs/includes/ckeditor/ckeditor/contents.css +++ b/htdocs/includes/ckeditor/ckeditor/contents.css @@ -16,7 +16,7 @@ body /* Remove the background color to make it transparent. */ background-color: #fff; - margin: 20px; + margin: 5px; } .cke_editable From 165ee28823dd8eb741d185d58be2a7c9e4eb2a46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 12 Sep 2019 21:48:00 +0200 Subject: [PATCH 07/27] Update .editorconfig editorconfig control the github online editor --- .editorconfig | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 2df455f0d4f..3e3bd16bb34 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,14 +1,21 @@ -# EditorConfig is awesome: http://EditorConfig.org +# EditorConfig is awesome: https://editorconfig.org # top-most EditorConfig file root = true + # Unix-style newlines with a newline ending every file [*] charset = utf-8 end_of_line = lf insert_final_newline = true + +# PHP PSR-2 Coding Standards +# http://www.php-fig.org/psr/psr-2/ [*.php] indent_style = tab +indent_size = 4 +trim_trailing_whitespace = true +insert_final_newline = true [*.js] indent_style = tab [*.css] From 48e03e1ab5be55bb47158582ba37b77a44ffc4de Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 13 Sep 2019 01:38:41 +0200 Subject: [PATCH 08/27] Fix responsive --- htdocs/theme/eldy/global.inc.php | 9 ++++++--- htdocs/theme/md/style.css.php | 13 +++++++++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 86b4fa82c12..cbb69df74f9 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -5789,10 +5789,13 @@ div.tabsElem a.tab { } .titlefield { - width: auto !important; /* We want to ignor the 30%, try to use more if you can */ + width: auto !important; /* We want to ignore the 30%, try to use more if you can */ } - .tableforfield>tr>td:first-child { - max-width: 100px; /* but no more than 100px */ + .tableforfield>tr>td:first-child, .tableforfield>tbody>tr>td:first-child, div.tableforfield div.tagtr>div.tagtd:first-of-type { + /* max-width: 100px; */ /* but no more than 100px */ + } + .tableforfield>tr>td:nth-child(2), .tableforfield>tbody>tr>td:nth-child(2), div.tableforfield div.tagtr>div.tagtd:nth-child(2) { + word-break: break-word; } .badge { line-height: 1.2em; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 205ed21bdcf..ebf6b1df23d 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1137,11 +1137,17 @@ select.selectarrowonleft option { } } .linkobject { cursor: pointer; } + +table.tableforfield tr>td:first-of-type, div.tableforfield div.tagtr>div.tagtd:first-of-type { + color: #666; +} + .hideonprint { display: none; } + /* ============================================================================== */ /* Styles for dragging lines */ /* ============================================================================== */ @@ -5716,8 +5722,11 @@ border-top-right-radius: 6px; .titlefield { width: auto !important; /* We want to ignor the 30%, try to use more if you can */ } - .tableforfield>tr>td:first-child, div.tableforfield div.tagtr>div.tagtd:first-of-type { - max-width: 100px; /* but no more than 100px */ + .tableforfield>tr>td:first-child, .tableforfield>tbody>tr>td:first-child, div.tableforfield div.tagtr>div.tagtd:first-of-type { + /* max-width: 100px; */ /* but no more than 100px */ + } + .tableforfield>tr>td:nth-child(2), .tableforfield>tbody>tr>td:nth-child(2), div.tableforfield div.tagtr>div.tagtd:nth-child(2) { + word-break: break-word; } } From 5137104b927e045c9650a3e35423c6012ad8bf11 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 13 Sep 2019 01:38:41 +0200 Subject: [PATCH 09/27] Fix responsive --- htdocs/theme/eldy/global.inc.php | 9 ++++++--- htdocs/theme/md/style.css.php | 13 +++++++++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index a63ce37fdfe..82001a31a41 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -5734,10 +5734,13 @@ div.tabsElem a.tab { } .titlefield { - width: auto !important; /* We want to ignor the 30%, try to use more if you can */ + width: auto !important; /* We want to ignore the 30%, try to use more if you can */ } - .tableforfield>tr>td:first-child { - max-width: 100px; /* but no more than 100px */ + .tableforfield>tr>td:first-child, .tableforfield>tbody>tr>td:first-child, div.tableforfield div.tagtr>div.tagtd:first-of-type { + /* max-width: 100px; */ /* but no more than 100px */ + } + .tableforfield>tr>td:nth-child(2), .tableforfield>tbody>tr>td:nth-child(2), div.tableforfield div.tagtr>div.tagtd:nth-child(2) { + word-break: break-word; } .badge { line-height: 1.2em; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index c621e909095..3b9064e51a1 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1133,11 +1133,17 @@ select.selectarrowonleft option { } } .linkobject { cursor: pointer; } + +table.tableforfield tr>td:first-of-type, div.tableforfield div.tagtr>div.tagtd:first-of-type { + color: #666; +} + .hideonprint { display: none; } + /* ============================================================================== */ /* Styles for dragging lines */ /* ============================================================================== */ @@ -5835,8 +5841,11 @@ border-top-right-radius: 6px; .titlefield { width: auto !important; /* We want to ignor the 30%, try to use more if you can */ } - .tableforfield>tr>td:first-child, div.tableforfield div.tagtr>div.tagtd:first-of-type { - max-width: 100px; /* but no more than 100px */ + .tableforfield>tr>td:first-child, .tableforfield>tbody>tr>td:first-child, div.tableforfield div.tagtr>div.tagtd:first-of-type { + /* max-width: 100px; */ /* but no more than 100px */ + } + .tableforfield>tr>td:nth-child(2), .tableforfield>tbody>tr>td:nth-child(2), div.tableforfield div.tagtr>div.tagtd:nth-child(2) { + word-break: break-word; } } From 9eb736b110f63345d6baeb4d961be970e7782650 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 13 Sep 2019 10:12:43 +0200 Subject: [PATCH 10/27] FIX stripe payment when there is a quote into address --- htdocs/public/payment/newpayment.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index a9e712c92db..3227664e3e3 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -2109,13 +2109,13 @@ if (preg_match('/^dopayment/', $action)) // If we choosed/click on the payment payment_method_data: { billing_details: { name: cardholderName.value - , email: '' - thirdparty) && is_object($object->thirdparty->phone)) { ?>, phone: 'thirdparty->phone; ?>' + , email: '' + thirdparty) && is_object($object->thirdparty->phone)) { ?>, phone: 'thirdparty->phone); ?>' thirdparty)) { ?>, address: { - city: 'thirdparty->town; ?>', - country: 'thirdparty->country_code; ?>', - line1: 'thirdparty->address; ?>', - postal_code: 'thirdparty->zip; ?>'} + city: 'thirdparty->town); ?>', + country: 'thirdparty->country_code); ?>', + line1: 'thirdparty->address); ?>', + postal_code: 'thirdparty->zip); ?>'} } /* TODO Add all other known data like emails, ... to be SCA compliant */ }, save_payment_method: /* true when a customer was provided when creating payment intent. true ask to save the card */ From 7b73e2d57a66f1472619c6d67b1730d8a7116536 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 13 Sep 2019 11:05:50 +0200 Subject: [PATCH 11/27] FIX label of thirdparty is wrong on open project list --- htdocs/projet/index.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/projet/index.php b/htdocs/projet/index.php index 75cdff186d7..08181ed9a66 100644 --- a/htdocs/projet/index.php +++ b/htdocs/projet/index.php @@ -246,6 +246,9 @@ if ($resql) else dol_print_error($db); +$companystatic=new Societe($db); // We need a clean new object for next loop because current one has some properties set. + + // Open project per thirdparty print '
'; print ''; From 166d56f7a374ff6379bd09078062ebe802859c14 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 13 Sep 2019 11:15:49 +0200 Subject: [PATCH 12/27] Removed function dol_micro_time. Use native PHP microtime instead. --- htdocs/core/lib/functions.lib.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 03c13a9c230..12b5f63d7e1 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5753,20 +5753,6 @@ function dol_nboflines_bis($text, $maxlinesize = 0, $charset = 'UTF-8') return $nblines; } -/** - * Same function than microtime in PHP 5 but compatible with PHP4 - * - * @return float Time (millisecondes) with microsecondes in decimal part - * @deprecated Dolibarr does not support PHP4, you should use native function - * @see microtime() - */ -function dol_microtime_float() -{ - dol_syslog(__FUNCTION__ . " is deprecated", LOG_WARNING); - - return microtime(true); -} - /** * Return if a text is a html content * From 9e851eaa78cc267d66c28cc7f75ecb5175009728 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 13 Sep 2019 11:16:03 +0200 Subject: [PATCH 13/27] Removed function dol_micro_time. Use native PHP microtime instead. --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 584b7c1ee0c..b8a3fea2ce9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,7 +21,7 @@ Following changes may create regressions for some external modules, but were nec * The hook "moreFamily" must return payment into var "totalpayment" and no more "paiement" (english replace french). * Removed deprecated method actioncomm->add(), use create() instead * If you have developed your own emailing target selector and used parent::add_to_target(...), you must now use parent::addToTargets(...) - +* Removed function dol_micro_time. Use native PHP microtime instead. ***** ChangeLog for 10.0.2 compared to 10.0.1 ***** From 9df4f0601d0ed4ea39b8a68b5bd65a96c0bace1d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 13 Sep 2019 11:18:08 +0200 Subject: [PATCH 14/27] Clean address line to be on 1 line --- htdocs/public/payment/newpayment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 3227664e3e3..dbceb483f97 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -2114,7 +2114,7 @@ if (preg_match('/^dopayment/', $action)) // If we choosed/click on the payment thirdparty)) { ?>, address: { city: 'thirdparty->town); ?>', country: 'thirdparty->country_code); ?>', - line1: 'thirdparty->address); ?>', + line1: 'thirdparty->address)); ?>', postal_code: 'thirdparty->zip); ?>'} } /* TODO Add all other known data like emails, ... to be SCA compliant */ }, From 44fa2e4cd115605654a5ec9a5d82a691a748fae3 Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Fri, 13 Sep 2019 12:23:34 +0200 Subject: [PATCH 15/27] NEW multiselect with checkbox in categories/tags search for product list --- htdocs/product/list.php | 50 ++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index e7e8f1e4999..d8d9686ae4a 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -57,7 +57,8 @@ $search_label=GETPOST("search_label", 'alpha'); $search_type = GETPOST("search_type", 'int'); $search_sale = GETPOST("search_sale", 'int'); $search_vatrate=GETPOST("search_vatrate", 'alpha'); -$search_categ = GETPOST("search_categ", 'int'); +$searchCategoryProductOperator = (GETPOST('search_category_product_operator', 'int') ? GETPOST('search_category_product_operator', 'int') : 0); +$searchCategoryProductList = GETPOST('search_category_product_list', 'array'); $search_tosell = GETPOST("search_tosell", 'int'); $search_tobuy = GETPOST("search_tobuy", 'int'); $fourn_id = GETPOST("fourn_id", 'int'); @@ -231,7 +232,8 @@ if (empty($reshook)) $search_ref=""; $search_label=""; $search_barcode=""; - $search_categ=0; + $searchCategoryProductOperator = 0; + $searchCategoryProductList = array(); $search_tosell=""; $search_tobuy=""; $search_vatrate=""; @@ -301,7 +303,7 @@ $reshook=$hookmanager->executeHooks('printFieldListSelect', $parameters); // $sql.=$hookmanager->resPrint; $sql.= ' FROM '.MAIN_DB_PREFIX.'product as p'; if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_extrafields as ef on (p.rowid = ef.fk_object)"; -if (! empty($search_categ) || ! empty($catid)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product"; // We'll need this table joined to the select in order to filter by categ +if (!empty($searchCategoryProductList) || !empty($catid)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product"; // We'll need this table joined to the select in order to filter by categ $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product"; // multilang if (! empty($conf->global->MAIN_MULTILANGS)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_lang as pl ON pl.fk_product = p.rowid AND pl.lang = '".$langs->getDefaultLang() ."'"; @@ -333,8 +335,30 @@ if ($search_vatrate) $sql .= natural_search('p.tva_tx', $search_vatrate); if (dol_strlen($canvas) > 0) $sql.= " AND p.canvas = '".$db->escape($canvas)."'"; if ($catid > 0) $sql.= " AND cp.fk_categorie = ".$catid; if ($catid == -2) $sql.= " AND cp.fk_categorie IS NULL"; -if ($search_categ > 0) $sql.= " AND cp.fk_categorie = ".$db->escape($search_categ); -if ($search_categ == -2) $sql.= " AND cp.fk_categorie IS NULL"; +$searchCategoryProductSqlList = array(); +if ($searchCategoryProductOperator == 1) { + foreach ($searchCategoryProductList as $searchCategoryProduct) { + if (intval($searchCategoryProduct) == -2) { + $searchCategoryProductSqlList[] = "cp.fk_categorie IS NULL"; + } elseif (intval($searchCategoryProduct) > 0) { + $searchCategoryProductSqlList[] = "cp.fk_categorie = " . $db->escape($searchCategoryProduct); + } + } + if (!empty($searchCategoryProductSqlList)) { + $sql .= " AND (" . implode(' OR ', $searchCategoryProductSqlList) . ")"; + } +} else { + foreach ($searchCategoryProductList as $searchCategoryProduct) { + if (intval($searchCategoryProduct) == -2) { + $searchCategoryProductSqlList[] = "cp.fk_categorie IS NULL"; + } elseif (intval($searchCategoryProduct) > 0) { + $searchCategoryProductSqlList[] = "p.rowid IN (SELECT fk_product FROM " . MAIN_DB_PREFIX . "categorie_product WHERE fk_categorie = " . $searchCategoryProduct . ")"; + } + } + if (!empty($searchCategoryProductSqlList)) { + $sql .= " AND (" . implode(' AND ', $searchCategoryProductSqlList) . ")"; + } +} if ($fourn_id > 0) $sql.= " AND pfp.fk_soc = ".$fourn_id; if ($search_tobatch != '' && $search_tobatch >= 0) $sql.= " AND p.tobatch = ".$db->escape($search_tobatch); if ($search_accountancy_code_sell) $sql.= natural_search('p.accountancy_code_sell', $search_accountancy_code_sell); @@ -421,7 +445,10 @@ if ($resql) if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage); if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.urlencode($limit); if ($sall) $param.="&sall=".urlencode($sall); - if ($search_categ > 0) $param.="&search_categ=".urlencode($search_categ); + if ($searchCategoryProductOperator == 1) $param .= "&search_category_product_operator=" . urlencode($searchCategoryProductOperator); + foreach ($searchCategoryProductList as $searchCategoryProduct) { + $param .= "&search_category_product_list[]=" . urlencode($searchCategoryProduct); + } if ($search_ref) $param="&search_ref=".urlencode($search_ref); if ($search_ref_supplier) $param="&search_ref_supplier=".urlencode($search_ref_supplier); if ($search_barcode) $param.=($search_barcode?"&search_barcode=".urlencode($search_barcode):""); @@ -430,7 +457,7 @@ if ($resql) if ($search_tobuy != '') $param.="&search_tobuy=".urlencode($search_tobuy); if ($search_vatrate) $sql .= natural_search('p.tva_tx', $search_vatrate); if ($fourn_id > 0) $param.=($fourn_id?"&fourn_id=".$fourn_id:""); - if ($seach_categ) $param.=($search_categ?"&search_categ=".urlencode($search_categ):""); + //if ($seach_categ) $param.=($search_categ?"&search_categ=".urlencode($search_categ):""); if ($show_childproducts) $param.=($show_childproducts?"&search_show_childproducts=".urlencode($show_childproducts):""); if ($type != '') $param.='&type='.urlencode($type); if ($search_type != '') $param.='&search_type='.urlencode($search_type); @@ -465,7 +492,7 @@ if ($resql) $label='NewProduct'; if($type == Product::TYPE_SERVICE) $label='NewService'; $newcardbutton.= dolGetButtonTitle($langs->trans($label), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/product/card.php?action=create&type='.$type); - } + } print '
'; if ($optioncss != '') print ''; @@ -507,8 +534,11 @@ if ($resql) { $moreforfilter.='
'; $moreforfilter.=$langs->trans('Categories'). ': '; - $moreforfilter.=$htmlother->select_categories(Categorie::TYPE_PRODUCT, $search_categ, 'search_categ', 1); - $moreforfilter.='
'; + $categoriesProductArr = $form->select_all_categories(Categorie::TYPE_PRODUCT, '', '', 64, 0, 1); + $categoriesProductArr[-2] = '- ' . $langs->trans('NotCategorized') . ' -'; + $moreforfilter.=Form::multiselectarray('search_category_product_list', $categoriesProductArr, $searchCategoryProductList, 0, 0, 'minwidth300'); + $moreforfilter.=' ' . $langs->trans('or'); + $moreforfilter.=''; } //Show/hide child products. Hidden by default From 84544b6bdc664aca71816f324280970f85da362b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 13 Sep 2019 13:50:17 +0200 Subject: [PATCH 16/27] More details in log for CSRF error. --- htdocs/public/test/test_csrf.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 htdocs/public/test/test_csrf.php diff --git a/htdocs/public/test/test_csrf.php b/htdocs/public/test/test_csrf.php new file mode 100644 index 00000000000..8c242cade64 --- /dev/null +++ b/htdocs/public/test/test_csrf.php @@ -0,0 +1,22 @@ + + +This is a form to test a CSRF.
+
+Open this form into a Virtual server A.
+Change url to send request to into file to send request to virtual server B.
+ +
+
'; +?> + + + + + + + \ No newline at end of file From 70ffd6270fe5a7a91215b7c1c0eba5b22807cbce Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 13 Sep 2019 13:51:26 +0200 Subject: [PATCH 17/27] More details in log for CSRF error. --- htdocs/filefunc.inc.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index c035adbcd60..a4ae8c15542 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -152,7 +152,7 @@ if (empty($dolibarr_strict_mode)) $dolibarr_strict_mode=0; // For debug in php s // See also option $conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN for a stronger CSRF protection. if (! defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck)) { - if (! empty($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'GET' && ! empty($_SERVER['HTTP_HOST'])) + if (! empty($_SERVER['REQUEST_METHOD']) && ! in_array($_SERVER['REQUEST_METHOD'], array('GET', 'HEAD')) && ! empty($_SERVER['HTTP_HOST'])) { $csrfattack=false; if (empty($_SERVER['HTTP_REFERER'])) $csrfattack=true; // An evil browser was used @@ -165,8 +165,8 @@ if (! defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck)) if ($csrfattack) { //print 'NOCSRFCHECK='.defined('NOCSRFCHECK').' REQUEST_METHOD='.$_SERVER['REQUEST_METHOD'].' HTTP_HOST='.$_SERVER['HTTP_HOST'].' HTTP_REFERER='.$_SERVER['HTTP_REFERER']; - print "Access refused by CSRF protection in main.inc.php. Referer of form is outside server that serve the POST.\n"; - print "If you access your server behind a proxy using url rewriting, you might check that all HTTP header is propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file).\n"; + print "Access refused by CSRF protection in main.inc.php. Referer of form (".$_SERVER['HTTP_REFERER'].") is outside the server that serve this page (with method = ".$_SERVER['REQUEST_METHOD'].").\n"; + print "If you access your server behind a proxy using url rewriting, you might check that all HTTP headers are propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file to remove this security check).\n"; die; } } From b4831f9670f79fc8ea2b441f1e44451744c58610 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 13 Sep 2019 17:26:07 +0200 Subject: [PATCH 18/27] Code comment --- htdocs/public/payment/newpayment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 4b6364ea3be..93f5765c432 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -1834,7 +1834,7 @@ if (preg_match('/^dopayment/', $action)) // If we choosed/click on the payment print '
'; - print ''."\n"; + print ''."\n"; print '
'."\n"; print ''."\n"; From 7e923f6c1f68c63a0ab00de4c20cac13d7596626 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 13 Sep 2019 18:51:03 +0200 Subject: [PATCH 19/27] Fix remove test code and chen paymentintent is not null --- htdocs/public/payment/newpayment.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 93f5765c432..9b3234aef29 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -1909,7 +1909,7 @@ if (preg_match('/^dopayment/', $action)) // If we choosed/click on the payment
'; - print ''; + print ''; print ''; print ' @@ -1943,7 +1943,6 @@ if (preg_match('/^dopayment/', $action)) // If we choosed/click on the payment { print ''; print ''."\n"; - $urllogofull = 'http://home.destailleur.fr:805/dolibarr_dev/htdocs/viewimage.php?modulepart=mycompany&entity=1&file=logos%2Fthumbs%2Ffbm+logo_small.png'; print ''."\n"; // Code to ask the credit card. This use the default "API version". No way to force API version when using JS code. From 8e836155338a47e6831760724e9d33141627b8dd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 13 Sep 2019 18:52:35 +0200 Subject: [PATCH 20/27] Add method getSetupIntent --- htdocs/stripe/class/stripe.class.php | 148 ++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 2 deletions(-) diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index 9defab81a73..9c0bc9ebae3 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -293,7 +293,7 @@ class Stripe extends CommonObject } /** - * Get the Stripe payment intent. Create it with confirm=false + * Get the Stripe payment intent. Create it with confirmnow=false * Warning. If a payment was tried and failed, a payment intent was created. * But if we change something on object to pay (amount or other), reusing same payment intent is not allowed. * Recommanded solution is to recreate a new payment intent each time we need one (old one will be automatically closed after a delay), @@ -312,7 +312,7 @@ class Stripe extends CommonObject * @param int $usethirdpartyemailforreceiptemail 1=use thirdparty email for receipt * @param int $mode automatic=automatic confirmation/payment when conditions are ok, manual=need to call confirm() on intent * @param boolean $confirmnow false=default, true=try to confirm immediatly after create (if conditions are ok) - * @return \Stripe\PaymentIntent|null Stripe PaymentIntent or null if not found + * @return \Stripe\PaymentIntent|null Stripe PaymentIntent or null if not found and failed to create */ public function getPaymentIntent($amount, $currency_code, $tag, $description = '', $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false) { @@ -503,6 +503,149 @@ class Stripe extends CommonObject } } + + /** + * Get the Stripe payment intent. Create it with confirmnow=false + * Warning. If a payment was tried and failed, a payment intent was created. + * But if we change something on object to pay (amount or other), reusing same payment intent is not allowed. + * Recommanded solution is to recreate a new payment intent each time we need one (old one will be automatically closed after a delay), + * that's why i comment the part of code to retreive a payment intent with object id (never mind if we cumulate payment intent with old ones that will not be used) + * Note: This is used when option STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION is on when making a payment from the public/payment/newpayment.php page + * but not when using the STRIPE_USE_NEW_CHECKOUT. + * + * @param string $description Description + * @param Societe $object Object to pay with Stripe + * @param string $customer Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe() + * @param string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect + * @param int $status Status (0=test, 1=live) + * @param int $usethirdpartyemailforreceiptemail 1=use thirdparty email for receipt + * @param boolean $confirmnow false=default, true=try to confirm immediatly after create (if conditions are ok) + * @return \Stripe\SetupIntent|null Stripe SetupIntent or null if not found and failed to create + */ + public function getSetupIntent($description, $object, $customer, $key, $status, $usethirdpartyemailforreceiptemail = 0, $confirmnow = false) + { + global $conf; + + dol_syslog("getSetupIntent", LOG_INFO, 1); + + $error = 0; + + if (empty($status)) $service = 'StripeTest'; + else $service = 'StripeLive'; + + $setupintent = null; + + if (empty($setupintent)) + { + $ipaddress=getUserRemoteIP(); + $metadata = array('dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>$ipaddress); + if (is_object($object)) + { + $metadata['dol_type'] = $object->element; + $metadata['dol_id'] = $object->id; + if (is_object($object->thirdparty) && $object->thirdparty->id > 0) $metadata['dol_thirdparty_id'] = $object->thirdparty->id; + } + + $dataforintent = array( + "confirm" => $confirmnow, // Do not confirm immediatly during creation of intent + "payment_method_types" => array("card"), + "description" => $description, + "usage" => "off_session", + "metadata" => $metadata + ); + if (! is_null($customer)) $dataforintent["customer"]=$customer; + // payment_method = + // payment_method_types = array('card') + //var_dump($dataforintent); + + if ($usethirdpartyemailforreceiptemail && is_object($object) && $object->thirdparty->email) + { + $dataforintent["receipt_email"] = $object->thirdparty->email; + } + + try { + // Force to use the correct API key + global $stripearrayofkeysbyenv; + \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']); + + // Note: If all data for payment intent are same than a previous on, even if we use 'create', Stripe will return ID of the old existing payment intent. + if (empty($key)) { // If the Stripe connect account not set, we use common API usage + //$setupintent = \Stripe\SetupIntent::create($dataforintent, array("idempotency_key" => "$description")); + $setupintent = \Stripe\SetupIntent::create($dataforintent, array()); + } else { + //$setupintent = \Stripe\SetupIntent::create($dataforintent, array("idempotency_key" => "$description", "stripe_account" => $key)); + $setupintent = \Stripe\SetupIntent::create($dataforintent, array("stripe_account" => $key)); + } + //var_dump($setupintent->id); + + // Store the setup intent + /*if (is_object($object)) + { + $setupintentalreadyexists = 0; + // Check that payment intent $setupintent->id is not already recorded. + $sql = "SELECT pi.rowid"; + $sql.= " FROM " . MAIN_DB_PREFIX . "prelevement_facture_demande as pi"; + $sql.= " WHERE pi.entity IN (".getEntity('societe').")"; + $sql.= " AND pi.ext_payment_site = '" . $service . "'"; + $sql.= " AND pi.ext_payment_id = '".$this->db->escape($setupintent->id)."'"; + + dol_syslog(get_class($this) . "::getPaymentIntent search if payment intent already in prelevement_facture_demande", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + if ($num) + { + $obj = $this->db->fetch_object($resql); + if ($obj) $setupintentalreadyexists++; + } + } + else dol_print_error($this->db); + + // If not, we create it. + if (! $setupintentalreadyexists) + { + $now=dol_now(); + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "prelevement_facture_demande (date_demande, fk_user_demande, ext_payment_id, fk_facture, sourcetype, entity, ext_payment_site)"; + $sql .= " VALUES ('".$this->db->idate($now)."', '0', '".$this->db->escape($setupintent->id)."', ".$object->id.", '".$this->db->escape($object->element)."', " . $conf->entity . ", '" . $service . "')"; + $resql = $this->db->query($sql); + if (! $resql) + { + $error++; + $this->error = $this->db->lasterror(); + dol_syslog(get_class($this) . "::PaymentIntent failed to insert paymentintent with id=".$setupintent->id." into database."); + } + } + } + else + { + $_SESSION["stripe_setup_intent"] = $setupintent; + }*/ + } + catch(Exception $e) + { + /*var_dump($dataforintent); + var_dump($description); + var_dump($key); + var_dump($setupintent); + var_dump($e->getMessage());*/ + $error++; + $this->error = $e->getMessage(); + } + } + + dol_syslog("getSetupIntent return error=".$error, LOG_INFO, -1); + + if (! $error) + { + return $setupintent; + } + else + { + return null; + } + } + + /** * Get the Stripe card of a company payment mode (with option to create it on Stripe if not linked yet) * @@ -609,6 +752,7 @@ class Stripe extends CommonObject /** * Create charge with public/payment/newpayment.php, stripe/card.php, cronjobs or REST API + * This is using old Stripe API charge. * * @param int $amount Amount to pay * @param string $currency EUR, GPB... From aad6b003fb13ff1fd708450276d858b8bccecdff Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 14 Sep 2019 00:02:48 +0200 Subject: [PATCH 21/27] Add cache in fetch_optionnals() to avoid duplicate call to fetch_name_optionals_label --- htdocs/core/class/commonobject.class.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index ebfe7f1abee..26102b9b42a 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4517,7 +4517,7 @@ abstract class CommonObject $parameters = array('modelspath'=>$modelspath,'modele'=>$modele,'outputlangs'=>$outputlangs,'hidedetails'=>$hidedetails,'hidedesc'=>$hidedesc,'hideref'=>$hideref, 'moreparams'=>$moreparams); $reshook = $hookmanager->executeHooks('commonGenerateDocument', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - + if(empty($reshook)) { dol_syslog("commonGenerateDocument modele=".$modele." outputlangs->defaultlang=".(is_object($outputlangs)?$outputlangs->defaultlang:'null')); @@ -4902,13 +4902,12 @@ abstract class CommonObject if (! is_array($optionsArray)) { // If $extrafields is not a known object, we initialize it. Best practice is to have $extrafields defined into card.php or list.php page. - // TODO Use of existing $extrafield is not yet ready (must mutualize code that use extrafields in form first) - // global $extrafields; - //if (! is_object($extrafields)) - //{ + global $extrafields; + if (! isset($extrafields) || ! is_object($extrafields)) + { require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $extrafields = new ExtraFields($this->db); - //} + } // Load array of extrafields for elementype = $this->table_element if (empty($extrafields->attributes[$this->table_element]['loaded'])) From 08f056a0f44d3427494a666b193eeabe710a1b40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 14 Sep 2019 09:09:41 +0200 Subject: [PATCH 22/27] Delete interface_50_modIFTTT_IFTTT.class.php IFTTT has been removed --- .../interface_50_modIFTTT_IFTTT.class.php | 147 ------------------ 1 file changed, 147 deletions(-) delete mode 100644 htdocs/core/triggers/interface_50_modIFTTT_IFTTT.class.php diff --git a/htdocs/core/triggers/interface_50_modIFTTT_IFTTT.class.php b/htdocs/core/triggers/interface_50_modIFTTT_IFTTT.class.php deleted file mode 100644 index c7ce8f121fc..00000000000 --- a/htdocs/core/triggers/interface_50_modIFTTT_IFTTT.class.php +++ /dev/null @@ -1,147 +0,0 @@ - - * 2016 Christophe Battarel - * - * 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 . - */ - -/** - * \file htdocs/core/triggers/interface_50_modIFTTT_IFTTT.class.php - * \ingroup core - * \brief File of trigger for IFTTT module - */ -require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php'; - - -/** - * Class of triggers for IFTTT module - */ -class InterfaceIFTTT extends DolibarrTriggers -{ - /** - * @var DoliDB Database handler. - */ - public $db; - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - public function __construct($db) - { - $this->db = $db; - - $this->name = preg_replace('/^Interface/i', '', get_class($this)); - $this->family = "ifttt"; - $this->description = "Triggers of the module IFTTT"; - $this->version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' or version - $this->picto = 'ifttt'; - } - - /** - * Return name of trigger file - * - * @return string Name of trigger file - */ - public function getName() - { - return $this->name; - } - - /** - * Return description of trigger file - * - * @return string Description of trigger file - */ - public function getDesc() - { - return $this->description; - } - - /** - * Return version of trigger file - * - * @return string Version of trigger file - */ - public function getVersion() - { - global $langs; - $langs->load("admin"); - - if ($this->version == 'development') { - return $langs->trans("Development"); - } elseif ($this->version == 'experimental') { - return $langs->trans("Experimental"); - } elseif ($this->version == 'dolibarr') { - return DOL_VERSION; - } elseif ($this->version) { - return $this->version; - } else { - return $langs->trans("Unknown"); - } - } - - /** - * Function called when a Dolibarrr business event is done. - * All functions "runTrigger" are triggered if file is inside directory htdocs/core/triggers - * - * @param string $action Event action code - * @param Object $object Object - * @param User $user Object user - * @param Translate $langs Object langs - * @param conf $conf Object conf - * @return int <0 if KO, 0 if no triggered ran, >0 if OK - */ - public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) - { - $ok = 0; - - if (empty($conf->ifttt->enabled)) return 0; // Module not active, we do nothing - - switch ($action) { - case 'THIRDPARTY_CREATED': - dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id); - - include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; - - // See https://platform.ifttt.com/docs/api_reference#realtime-api - - $arrayofdata=array(); - $arrayofdata['user_id']=$conf->global->IFTTT_USER_ID; - $arrayofdata['trigger_identity']=$conf->global->IFTTT_TRIGGER_IDENTITY; - $arrayofdata['name']='testabcdef'; - $arrayofdata['email']='testemailabcdef'; - - $url = 'https://realtime.ifttt.com/v1/notifications'; - - $addheaders=array( - 'IFTTT-Service-Key'=>'123', - 'Accept'=>'application/json', - 'Accept-Charset'=>'utf-8', - 'Accept-Encoding'=>'gzip, deflate', - 'Content-Type'=>'application/json', - 'X-Request-ID'=>getRandomPassword(true, null) - ); - - $result = getURLContent($url, 'POSTALREADYFORMATED', '', 1, $addheaders); - - $ok = 1; - break; - } - - return $ok; - } -} From 76f478dc4417c4d97e2c9c7b054fcfa494aa413c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 14 Sep 2019 14:25:47 +0200 Subject: [PATCH 23/27] Fix look and feel --- htdocs/societe/paymentmodes.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index 3731cfe07fa..90d90b388ac 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -600,7 +600,7 @@ if (empty($reshook)) $db->rollback(); } } - + if ($action == 'setkey_account_supplier') { $error = 0; @@ -819,7 +819,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print '
'; print '
'; - print '
'; + print '
'; if ($object->client) { @@ -872,7 +872,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print ''; } } - + if ($object->fournisseur) { print ''; print ''; print ''; - + if (is_array($balance->available) && count($balance->available)) { foreach ($balance->available as $cpt) @@ -1322,7 +1322,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print ''; } } - + if (is_array($balance->pending) && count($balance->pending)) { foreach ($balance->pending as $cpt) @@ -1598,7 +1598,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' // Edit BAN if ($socid && $action == 'edit' && $user->rights->societe->creer) { - dol_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company'); + dol_fiche_head($head, 'rib', $langs->trans("ThirdParty"), -1, 'company'); $linkback = ''.$langs->trans("BackToList").''; @@ -1705,7 +1705,7 @@ if ($socid && $action == 'edit' && $user->rights->societe->creer) // Edit Card if ($socid && $action == 'editcard' && $user->rights->societe->creer) { - dol_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company'); + dol_fiche_head($head, 'rib', $langs->trans("ThirdParty"), -1, 'company'); $linkback = ''.$langs->trans("BackToList").''; @@ -1753,7 +1753,7 @@ if ($socid && $action == 'editcard' && $user->rights->societe->creer) // Create BAN if ($socid && $action == 'create' && $user->rights->societe->creer) { - dol_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company'); + dol_fiche_head($head, 'rib', $langs->trans("ThirdParty"), -1, 'company'); $linkback = ''.$langs->trans("BackToList").''; @@ -1854,7 +1854,7 @@ if ($socid && $action == 'create' && $user->rights->societe->creer) // Create Card if ($socid && $action == 'createcard' && $user->rights->societe->creer) { - dol_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company'); + dol_fiche_head($head, 'rib', $langs->trans("ThirdParty"), -1, 'company'); $linkback = ''.$langs->trans("BackToList").''; From 7965804a34edf52bc8673a1b1975e1fc9d794f43 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 14 Sep 2019 16:35:00 +0200 Subject: [PATCH 24/27] Update ldap_groups.php --- htdocs/admin/ldap_groups.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/ldap_groups.php b/htdocs/admin/ldap_groups.php index 6dcc26a23e0..6412d2f6a59 100644 --- a/htdocs/admin/ldap_groups.php +++ b/htdocs/admin/ldap_groups.php @@ -58,7 +58,7 @@ if ($action == 'setvalue' && $user->admin) //if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_NAME',$_POST["fieldname"],'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_DESCRIPTION', GETPOST("fielddescription"), 'chaine', 0, '', $conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_GROUPMEMBERS', GETPOST("fieldgroupmembers"), 'chaine', 0, '', $conf->entity)) $error++; - if (! dolibarr_set_const($db, 'LDAP_FIELD_GROUPID', GETPOST("fieldgroupid"), 'chaine', 0, '', $conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_GROUPID', GETPOST("fieldgroupid"), 'chaine', 0, '', $conf->entity)) $error++; // This one must be after the others $valkey=''; From 9934f73574d32d8b51825a2407c674112f6e13a6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 14 Sep 2019 16:36:04 +0200 Subject: [PATCH 25/27] Update ldap_groups.php --- htdocs/admin/ldap_groups.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/ldap_groups.php b/htdocs/admin/ldap_groups.php index 6412d2f6a59..8ae918ce180 100644 --- a/htdocs/admin/ldap_groups.php +++ b/htdocs/admin/ldap_groups.php @@ -173,7 +173,7 @@ print ''; // Group id print ''; print ''; print ''; From d380ef1812535ea1adc2fdc571bf61a8d1d10e54 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 14 Sep 2019 16:37:07 +0200 Subject: [PATCH 26/27] Update usergroup.class.php --- htdocs/user/class/usergroup.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index 03c514f79f3..a89126b122f 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -980,8 +980,8 @@ class UserGroup extends CommonObject } $info[$conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS] = (!empty($valueofldapfield)?$valueofldapfield:''); } - if(!empty($info[$conf->global->LDAP_FIELD_GROUPID])){ - $info[$conf->global->LDAP_FIELD_GROUPID]=$this->id; + if(!empty($info[$conf->global->LDAP_GROUP_FIELD_GROUPID])){ + $info[$conf->global->LDAP_GROUP_FIELD_GROUPID]=$this->id; } return $info; } From c015bbda14b79b0046d3ddeef356c66e4aa70daa Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 14 Sep 2019 16:39:08 +0200 Subject: [PATCH 27/27] Update ldap.class.php --- htdocs/core/class/ldap.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index 266b41867e8..267949e2149 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -609,7 +609,7 @@ class Ldap } if ($result <= 0) { - $this->error = ldap_errno($this->connection)." ".$this->error; + $this->error = ldap_error($this->connection).' (Code '.ldap_errno($this->connection).") ".$this->error; dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR); //print_r($info); return -1;
'; @@ -891,12 +891,12 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' if ($conf->facture->enabled && $user->rights->facture->lire) $elementTypeArray['invoice']=$langs->transnoentitiesnoconv('Invoices'); if ($conf->contrat->enabled && $user->rights->contrat->lire) $elementTypeArray['contract']=$langs->transnoentitiesnoconv('Contracts'); } - + if (! empty($conf->stripe->enabled) && ! empty($conf->stripeconnect->enabled) && $conf->global->MAIN_FEATURES_LEVEL >= 2) { $permissiontowrite = $user->rights->societe->creer; $stripesupplieracc = $stripe->getStripeAccount($service, $object->id); // Get Stripe OAuth connect account (no network access here) - + // Stripe customer key 'cu_....' stored into llx_societe_account print '
'; print $form->editfieldkey("StripeConnectAccount", 'key_account_supplier', $stripesupplieracc, $object, $permissiontowrite, 'string', '', 0, 2, 'socid'); @@ -905,7 +905,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' if (! empty($conf->stripe->enabled) && $stripesupplieracc && $action != 'editkey_account_supplier') { $connect=''; - + $url='https://dashboard.stripe.com/test/connect/accounts/'.$stripesupplieracc; if ($servicestatus) { @@ -1299,7 +1299,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print ""; print '
'; } - + // List of Stripe payment modes if (! empty($conf->stripe->enabled) && ! empty($conf->stripeconnect->enabled) && $object->fournisseur && ! empty($stripesupplieracc)) { @@ -1311,7 +1311,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print '
'.$langs->trans('Amount').''.$langs->trans('Currency').'
'.$langs->trans("Available").''.price($amount, 0, '', 1, - 1, - 1, strtoupper($cpt->currency)).' '.$langs->trans("Currency".strtoupper($cpt->currency)).'
'.$langs->trans("LDAPFieldGroupid").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldGroupidExample").'