1<?php 2 3/* Copyright (c) 1998-2014 ILIAS open source, Extended GPL, see docs/LICENSE */ 4 5/** 6 * Class handles translation mode for an object. 7 * 8 * Objects may not use any translations at all 9 * - use translations for title/description only or 10 * - use translation for (the page editing) content, too. 11 * 12 * Currently supported by container objects and ILIAS learning modules. 13 * 14 * Content master lang vs. default language 15 * - If no translation mode for the content is active no master lang will be 16 * set and no record in table obj_content_master_lng will be saved. For the 17 * title/descriptions the default will be marked by field lang_default in table 18 * object_translation. 19 * - If translation for content is activated a master language must be set (since 20 * concent may already exist the language of this content is defined through 21 * setting the master language (in obj_content_master_lng). Modules that use 22 * this mode will not get informed about this, so they can not internally 23 * assign existing content to the master lang 24 * 25 * @author Alex Killing <alex.killing@gmx.de> 26 * @version $Id$ 27 * @ingroup ServicesObject 28 */ 29class ilMultilingualism 30{ 31 /** 32 * @var ilLanguage 33 */ 34 protected $lng; 35 36 protected $db; 37 protected $obj_id; 38 protected $languages = array(); 39 protected $type = ""; 40 protected static $instances = array(); 41 42 /** 43 * Constructor 44 * 45 * @param int $a_obj_id object id 46 * @param string $a_type id type 47 * @throws ilObjectException 48 */ 49 private function __construct($a_obj_id, $a_type) 50 { 51 global $DIC; 52 53 $this->lng = $DIC->language(); 54 $ilDB = $DIC->database(); 55 56 $this->db = $ilDB; 57 58 $this->setObjId($a_obj_id); 59 $this->setType($a_type); 60 61 if ($this->getObjId() <= 0) { 62 include_once("./Services/Object/exceptions/class.ilObjectException.php"); 63 throw new ilObjectException("ilObjectTranslation: No object ID passed."); 64 } 65 66 $this->read(); 67 } 68 69 /** 70 * Get instance 71 * 72 * @param integer $a_obj_id (repository) object id 73 * @return ilMultilingualism translation object 74 */ 75 public static function getInstance($a_obj_id, $a_type) 76 { 77 if (!isset(self::$instances[$a_type][$a_obj_id])) { 78 self::$instances[$a_type][$a_obj_id] = new self($a_obj_id, $a_type); 79 } 80 81 return self::$instances[$a_type][$a_obj_id]; 82 } 83 84 85 /** 86 * Set object id 87 * 88 * @param int $a_val object id 89 */ 90 public function setObjId($a_val) 91 { 92 $this->obj_id = $a_val; 93 } 94 95 /** 96 * Get object id 97 * 98 * @return int object id 99 */ 100 public function getObjId() 101 { 102 return $this->obj_id; 103 } 104 105 /** 106 * Set languages 107 * 108 * @param array $a_val array of language codes 109 */ 110 public function setLanguages(array $a_val) 111 { 112 $this->languages = $a_val; 113 } 114 115 /** 116 * Get languages 117 * 118 * @return array array of language codes 119 */ 120 public function getLanguages() 121 { 122 return $this->languages; 123 } 124 125 /** 126 * @return string 127 */ 128 public function getType() 129 { 130 return $this->type; 131 } 132 133 /** 134 * @param string $type 135 */ 136 public function setType($type) 137 { 138 $this->type = $type; 139 } 140 141 public function getDefaultLanguage() 142 { 143 $lng = $this->lng; 144 145 foreach ($this->languages as $k => $v) { 146 if ($v["lang_default"]) { 147 return $k; 148 } 149 } 150 151 return $lng->getDefaultLanguage(); 152 } 153 154 155 /** 156 * Add language 157 * 158 * @param string $a_lang language 159 * @param string $a_title title 160 * @param string $a_description description 161 * @param bool $a_default default language? 162 */ 163 public function addLanguage($a_lang, $a_title, $a_description, $a_default, $a_force = false) 164 { 165 if ($a_lang != "" && (!isset($this->languages[$a_lang]) || $a_force)) { 166 if ($a_default) { 167 foreach ($this->languages as $k => $l) { 168 $this->languages[$k]["lang_default"] = false; 169 } 170 } 171 $this->languages[$a_lang] = array("lang_code" => $a_lang, "lang_default" => $a_default, 172 "title" => $a_title, "description" => $a_description); 173 } 174 } 175 176 /** 177 * Get default title 178 * 179 * @return string title of default language 180 */ 181 public function getDefaultTitle() 182 { 183 foreach ($this->languages as $l) { 184 if ($l["lang_default"]) { 185 return $l["title"]; 186 } 187 } 188 return ""; 189 } 190 191 /** 192 * Set default title 193 * 194 * @param string $a_title title 195 */ 196 public function setDefaultTitle($a_title) 197 { 198 foreach ($this->languages as $k => $l) { 199 if ($l["lang_default"]) { 200 $this->languages[$k]["title"] = $a_title; 201 } 202 } 203 } 204 205 /** 206 * Get default description 207 * 208 * @return string description of default language 209 */ 210 public function getDefaultDescription() 211 { 212 foreach ($this->languages as $l) { 213 if ($l["lang_default"]) { 214 return $l["description"]; 215 } 216 } 217 return ""; 218 } 219 220 /** 221 * Set default description 222 * 223 * @param string $a_description description 224 */ 225 public function setDefaultDescription($a_description) 226 { 227 foreach ($this->languages as $k => $l) { 228 if ($l["lang_default"]) { 229 $this->languages[$k]["description"] = $a_description; 230 } 231 } 232 } 233 234 235 /** 236 * Remove language 237 * 238 * @param string $a_lang language code 239 */ 240 public function removeLanguage($a_lang) 241 { 242 if ($a_lang != $this->getDefaultLanguage()) { 243 unset($this->languages[$a_lang]); 244 } 245 } 246 247 /** 248 * Read 249 */ 250 public function read() 251 { 252 $this->setLanguages(array()); 253 $set = $this->db->query( 254 "SELECT * FROM il_translations " . 255 " WHERE id = " . $this->db->quote($this->getObjId(), "integer") . 256 " AND id_type = " . $this->db->quote($this->getType(), "text") 257 ); 258 while ($rec = $this->db->fetchAssoc($set)) { 259 $this->addLanguage($rec["lang_code"], $rec["title"], $rec["description"], $rec["lang_default"]); 260 } 261 } 262 263 /** 264 * Delete 265 */ 266 public function delete() 267 { 268 $this->db->manipulate( 269 "DELETE FROM il_translations " . 270 " WHERE id = " . $this->db->quote($this->getObjId(), "integer") . 271 " AND id_type = " . $this->db->quote($this->getType(), "text") 272 ); 273 } 274 275 /** 276 * Save 277 */ 278 public function save() 279 { 280 $this->delete(); 281 282 foreach ($this->getLanguages() as $l => $trans) { 283 $this->db->manipulate($t = "INSERT INTO il_translations " . 284 "(id, id_type, title, description, lang_code, lang_default) VALUES (" . 285 $this->db->quote($this->getObjId(), "integer") . "," . 286 $this->db->quote($this->getType(), "text") . "," . 287 $this->db->quote($trans["title"], "text") . "," . 288 $this->db->quote($trans["description"], "text") . "," . 289 $this->db->quote($l, "text") . "," . 290 $this->db->quote($trans["lang_default"], "integer") . 291 ")"); 292 } 293 } 294 295 /** 296 * Copy multilinguality settings 297 * 298 * @param string $a_type parent object type 299 * @param int $a_obj_id parent object id 300 * @return ilObjectTranslation target multilang object 301 */ 302 public function copy($a_obj_id) 303 { 304 $target_ml = new self($a_obj_id, $this->getType()); 305 $target_ml->setLanguages($this->getLanguages()); 306 $target_ml->save(); 307 return $target_ml; 308 } 309 310 311 312 /** 313 * Export 314 * @param ilXmlWriter $writer 315 * @return ilXmlWriter 316 */ 317 public function toXml(ilXmlWriter $writer) 318 { 319 $writer->xmlStartTag('translations'); 320 321 foreach ($this->getLanguages() as $k => $v) { 322 $writer->xmlStartTag('translation', array('language' => $k, 'default' => $v['lang_default'] ? 1 : 0)); 323 $writer->xmlElement('title', array(), $v['title']); 324 $writer->xmlElement('description', array(), $v['description']); 325 $writer->xmlEndTag('translation'); 326 } 327 $writer->xmlEndTag('translations'); 328 329 return $writer; 330 } 331 332 /** 333 * xml import 334 * 335 * @param SimpleXMLElement $root 336 * @return mixed 337 */ 338 public function fromXML(SimpleXMLElement $root) 339 { 340 if ($root->translations) { 341 $root = $root->translations; 342 } 343 344 foreach ($root->translation as $trans) { 345 $this->addLanguage( 346 (string) trim($trans["language"]), 347 (string) trim($trans->title), 348 (string) trim($trans->description), 349 (int) $trans["default"] != 0?true:false 350 ); 351 } 352 } 353} 354