From b1f750ac2f55959b9f6371c04ad21bec6cd7edf2 Mon Sep 17 00:00:00 2001 From: Quentin VIAL-GOUTEYRON Date: Tue, 4 Jan 2022 10:35:44 +0100 Subject: [PATCH 01/15] NEW: Project contact tab --- htdocs/contact/project.php | 118 +++++++++++++++++++++++ htdocs/core/lib/contact.lib.php | 159 +++++++++++++++++++++++++++++++ htdocs/langs/en_US/projects.lang | 1 + htdocs/langs/fr_FR/projects.lang | 1 + 4 files changed, 279 insertions(+) create mode 100644 htdocs/contact/project.php diff --git a/htdocs/contact/project.php b/htdocs/contact/project.php new file mode 100644 index 00000000000..2a5888f02f5 --- /dev/null +++ b/htdocs/contact/project.php @@ -0,0 +1,118 @@ + + * + * 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/contact/project.php + * \ingroup contact + * \brief Page of third party projects + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + +$langs->loadLangs(array("contacts", "companies", "projects")); + +// Security check +$id = GETPOST('id', 'int'); +$result = restrictedArea($user, 'contact', $id, 'socpeople&societe'); + +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('projectcontact')); + +/* + * Actions + */ + +$parameters = array('id' => $id); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +/* + * View + */ + +$form = new Form($db); + +if($id) { + require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/contact.lib.php'; + + $object = new Contact($db); + + $result = $object->fetch($id); + if(empty($object->thirdparty)) { + $object->fetch_thirdparty(); + } + $socid = $object->thirdparty->id; + $title = $langs->trans("Projects"); + if(! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/', $conf->global->MAIN_HTML_TITLE) && $object->name) { + $title = $object->name." - ".$title; + } + llxHeader('', $title); + + if(! empty($conf->notification->enabled)) { + $langs->load("mails"); + } + $head = contact_prepare_head($object); + + print dol_get_fiche_head($head, 'project', $langs->trans("Contact"), -1, 'contact'); + + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
'; + if(empty($conf->global->SOCIETE_DISABLE_CONTACTS) && !empty($socid)) { + $object->thirdparty->fetch($socid); + // Thirdparty + $morehtmlref .= $langs->trans('ThirdParty').' : '; + if($object->thirdparty->id > 0) { + $morehtmlref .= $object->thirdparty->getNomUrl(1, 'contact'); + } + else { + $morehtmlref .= $langs->trans("ContactNotLinkedToCompany"); + } + } + $morehtmlref .= '
'; + + dol_banner_tab($object, 'id', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom', $morehtmlref); + + print '
'; + + print '
'; + print ''; + +// Civility + print ''; + + print '
'.$langs->trans("UserTitle").''; + print $object->getCivilityLabel(); + print '
'; + + print '
'; + + print dol_get_fiche_end(); + print '
'; + + // Projects list + $result = show_contacts_projects($conf, $langs, $db, $object, $_SERVER["PHP_SELF"].'?id='.$object->id, 1); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/core/lib/contact.lib.php b/htdocs/core/lib/contact.lib.php index c60cb0c8c18..e2f735dc25d 100644 --- a/htdocs/core/lib/contact.lib.php +++ b/htdocs/core/lib/contact.lib.php @@ -57,6 +57,40 @@ function contact_prepare_head(Contact $object) $head[$tab][2] = 'perso'; $tab++; + if (!empty($conf->projet->enabled) && (!empty($user->rights->projet->lire))) { + $nbProject = 0; + // Enable caching of thirdrparty count projects + require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php'; + $cachekey = 'count_projects_contact_'.$object->id; + $dataretrieved = dol_getcache($cachekey); + + if (!is_null($dataretrieved)) { + $nbProject = $dataretrieved; + } else { + $sql = 'SELECT COUNT(n.rowid) as nb'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'projet as n'; + $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'element_contact as cc ON (n.rowid = cc.element_id)'; + $sql .= ' WHERE cc.fk_socpeople = '.((int) $object->id); + $sql .= ' AND cc.fk_c_type_contact IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE element="project" AND source="external")'; + $sql .= ' AND n.entity IN ('.getEntity('project').')'; + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + $nbProject = $obj->nb; + } else { + dol_print_error($db); + } + dol_setcache($cachekey, $nbProject, 120); // If setting cache fails, this is not a problem, so we do not test result. + } + $head[$tab][0] = DOL_URL_ROOT.'/contact/project.php?id='.$object->id; + $head[$tab][1] = $langs->trans("Projects"); + if ($nbProject > 0) { + $head[$tab][1] .= ''.$nbProject.''; + } + $head[$tab][2] = 'project'; + $tab++; + } + // Related items if (!empty($conf->commande->enabled) || !empty($conf->propal->enabled) || !empty($conf->facture->enabled) || !empty($conf->ficheinter->enabled) || (!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) { $head[$tab][0] = DOL_URL_ROOT.'/contact/consumption.php?id='.$object->id; @@ -117,3 +151,128 @@ function contact_prepare_head(Contact $object) return $head; } + +/** + * Show html area for list of projects + * + * @param Conf $conf Object conf + * @param Translate $langs Object langs + * @param DoliDB $db Database handler + * @param Object $object Third party object + * @param string $backtopage Url to go once contact is created + * @param int $nocreatelink 1=Hide create project link + * @param string $morehtmlright More html on right of title + * @return int + */ +function show_contacts_projects($conf, $langs, $db, $object, $backtopage = '', $nocreatelink = 0, $morehtmlright = '') +{ + global $user; + + $i = -1; + + if (!empty($conf->projet->enabled) && $user->rights->projet->lire) { + $langs->load("projects"); + + $newcardbutton = ''; + if (!empty($conf->projet->enabled) && $user->rights->projet->creer && empty($nocreatelink)) { + $newcardbutton .= dolGetButtonTitle($langs->trans('AddProject'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/projet/card.php?socid='.$object->id.'&action=create&backtopage='.urlencode($backtopage)); + } + + print "\n"; + print load_fiche_titre($langs->trans("ProjectsHavingThisContact"), $newcardbutton.$morehtmlright, ''); + print '
'; + print "\n".''; + + $sql = 'SELECT p.rowid as id, p.entity, p.title, p.ref, p.public, p.dateo as do, p.datee as de, p.fk_statut as status, p.fk_opp_status, p.opp_amount, p.opp_percent, p.tms as date_update, p.budget_amount'; + $sql .= ', cls.code as opp_status_code'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'projet as p'; + $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_lead_status as cls on p.fk_opp_status = cls.rowid'; + $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'element_contact as cc ON (p.rowid = cc.element_id)'; + $sql .= ' WHERE cc.fk_socpeople = '.((int) $object->id); + $sql .= ' AND cc.fk_c_type_contact IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE element="project" AND source="external")'; + $sql .= ' AND p.entity IN ('.getEntity('project').')'; + $sql .= ' ORDER BY p.dateo DESC'; + + $result = $db->query($sql); + if ($result) { + $num = $db->num_rows($result); + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + if ($num > 0) { + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + + $projecttmp = new Project($db); + + $i = 0; + + while ($i < $num) { + $obj = $db->fetch_object($result); + $projecttmp->fetch($obj->id); + + // To verify role of users + $userAccess = $projecttmp->restrictedProjectArea($user); + + if ($user->rights->projet->lire && $userAccess > 0) { + print ''; + + // Ref + print ''; + + // Label + print ''; + // Date start + print ''; + // Date end + print ''; + // Opp amount + print ''; + // Opp status + print ''; + // Opp percent + print ''; + // Status + print ''; + + print ''; + } + $i++; + } + } else { + print ''; + } + $db->free($result); + } else { + dol_print_error($db); + } + print "
'.$langs->trans("Ref").''.$langs->trans("Name").''.$langs->trans("DateStart").''.$langs->trans("DateEnd").''.$langs->trans("OpportunityAmountShort").''.$langs->trans("OpportunityStatusShort").''.$langs->trans("OpportunityProbabilityShort").''.$langs->trans("Status").'
'; + print $projecttmp->getNomUrl(1); + print ''.$obj->title.''.dol_print_date($db->jdate($obj->do), "day").''.dol_print_date($db->jdate($obj->de), "day").''; + if ($obj->opp_status_code) { + print price($obj->opp_amount, 1, '', 1, -1, -1, ''); + } + print ''; + if ($obj->opp_status_code) { + print $langs->trans("OppStatus".$obj->opp_status_code); + } + print ''; + if ($obj->opp_percent) { + print price($obj->opp_percent, 1, '', 1, 0).'%'; + } + print ''.$projecttmp->getLibStatut(5).'
'.$langs->trans("None").'
"; + print '
'; + + print "
\n"; + } + + return $i; +} \ No newline at end of file diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index c19f32a0396..517eb09ae2d 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -284,3 +284,4 @@ PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE_help=Note: existing projects with al SelectLinesOfTimeSpentToInvoice=Select lines of time spent that are unbilled, then bulk action "Generate Invoice" to bill them ProjectTasksWithoutTimeSpent=Project tasks without time spent FormForNewLeadDesc=Thanks to fill the following form to contact us. You can also send us an email directly to %s. +ProjectsHavingThisContact=Projects having this contact \ No newline at end of file diff --git a/htdocs/langs/fr_FR/projects.lang b/htdocs/langs/fr_FR/projects.lang index b158ed28334..dc8ecb24b55 100644 --- a/htdocs/langs/fr_FR/projects.lang +++ b/htdocs/langs/fr_FR/projects.lang @@ -284,3 +284,4 @@ PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE_help=Remarque : les projets existant SelectLinesOfTimeSpentToInvoice=Sélectionnez les lignes de temps passé non facturées, puis l'action groupée "Générer la facture" pour les facturer ProjectTasksWithoutTimeSpent=Tâches de projet sans temps consommé FormForNewLeadDesc=Veuillez remplir ce formulaire de contact ou écrivez un e-mail à %s. +ProjectsHavingThisContact=Projets ayant ce contact associé \ No newline at end of file From f0677ed665280517df698247585fb018a033216b Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Tue, 4 Jan 2022 09:42:24 +0000 Subject: [PATCH 02/15] Fixing style errors. --- htdocs/contact/project.php | 97 ++++++++++++++++----------------- htdocs/core/lib/contact.lib.php | 32 +++++------ 2 files changed, 64 insertions(+), 65 deletions(-) diff --git a/htdocs/contact/project.php b/htdocs/contact/project.php index 2a5888f02f5..b05709f019a 100644 --- a/htdocs/contact/project.php +++ b/htdocs/contact/project.php @@ -40,8 +40,8 @@ $hookmanager->initHooks(array('projectcontact')); $parameters = array('id' => $id); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks -if($reshook < 0) { - setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } /* @@ -50,67 +50,66 @@ if($reshook < 0) { $form = new Form($db); -if($id) { - require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; - require_once DOL_DOCUMENT_ROOT.'/core/lib/contact.lib.php'; +if ($id) { + require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/contact.lib.php'; - $object = new Contact($db); + $object = new Contact($db); - $result = $object->fetch($id); - if(empty($object->thirdparty)) { - $object->fetch_thirdparty(); - } - $socid = $object->thirdparty->id; - $title = $langs->trans("Projects"); - if(! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/', $conf->global->MAIN_HTML_TITLE) && $object->name) { - $title = $object->name." - ".$title; - } - llxHeader('', $title); + $result = $object->fetch($id); + if (empty($object->thirdparty)) { + $object->fetch_thirdparty(); + } + $socid = $object->thirdparty->id; + $title = $langs->trans("Projects"); + if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/', $conf->global->MAIN_HTML_TITLE) && $object->name) { + $title = $object->name." - ".$title; + } + llxHeader('', $title); - if(! empty($conf->notification->enabled)) { - $langs->load("mails"); - } - $head = contact_prepare_head($object); + if (! empty($conf->notification->enabled)) { + $langs->load("mails"); + } + $head = contact_prepare_head($object); - print dol_get_fiche_head($head, 'project', $langs->trans("Contact"), -1, 'contact'); + print dol_get_fiche_head($head, 'project', $langs->trans("Contact"), -1, 'contact'); - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; - $morehtmlref = '
'; - if(empty($conf->global->SOCIETE_DISABLE_CONTACTS) && !empty($socid)) { - $object->thirdparty->fetch($socid); - // Thirdparty - $morehtmlref .= $langs->trans('ThirdParty').' : '; - if($object->thirdparty->id > 0) { - $morehtmlref .= $object->thirdparty->getNomUrl(1, 'contact'); - } - else { - $morehtmlref .= $langs->trans("ContactNotLinkedToCompany"); - } - } - $morehtmlref .= '
'; + $morehtmlref = '
'; + if (empty($conf->global->SOCIETE_DISABLE_CONTACTS) && !empty($socid)) { + $object->thirdparty->fetch($socid); + // Thirdparty + $morehtmlref .= $langs->trans('ThirdParty').' : '; + if ($object->thirdparty->id > 0) { + $morehtmlref .= $object->thirdparty->getNomUrl(1, 'contact'); + } else { + $morehtmlref .= $langs->trans("ContactNotLinkedToCompany"); + } + } + $morehtmlref .= '
'; - dol_banner_tab($object, 'id', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom', $morehtmlref); + dol_banner_tab($object, 'id', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom', $morehtmlref); - print '
'; + print '
'; - print '
'; - print ''; + print '
'; + print '
'; -// Civility - print ''; + // Civility + print ''; - print '
'.$langs->trans("UserTitle").''; - print $object->getCivilityLabel(); - print '
'.$langs->trans("UserTitle").''; + print $object->getCivilityLabel(); + print '
'; + print ''; - print '
'; + print '
'; - print dol_get_fiche_end(); - print '
'; + print dol_get_fiche_end(); + print '
'; - // Projects list - $result = show_contacts_projects($conf, $langs, $db, $object, $_SERVER["PHP_SELF"].'?id='.$object->id, 1); + // Projects list + $result = show_contacts_projects($conf, $langs, $db, $object, $_SERVER["PHP_SELF"].'?id='.$object->id, 1); } // End of page diff --git a/htdocs/core/lib/contact.lib.php b/htdocs/core/lib/contact.lib.php index e2f735dc25d..ba116d3b904 100644 --- a/htdocs/core/lib/contact.lib.php +++ b/htdocs/core/lib/contact.lib.php @@ -57,7 +57,7 @@ function contact_prepare_head(Contact $object) $head[$tab][2] = 'perso'; $tab++; - if (!empty($conf->projet->enabled) && (!empty($user->rights->projet->lire))) { + if (!empty($conf->projet->enabled) && (!empty($user->rights->projet->lire))) { $nbProject = 0; // Enable caching of thirdrparty count projects require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php'; @@ -67,12 +67,12 @@ function contact_prepare_head(Contact $object) if (!is_null($dataretrieved)) { $nbProject = $dataretrieved; } else { - $sql = 'SELECT COUNT(n.rowid) as nb'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'projet as n'; - $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'element_contact as cc ON (n.rowid = cc.element_id)'; - $sql .= ' WHERE cc.fk_socpeople = '.((int) $object->id); - $sql .= ' AND cc.fk_c_type_contact IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE element="project" AND source="external")'; - $sql .= ' AND n.entity IN ('.getEntity('project').')'; + $sql = 'SELECT COUNT(n.rowid) as nb'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'projet as n'; + $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'element_contact as cc ON (n.rowid = cc.element_id)'; + $sql .= ' WHERE cc.fk_socpeople = '.((int) $object->id); + $sql .= ' AND cc.fk_c_type_contact IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE element="project" AND source="external")'; + $sql .= ' AND n.entity IN ('.getEntity('project').')'; $resql = $db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); @@ -184,14 +184,14 @@ function show_contacts_projects($conf, $langs, $db, $object, $backtopage = '', $ print "\n".''; $sql = 'SELECT p.rowid as id, p.entity, p.title, p.ref, p.public, p.dateo as do, p.datee as de, p.fk_statut as status, p.fk_opp_status, p.opp_amount, p.opp_percent, p.tms as date_update, p.budget_amount'; - $sql .= ', cls.code as opp_status_code'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'projet as p'; - $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_lead_status as cls on p.fk_opp_status = cls.rowid'; - $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'element_contact as cc ON (p.rowid = cc.element_id)'; - $sql .= ' WHERE cc.fk_socpeople = '.((int) $object->id); - $sql .= ' AND cc.fk_c_type_contact IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE element="project" AND source="external")'; - $sql .= ' AND p.entity IN ('.getEntity('project').')'; - $sql .= ' ORDER BY p.dateo DESC'; + $sql .= ', cls.code as opp_status_code'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'projet as p'; + $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_lead_status as cls on p.fk_opp_status = cls.rowid'; + $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'element_contact as cc ON (p.rowid = cc.element_id)'; + $sql .= ' WHERE cc.fk_socpeople = '.((int) $object->id); + $sql .= ' AND cc.fk_c_type_contact IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE element="project" AND source="external")'; + $sql .= ' AND p.entity IN ('.getEntity('project').')'; + $sql .= ' ORDER BY p.dateo DESC'; $result = $db->query($sql); if ($result) { @@ -275,4 +275,4 @@ function show_contacts_projects($conf, $langs, $db, $object, $backtopage = '', $ } return $i; -} \ No newline at end of file +} From 8034b5316a777596b817e02133f90dc4d9565387 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 4 Jan 2022 12:05:06 +0100 Subject: [PATCH 03/15] NEW Add possibility with constant MAIN_LOGIN_BADCHARUNAUTHORIZED to define bad character unauthorized into login name --- htdocs/user/class/user.class.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 780744b4c8e..4da393f6564 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1393,6 +1393,8 @@ class User extends CommonObject dol_syslog(get_class($this)."::create login=".$this->login.", user=".(is_object($user) ? $user->id : ''), LOG_DEBUG); + $badCharUnauthorizedIntoLoginName = getDolGlobalString('MAIN_LOGIN_BADCHARUNAUTHORIZED', '/[,@<>"\']/'); + // Check parameters if (!empty($conf->global->USER_MAIL_REQUIRED) && !isValidEMail($this->email)) { $langs->load("errors"); @@ -1403,7 +1405,7 @@ class User extends CommonObject $langs->load("errors"); $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Login")); return -1; - } elseif (preg_match('/[,@<>"\']/', $this->login)) { + } elseif (preg_match($badCharUnauthorizedIntoLoginName, $this->login)) { $langs->load("errors"); $this->error = $langs->trans("ErrorBadCharIntoLoginName"); return -1; @@ -1787,6 +1789,8 @@ class User extends CommonObject $this->fk_warehouse = (int) $this->fk_warehouse; // Check parameters + $badCharUnauthorizedIntoLoginName = getDolGlobalString('MAIN_LOGIN_BADCHARUNAUTHORIZED', '/[,@<>"\']/'); + if (!empty($conf->global->USER_MAIL_REQUIRED) && !isValidEMail($this->email)) { $langs->load("errors"); $this->error = $langs->trans("ErrorBadEMail", $this->email); @@ -1796,7 +1800,7 @@ class User extends CommonObject $langs->load("errors"); $this->error = $langs->trans("ErrorFieldRequired", 'Login'); return -1; - } elseif (preg_match('/[,@<>"\']/', $this->login)) { + } elseif (preg_match($badCharUnauthorizedIntoLoginName, $this->login)) { $langs->load("errors"); $this->error = $langs->trans("ErrorBadCharIntoLoginName"); return -1; From 7a4b0e38cdd8d7050ca6cbee4d51a743d42bb4f9 Mon Sep 17 00:00:00 2001 From: Quentin VIAL-GOUTEYRON Date: Wed, 5 Jan 2022 14:35:11 +0100 Subject: [PATCH 04/15] NEW : Contact filter project list --- htdocs/core/class/html.form.class.php | 17 +++++++++++------ htdocs/langs/en_US/projects.lang | 1 + htdocs/langs/fr_FR/projects.lang | 1 + htdocs/projet/list.php | 26 +++++++++++++++++++++++--- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 89c45d4236b..dfd22cd644f 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1690,12 +1690,17 @@ class Form $out .= ''; } - if($showempty && !is_numeric($showempty)) { - $textforempty = $showempty; - $out .= ''; - } else { - if(($showempty == 1 || ($showempty == 3 && $num > 1)) && ! $multiple) { - $out .= ''; - } - if($showempty == 2) { - $out .= ''; - } - } + if ($showempty && ! is_numeric($showempty)) { + $textforempty = $showempty; + $out .= ''; + } + else { + if (($showempty == 1 || ($showempty == 3 && $num > 1)) && ! $multiple) { + $out .= ''; + } + if ($showempty == 2) { + $out .= ''; + } + } $i = 0; if ($num) { diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 2f99fd99b4a..bd7442b1827 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -371,7 +371,7 @@ $sql .= " WHERE ctc.element = '".$db->escape($object->element)."'"; $resql = $db->query($sql); if ($resql) { while ($obj = $db->fetch_object($resql)) { - if($obj->source == 'internal') $listofprojectcontacttype[$obj->rowid] = $obj->code; + if ($obj->source == 'internal') $listofprojectcontacttype[$obj->rowid] = $obj->code; else $listofprojectcontacttypeexternal[$obj->rowid] = $obj->code; } } else { From 5fc0f18b0bc997ead31cb6b1cbf00dfd7048169f Mon Sep 17 00:00:00 2001 From: Quentin VIAL-GOUTEYRON Date: Fri, 7 Jan 2022 10:17:00 +0100 Subject: [PATCH 06/15] add column contact type --- htdocs/core/lib/contact.lib.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/contact.lib.php b/htdocs/core/lib/contact.lib.php index e2f735dc25d..a97a59a3da3 100644 --- a/htdocs/core/lib/contact.lib.php +++ b/htdocs/core/lib/contact.lib.php @@ -184,12 +184,13 @@ function show_contacts_projects($conf, $langs, $db, $object, $backtopage = '', $ print "\n".'
'; $sql = 'SELECT p.rowid as id, p.entity, p.title, p.ref, p.public, p.dateo as do, p.datee as de, p.fk_statut as status, p.fk_opp_status, p.opp_amount, p.opp_percent, p.tms as date_update, p.budget_amount'; - $sql .= ', cls.code as opp_status_code'; + $sql .= ', cls.code as opp_status_code, ctc.libelle'; $sql .= ' FROM '.MAIN_DB_PREFIX.'projet as p'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_lead_status as cls on p.fk_opp_status = cls.rowid'; $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'element_contact as cc ON (p.rowid = cc.element_id)'; + $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_contact as ctc ON (ctc.rowid = cc.fk_c_type_contact)'; $sql .= ' WHERE cc.fk_socpeople = '.((int) $object->id); - $sql .= ' AND cc.fk_c_type_contact IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'c_type_contact WHERE element="project" AND source="external")'; + $sql .= ' AND ctc.element="project" AND ctc.source="external"'; $sql .= ' AND p.entity IN ('.getEntity('project').')'; $sql .= ' ORDER BY p.dateo DESC'; @@ -200,6 +201,7 @@ function show_contacts_projects($conf, $langs, $db, $object, $backtopage = '', $ print ''; print ''; print ''; + print ''; print ''; print ''; print ''; @@ -232,6 +234,7 @@ function show_contacts_projects($conf, $langs, $db, $object, $backtopage = '', $ // Label print ''; + print ''; // Date start print ''; // Date end From f78a9ea6f5d7eba399b535172f6f13cfdbf26d53 Mon Sep 17 00:00:00 2001 From: Quentin VIAL-GOUTEYRON Date: Fri, 7 Jan 2022 10:19:44 +0100 Subject: [PATCH 07/15] missing column --- htdocs/core/lib/contact.lib.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/core/lib/contact.lib.php b/htdocs/core/lib/contact.lib.php index 2e512fa7182..5a0c6c376fb 100644 --- a/htdocs/core/lib/contact.lib.php +++ b/htdocs/core/lib/contact.lib.php @@ -201,6 +201,7 @@ function show_contacts_projects($conf, $langs, $db, $object, $backtopage = '', $ print ''; print ''; print ''; + print ''; print ''; print ''; print ''; @@ -233,6 +234,7 @@ function show_contacts_projects($conf, $langs, $db, $object, $backtopage = '', $ // Label print ''; + print ''; // Date start print ''; // Date end From ecc4a7c1ae899ff5a5d2d683fc569430c92deadd Mon Sep 17 00:00:00 2001 From: Markusi13 Date: Tue, 25 Jan 2022 14:55:34 +0100 Subject: [PATCH 08/15] Updated the old issue form to the new yml format --- .github/ISSUE_TEMPLATE/bug_report.md | 35 ------------ .github/ISSUE_TEMPLATE/bug_report.yml | 81 +++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 35 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 432f30f2332..00000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: Bug report -about: Create a report to help us fix something that is broken -title: '' -labels: Bug -assignees: '' - ---- - -# Instructions -*This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report.* -*Please:* -- *replace the bracket enclosed texts with meaningful information* -- *remove any unused sub-section* - - -# Bug -[*Short description*] - -## Environment -- **Version**: [*Affected Dolibarr version(s)*] -- **OS**: [*Server OS type and version*] -- **Web server**: [*Webserver type and version*] -- **PHP**: [*PHP version*] -- **Database**: [*Database type and version*] -- **URL(s)**: [*Affected URL(s)*] - -## Expected and actual behavior -[*Verbose description*] - -## Steps to reproduce the behavior -[*Verbose description*] - -## [Attached files](https://help.github.com/articles/issue-attachments) (Screenshots, screencasts, dolibarr.log, debugging informations…) -[*Files*] diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000000..23948ad189c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,81 @@ +name: Bug report +description: Create a report to help us fix something that is broken +title: '' +labels: ["Bug"] + +body: + - type: markdown + attributes: + value: | + This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report. + + - type: textarea + id: bug + attributes: + label: Bug + description: Please give a short description of the bug + validations: + required: true + + - type: input + id: environmentversion + attributes: + label: Environment Version + description: Affected Dolibarr version(s) + + - type: input + id: environmentos + attributes: + label: Environment OS + description: Server OS type and version + + - type: input + id: environmentwebserver + attributes: + label: Environment Web server + description: Webserver type and version + + - type: input + id: environmentphp + attributes: + label: Environment PHP + description: PHP version + + - type: input + id: environmentdatabase + attributes: + label: Environment Database + description: Database type and version + + - type: input + id: environmenturls + attributes: + label: Environment URL(s) + description: Affected URL(s) + + - type: textarea + id: expectedbehaviour + attributes: + label: Expected and actual behavior + description: Verbose description + + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce the behavior + description: Verbose description + + - type: textarea + id: files + attributes: + label: Attached files + description: Screenshots, screencasts, dolibarr.log, debugging informations + + - type: checkboxes + id: terms + attributes: + label: Code of Conduct + description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/Dolibarr/dolibarr/blob/develop/.github/CODE_OF_CONDUCT.md) + options: + - label: I agree to follow this project's Code of Conduct + required: true From 7efa219e33e4aa6b17c6bcbaee916c688002167b Mon Sep 17 00:00:00 2001 From: Markusi13 Date: Tue, 25 Jan 2022 14:55:52 +0100 Subject: [PATCH 09/15] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 23948ad189c..2459458dc90 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,6 +1,6 @@ name: Bug report description: Create a report to help us fix something that is broken -title: '' +title: labels: ["Bug"] body: From 688e74aad877bdcb9966acd4a73083c20db093a0 Mon Sep 17 00:00:00 2001 From: Markusi13 Date: Tue, 25 Jan 2022 14:56:01 +0100 Subject: [PATCH 10/15] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 2459458dc90..b215dc62f9c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,6 +1,5 @@ name: Bug report description: Create a report to help us fix something that is broken -title: labels: ["Bug"] body: From ea6dfb172c4f94c8afe9ed6c74d82e34f7682e5e Mon Sep 17 00:00:00 2001 From: Markusi13 Date: Tue, 25 Jan 2022 15:01:29 +0100 Subject: [PATCH 11/15] Update the feature request template to the new yml format --- .github/ISSUE_TEMPLATE/feature_request.md | 27 ------------- .github/ISSUE_TEMPLATE/feature_request.yml | 44 ++++++++++++++++++++++ 2 files changed, 44 insertions(+), 27 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 32e2deff2c1..00000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: Feature request -about: Suggest a new idea for this project -title: '' -labels: Feature request -assignees: '' - ---- - -# Instructions -*This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report.* -*Please:* -- *replace the bracket enclosed texts with meaningful information* -- *remove any unused sub-section* - - -# Feature Request -[*Short description*] - -## Use case -[*Verbose description*] - -## Suggested implementation -[*Verbose description*] - -## Suggested steps -[*List of tasks to achieve goal*] diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000000..f4975622a8f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,44 @@ +name: Feature request +description: Suggest a new idea for this project +labels: ["Feature request"] + +body: + - type: markdown + attributes: + value: | + This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report. + + - type: textarea + id: feature-request + attributes: + label: Feature Request + description: Short description + validations: + required: true + + - type: textarea + id: use-case + attributes: + label: Use case + description: Verbose description + + - type: textarea + id: suggested-implementation + attributes: + label: Suggested implementation + description: Verbose description + + - type: textarea + id: suggested-steps + attributes: + label: Suggested steps + description: List of tasks to achieve goal + + - type: checkboxes + id: terms + attributes: + label: Code of Conduct + description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/Dolibarr/dolibarr/blob/develop/.github/CODE_OF_CONDUCT.md) + options: + - label: I agree to follow this project's Code of Conduct + required: true From 4ab28b10ea0f4556cb4413fa674523433516e0f3 Mon Sep 17 00:00:00 2001 From: Markusi13 Date: Tue, 25 Jan 2022 15:02:11 +0100 Subject: [PATCH 12/15] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index b215dc62f9c..7e7a62c1e84 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -17,43 +17,43 @@ body: required: true - type: input - id: environmentversion + id: environment-version attributes: label: Environment Version description: Affected Dolibarr version(s) - type: input - id: environmentos + id: environment-os attributes: label: Environment OS description: Server OS type and version - type: input - id: environmentwebserver + id: environment-webserver attributes: label: Environment Web server description: Webserver type and version - type: input - id: environmentphp + id: environment-php attributes: label: Environment PHP description: PHP version - type: input - id: environmentdatabase + id: environment-database attributes: label: Environment Database description: Database type and version - type: input - id: environmenturls + id: environment-urls attributes: label: Environment URL(s) description: Affected URL(s) - type: textarea - id: expectedbehaviour + id: expected-behaviour attributes: label: Expected and actual behavior description: Verbose description From 0126be54a330c0cf1830146404fa69289968889b Mon Sep 17 00:00:00 2001 From: Thomas Negre Date: Tue, 25 Jan 2022 15:12:32 +0100 Subject: [PATCH 13/15] fix ticket : an external user should be able to access only its own company tickets. --- htdocs/ticket/list.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index e4ba75b84c5..44b9edf358e 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -157,6 +157,8 @@ $arrayfields = dol_sort_array($arrayfields, 'position'); if (!$user->rights->ticket->read) { accessforbidden(); } +// restrict view to current user's company +if ($user->socid > 0) $socid = $user->socid; // Store current page url $url_page_current = DOL_URL_ROOT.'/ticket/list.php'; From 6677eccf45e01f334f84fc51449d4e96fb97ce05 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 25 Jan 2022 16:01:50 +0100 Subject: [PATCH 14/15] Update user.class.php --- htdocs/user/class/user.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 6d4530d6077..a9dcbfe3b87 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1393,7 +1393,7 @@ class User extends CommonObject dol_syslog(get_class($this)."::create login=".$this->login.", user=".(is_object($user) ? $user->id : ''), LOG_DEBUG); - $badCharUnauthorizedIntoLoginName = getDolGlobalString('MAIN_LOGIN_BADCHARUNAUTHORIZED', '/[,@<>"\']/'); + $badCharUnauthorizedIntoLoginName = getDolGlobalString('MAIN_LOGIN_BADCHARUNAUTHORIZED', ',@<>"\''); // Check parameters if (!empty($conf->global->USER_MAIL_REQUIRED) && !isValidEMail($this->email)) { @@ -1405,7 +1405,7 @@ class User extends CommonObject $langs->load("errors"); $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Login")); return -1; - } elseif (preg_match($badCharUnauthorizedIntoLoginName, $this->login)) { + } elseif (preg_match('/['.preg_quote($badCharUnauthorizedIntoLoginName, '/').']/', $this->login)) { $langs->load("errors"); $this->error = $langs->trans("ErrorBadCharIntoLoginName"); return -1; From 05ff99f2e61bd44af1646020a6a85299304d97f7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 25 Jan 2022 16:03:30 +0100 Subject: [PATCH 15/15] Update user.class.php --- htdocs/user/class/user.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index a9dcbfe3b87..cd38b9f2d66 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1789,7 +1789,7 @@ class User extends CommonObject $this->fk_warehouse = (int) $this->fk_warehouse; // Check parameters - $badCharUnauthorizedIntoLoginName = getDolGlobalString('MAIN_LOGIN_BADCHARUNAUTHORIZED', '/[,@<>"\']/'); + $badCharUnauthorizedIntoLoginName = getDolGlobalString('MAIN_LOGIN_BADCHARUNAUTHORIZED', ',@<>"\''); if (!empty($conf->global->USER_MAIL_REQUIRED) && !isValidEMail($this->email)) { $langs->load("errors"); @@ -1800,7 +1800,7 @@ class User extends CommonObject $langs->load("errors"); $this->error = $langs->trans("ErrorFieldRequired", 'Login'); return -1; - } elseif (preg_match($badCharUnauthorizedIntoLoginName, $this->login)) { + } elseif (preg_match('/['.preg_quote($badCharUnauthorizedIntoLoginName, '/').']/', $this->login)) { $langs->load("errors"); $this->error = $langs->trans("ErrorBadCharIntoLoginName"); return -1;
'.$langs->trans("Ref").''.$langs->trans("Name").''.$langs->trans("ContactType").''.$langs->trans("DateStart").''.$langs->trans("DateEnd").''.$langs->trans("OpportunityAmountShort").''.$obj->title.''.$obj->libelle.''.dol_print_date($db->jdate($obj->do), "day").'
'.$langs->trans("Ref").''.$langs->trans("Name").''.$langs->trans("ContactType").''.$langs->trans("DateStart").''.$langs->trans("DateEnd").''.$langs->trans("OpportunityAmountShort").''.$obj->title.''.$obj->libelle.''.dol_print_date($db->jdate($obj->do), "day").'