From 5c839effb293a1f7436039c4b0cf869e89c3a9ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Tue, 17 Sep 2024 12:43:34 +0200 Subject: [PATCH] Fix escaping handling in `formatUserName()` and `getUserName()` --- CHANGELOG.md | 4 + ajax/comments.php | 24 ++- front/stat.graph.php | 13 +- src/Change.php | 16 +- src/CommonDBTM.php | 9 +- src/CommonITILObject.php | 132 ++++++++------- src/DbUtils.php | 197 +++++++++++------------ src/Document.php | 6 +- src/Glpi/Features/PlanningEvent.php | 6 +- src/Glpi/Search/Provider/SQLProvider.php | 82 +++++----- src/Item_SoftwareLicense.php | 4 +- src/Item_SoftwareVersion.php | 4 +- src/KnowbaseItem.php | 11 +- src/NotificationTarget.php | 4 +- src/ObjectLock.php | 13 +- src/Problem.php | 14 +- src/Profile_User.php | 6 +- src/Project.php | 11 +- src/Ticket.php | 14 +- src/User.php | 67 ++++++-- src/autoload/dbutils-aliases.php | 70 ++++++-- 21 files changed, 381 insertions(+), 326 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b20ec7cd22..8c845d9cdac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -219,6 +219,8 @@ The present file will list all changes made to the project; according to the - `js/Forms/FaIconSelector.js` and therefore `window.GLPI.Forms.FaIconSelector` has been deprecated and replaced by `js/modules/Form/WebIconSelector.js` - `linkuser_types`, `linkgroup_types`, `linkuser_tech_types`, `linkgroup_tech_types` configuration entries have been merged in a unique `assignable_types` configuration entry. - Usage of the `front/dropdown.common.php` and the `dropdown.common.form.php` files. There is now a generic controller that will serve the search and form pages of any `Dropdown` class. +- Usage of the `$link` parameter in `formatUserName()` and `DbUtils::formatUserName()`. Use `formatUserLink()` or `DbUtils::formatUserLink()` instead. +- Usage of the `$link` parameter in `getUserName()` and `DbUtils::getUserName()`. Use `getUserLink()`, `DbUtils::getUserLink()`, or `User::getInfoCard()` instead. - `Auth::getErr()` - `AuthLDAP::dropdownUserDeletedActions()` - `AuthLDAP::getOptions()` @@ -311,6 +313,7 @@ The present file will list all changes made to the project; according to the - `CommonGLPI::showDislayOptions()` - `CommonITILActor::showUserNotificationForm()` - `CommonITILActor::showSupplierNotificationForm()` +- `CommonITILObject::getAssignName()` - `CommonITILValidation::alreadyExists()` - `CommonITILValidation::getTicketStatusNumber()` - `CommonTreeDropdown::sanitizeSeparatorInCompletename()` @@ -496,6 +499,7 @@ The present file will list all changes made to the project; according to the - `ajax/planningcheck.php` script. Use `Planning::showPlanningCheck()` instead. - `test_ldap` and `test_ldap_replicate` actions in `front/authldap.form.php`. Use `ajax/ldap.php` instead. - `ajax/ticketsatisfaction.php` and `ajax/changesatisfaction.php` scripts. Access `ajax/commonitilsatisfaction.php` directly instead. +- Usage of the `$cut` parameter in `formatUserName()` and `DbUtils::formatUserName()`. ## [10.0.17] unreleased diff --git a/ajax/comments.php b/ajax/comments.php index 4562241f8d2..6fadc953ff2 100644 --- a/ajax/comments.php +++ b/ajax/comments.php @@ -60,36 +60,32 @@ switch ($_POST["itemtype"]) { case User::getType(): + $link = null; + $comments = []; if ($_POST['value'] == 0) { - $tmpname = [ - 'link' => $CFG_GLPI['root_doc'] . "/front/user.php", - 'comment' => "", - ]; + $link = $CFG_GLPI['root_doc'] . "/front/user.php"; } else { $user = new \User(); if (is_array($_POST["value"])) { - $comments = []; foreach ($_POST["value"] as $users_id) { if ($user->getFromDB($users_id) && $user->canView()) { - $username = getUserName($users_id, 2); - $comments[] = $username['comment'] ?? ""; + $comments[] = $user->getInfoCard(); } } - $tmpname = [ - 'comment' => implode("
", $comments), - ]; unset($_POST['withlink']); } else { if ($user->getFromDB($_POST['value']) && $user->canView()) { - $tmpname = getUserName($_POST["value"], 2); + $link = $user->getLinkURL(); + $comments[] = $user->getInfoCard(); } } } - echo($tmpname["comment"] ?? ''); - if (isset($_POST['withlink']) && isset($tmpname['link'])) { + echo(implode("
", $comments)); + + if (isset($_POST['withlink']) && $link !== null) { echo "\n"; } break; diff --git a/front/stat.graph.php b/front/stat.graph.php index 133e79033b3..42dbe6fa9d8 100644 --- a/front/stat.graph.php +++ b/front/stat.graph.php @@ -88,12 +88,10 @@ $val1 = $_GET["id"]; $val2 = ""; $values = Stat::getItems($_GET["itemtype"], $_GET["date1"], $_GET["date2"], $_GET["type"]); - $link = User::canView() ? 1 : 0; - $name = $item->getAssignName($_GET["id"], 'User', $link); $title = sprintf( __s('%1$s: %2$s'), __s('Technician'), - $link ? $name : htmlspecialchars($name) + getUserLink($_GET["id"]) ); break; @@ -101,12 +99,11 @@ $val1 = $_GET["id"]; $val2 = ""; $values = Stat::getItems($_GET["itemtype"], $_GET["date1"], $_GET["date2"], $_GET["type"]); - $link = Supplier::canView() ? 1 : 0; - $name = $item->getAssignName($_GET["id"], 'Supplier', $link); + $supplier = Supplier::getById($_GET["id"]); $title = sprintf( __s('%1$s: %2$s'), Supplier::getTypeName(1), - $link ? $name : htmlspecialchars($name) + $supplier !== false ? $supplier->getLink(['comments' => true]) : '' ); break; @@ -115,12 +112,10 @@ $val1 = $_GET["id"]; $val2 = ""; $values = Stat::getItems($_GET["itemtype"], $_GET["date1"], $_GET["date2"], $_GET["type"]); - $link = User::canView() ? 1 : 0; - $name = getUserName($_GET["id"], $link); $title = sprintf( __s('%1$s: %2$s'), User::getTypeName(1), - $link ? $name : htmlspecialchars($name) + getUserLink($_GET["id"]) ); break; diff --git a/src/Change.php b/src/Change.php index 685a137fcc3..900de7cedac 100644 --- a/src/Change.php +++ b/src/Change.php @@ -1224,9 +1224,8 @@ public static function showCentralList($start, $status = "process", $showgroupch ) { foreach ($change->users[CommonITILActor::REQUESTER] as $d) { if ($d["users_id"] > 0) { - $userdata = getUserName($d["users_id"], 2); $name = '' . - $userdata['name']; + htmlspecialchars(getUserName($d["users_id"])); $requesters[] = $name; } else { $requesters[] = '' . @@ -1451,16 +1450,17 @@ public static function showVeryShort($ID, $forcetab = '') && count($change->users[CommonITILActor::REQUESTER]) ) { foreach ($change->users[CommonITILActor::REQUESTER] as $d) { - if ($d["users_id"] > 0) { - $userdata = getUserName($d["users_id"], 2); - $name = "" . $userdata['name'] . ""; + $user = new User(); + if ($d["users_id"] > 0 && $user->getFromDB($d["users_id"])) { + $name = "" . htmlspecialchars($user->getName()) . ""; if ($viewusers) { $name = sprintf( - __('%1$s %2$s'), + __s('%1$s %2$s'), $name, Html::showToolTip( - $userdata["comment"], - ['link' => $userdata["link"], + $user->getInfoCard(), + [ + 'link' => $user->getLinkURL(), 'display' => false ] ) diff --git a/src/CommonDBTM.php b/src/CommonDBTM.php index c27ed3ca081..0c2bef7e231 100644 --- a/src/CommonDBTM.php +++ b/src/CommonDBTM.php @@ -4911,11 +4911,14 @@ public function getValueToDisplay($field_id_or_search_options, $values, $options return $searchoptions['emptylabel']; } + $user = new User(); if ($searchoptions['table'] == 'glpi_users') { + if (!$user->getFromDB($value)) { + return ''; + } if ($param['comments']) { - $tmp = getUserName($value, 2); - return $tmp['name'] . ' ' . Html::showToolTip( - $tmp['comment'], + return $user->getLink() . ' ' . Html::showToolTip( + $user->getInfoCard(), ['display' => false] ); } diff --git a/src/CommonITILObject.php b/src/CommonITILObject.php index cfdfb4bb3d1..475c92d2b57 100644 --- a/src/CommonITILObject.php +++ b/src/CommonITILObject.php @@ -5542,35 +5542,6 @@ public static function getActionTime($actiontime) return Html::timestampToString($actiontime, false); } - - /** - * @param $ID - * @param $itemtype - * @param $link (default 0) - **/ - public static function getAssignName($ID, $itemtype, $link = 0) - { - - switch ($itemtype) { - case 'User': - if ($ID == 0) { - return ""; - } - return getUserName($ID, $link); - - case 'Supplier': - case 'Group': - $item = new $itemtype(); - if ($item->getFromDB($ID)) { - if ($link) { - return $item->getLink(['comments' => true]); - } - return $item->getNameID(); - } - return ""; - } - } - /** * Form to add a solution to an ITIL object * @@ -5960,12 +5931,11 @@ public function getUsedAuthorBetween($date1 = '', $date2 = '') foreach ($iterator as $line) { $tab[] = [ 'id' => $line['users_id'], - 'link' => formatUserName( + 'link' => formatUserLink( $line['users_id'], $line['name'], $line['realname'], - $line['firstname'], - 1 + $line['firstname'] ) ]; } @@ -6028,12 +5998,11 @@ public function getUsedRecipientBetween($date1 = '', $date2 = '') foreach ($iterator as $line) { $tab[] = [ 'id' => $line['user_id'], - 'link' => formatUserName( + 'link' => formatUserLink( $line['user_id'], $line['name'], $line['realname'], $line['firstname'], - 1 ) ]; } @@ -6444,7 +6413,6 @@ public function getUsedTechBetween($date1 = '', $date2 = '') $linkclass = new $this->userlinkclass(); $linktable = $linkclass->getTable(); - $showlink = User::canView(); $ctable = $this->getTable(); $criteria = [ @@ -6499,7 +6467,7 @@ public function getUsedTechBetween($date1 = '', $date2 = '') foreach ($iterator as $line) { $tab[] = [ 'id' => $line['users_id'], - 'link' => formatUserName($line['users_id'], $line['name'], $line['realname'], $line['firstname'], $showlink), + 'link' => formatUserLink($line['users_id'], $line['name'], $line['realname'], $line['firstname']), ]; } return $tab; @@ -6519,7 +6487,6 @@ public function getUsedTechTaskBetween($date1 = '', $date2 = '') global $DB; $linktable = getTableForItemType($this->getType() . 'Task'); - $showlink = User::canView(); $ctable = $this->getTable(); $criteria = [ @@ -6592,7 +6559,7 @@ public function getUsedTechTaskBetween($date1 = '', $date2 = '') foreach ($iterator as $line) { $tab[] = [ 'id' => $line['users_id'], - 'link' => formatUserName($line['users_id'], $line['name'], $line['realname'], $line['firstname'], $showlink), + 'link' => formatUserLink($line['users_id'], $line['name'], $line['realname'], $line['firstname']), ]; } return $tab; @@ -6906,18 +6873,21 @@ public static function showShort($id, $options = []) // eighth Column $eighth_col = ""; foreach ($item->getUsers(CommonITILActor::REQUESTER) as $d) { - $userdata = getUserName($d["users_id"], 2); - $eighth_col .= sprintf( - __('%1$s %2$s'), - "" . $userdata['name'] . "", - Html::showToolTip( - $userdata["comment"], - ['link' => $userdata["link"], - 'display' => false - ] - ) - ); - $eighth_col .= "
"; + $user = new User(); + if ($user->getFromDB($d["users_id"])) { + $eighth_col .= sprintf( + __('%1$s %2$s'), + "" . htmlspecialchars($user->getName()) . "", + Html::showToolTip( + $user->getInfoCard(), + [ + 'link' => $user->getLinkURL(), + 'display' => false + ] + ) + ); + $eighth_col .= "
"; + } } foreach ($item->getGroups(CommonITILActor::REQUESTER) as $d) { @@ -6930,6 +6900,7 @@ public static function showShort($id, $options = []) // ninth column $ninth_col = ""; foreach ($item->getUsers(CommonITILActor::ASSIGN) as $d) { + $user = new User(); if ( Session::getCurrentInterface() == 'helpdesk' && !empty($anon_name = User::getAnonymizedNameForUser( @@ -6938,14 +6909,14 @@ public static function showShort($id, $options = []) )) ) { $ninth_col .= $anon_name; - } else { - $userdata = getUserName($d["users_id"], 2); + } elseif ($user->getFromDB($d["users_id"])) { $ninth_col .= sprintf( __('%1$s %2$s'), - "" . $userdata['name'] . "", + "" . htmlspecialchars($user->getName()) . "", Html::showToolTip( - $userdata["comment"], - ['link' => $userdata["link"], + $user->getInfoCard(), + [ + 'link' => $user->getLinkURL(), 'display' => false ] ) @@ -7338,22 +7309,22 @@ public static function getDatatableEntries(array $data, $params = []): array $entry['requester'] = ''; foreach ($item->getUsers(CommonITILActor::REQUESTER) as $d) { - if (!isset($user_cache[$d["users_id"]])) { - $userdata = getUserName($d["users_id"], 2); + $user = new User(); + if (!isset($user_cache[$d["users_id"]]) && $user->getFromDB($d["users_id"])) { $user_value = sprintf( - __('%1$s %2$s'), - htmlspecialchars($userdata['name']), + __s('%1$s %2$s'), + htmlspecialchars($user->getName()), Html::showToolTip( - $userdata["comment"], + $user->getInfoCard(), [ - 'link' => $userdata["link"], + 'link' => $user->getLinkURL(), 'display' => false ] ) ); $user_cache[$d['users_id']] = $user_value; } - $entry['requester'] .= $user_cache[$d['users_id']] . '
'; + $entry['requester'] .= isset($user_cache[$d["users_id"]]) ? $user_cache[$d['users_id']] . '
' : ''; } foreach ($item->getGroups(CommonITILActor::REQUESTER) as $d) { if (!isset($group_cache[$d['groups_id']])) { @@ -7367,11 +7338,22 @@ public static function getDatatableEntries(array $data, $params = []): array if (Session::getCurrentInterface() === 'helpdesk' && !empty($anon_name = User::getAnonymizedNameForUser($d['users_id'], $item->getEntityID()))) { $entry['assigned'] .= htmlspecialchars($anon_name) . '
'; } else { - if (!isset($user_cache[$d['users_id']])) { - $user_cache[$d['users_id']] = getUserName($d['users_id'], 2); + $user = new User(); + if (!isset($user_cache[$d["users_id"]]) && $user->getFromDB($d["users_id"])) { + $user_value = sprintf( + __s('%1$s %2$s'), + htmlspecialchars($user->getName()), + Html::showToolTip( + $user->getInfoCard(), + [ + 'link' => $user->getLinkURL(), + 'display' => false + ] + ) + ); + $user_cache[$d['users_id']] = $user_value; } - $user_name = is_array($user_cache[$d['users_id']]) ? htmlspecialchars($user_cache[$d['users_id']]['name']) : $user_cache[$d['users_id']]; - $entry['assigned'] .= $user_name . '
'; + $entry['assigned'] .= isset($user_cache[$d["users_id"]]) ? $user_cache[$d['users_id']] . '
' : ''; } } foreach ($item->getGroups(CommonITILActor::ASSIGN) as $d) { @@ -7440,10 +7422,22 @@ public static function getDatatableEntries(array $data, $params = []): array $planned_infos .= htmlspecialchars(sprintf(__('From %s'), Html::convDateTime($plan['begin']))); $planned_infos .= htmlspecialchars(sprintf(__('To %s'), Html::convDateTime($plan['end']))); if ($plan['users_id_tech']) { - if (!isset($user_cache[$plan['users_id_tech']])) { - $user_cache[$plan['users_id_tech']] = getUserName($plan['users_id_tech'], 2); + $user = new User(); + if (!isset($user_cache[$plan["users_id_tech"]]) && $user->getFromDB($plan["users_id_tech"])) { + $user_value = sprintf( + __s('%1$s %2$s'), + htmlspecialchars($user->getName()), + Html::showToolTip( + $user->getInfoCard(), + [ + 'link' => $user->getLinkURL(), + 'display' => false + ] + ) + ); + $user_cache[$plan['users_id']] = $user_value; } - $planned_infos .= htmlspecialchars(sprintf(__('By %s'), $user_cache[$plan['users_id_tech']]['name'])); + $planned_infos .= htmlspecialchars(sprintf(__s('By %s'), $user_cache[$plan['users_id_tech']])); } $planned_infos .= "
"; } diff --git a/src/DbUtils.php b/src/DbUtils.php index f4511922c76..ddc0abf7cf8 100644 --- a/src/DbUtils.php +++ b/src/DbUtils.php @@ -1684,20 +1684,32 @@ public function constructListFromTree($tree, $parent = 0) /** - * Format a user name + * Format a user name. * - * @param integer $ID ID of the user. - * @param string|null $login login of the user - * @param string|null $realname realname of the user - * @param string|null $firstname firstname of the user - * @param integer $link include link (only if $link==1) (default =0) - * @param integer $cut limit string length (0 = no limit) (default =0) - * @param boolean $force_config force order and id_visible to use common config (false by default) + * @param integer $ID ID of the user. + * @param string|null $login login of the user + * @param string|null $realname realname of the user + * @param string|null $firstname firstname of the user + * @param integer $link include link + * @param integer $cut IGNORED PARAMETER + * @param boolean $force_config force order and id_visible to use common config * - * @return string formatted username + * @return string + * + * @since 11.0 `$link` parameter is deprecated + * @since 11.0 `$cut` parameter is ignored */ - public function formatUserName($ID, $login, $realname, $firstname, $link = 1, $cut = 0, $force_config = false) + public function formatUserName($ID, $login, $realname, $firstname, $link = 0, $cut = 0, $force_config = false) { + if ((bool) $cut) { + trigger_error('`$cut` parameter is now ignored.', E_USER_WARNING); + } + + if ((bool) $link) { + Toolbox::deprecated('`$link` parameter is deprecated. Use `formatUserLink()` instead.'); + return $this->formatUserLink($ID, $login, $realname, $firstname); + } + /** @var array $CFG_GLPI */ global $CFG_GLPI; @@ -1739,21 +1751,33 @@ public function formatUserName($ID, $login, $realname, $firstname, $link = 1, $c $formatted = sprintf(__('%1$s (%2$s)'), $formatted, $ID); } - $username = $formatted; + return $formatted; + } - if ( - ($link == 1) - && ($ID > 0) - ) { - $username = sprintf( - '%s', - htmlspecialchars($formatted), - User::getFormURLWithID($ID), - htmlspecialchars($formatted) - ); + /** + * Format a user link. + * + * @param integer $id ID of the user. + * @param string|null $login login of the user + * @param string|null $realname realname of the user + * @param string|null $firstname firstname of the user + * + * @return string + */ + public function formatUserLink(int $id, ?string $login, ?string $realname, ?string $firstname): string + { + $username = $this->formatUserName($id, $login, $realname, $firstname); + + if ($id <= 0 || !User::canView()) { + return htmlspecialchars($username); } - return $username; + return sprintf( + '%s', + htmlspecialchars($username), + User::getFormURLWithID($id), + htmlspecialchars($username) + ); } @@ -1766,102 +1790,73 @@ public function formatUserName($ID, $login, $realname, $firstname, $link = 1, $c * @param $disable_anon bool disable anonymization of username. * * @return string[]|string username string (realname if not empty and name if realname is empty). + * + * @since 11.0 `$link` parameter is deprecated. */ public function getUserName($ID, $link = 0, $disable_anon = false) { /** @var \DBmysql $DB */ global $DB; - $user = ""; - if ($link == 2) { - $user = ["name" => "", - "link" => "", - "comment" => "" - ]; - } + $username = ""; + $user = new User(); + $valid_user = false; + $anon_name = null; if ($ID === 'myself') { - $name = __('Myself'); - if (isset($user['name'])) { - $user['name'] = $name; - } else { - $user = $name; - } + $username = __('Myself'); } else if ($ID === 'requester_manager') { - $name = __("Requester's manager"); - if (isset($user['name'])) { - $user['name'] = $name; - } else { - $user = $name; - } + $username = __("Requester's manager"); } else if ($ID) { - $iterator = $DB->request([ - 'FROM' => 'glpi_users', - 'WHERE' => ['id' => $ID] - ]); - - if ($link == 2) { - $user = ["name" => "", - "comment" => "", - "link" => "" - ]; + $anon_name = !$disable_anon && $ID != ($_SESSION['glpiID'] ?? 0) && Session::getCurrentInterface() == 'helpdesk' ? User::getAnonymizedNameForUser($ID) : null; + if ($anon_name !== null) { + $username = $anon_name; + } elseif ($valid_user = $user->getFromDB($ID)) { + $username = $user->getName(); } + } - if (count($iterator) == 1) { - $data = $iterator->current(); + if ($link == 1) { + Toolbox::deprecated('Usage of `$link` parameter is deprecated. Use `getUserLink()` instead.'); + return $valid_user + ? sprintf('%s', htmlspecialchars($username), User::getFormURLWithID($ID), htmlspecialchars($username)) + : htmlspecialchars($username); + } - $anon_name = !$disable_anon && $ID != ($_SESSION['glpiID'] ?? 0) && Session::getCurrentInterface() == 'helpdesk' ? User::getAnonymizedNameForUser($ID) : null; - if ($anon_name !== null) { - $username = $anon_name; - } else { - $username = $this->formatUserName( - $data["id"], - $data["name"], - $data["realname"], - $data["firstname"], - $link - ); - } + if ($link == 2) { + Toolbox::deprecated('Usage of `$link` parameter is deprecated. Use `User::getInforCard()` instead.'); - if ($link == 2) { - $user["name"] = $username; - $user["link"] = User::getFormURLWithID($ID); - $user['comment'] = ''; + return [ + 'name' => $username, + 'link' => $valid_user ? $user->getLinkUrl() : '', + 'comment' => $valid_user ? $user->getInfoCard() : '', + ]; + } - $user_params = [ - 'id' => $ID, - 'user_name' => $username, - ]; + return $username; + } - if ($anon_name === null) { - $user_params = array_merge($user_params, [ - 'email' => UserEmail::getDefaultForUser($ID), - 'phone' => $data["phone"], - 'phone2' => $data["phone2"], - 'mobile' => $data["mobile"], - 'locations_id' => $data['locations_id'], - 'usertitles_id' => $data['usertitles_id'], - 'usercategories_id' => $data['usercategories_id'], - 'registration_number' => $data['registration_number'], - ]); - - if (Session::haveRight('user', READ)) { - $user_params['login'] = $data['name']; - } - if (!empty($data["groups_id"])) { - $user_params['groups_id'] = $data["groups_id"]; - } - $user['comment'] = TemplateRenderer::getInstance()->render('components/user/info_card.html.twig', [ - 'user' => $user_params, - 'enable_anonymization' => Session::getCurrentInterface() == 'helpdesk', - ]); - } - } else { - $user = $username; - } - } + /** + * Get link of the given user. + * + * @param int $id + * + * @return string + */ + public function getUserLink(int $id): string + { + $username = $this->getUserName($id); + + if (!is_int($id) || $id <= 0 || !User::canView()) { + return htmlspecialchars($username); } - return $user; + + return sprintf( + '%s', + htmlspecialchars($username), + User::getFormURLWithID($id), + htmlspecialchars($username) + ); } /** diff --git a/src/Document.php b/src/Document.php index 45179f4ff9e..66aaf47557f 100644 --- a/src/Document.php +++ b/src/Document.php @@ -364,14 +364,10 @@ public function showForm($ID, array $options = []) if ($ID > 0) { $this->check($ID, READ); } - $showuserlink = 0; - if (Session::haveRight('user', READ)) { - $showuserlink = 1; - } TemplateRenderer::getInstance()->display('pages/management/document.html.twig', [ 'item' => $this, - 'uploader' => $this->fields['users_id'] > 0 ? getUserName($this->fields["users_id"], $showuserlink) : '', + 'uploader' => $this->fields['users_id'] > 0 ? getUserLink($this->fields["users_id"]) : '', 'uploaded_files' => self::getUploadedFiles(), 'params' => [ 'canedit' => $this->canUpdateItem(), diff --git a/src/Glpi/Features/PlanningEvent.php b/src/Glpi/Features/PlanningEvent.php index a1c3e3e512b..9e004fa353d 100644 --- a/src/Glpi/Features/PlanningEvent.php +++ b/src/Glpi/Features/PlanningEvent.php @@ -1101,11 +1101,7 @@ public static function getSpecificValueToDisplay($field, $values, array $options return ''; } foreach (json_decode($values[$field], true) as $user_id) { - $users[] = sprintf( - '%s', - User::getFormURLWithID($user_id), - getUserName($user_id, 1) - ); + $users[] = getUserLink($user_id); } return implode(', ', $users); } diff --git a/src/Glpi/Search/Provider/SQLProvider.php b/src/Glpi/Search/Provider/SQLProvider.php index 6171b186c04..31c525bf152 100644 --- a/src/Glpi/Search/Provider/SQLProvider.php +++ b/src/Glpi/Search/Provider/SQLProvider.php @@ -5078,11 +5078,6 @@ public static function giveItem( $count_display = 0; $added = []; - $showuserlink = 0; - if (Session::haveRight('user', READ)) { - $showuserlink = 1; - } - for ($k = 0; $k < $data[$ID]['count']; $k++) { if ( (isset($data[$ID][$k]['name']) && ($data[$ID][$k]['name'] > 0)) @@ -5092,11 +5087,8 @@ public static function giveItem( $out .= \Search::LBBR; } - if ($itemtype == 'Ticket') { - if ( - isset($data[$ID][$k]['name']) - && $data[$ID][$k]['name'] > 0 - ) { + if (isset($data[$ID][$k]['name']) && $data[$ID][$k]['name'] > 0) { + if ($itemtype == 'Ticket') { if ( Session::getCurrentInterface() == 'helpdesk' && $orig_id == 5 // -> Assigned user @@ -5107,24 +5099,27 @@ public static function giveItem( ) { $out .= $anon_name; } else { - $userdata = getUserName($data[$ID][$k]['name'], 2); - $tooltip = ""; - if (Session::haveRight('user', READ)) { - $tooltip = \Html::showToolTip( - $userdata["comment"], - ['link' => $userdata["link"], - 'display' => false - ] - ); + $user = new \User(); + if ($user->getFromDB($data[$ID][$k]['name'])) { + $tooltip = ""; + if (Session::haveRight('user', READ)) { + $tooltip = \Html::showToolTip( + $user->getInfoCard(), + [ + 'link' => $user->getLinkURL(), + 'display' => false + ] + ); + } + $out .= sprintf(__s('%1$s %2$s'), htmlspecialchars($user->getName()), $tooltip); } - $out .= sprintf(__('%1$s %2$s'), $userdata['name'], $tooltip); } + $count_display++; + } else { + $out .= getUserLink($data[$ID][$k]['name']); $count_display++; } - } else { - $out .= getUserName($data[$ID][$k]['name'], $showuserlink); - $count_display++; } // Manage alternative_email for tickets_users @@ -5149,27 +5144,30 @@ public static function giveItem( return $out; } if ($itemtype != 'User') { - $toadd = ''; - if ( - ($itemtype == 'Ticket') - && ($data[$ID][0]['id'] > 0) - ) { - $userdata = getUserName($data[$ID][0]['id'], 2); - $toadd = \Html::showToolTip( - $userdata["comment"], - ['link' => $userdata["link"], - 'display' => false - ] + $out = ''; + if ($data[$ID][0]['id'] > 0) { + $toadd = ''; + if ($itemtype == 'Ticket') { + $user = new \User(); + if (Session::haveRight('user', READ) && $user->getFromDB($data[$ID][0]['id'])) { + $toadd = \Html::showToolTip( + $user->getInfoCard(), + [ + 'link' => $user->getLinkURL(), + 'display' => false + ] + ); + } + } + $userlink = formatUserLink( + $data[$ID][0]['id'], + $data[$ID][0]['name'], + $data[$ID][0]['realname'], + $data[$ID][0]['firstname'], ); + $out = sprintf(__s('%1$s %2$s'), $userlink, $toadd); } - $usernameformat = formatUserName( - $data[$ID][0]['id'], - $data[$ID][0]['name'], - $data[$ID][0]['realname'], - $data[$ID][0]['firstname'], - 1 - ); - return sprintf(__('%1$s %2$s'), $usernameformat, $toadd); + return $out; } if ($html_output) { diff --git a/src/Item_SoftwareLicense.php b/src/Item_SoftwareLicense.php index bb24494d2c8..dfed22e902c 100644 --- a/src/Item_SoftwareLicense.php +++ b/src/Item_SoftwareLicense.php @@ -787,7 +787,6 @@ function updateItemDropdown(itemtype_el) { $soft = new Software(); $soft->getFromDB($license->fields['softwares_id']); $showEntity = ($license->isRecursive()); - $linkUser = User::canView(); $text = sprintf(__('%1$s = %2$s'), Software::getTypeName(1), $soft->fields["name"]); $text = sprintf(__('%1$s - %2$s'), $text, $data["license"]); @@ -863,12 +862,11 @@ function updateItemDropdown(itemtype_el) { echo "" . $data['location'] . ""; echo "" . $data['state'] . ""; echo "" . $data['groupe'] . ""; - echo "" . formatUserName( + echo "" . formatUserLink( $data['userid'], $data['username'], $data['userrealname'], $data['userfirstname'], - $linkUser ) . ""; echo "\n"; diff --git a/src/Item_SoftwareVersion.php b/src/Item_SoftwareVersion.php index bf2b6bebe49..cd7ada579e7 100644 --- a/src/Item_SoftwareVersion.php +++ b/src/Item_SoftwareVersion.php @@ -650,7 +650,6 @@ private static function showInstallations($searchID, $crit) $softwares_id = $data['sID']; $soft = new Software(); $showEntity = ($soft->getFromDB($softwares_id) && $soft->isRecursive()); - $linkUser = User::canView(); $title = $soft->fields["name"]; if ($crit === "id") { @@ -763,12 +762,11 @@ private static function showInstallations($searchID, $crit) echo "" . $data['location'] . ""; echo "" . $data['state'] . ""; echo "" . $data['groupe'] . ""; - echo "" . formatUserName( + echo "" . formatUserLink( $data['userid'], $data['username'], $data['userrealname'], $data['userfirstname'], - $linkUser ) . ""; $lics = Item_SoftwareLicense::getLicenseForInstallation( diff --git a/src/KnowbaseItem.php b/src/KnowbaseItem.php index f5bbdf2044b..7d3c02ead94 100644 --- a/src/KnowbaseItem.php +++ b/src/KnowbaseItem.php @@ -954,10 +954,7 @@ public function showFull($options = []) $writer_link = ''; if ($this->fields["users_id"]) { - $writer_link = getUserName( - $this->fields["users_id"], - $linkusers_id ? 1 : 0 // Integer because true may be 2 and getUserName return array - ); + $writer_link = getUserLink($this->fields["users_id"]); } $out = TemplateRenderer::getInstance()->render('pages/tools/kb/article.html.twig', [ @@ -1607,14 +1604,10 @@ public static function showList($options, $type = 'search') echo Search::showItem($output_type, htmlspecialchars(RichText::getTextFromHtml($answer, true, false, true)), $item_num, $row_num); } - $showuserlink = 0; - if (Session::haveRight('user', READ)) { - $showuserlink = 1; - } if ($showwriter) { echo Search::showItem( $output_type, - getUserName($data["users_id"], $showuserlink), + getUserLink($data["users_id"]), $item_num, $row_num ); diff --git a/src/NotificationTarget.php b/src/NotificationTarget.php index a508b6dd70f..44fac55e96f 100644 --- a/src/NotificationTarget.php +++ b/src/NotificationTarget.php @@ -607,9 +607,7 @@ public function addToRecipientsList(array $data) $user->getField('name'), $user->getField('realname'), $user->getField('firstname'), - 0, - 0, - true + force_config: true ); } // It is a GLPI user : diff --git a/src/ObjectLock.php b/src/ObjectLock.php index 33b8f8533e9..2e5141d8359 100644 --- a/src/ObjectLock.php +++ b/src/ObjectLock.php @@ -112,11 +112,18 @@ private function lockObject() $ret = false; $new_lock = false; $showAskUnlock = false; - $user_data = []; + $user_data = [ + 'name' => null, + 'comment' => null, + ]; $autolock = $this->isAutolockReadonlyMode(); - if (isset($this->fields['users_id']) && $this->fields['users_id'] > 0) { - $user_data = getUserName($this->fields['users_id'], 2); + $user = new User(); + if (isset($this->fields['users_id']) && $this->fields['users_id'] > 0 && $user->getFromDB($this->fields['users_id'])) { + $user_data = [ + 'name' => $user->getName(), + 'comment' => $user->getInfoCard(), + ]; // should get locking user info $useremail = new UserEmail(); $showAskUnlock = $useremail->getFromDBByCrit([ diff --git a/src/Problem.php b/src/Problem.php index e8e6a9c629e..ec6cd287afa 100644 --- a/src/Problem.php +++ b/src/Problem.php @@ -1030,9 +1030,8 @@ public static function showCentralList($start, $status = "process", $showgrouppr ) { foreach ($problem->users[CommonITILActor::REQUESTER] as $d) { if ($d["users_id"] > 0) { - $userdata = getUserName($d["users_id"], 2); $name = '' . - $userdata['name']; + htmlspecialchars(getUserName($d["users_id"])); $requesters[] = $name; } else { $requesters[] = '' . @@ -1258,16 +1257,17 @@ public static function showVeryShort($ID, $forcetab = '') && count($problem->users[CommonITILActor::REQUESTER]) ) { foreach ($problem->users[CommonITILActor::REQUESTER] as $d) { - if ($d["users_id"] > 0) { - $userdata = getUserName($d["users_id"], 2); - $name = "" . $userdata['name'] . ""; + $user = new User(); + if ($d["users_id"] > 0 && $user->getFromDB($d["users_id"])) { + $name = "" . htmlspecialchars($user->getName()) . ""; if ($viewusers) { $name = sprintf( __('%1$s %2$s'), $name, Html::showToolTip( - $userdata["comment"], - ['link' => $userdata["link"], + $user->getInfoCard(), + [ + 'link' => $user->getLinkURL(), 'display' => false ] ) diff --git a/src/Profile_User.php b/src/Profile_User.php index 77024bd8c20..977cc18f572 100644 --- a/src/Profile_User.php +++ b/src/Profile_User.php @@ -350,12 +350,11 @@ public static function showForEntity(Entity $entity) $entries = []; foreach ($iterator as $data) { - $username = formatUserName( + $username = formatUserLink( $data["id"], $data["name"], $data["realname"], $data["firstname"], - 1 ); if ($data["is_dynamic"] || $data["is_recursive"]) { $username = sprintf(__('%1$s %2$s'), $username, "("); @@ -537,12 +536,11 @@ public static function showForProfile(Profile $prof) if (!isset($entity_names[$data['entity']])) { $entity_names[$data['entity']] = Dropdown::getDropdownName('glpi_entities', $data['entity']); } - $username = formatUserName( + $username = formatUserLink( $data["id"], $data["name"], $data["realname"], $data["firstname"], - 1 ); if ($data["is_dynamic"] || $data["is_recursive"]) { $username = sprintf(__('%1$s %2$s'), $username, "("); diff --git a/src/Project.php b/src/Project.php index 3784bac187d..328b2f15396 100644 --- a/src/Project.php +++ b/src/Project.php @@ -1288,14 +1288,15 @@ public static function showShort($id, $options = []) // Fourth Column $fourth_col = ""; - if ($item->fields["users_id"]) { - $userdata = getUserName($item->fields["users_id"], 2); + $user = new User(); + if ($item->fields["users_id"] && $user->getFromDB($item->fields["users_id"])) { $fourth_col .= sprintf( __('%1$s %2$s'), - "" . $userdata['name'] . "", + "" . htmlspecialchars($user->getName()) . "", Html::showToolTip( - $userdata["comment"], - ['link' => $userdata["link"], + $user->getInfoCard(), + [ + 'link' => $user->getLinkURL(), 'display' => false ] ) diff --git a/src/Ticket.php b/src/Ticket.php index 43113aa7965..7b9c85ba75d 100644 --- a/src/Ticket.php +++ b/src/Ticket.php @@ -4677,9 +4677,8 @@ public static function showCentralList($start, $status = "process", bool $showgr ) { foreach ($job->users[CommonITILActor::REQUESTER] as $d) { if ($d["users_id"] > 0) { - $userdata = getUserName($d["users_id"], 2); $name = '' . - $userdata['name']; + htmlspecialchars(getUserName($d["users_id"])); $requesters[] = $name; } else { $requesters[] = '' . @@ -5082,15 +5081,16 @@ public static function showVeryShort($ID, $forcetab = '') && count($job->users[CommonITILActor::REQUESTER]) ) { foreach ($job->users[CommonITILActor::REQUESTER] as $d) { - if ($d["users_id"] > 0) { - $userdata = getUserName($d["users_id"], 2); - $name = "" . $userdata['name'] . ""; + $user = new User(); + if ($d["users_id"] > 0 && $user->getFromDB($d["users_id"])) { + $name = "" . htmlspecialchars($user->getName()) . ""; $name = sprintf( __('%1$s %2$s'), $name, Html::showToolTip( - $userdata["comment"], - ['link' => $userdata["link"], + $user->getInfoCard(), + [ + 'link' => $user->getLinkURL(), 'display' => false ] ) diff --git a/src/User.php b/src/User.php index b7fce79fcbc..49ad6d9d061 100644 --- a/src/User.php +++ b/src/User.php @@ -1807,6 +1807,38 @@ protected function computeFriendlyName() return ''; } + /** + * Get the user info card HTML. + * + * @return string + */ + public function getInfoCard(): string + { + $user_params = [ + 'id' => $this->getID(), + 'user_name' => $this->getName(), + 'email' => UserEmail::getDefaultForUser($this->getID()), + 'phone' => $this->fields["phone"], + 'phone2' => $this->fields["phone2"], + 'mobile' => $this->fields["mobile"], + 'locations_id' => $this->fields['locations_id'], + 'usertitles_id' => $this->fields['usertitles_id'], + 'usercategories_id' => $this->fields['usercategories_id'], + 'registration_number' => $this->fields['registration_number'], + ]; + + if (Session::haveRight('user', READ)) { + $user_params['login'] = $this->fields['name']; + } + if (!empty($this->fields["groups_id"])) { + $user_params['groups_id'] = $this->fields["groups_id"]; + } + return TemplateRenderer::getInstance()->render('components/user/info_card.html.twig', [ + 'user' => $user_params, + 'enable_anonymization' => Session::getCurrentInterface() == 'helpdesk', + ]); + } + /** * Function that tries to load the user membership from LDAP @@ -4814,18 +4846,27 @@ public static function dropdown($options = []) $default = ''; $valuesnames = []; + $tooltip_url = ''; + $tooltip_content = ''; + if (!$p['multiple']) { - /** @var array $user */ - $user = getUserName($p['value'], 2, true); + $user_name = ''; + + $user = new User(); + if ($p['value'] >= 0 && $user->getFromDB($p['value'])) { + $user_name = $user->getName(); + $tooltip_url = $user->getLinkURL(); + $tooltip_content = $user->getInfoCard(); + } if ($p['readonly']) { - return '' . $user["name"] . ''; + return '' . htmlspecialchars($user_name) . ''; } if ($p['value'] === 'myself') { $default = __("Myself"); } else if (!empty($p['value']) && ($p['value'] > 0)) { - $default = $user["name"]; + $default = $user_name; } else { if ($p['all']) { $default = __('All'); @@ -4837,9 +4878,7 @@ public static function dropdown($options = []) // get multiple values name foreach ($p['values'] as $value) { if (!empty($value) && ($value > 0)) { - /** @var array $user */ - $user = getUserName($value, 2); - $valuesnames[] = $user["name"]; + $valuesnames[] = getUserName($value); } else { unset($p['values'][$value]); } @@ -4905,13 +4944,13 @@ public static function dropdown($options = []) $comment_id = Html::cleanId("comment_" . $p['name'] . $p['rand']); $link_id = Html::cleanId("comment_link_" . $p["name"] . $p['rand']); if (!$view_users) { - $user["link"] = ''; - } else if (empty($user["link"])) { - $user["link"] = $CFG_GLPI['root_doc'] . "/front/user.php"; + $tooltip_url = ''; + } else if ($tooltip_url === '') { + $tooltip_url = $CFG_GLPI['root_doc'] . "/front/user.php"; } - if (empty($user['comment'])) { - $user['comment'] = Toolbox::ucfirst( + if ($tooltip_content === '') { + $tooltip_content = Toolbox::ucfirst( sprintf( __s('Show %1$s'), self::getTypeName(Session::getPluralNumber()) @@ -4936,10 +4975,10 @@ public static function dropdown($options = []) false ); - $icons .= Html::showToolTip($user["comment"], [ + $icons .= Html::showToolTip($tooltip_content, [ 'contentid' => $comment_id, 'display' => false, - 'link' => $user["link"], + 'link' => $tooltip_url, 'linkid' => $link_id ]); $icons .= ''; diff --git a/src/autoload/dbutils-aliases.php b/src/autoload/dbutils-aliases.php index 177508a67de..b04d3373eaf 100644 --- a/src/autoload/dbutils-aliases.php +++ b/src/autoload/dbutils-aliases.php @@ -404,24 +404,52 @@ function contructListFromTree($tree, $parent = 0) } - /** - * Format a user name + * Format a user name. * - *@param $ID integer ID of the user. - *@param $login string login of the user - *@param $realname string realname of the user - *@param $firstname string firstname of the user - *@param $link integer include link (only if $link==1) (default =0) - *@param $cut integer limit string length (0 = no limit) (default =0) - *@param $force_config boolean force order and id_visible to use common config (false by default) + * @param integer $ID ID of the user. + * @param string|null $login login of the user + * @param string|null $realname realname of the user + * @param string|null $firstname firstname of the user + * @param integer $link include link + * @param integer $cut IGNORED PARAMETER + * @param boolean $force_config force order and id_visible to use common config * - *@return string : formatted username - **/ + * @return string + * + * @since 11.0 `$link` parameter is deprecated + * @since 11.0 `$cut` parameter is ignored + */ function formatUserName($ID, $login, $realname, $firstname, $link = 0, $cut = 0, $force_config = false) { $dbu = new DbUtils(); - return $dbu->formatUserName($ID, $login, $realname, $firstname, $link, $cut, $force_config); + + if ((bool) $cut) { + trigger_error('`$cut` parameter is now ignored.', E_USER_WARNING); + } + + if ((bool) $link) { + Toolbox::deprecated('`$link` parameter is deprecated. Use `formatUserLink()` instead.'); + return $dbu->formatUserLink($ID, $login, $realname, $firstname); + } + + return $dbu->formatUserName($ID, $login, $realname, $firstname, 0, 0, $force_config); +} + +/** + * Format a user link. + * + * @param integer $id ID of the user. + * @param string|null $login login of the user + * @param string|null $realname realname of the user + * @param string|null $firstname firstname of the user + * + * @return string + */ +function formatUserLink(int $id, ?string $login, ?string $realname, ?string $firstname) +{ + $dbu = new DbUtils(); + return $dbu->formatUserLink($id, $login, $realname, $firstname); } @@ -434,13 +462,31 @@ function formatUserName($ID, $login, $realname, $firstname, $link = 0, $cut = 0, *@param $disable_anon bool disable anonymization of username. * *@return string[]|string : username string (realname if not empty and name if realname is empty). + * + * @since 11.0 `$link` parameter is deprecated. **/ function getUserName($ID, $link = 0, $disable_anon = false) { + if ($link != 0) { + Toolbox::deprecated('Usage of `$link` parameter is deprecated. See `DbUtils::getUserName()`.'); + } $dbu = new DbUtils(); return $dbu->getUserName($ID, $link, $disable_anon); } +/** + * Get link of the given user. + * + * @param int $id + * + * @return string + */ +function getUserLink(int $id): string +{ + $dbu = new DbUtils(); + return $dbu->getUserLink($id); +} + /** * Determine if an index exists in database