grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026. -------------------------------------------------------------------------- */ if (!defined('GLPI_ROOT')) { die("Sorry. You can't access this file directly"); } /** * DropdownTranslation Class * *@since version 0.85 **/ class DropdownTranslation extends CommonDBChild { static public $itemtype = 'itemtype'; static public $items_id = 'items_id'; public $dohistory = true; static $rightname = 'dropdown'; static function getTypeName($nb = 0) { return _n('Translation', 'Translations', $nb); } /** * Forbidden massives actions **/ function getForbiddenStandardMassiveAction() { $forbidden = parent::getForbiddenStandardMassiveAction(); $forbidden[] = 'update'; return $forbidden; } /** * @see CommonGLPI::getTabNameForItem() **/ function getTabNameForItem(CommonGLPI $item, $withtemplate=0) { if (self::canBeTranslated($item)) { $nb = 0; if ($_SESSION['glpishow_count_on_tabs']) { $nb = self::getNumberOfTranslationsForItem($item); } return self::createTabEntry(self::getTypeName(Session::getPluralNumber()), $nb); } return ''; } /** * @param $item CommonGLPI object * @param $tabnum (default 1) * @param $withtemplate (default 0) **/ static function displayTabContentForItem(CommonGLPI $item, $tabnum=1, $withtemplate=0) { if (DropdownTranslation::canBeTranslated($item)) { DropdownTranslation::showTranslations($item); } return true; } function prepareInputForAdd($input) { if ($this->checkBeforeAddorUpdate($input, true)) { return $input; } Session::addMessageAfterRedirect(__("There's already a translation for this field in this language"), true, ERROR); return false; } function prepareInputForUpdate($input) { if ($this->checkBeforeAddorUpdate($input,false)) { return $input; } Session::addMessageAfterRedirect(__("There's already a translation for this field in this language"), true, ERROR); return false; } function post_purgeItem() { if ($this->fields['field'] == 'name') { $translation = new self(); //If last translated field is deleted, then delete also completename record if ($this->getNumberOfTranslations($this->fields['itemtype'], $this->fields['items_id'], $this->fields['field'], $this->fields['language']) == 0) { if ($completenames_id = self::getTranslationID($this->fields['items_id'], $this->fields['itemtype'], 'completename', $this->fields['language'])) { $translation->delete(array('id' => $completenames_id)); } } // If only completename for sons : drop // foreach (getSonsOf(getTableForItemType($this->fields['itemtype']), // $this->fields['items_id']) as $son) { // // if ($this->getNumberOfTranslations($this->fields['itemtype'], $son, // 'name', $this->fields['language']) == 0) { // // $completenames_id = self::getTranslationID($son, $this->fields['itemtype'], // 'completename', // $this->fields['language']); // if ($completenames_id) { // $translation = new self(); // $translation->delete(array('id' => $completenames_id)); // } // } // } // Then update all sons records if (!isset($this->input['_no_completename'])) { $translation->generateCompletename($this->fields, false); } } return true; } function post_updateItem($history=1) { if (!isset($this->input['_no_completename'])) { $translation = new self(); $translation->generateCompletename($this->fields, false); } } function post_addItem() { // Add to session $_SESSION['glpi_dropdowntranslations'][$this->fields['itemtype']][$this->fields['field']] = $this->fields['field']; if (!isset($this->input['_no_completename'])) { $translation = new self(); $translation->generateCompletename($this->fields, true); } } /** * Return the number of translations for a field in a language * * @param itemtype * @param items_id * @param field * @param language * * @return the number of translations for this field **/ static function getNumberOfTranslations($itemtype, $items_id, $field, $language) { return countElementsInTable(getTableForItemType(__CLASS__), "`itemtype`='".$itemtype."' AND `items_id`='".$items_id."' AND `field`='".$field."' AND `language`='".$language."'"); } /** * Return the number of translations for an item * * @param item * * @return the number of translations for this item **/ static function getNumberOfTranslationsForItem($item) { return countElementsInTable(getTableForItemType(__CLASS__), "`itemtype`='".$item->getType()."' AND `items_id`='".$item->getID()."' AND `field` <> 'completename'"); } /** * Check if a field's translation can be added or updated * * @param $input translation's fields * @param $add boolean true if a transaltion must be added, false if updated (true by default) * * @return true if translation can be added/update, false otherwise **/ function checkBeforeAddorUpdate($input, $add=true) { global $DB; $number = $this->getNumberOfTranslations($input['itemtype'], $input['items_id'], $input['field'], $input['language']); if ($add) { return ($number == 0); } return ($number > 0); } /** * Generate completename associated with a tree dropdown * * @param $input array of user values * @param $add boolean true if translation is added, false if update (tgrue by default) * * @return nothing **/ function generateCompletename($input, $add=true) { 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 $completenames_id = self::getTranslationID($input['items_id'], $input['itemtype'], 'completename', $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() ; //Regenerate completename : look for item's ancestors $completename = ""; //Get ancestors as an array if ($item->fields[$foreignKey] != 0) { $completename = self::getTranslatedValue($item->fields[$foreignKey], $input['itemtype'], 'completename', $input['language']); } if ($completename != '') { $completename.= " > "; } $completename .= self::getTranslatedValue($item->getID(), $input['itemtype'], 'name', $input['language']); //Add or update completename for this language $translation = new self(); $tmp = array(); $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(array('id' => $completenames_id)); } else { $translation->update($tmp); } } else { if ($completename != $item->fields['completename']) { $translation->add($tmp); } } $query = "SELECT `id` FROM `".$item->getTable()."` WHERE `$foreignKey` = '".$item->getID()."'"; foreach ($DB->request($query) as $tmp) { $input2 = $input; $input2['items_id'] = $tmp['id']; $this->generateCompletename($input2, $add); } } } /** * Display all translated field for a dropdown * * @param $item a Dropdown item * * @return true; **/ static function showTranslations(CommonDropdown $item) { global $DB, $CFG_GLPI; $rand = mt_rand(); $canedit = $item->can($item->getID(), UPDATE); if ($canedit) { echo "
\n"; echo "\n"; echo "
". "". __('Add a new translation'). "

"; } $query = "SELECT * FROM `".getTableForItemType(__CLASS__)."` WHERE `itemtype` = '".get_class($item)."' AND `items_id` = '".$item->getID()."' AND `field` <> 'completename' ORDER BY `language` ASC"; $results = $DB->query($query); if ($DB->numrows($results)) { if ($canedit) { Html::openMassiveActionsForm('mass'.__CLASS__.$rand); $massiveactionparams = array('container' => 'mass'.__CLASS__.$rand); Html::showMassiveActions($massiveactionparams); } echo "
"; echo ""; echo ""; if ($canedit) { echo ""; } echo ""; echo ""; echo ""; while ($data = $DB->fetch_array($results)) { $onhover = ''; if ($canedit) { $onhover = "style='cursor:pointer' onClick=\"viewEditTranslation".$data['itemtype'].$data['id']."$rand();\""; } echo ""; if ($canedit) { echo ""; } echo ""; echo ""; echo ""; } echo "
".__("List of translations")."
"; Html::checkAllAsCheckbox('mass'.__CLASS__.$rand); echo "".__("Language")."".__("Field")."".__("Value")."
"; Html::showMassiveActionCheckBox(__CLASS__, $data["id"]); echo ""; if ($canedit) { echo "\n\n"; } echo Dropdown::getLanguageName($data['language']); echo ""; $searchOption = $item->getSearchOptionByField('field', $data['field']); echo $searchOption['name']."".$data['value']."
"; if ($canedit) { $massiveactionparams['ontop'] = false; Html::showMassiveActions($massiveactionparams); Html::closeForm(); } } else { echo ""; echo "
" . __("No translation found")."
"; } return true; } /** * Display translation form * * @param $ID field (default -1) * @param $options array */ function showForm($ID=-1, $options=array()) { global $CFG_GLPI; if (isset($options['parent']) && !empty($options['parent'])) { $item = $options['parent']; } if ($ID > 0) { $this->check($ID, READ); } else { $options['itemtype'] = get_class($item); $options['items_id'] = $item->getID(); // Create item $this->check(-1 , CREATE, $options); } $rand = mt_rand(); $this->showFormHeader($options); echo ""; echo "".__('Language').""; echo ""; echo ""; echo ""; if ($ID > 0) { echo ""; echo Dropdown::getLanguageName($this->fields['language']); } else { $rand = Dropdown::showLanguages("language", array('display_none' => false, 'value' => $_SESSION['glpilanguage'])); $params = array('language' => '__VALUE__', 'itemtype' => get_class($item), 'items_id' => $item->getID()); Ajax::updateItemOnSelectEvent("dropdown_language$rand", "span_fields", $CFG_GLPI["root_doc"]."/ajax/updateTranslationFields.php", $params); } echo " "; echo "".__('Field').""; echo ""; if ($ID > 0) { echo ""; $searchOption = $item->getSearchOptionByField('field', $this->fields['field']); echo $searchOption['name']; } else { echo ""; self::dropdownFields($item, $_SESSION['glpilanguage']); echo ""; } echo ""; echo "".__('Value').""; echo "fields['value']."\" size='50'>"; echo ""; echo "\n"; $this->showFormButtons($options); return true; } /** * Display a dropdown with fields that can be translated for an itemtype * * @param $item a Dropdown item * @param $language language to look for translations (default '') * @param $value field which must be selected by default (default '') * * @return the dropdown's random identifier **/ static function dropdownFields(CommonDBTM $item, $language='', $value='') { global $DB; $options = array(); foreach (Search::getOptions(get_class($item)) as $id => $field) { //Can only translate name, and fields whose datatype is text or string if (isset ($field['field']) && ($field['field'] == 'name') && ($field['table'] == getTableForItemType(get_class($item))) || (isset($field['datatype']) && in_array($field['datatype'], array('text', 'string')))) { $options[$field['field']] = $field['name']; } } $used = array(); if (!empty($options)) { $query = "SELECT `field` FROM `".self::getTable()."` WHERE `itemtype`='".get_class($item)."' AND `items_id` = '".$item->getID()."' AND `language` = '$language'"; $results = $DB->query($query); if ($DB->numrows($results) > 0) { while ($data = $DB->fetch_array($results)) { $used[$data['field']] = $data['field']; } } } //$used = array(); return Dropdown::showFromArray('field', $options, array('value' => $value, 'used' => $used)); } /** * Get translated value for a field in a particular language * * @param $ID dropdown item's id * @param $itemtype dropdown itemtype * @param $field the field to look for (default 'name') * @param $language get translation for this language * @param $value default value for the field (default '') * * @return the translated value of the value in the default language **/ static function getTranslatedValue($ID, $itemtype, $field='name', $language, $value='') { global $DB; //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)) { return $value; } //ID > 0 : dropdown item might be translated ! if ($ID > 0) { //There's at least one translation for this itemtype if (self::hasItemtypeATranslation($itemtype)) { $query = "SELECT `value` FROM `".self::getTable()."` WHERE `itemtype` = '".$itemtype."' AND `items_id` = '".$ID."' AND `field` = '$field' AND `language` = '$language'"; $result_translations = $DB->query($query); //The field is already translated in this language if ($DB->numrows($result_translations)) { return $DB->result($result_translations, 0, 'value'); } } //Get the value coming from the dropdown table $query = "SELECT `$field` FROM `".getTableForItemType($itemtype)."` WHERE `id` = '$ID'"; $results = $DB->query($query); if ($DB->numrows($results)) { return $DB->result($results, 0, $field); } } return ""; } /** * Get the id of a translated string * * @param $ID item id * @param $itemtype item type * @param $field the field for which the translation is needed * @param $language the target language * * @return the row id or 0 if not translation found **/ static function getTranslationID($ID, $itemtype, $field, $language) { global $DB; $query = "SELECT `id` FROM `".self::getTable()."` WHERE `itemtype` = '".$itemtype."' AND `items_id` = '".$ID."' AND `language` = '$language' AND `field` = '$field'"; $results = $DB->query($query); if ($DB->numrows($results)) { return $DB->result($results, 0, 'id'); } return 0; } /** * Check if an item can be translated * It be translated if translation if globally on and item is an instance of CommonDropdown * or CommonTreeDropdown and if translation is enabled for this class * * @param $item the item to check * * @return true if item can be translated, false otherwise **/ static function canBeTranslated(CommonGLPI $item) { return (self::isDropdownTranslationActive() && (($item instanceof CommonDropdown) && $item->maybeTranslated())); } /** * Is dropdown item translation functionnality active * * @return true if active, false if not **/ static function isDropdownTranslationActive() { global $CFG_GLPI; return $CFG_GLPI['translate_dropdowns']; } /** * Get a translation for a value * * @param $itemtype itemtype * @param $field field to query * @param $value value to translate * * @return the value translated if a translation is available, or the same value if not **/ static function getTranslationByName($itemtype, $field, $value) { global $DB; $query = "SELECT `id` FROM `".getTableForItemType($itemtype)."` WHERE `$field` = '".Toolbox::addslashes_deep($value)."'"; $results = $DB->query($query); if ($DB->numrows($results) > 0) { return self::getTranslatedValue($DB->result($results, 0, 'id'), $itemtype, $field, $_SESSION['glpilanguage'], $value); } return $value; } /** * Get translations for an item * * @param $itemtype itemtype * @param $field the field for which the translation is needed * @param $items_id item ID * * @return the value translated if a translation is available, or the same value if not **/ static function getTranslationsForAnItem($itemtype, $items_id, $field) { global $DB; $query = "SELECT * FROM `".self::getTable()."` WHERE `itemtype` = '$itemtype' AND `items_id` = '$items_id' AND `field` = '$field'"; $data = array(); foreach ($DB->request($query) as $tmp) { $data[$tmp['id']] = $tmp; } return $data; } /** * Regenerate all completename translations for an item * * @param $itemtype itemtype * @param $items_id item ID * * @return the value translated if a translation is available, or the same value if not **/ static function regenerateAllCompletenameTranslationsFor($itemtype, $items_id) { foreach (self::getTranslationsForAnItem($itemtype, $items_id, 'completename') as $data) { $dt = new DropdownTranslation(); $dt->generateCompletename($data, false); } } /** * Check if there's at least one translation for this itemtype * * @param $itemtype itemtype to check * * @return true if there's at least one translation, otherwise false **/ static function hasItemtypeATranslation($itemtype) { return countElementsInTable(self::getTable(), "`itemtype`='$itemtype'"); } /** * Get available translations for a language * * @param $language language * * @return array of table / field translated item **/ static function getAvailableTranslations($language) { global $DB; $tab = array(); if (self::isDropdownTranslationActive()) { $query = "SELECT DISTINCT `itemtype`, `field` FROM `".self::getTable()."` WHERE `language` = '$language'"; foreach ($DB->request($query) as $data) { $tab[$data['itemtype']][$data['field']] = $data['field']; } } return $tab; } } ?>