From 992a33835a1940570acee1effaa34b2c2b0cbf2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Tue, 24 Oct 2023 16:23:00 +0200 Subject: [PATCH] Fix completename translated value fixes #15801 --- src/DropdownTranslation.php | 118 ++++++++++++----------- tests/functional/DropdownTranslation.php | 105 ++++++++++++++++++++ 2 files changed, 166 insertions(+), 57 deletions(-) create mode 100644 tests/functional/DropdownTranslation.php diff --git a/src/DropdownTranslation.php b/src/DropdownTranslation.php index 14f50bdbffd1..18914a036aee 100644 --- a/src/DropdownTranslation.php +++ b/src/DropdownTranslation.php @@ -279,10 +279,12 @@ public function generateCompletename($input, $add = true) { /** @var \DBmysql $DB */ global $DB; - // Force completename translated : used for the first translation - $_SESSION['glpi_dropdowntranslations'][$input['itemtype']]['completename'] = 'completename'; - //If there's already a completename for this language, get it's ID, otherwise 0 + if (!is_a($input['itemtype'], CommonTreeDropdown::class, true)) { + return; // `completename` is used only for tree dropdowns + } + + //If there's already a completename for this language, get it's ID, otherwise 0 $completenames_id = self::getTranslationID( $input['items_id'], $input['itemtype'], @@ -290,73 +292,71 @@ public function generateCompletename($input, $add = true) $input['language'] ); $item = new $input['itemtype'](); - //Completename is used only for tree dropdowns ! - if ( - $item instanceof CommonTreeDropdown - && isset($input['language']) - ) { - $item->getFromDB($input['items_id']); - $foreignKey = $item->getForeignKeyField(); + $item->getFromDB($input['items_id']); + $foreignKey = $item->getForeignKeyField(); - //Regenerate completename : look for item's ancestors - $completename = ""; + $completename = ""; - //Get ancestors as an array - - if ($item->fields[$foreignKey] != 0) { + if ($item->fields[$foreignKey] != 0) { + // Get translated complename from parent + $parent = new $input['itemtype'](); + if ($parent->getFromDB($item->fields[$foreignKey])) { $completename = self::getTranslatedValue( - $item->fields[$foreignKey], + $parent->getID(), $input['itemtype'], 'completename', - $input['language'] + $input['language'], + $parent->fields['completename'] ); - } - if ($completename != '') { + // Append complename separator $completename .= " > "; } - $completename .= self::getTranslatedValue( - $item->getID(), - $input['itemtype'], - 'name', - $input['language'] - ); + } - //Add or update completename for this language - $translation = new self(); - $tmp = []; - $tmp['items_id'] = $input['items_id']; - $tmp['itemtype'] = $input['itemtype']; - $tmp['field'] = 'completename'; - $tmp['value'] = addslashes($completename); - $tmp['language'] = $input['language']; - $tmp['_no_completename'] = true; - if ($completenames_id) { - $tmp['id'] = $completenames_id; - if ($completename === $item->fields['completename']) { - $translation->delete(['id' => $completenames_id]); - } else { - $translation->update($tmp); - } + // Append translated name of item + $completename .= self::getTranslatedValue( + $item->getID(), + $input['itemtype'], + 'name', + $input['language'], + $item->fields['name'] + ); + + // Add or update completename for this language + $translation = new self(); + $tmp = []; + $tmp['items_id'] = $input['items_id']; + $tmp['itemtype'] = $input['itemtype']; + $tmp['field'] = 'completename'; + $tmp['value'] = addslashes($completename); + $tmp['language'] = $input['language']; + $tmp['_no_completename'] = true; + if ($completenames_id) { + $tmp['id'] = $completenames_id; + if ($completename === $item->fields['completename']) { + $translation->delete(['id' => $completenames_id]); } else { - if ($completename != $item->fields['completename']) { - $translation->add($tmp); - } + $translation->update($tmp); } + } else { + if ($completename != $item->fields['completename']) { + $translation->add($tmp); + } + } - $iterator = $DB->request([ - 'SELECT' => ['id'], - 'FROM' => $item->getTable(), - 'WHERE' => [ - $foreignKey => $item->getID() - ] - ]); + $iterator = $DB->request([ + 'SELECT' => ['id'], + 'FROM' => $item->getTable(), + 'WHERE' => [ + $foreignKey => $item->getID() + ] + ]); - foreach ($iterator as $tmp) { - $input2 = $input; - $input2['items_id'] = $tmp['id']; - $this->generateCompletename($input2, $add); - } + foreach ($iterator as $tmp) { + $input2 = $input; + $input2['items_id'] = $tmp['id']; + $this->generateCompletename($input2, $add); } } @@ -674,12 +674,16 @@ public static function getTranslatedValue($ID, $itemtype, $field = 'name', $lang $language = $_SESSION['glpilanguage']; } + $translated_fields = $language === $_SESSION['glpilanguage'] + ? $_SESSION['glpi_dropdowntranslations'] + : DropdownTranslation::getAvailableTranslations($language); + //If dropdown translation is globally off, or if this itemtype cannot be translated, //then original value should be returned $item = new $itemtype(); if ( !$ID - || !Session::haveTranslations($itemtype, $field) + || !isset($translated_fields[$itemtype][$field]) ) { return $value; } diff --git a/tests/functional/DropdownTranslation.php b/tests/functional/DropdownTranslation.php new file mode 100644 index 000000000000..6f9a3dfc4236 --- /dev/null +++ b/tests/functional/DropdownTranslation.php @@ -0,0 +1,105 @@ +. + * + * --------------------------------------------------------------------- + */ + +namespace tests\units; + +use DbTestCase; +use Generator; +use Glpi\Socket; +use Glpi\Toolbox\Sanitizer; +use Session; +use State; + +class DropdownTranslation extends DbTestCase +{ + /** + * @return void + * @see https://github.com/glpi-project/glpi/issues/15801 + */ + public function testCompleteNameGeneration() + { + global $CFG_GLPI; + $CFG_GLPI['translate_dropdowns'] = 1; + + $this->login(); + $itilcategory = new \ITILCategory(); + $this->integer($itilcategory->add([ + 'name' => 'test', + ]))->isGreaterThan(0); + + $this->string(\DropdownTranslation::getTranslatedValue($itilcategory->getID(), 'ITILCategory', 'completename')) + ->isEqualTo(''); + + $trans = new \DropdownTranslation(); + $this->integer($trans->add([ + 'language' => 'fr_FR', + 'itemtype' => 'ITILCategory', + 'items_id' => $itilcategory->getID(), + 'field' => 'name', + 'value' => 'test_FR', + ]))->isGreaterThan(0); + $_SESSION['glpilanguage'] = 'fr_FR'; + $_SESSION['glpi_dropdowntranslations'] = \DropdownTranslation::getAvailableTranslations($_SESSION["glpilanguage"]); + + $this->string(\DropdownTranslation::getTranslatedValue($itilcategory->getID(), 'ITILCategory', 'name')) + ->isEqualTo('test_FR'); + $this->string(\DropdownTranslation::getTranslatedValue($itilcategory->getID(), 'ITILCategory', 'completename')) + ->isEqualTo('test_FR'); + + $_SESSION['glpilanguage'] = 'en_GB'; + $_SESSION['glpi_dropdowntranslations'] = \DropdownTranslation::getAvailableTranslations($_SESSION["glpilanguage"]); + + $this->string(\DropdownTranslation::getTranslatedValue($itilcategory->getID(), 'ITILCategory', 'completename')) + ->isEqualTo(''); + + $this->integer($trans->add([ + 'language' => 'fr_FR', + 'itemtype' => 'ITILCategory', + 'items_id' => $itilcategory->getID(), + 'field' => 'comment', + 'value' => 'comment_FR', + ]))->isGreaterThan(0); + + $_SESSION['glpilanguage'] = 'fr_FR'; + + $_SESSION['glpi_dropdowntranslations'] = \DropdownTranslation::getAvailableTranslations($_SESSION["glpilanguage"]); + $this->string(\DropdownTranslation::getTranslatedValue($itilcategory->getID(), 'ITILCategory', 'name')) + ->isEqualTo('test_FR'); + $this->string(\DropdownTranslation::getTranslatedValue($itilcategory->getID(), 'ITILCategory', 'completename')) + ->isEqualTo('test_FR'); + $this->string(\DropdownTranslation::getTranslatedValue($itilcategory->getID(), 'ITILCategory', 'comment')) + ->isEqualTo('comment_FR'); + } +}